toolkit/content/tests/chrome/test_contextmenu_list.xul

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 <?xml version="1.0"?>
michael@0 2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
michael@0 3 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
michael@0 4
michael@0 5 <window title="Context Menu on List Tests"
michael@0 6 onload="setTimeout(startTest, 0);"
michael@0 7 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
michael@0 8
michael@0 9 <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
michael@0 10 <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
michael@0 11
michael@0 12 <spacer height="5"/>
michael@0 13
michael@0 14 <hbox style="padding-left: 10px;">
michael@0 15 <spacer width="5"/>
michael@0 16 <richlistbox id="list" context="themenu" style="padding: 0;" oncontextmenu="checkContextMenu(event)">
michael@0 17 <richlistitem id="item1" style="padding-top: 3px; margin: 0;"><button label="One"/></richlistitem>
michael@0 18 <richlistitem id="item2" height="22"><checkbox label="Checkbox"/></richlistitem>
michael@0 19 <richlistitem id="item3"><button label="Three"/></richlistitem>
michael@0 20 <richlistitem id="item4"><checkbox label="Four"/></richlistitem>
michael@0 21 </richlistbox>
michael@0 22
michael@0 23 <tree id="tree" rows="5" flex="1" context="themenu" style="-moz-appearance: none; border: 0">
michael@0 24 <treecols>
michael@0 25 <treecol label="Name" flex="1"/>
michael@0 26 <splitter class="tree-splitter"/>
michael@0 27 <treecol label="Moons"/>
michael@0 28 </treecols>
michael@0 29 <treechildren id="treechildren">
michael@0 30 <treeitem>
michael@0 31 <treerow>
michael@0 32 <treecell label="Mercury"/>
michael@0 33 <treecell label="0"/>
michael@0 34 </treerow>
michael@0 35 </treeitem>
michael@0 36 <treeitem>
michael@0 37 <treerow>
michael@0 38 <treecell label="Venus"/>
michael@0 39 <treecell label="0"/>
michael@0 40 </treerow>
michael@0 41 </treeitem>
michael@0 42 <treeitem>
michael@0 43 <treerow>
michael@0 44 <treecell label="Earth"/>
michael@0 45 <treecell label="1"/>
michael@0 46 </treerow>
michael@0 47 </treeitem>
michael@0 48 <treeitem>
michael@0 49 <treerow>
michael@0 50 <treecell label="Mars"/>
michael@0 51 <treecell label="2"/>
michael@0 52 </treerow>
michael@0 53 </treeitem>
michael@0 54 </treechildren>
michael@0 55 </tree>
michael@0 56
michael@0 57 <menu id="menu" label="Menu">
michael@0 58 <menupopup id="menupopup" onpopupshown="menuTests()" onpopuphidden="nextTest()"
michael@0 59 oncontextmenu="checkContextMenuForMenu(event)">
michael@0 60 <menuitem id="menu1" label="Menu 1"/>
michael@0 61 <menuitem id="menu2" label="Menu 2"/>
michael@0 62 <menuitem id="menu3" label="Menu 3"/>
michael@0 63 </menupopup>
michael@0 64 </menu>
michael@0 65
michael@0 66 </hbox>
michael@0 67
michael@0 68 <menupopup id="themenu" onpopupshowing="if (gTestId == -1) event.preventDefault()"
michael@0 69 onpopupshown="checkPopup()" onpopuphidden="setTimeout(nextTest, 0);">
michael@0 70 <menuitem label="Item"/>
michael@0 71 </menupopup>
michael@0 72
michael@0 73 <script class="testbody" type="application/javascript">
michael@0 74 <![CDATA[
michael@0 75
michael@0 76 SimpleTest.waitForExplicitFinish();
michael@0 77
michael@0 78 var gTestId = -1;
michael@0 79 var gTestElement = "list";
michael@0 80 var gSelectionStep = 0;
michael@0 81 var gContextMenuFired = false;
michael@0 82
michael@0 83 function startTest()
michael@0 84 {
michael@0 85 // first, check if the richlistbox selection changes on a contextmenu mouse event
michael@0 86 var element = $("list");
michael@0 87 synthesizeMouse(element.getItemAtIndex(3), 7, 1, { type : "mousedown", button: 2, ctrlKey: true });
michael@0 88 synthesizeMouse(element, 7, 4, { type : "contextmenu", button: 2 });
michael@0 89
michael@0 90 gSelectionStep++;
michael@0 91 synthesizeMouse(element.getItemAtIndex(1), 7, 1, { type : "mousedown", button: 2, ctrlKey: true, shiftKey: true });
michael@0 92 synthesizeMouse(element, 7, 4, { type : "contextmenu", button: 2 });
michael@0 93
michael@0 94 gSelectionStep++;
michael@0 95 synthesizeMouse(element.getItemAtIndex(1), 7, 1, { type : "mousedown", button: 2 });
michael@0 96 synthesizeMouse(element, 7, 4, { type : "contextmenu", button: 2 });
michael@0 97
michael@0 98 $("menu").open = true;
michael@0 99 }
michael@0 100
michael@0 101 function menuTests()
michael@0 102 {
michael@0 103 gSelectionStep = 0;
michael@0 104 var element = $("menu");
michael@0 105 synthesizeMouse(element, 0, 0, { type : "contextmenu", button: 0 });
michael@0 106 is(gContextMenuFired, true, "context menu fired when menu open");
michael@0 107
michael@0 108 gSelectionStep = 1;
michael@0 109 $("menu").boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).activeChild = $("menu2");
michael@0 110 synthesizeMouse(element, 0, 0, { type : "contextmenu", button: 0 });
michael@0 111
michael@0 112 $("menu").open = false;
michael@0 113 }
michael@0 114
michael@0 115 function nextTest()
michael@0 116 {
michael@0 117 gTestId++;
michael@0 118 if (gTestId > 2) {
michael@0 119 if (gTestElement == "list") {
michael@0 120 gTestElement = "tree";
michael@0 121 gTestId = 0;
michael@0 122 }
michael@0 123 else {
michael@0 124 SimpleTest.finish();
michael@0 125 return;
michael@0 126 }
michael@0 127 }
michael@0 128 var element = $(gTestElement);
michael@0 129 element.focus();
michael@0 130 if (gTestId == 0) {
michael@0 131 if (gTestElement == "list")
michael@0 132 element.selectedIndex = 2;
michael@0 133 element.currentIndex = 2;
michael@0 134 synthesizeMouse(element, 0, 0, { type : "contextmenu", button: 0 });
michael@0 135 }
michael@0 136 else if (gTestId == 1) {
michael@0 137 synthesizeMouse(element, 7, 4, { type : "contextmenu", button: 2 });
michael@0 138 }
michael@0 139 else {
michael@0 140 element.currentIndex = -1;
michael@0 141 element.selectedIndex = -1;
michael@0 142 synthesizeMouse(element, 0, 0, { type : "contextmenu", button: 0 });
michael@0 143 }
michael@0 144 }
michael@0 145
michael@0 146 // This is nasty so I'd better explain what's going on.
michael@0 147 // The basic problem is that the synthetic mouse coordinate generated
michael@0 148 // by DOMWindowUtils.sendMouseEvent and also the synthetic mouse coordinate
michael@0 149 // generated internally when contextmenu events are redirected to the focused
michael@0 150 // element are rounded to the nearest device pixel. But this rounding is done
michael@0 151 // while the coordinates are relative to the nearest widget. When this test
michael@0 152 // is run in the mochitest harness, the nearest widget is the main mochitest
michael@0 153 // window, and our document can have a fractional position within that
michael@0 154 // mochitest window. So when we round coordinates for comparison in this
michael@0 155 // test, we need to do so very carefully, especially if the target element
michael@0 156 // also has a fractional position within our document.
michael@0 157 //
michael@0 158 // For example, if the y-offset of our containing IFRAME is 100.4px,
michael@0 159 // and the offset of our expected point is 10.3px in our document, the actual
michael@0 160 // mouse event is dispatched to round(110.7) == 111px. This comes back
michael@0 161 // with a clientY of round(111 - 100.4) == round(10.6) == 11. This is not
michael@0 162 // equal to round(10.3) as you might expect.
michael@0 163
michael@0 164 function isRoundedX(a, b, msg)
michael@0 165 {
michael@0 166 is(Math.round(a + mozInnerScreenX), Math.round(b + mozInnerScreenX), msg);
michael@0 167 }
michael@0 168
michael@0 169 function isRoundedY(a, b, msg)
michael@0 170 {
michael@0 171 is(Math.round(a + mozInnerScreenY), Math.round(b + mozInnerScreenY), msg);
michael@0 172 }
michael@0 173
michael@0 174 function checkContextMenu(event)
michael@0 175 {
michael@0 176 var rect = $(gTestElement).getBoundingClientRect();
michael@0 177
michael@0 178 var frombase = (gTestId == -1 || gTestId == 1);
michael@0 179 if (!frombase)
michael@0 180 rect = event.originalTarget.getBoundingClientRect();
michael@0 181 var left = frombase ? rect.left + 7 : rect.left;
michael@0 182 var top = frombase ? rect.top + 4 : rect.bottom;
michael@0 183
michael@0 184 isRoundedX(event.clientX, left, gTestElement + " clientX " + gSelectionStep + " " + gTestId + "," + frombase);
michael@0 185 isRoundedY(event.clientY, top, gTestElement + " clientY " + gSelectionStep + " " + gTestId);
michael@0 186 ok(event.screenX > left, gTestElement + " screenX " + gSelectionStep + " " + gTestId);
michael@0 187 ok(event.screenY > top, gTestElement + " screenY " + gSelectionStep + " " + gTestId);
michael@0 188
michael@0 189 // context menu from mouse click
michael@0 190 switch (gTestId) {
michael@0 191 case -1:
michael@0 192 var expected = gSelectionStep == 2 ? 1 : (navigator.platform.indexOf("Mac") >= 0 ? 3 : 0);
michael@0 193 is($(gTestElement).selectedIndex, expected, "index after click " + gSelectionStep);
michael@0 194 break;
michael@0 195 case 0:
michael@0 196 if (gTestElement == "list")
michael@0 197 is(event.originalTarget, $("item3"), "list selection target");
michael@0 198 else
michael@0 199 is(event.originalTarget, $("treechildren"), "tree selection target");
michael@0 200 break;
michael@0 201 case 1:
michael@0 202 is(event.originalTarget.id, $("item1").id, "list mouse selection target");
michael@0 203 break;
michael@0 204 case 2:
michael@0 205 is(event.originalTarget, $("list"), "list no selection target");
michael@0 206 break;
michael@0 207 }
michael@0 208 }
michael@0 209
michael@0 210 function checkContextMenuForMenu(event)
michael@0 211 {
michael@0 212 gContextMenuFired = true;
michael@0 213
michael@0 214 var popuprect = (gSelectionStep ? $("menu2") : $("menupopup")).getBoundingClientRect();
michael@0 215 is(event.clientX, Math.round(popuprect.left), "menu left " + gSelectionStep);
michael@0 216 // the clientY is off by one sometimes on Windows (when loaded in the testing iframe
michael@0 217 // but not when loaded separately) so just check for both cases for now
michael@0 218 ok(event.clientY == Math.round(popuprect.bottom) ||
michael@0 219 event.clientY - 1 == Math.round(popuprect.bottom), "menu top " + gSelectionStep);
michael@0 220 }
michael@0 221
michael@0 222 function checkPopup()
michael@0 223 {
michael@0 224 var menurect = $("themenu").getBoundingClientRect();
michael@0 225
michael@0 226 if (gTestId == 0) {
michael@0 227 if (gTestElement == "list") {
michael@0 228 var itemrect = $("item3").getBoundingClientRect();
michael@0 229 isRoundedX(menurect.left, itemrect.left + 2,
michael@0 230 "list selection keyboard left");
michael@0 231 isRoundedY(menurect.top, itemrect.bottom + 2,
michael@0 232 "list selection keyboard top");
michael@0 233 }
michael@0 234 else {
michael@0 235 var tree = $("tree");
michael@0 236 var bodyrect = $("treechildren").getBoundingClientRect();
michael@0 237 isRoundedX(menurect.left, bodyrect.left + 2,
michael@0 238 "tree selection keyboard left");
michael@0 239 isRoundedY(menurect.top, bodyrect.top +
michael@0 240 tree.treeBoxObject.rowHeight * 3 + 2,
michael@0 241 "tree selection keyboard top");
michael@0 242 }
michael@0 243 }
michael@0 244 else if (gTestId == 1) {
michael@0 245 // activating a context menu with the mouse from position (7, 1).
michael@0 246 // Add 2 pixels to these values as context menus are offset by 2 pixels
michael@0 247 // so that they don't appear exactly only the menu making them easier to
michael@0 248 // dismiss. See nsXULPopupListener.
michael@0 249 var elementrect = $(gTestElement).getBoundingClientRect();
michael@0 250 isRoundedX(menurect.left, elementrect.left + 9,
michael@0 251 gTestElement + " mouse left");
michael@0 252 isRoundedY(menurect.top, elementrect.top + 6,
michael@0 253 gTestElement + " mouse top");
michael@0 254 }
michael@0 255 else {
michael@0 256 var elementrect = $(gTestElement).getBoundingClientRect();
michael@0 257 isRoundedX(menurect.left, elementrect.left + 2,
michael@0 258 gTestElement + " no selection keyboard left");
michael@0 259 isRoundedY(menurect.top, elementrect.bottom + 2,
michael@0 260 gTestElement + " no selection keyboard top");
michael@0 261 }
michael@0 262
michael@0 263 $("themenu").hidePopup();
michael@0 264 }
michael@0 265
michael@0 266 ]]>
michael@0 267 </script>
michael@0 268
michael@0 269 <body xmlns="http://www.w3.org/1999/xhtml">
michael@0 270 <p id="display">
michael@0 271 </p>
michael@0 272 <div id="content" style="display: none">
michael@0 273 </div>
michael@0 274 <pre id="test">
michael@0 275 </pre>
michael@0 276 </body>
michael@0 277
michael@0 278 </window>

mercurial