| <!DOCTYPE html> |
| |
| <script src="../../resources/js-test.js"></script> |
| <script src="../dom/resources/event-sender-util.js"></script> |
| <script> |
| description('This test checks if contextmenu event target is correct when handled at the document level and in the' + |
| ' presence of pinch-zoom. To test manually, first pinch-zoom into the page, scroll away from the origin' + |
| ' and then then press the menu key. There are three cases to check: nothing focused (the context menu is' + |
| ' expected to appear in the top left of the viewport), click on the orange box to focus it then use the' + |
| ' menu key, and select some text in the box and use the menu key. Note: on Mac there is no menu key.'); |
| |
| // Visual Viewport will be at the bottom right quadrant of the page. |
| var visualViewportContentX = 400; |
| var visualViewportContentY = 300; |
| var scale = 2; |
| |
| // Should match the static const in EventHandler::ShowNonLocatedContextMenu |
| var kContextMenuMargin = 1; |
| |
| var expectedX; |
| var expectedY; |
| var expectedScreenX; |
| var expectedScreenY; |
| var event; |
| |
| var anchor; |
| var textbox; |
| |
| function handleContextMenuNoFocus(e) { |
| event = e; |
| expectedX = kContextMenuMargin + visualViewportContentX; |
| expectedY = kContextMenuMargin + visualViewportContentY; |
| expectedScreenX = kContextMenuMargin * scale; |
| expectedScreenY = kContextMenuMargin * scale; |
| shouldBe('event.clientX', 'expectedX'); |
| shouldBe('event.clientY', 'expectedY'); |
| shouldBe('event.screenX', 'expectedScreenX'); |
| shouldBe('event.screenY', 'expectedScreenY'); |
| e.preventDefault(); |
| } |
| |
| function handleContextMenuFocus(e) { |
| event = e; |
| expectedX = anchor.offsetLeft + anchor.offsetWidth/2; |
| expectedY = anchor.offsetTop + anchor.offsetHeight/2; |
| expectedScreenX = (expectedX - visualViewportContentX) * scale; |
| expectedScreenY = (expectedY - visualViewportContentY) * scale; |
| shouldBe('event.clientX', 'expectedX'); |
| shouldBe('event.clientY', 'expectedY'); |
| shouldBe('event.screenX', 'expectedScreenX'); |
| shouldBe('event.screenY', 'expectedScreenY'); |
| e.preventDefault(); |
| } |
| |
| function handleContextMenuEditable(e) { |
| event = e; |
| |
| var rangeRect = window.getSelection().getRangeAt(0).getBoundingClientRect(); |
| expectedX = rangeRect.left; |
| |
| // EventHandler::ShowNonLocatedContextMenu takes the midpoint of the y values |
| // so that the context menu doesn't end up in the next line on multiline |
| // selections. |
| expectedY = Math.floor((rangeRect.bottom + rangeRect.top) / 2); |
| |
| expectedScreenX = (expectedX - visualViewportContentX) * scale; |
| expectedScreenY = (expectedY - visualViewportContentY) * scale; |
| |
| shouldBe('event.clientX', 'expectedX'); |
| shouldBe('event.clientY', 'expectedY'); |
| shouldBe('event.screenX', 'expectedScreenX'); |
| shouldBe('event.screenY', 'expectedScreenY'); |
| e.preventDefault(); |
| } |
| |
| var runTest = function() { |
| internals.setPageScaleFactor(scale); |
| |
| // Position the visual viewport. |
| eventSender.gestureScrollBegin(0, 0); |
| |
| // Start from visual viewport offset (0, 0). |
| eventSender.gestureScrollUpdate(-visualViewportContentX*scale, |
| -visualViewportContentY*scale); |
| eventSender.gestureScrollEnd(0, 0); |
| |
| anchor = document.getElementById("anchor"); |
| |
| // With nothing focused, the context menu should appear in the top left |
| // corner of the viewport. |
| document.addEventListener('contextmenu', handleContextMenuNoFocus, true); |
| eventSender.keyDown("ContextMenu"); |
| eventSender.keyDown("Escape"); |
| document.removeEventListener('contextmenu', handleContextMenuNoFocus, true); |
| |
| // Focus the anchor, make sure the client coordinates and screen coordinates |
| // take the viewport's position and scale into account. |
| anchor.focus(); |
| document.addEventListener('contextmenu', handleContextMenuFocus, true); |
| eventSender.keyDown("ContextMenu"); |
| eventSender.keyDown("Escape"); |
| document.removeEventListener('contextmenu', handleContextMenuFocus, true); |
| |
| // Place selection and make sure it still works. |
| window.getSelection().selectAllChildren(anchor); |
| document.addEventListener('contextmenu', handleContextMenuEditable, true); |
| eventSender.keyDown("ContextMenu"); |
| eventSender.keyDown("Escape"); |
| document.removeEventListener('contextmenu', handleContextMenuEditable, true); |
| |
| testRunner.notifyDone(); |
| } |
| |
| if (!window.eventSender || !window.testRunner || !window.internals) { |
| testFailed('This test needs to run in a test environment.'); |
| document.addEventListener('contextmenu', handleContextMenuEditable, true); |
| } else { |
| testRunner.waitUntilDone(); |
| window.addEventListener('load', runTest); |
| } |
| </script> |
| |
| <style> |
| #anchor { |
| background-color: orange; |
| position: absolute; |
| top: 380px; |
| left: 530px; |
| height: 100px; |
| width: 100px; |
| } |
| </style> |
| <div id="anchor" tabindex="0">Target</div> |
| <div id="console"></div> |