Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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> |