| <!DOCTYPE html> |
| <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"> |
| <style> |
| html { |
| font-family: Ahem; |
| font-size: 10px; |
| } |
| #testArea { |
| height: 6000px; |
| width: 500px; |
| background: red; |
| } |
| #target { |
| position: fixed; |
| left: 10px; |
| top: 10px; |
| width: 40px; |
| height: 40px; |
| background: yellow; |
| } |
| #frame { |
| display: block; |
| width: 100px; |
| height: 100px; |
| } |
| </style> |
| <div id=testArea> |
| <div id=target></div> |
| <br> |
| <br> |
| <br> |
| <iframe id=frame srcdoc='<div id="innerContent" style="width: 75px; height: 50px; background: blue"><input></input<div>'></iframe> |
| </div> |
| <p id="description"></p> |
| <div id="console"></div> |
| <script src="../../resources/js-test.js"></script> |
| <script> |
| |
| setPrintTestResultsLazily(); |
| if (window.internals) { |
| internals.settings.setViewportEnabled(true); |
| internals.settings.setMockScrollbarsEnabled(true); |
| } |
| |
| description("Ensure hit test cache works in correct scenarios of scrolling, dom and style changes."); |
| |
| function hitTestCountDelta() |
| { |
| var lastCount = 0; |
| if ('lastHitTestCount' in document) |
| lastCount = document.lastHitTestCount; |
| var newCount = internals.hitTestCount(document); |
| document.lastHitTestCount = newCount; |
| return newCount - lastCount; |
| } |
| |
| function hitTestCacheHitsDelta() |
| { |
| var lastCount = 0; |
| if ('lastHitTestCacheHits' in document) |
| lastCount = document.lastHitTestCacheHits; |
| var newCount = internals.hitTestCacheHits(document); |
| document.lastHitTestCacheHits = newCount; |
| return newCount - lastCount; |
| } |
| |
| function clearCounts() |
| { |
| internals.clearHitTestCache(document); |
| document.lastHitTestCount = internals.hitTestCount(document); |
| document.lastHitTestCacheHits = internals.hitTestCacheHits(document); |
| } |
| |
| function checkElementAt(x, y, expectedHitTestCount, expectedHitTestCacheCount) |
| { |
| shouldBe("document.elementFromPoint(" + x + "," + y + ")", |
| "internals.clearHitTestCache(document); internals.elementFromPoint(document, " + x + ", " + y + ", false, false)"); |
| shouldBeEqualToNumber("hitTestCountDelta()", expectedHitTestCount); |
| shouldBeEqualToNumber("hitTestCacheHitsDelta()", expectedHitTestCacheCount); |
| } |
| |
| function checkChildFrameElementAt(x, y) |
| { |
| shouldBe("internals.elementFromPoint(document, " + x + ", " + y + ", false, true)", |
| "internals.clearHitTestCache(document); internals.elementFromPoint(document, " + x + ", " + y + ", false, true)"); |
| } |
| |
| onload = function() { |
| clearCounts(); |
| debug('Hit test main div'); |
| debug('---------------------'); |
| |
| // Verify that the cache is working; the second call |
| // to checkElementAt should end up using the cache from the first call. |
| checkElementAt(60, 60, 2, 0); |
| checkElementAt(60, 60, 2, 1); |
| |
| debug(''); |
| debug('Hit test fixed div after scroll'); |
| debug('---------------------'); |
| |
| // Verify that after scroll the hit cache isn't used but the |
| // correct element is returned for the fixed position elements. |
| document.lastHitNode = document.elementFromPoint(12, 12); |
| clearCounts(); |
| checkElementAt(12, 12, 2, 0); |
| window.scrollTo(0, 50); |
| checkElementAt(12, 12, 2, 0); |
| shouldBe("document.lastHitNode", "document.elementFromPoint(12, 12)"); |
| |
| debug(''); |
| debug('Hit test after main frame scroll'); |
| debug('---------------------'); |
| |
| // Verify that after scroll the hit cache isn't used but |
| // the same element is returned for the adjusted co-ordinate. |
| window.scrollTo(0, 0); |
| document.lastHitNode = document.elementFromPoint(60, 75); |
| clearCounts(); |
| checkElementAt(60, 75, 2, 0); |
| window.scrollTo(0, 50); |
| checkElementAt(60, 25, 2, 0); |
| shouldBe("document.lastHitNode", "document.elementFromPoint(60, 25)"); |
| |
| clearCounts(); |
| debug(''); |
| debug('Hit test after style change'); |
| debug('---------------------'); |
| checkElementAt(12, 12, 2, 0); |
| document.getElementById('target').style.background = "blue"; |
| checkElementAt(12, 12, 2, 0); |
| |
| clearCounts(); |
| debug(''); |
| debug('Hit test after dom manipulation'); |
| debug('---------------------'); |
| checkElementAt(12, 12, 2, 0); |
| document.getElementById('target').setAttribute("foo", "bar"); |
| checkElementAt(12, 12, 2, 0); |
| |
| clearCounts(); |
| document.getElementById('target').style.display = "none"; |
| window.scrollTo(0, 0); |
| debug(''); |
| debug('Hit test iframe; ensuring child co-ordinates are not in parent cache'); |
| debug('---------------------'); |
| checkChildFrameElementAt(25, 80); |
| checkChildFrameElementAt(15, 40); |
| |
| finishJSTest(); |
| } |
| </script> |