test_contextmenu.xhtml (8314B)
1 <?xml version="1.0"?> 2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?> 3 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" 4 type="text/css"?> 5 6 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 7 title="menu tree and events"> 8 9 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> 10 <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/> 11 12 <script type="application/javascript" 13 src="../common.js" /> 14 <script type="application/javascript" 15 src="../events.js" /> 16 <script type="application/javascript" 17 src="../role.js" /> 18 <script type="application/javascript" 19 src="../states.js" /> 20 21 <script type="application/javascript"> 22 <![CDATA[ 23 24 function openMenu(aID, aTree) 25 { 26 this.eventSeq = [ 27 new invokerChecker(EVENT_MENUPOPUP_START, getNode(aID)) 28 ]; 29 30 this.invoke = function openMenu_invoke() 31 { 32 var button = getNode("button"); 33 getNode(aID).openPopup(button, "after_start", 0, 0, true, false); 34 } 35 36 this.finalCheck = function openMenu_finalCheck() 37 { 38 testStates(aID, STATE_FLOATING, 0, STATE_INVISIBLE | STATE_OFFSCREEN | STATE_COLLAPSED); 39 testAccessibleTree(aID, aTree); 40 } 41 42 this.getID = function openMenu_getID() 43 { 44 return "open menu " + prettyName(aID); 45 } 46 } 47 48 function selectNextMenuItem(aID) 49 { 50 this.eventSeq = [ 51 new invokerChecker(EVENT_FOCUS, getNode(aID)) 52 ]; 53 54 this.invoke = function selectMenuItem_invoke() 55 { 56 synthesizeKey("KEY_ArrowDown"); 57 } 58 59 this.getID = function selectMenuItem_getID() 60 { 61 return "select menuitem " + prettyName(aID); 62 } 63 } 64 65 function openSubMenu(aSubMenuID, aItemID, aMenuID, aTree) 66 { 67 this.eventSeq = [ 68 new invokerChecker(EVENT_FOCUS, getNode(aItemID)), 69 ]; 70 71 this.invoke = function openSubMenu_invoke() 72 { 73 synthesizeKey("KEY_Enter"); 74 } 75 76 this.finalCheck = function openSubMenu_finalCheck() 77 { 78 testAccessibleTree(aMenuID, aTree); 79 } 80 81 this.getID = function openSubMenu_getID() 82 { 83 return "open submenu " + prettyName(aSubMenuID) + " focusing item " + prettyName(aItemID); 84 } 85 } 86 87 function closeSubMenu(aSubMenuID, aItemID) 88 { 89 this.eventSeq = [ 90 new invokerChecker(EVENT_FOCUS, getNode(aItemID)), 91 ]; 92 93 this.invoke = function closeSubMenu_invoke() 94 { 95 synthesizeKey("KEY_Escape"); 96 } 97 98 this.getID = function closeSubMenu_getID() 99 { 100 return "close submenu " + prettyName(aSubMenuID) + " focusing item " + prettyName(aItemID); 101 } 102 } 103 104 function closeMenu(aID) 105 { 106 this.eventSeq = [ 107 new invokerChecker(EVENT_MENUPOPUP_END, getNode(aID)) 108 ]; 109 110 this.invoke = function closeMenu_invoke() 111 { 112 synthesizeKey("KEY_Escape"); 113 } 114 115 this.getID = function closeMenu_getID() 116 { 117 return "close menu " + prettyName(aID); 118 } 119 120 this.finalCheck = function closeMenu_finalCheck() 121 { 122 testStates(aID, STATE_FLOATING | STATE_INVISIBLE | STATE_OFFSCREEN, 0); 123 } 124 } 125 126 //gA11yEventDumpToConsole = true; 127 //enableLogging("tree,verbose"); 128 129 var gQueue = null; 130 var gContextTree = {}; 131 132 // Linux and Windows menu trees discrepancy: bug 527646. 133 134 /** 135 * Return the context menu tree before submenus were open. 136 */ 137 function getMenuTree1() 138 { 139 if (LINUX || SOLARIS) { 140 let tree = { 141 role: ROLE_MENUPOPUP, 142 children: [ 143 { 144 name: "item0", 145 role: ROLE_MENUITEM, 146 children: [] 147 }, 148 { 149 name: "item1", 150 role: ROLE_MENUITEM, 151 children: [] 152 }, 153 { 154 name: "item2", 155 role: ROLE_PARENT_MENUITEM, 156 children: [ ] 157 } 158 ] 159 }; 160 return tree; 161 } 162 163 // Windows 164 let tree = { 165 role: ROLE_MENUPOPUP, 166 children: [ 167 { 168 name: "item0", 169 role: ROLE_MENUITEM, 170 children: [] 171 }, 172 { 173 name: "item1", 174 role: ROLE_MENUITEM, 175 children: [] 176 }, 177 { 178 name: "item2", 179 role: ROLE_PARENT_MENUITEM, 180 children: [ 181 { 182 name: "item2", 183 role: ROLE_MENUPOPUP, 184 children: [ ] 185 } 186 ] 187 } 188 ] 189 }; 190 return tree; 191 } 192 193 /** 194 * Return context menu tree when submenu was open. 195 */ 196 function getMenuTree2() 197 { 198 var tree = getMenuTree1(); 199 if (LINUX || SOLARIS) { 200 let submenuTree = 201 { 202 name: "item2.0", 203 role: ROLE_PARENT_MENUITEM, 204 children: [ ] 205 }; 206 tree.children[2].children.push(submenuTree); 207 return tree; 208 } 209 210 // Windows 211 let submenuTree = 212 { 213 name: "item2.0", 214 role: ROLE_PARENT_MENUITEM, 215 children: [ 216 { 217 name: "item2.0", 218 role: ROLE_MENUPOPUP, 219 children: [ ] 220 } 221 ] 222 }; 223 224 tree.children[2].children[0].children.push(submenuTree); 225 return tree; 226 } 227 228 /** 229 * Return context menu tree when subsub menu was open. 230 */ 231 function getMenuTree3() 232 { 233 var tree = getMenuTree2(); 234 var subsubmenuTree = 235 { 236 name: "item2.0.0", 237 role: ROLE_MENUITEM, 238 children: [] 239 }; 240 241 if (LINUX || SOLARIS) 242 tree.children[2].children[0].children.push(subsubmenuTree); 243 else 244 tree.children[2].children[0].children[0].children[0].children.push(subsubmenuTree); 245 246 return tree; 247 } 248 249 250 function doTests() 251 { 252 gQueue = new eventQueue(); 253 254 // Check initial empty tree 255 testAccessibleTree("context", { MENUPOPUP: [] }); 256 257 // Open context menu and check that menu item accesibles are created. 258 gQueue.push(new openMenu("context", getMenuTree1())); 259 260 // Select items and check focus event on them. 261 gQueue.push(new selectNextMenuItem("item0")); 262 gQueue.push(new selectNextMenuItem("item1")); 263 gQueue.push(new selectNextMenuItem("item2")); 264 265 // Open sub menu and check menu accessible tree and focus event. 266 gQueue.push(new openSubMenu("submenu2", "item2.0", 267 "context", getMenuTree2())); 268 gQueue.push(new openSubMenu("submenu2.0", "item2.0.0", 269 "context", getMenuTree3())); 270 271 // Close submenus and check that focus goes to parent. 272 gQueue.push(new closeSubMenu("submenu2.0", "item2.0")); 273 gQueue.push(new closeSubMenu("submenu2", "item2")); 274 275 gQueue.push(new closeMenu("context")); 276 277 gQueue.invoke(); // Will call SimpleTest.finish(); 278 } 279 280 SimpleTest.waitForExplicitFinish(); 281 addA11yLoadEvent(doTests); 282 ]]> 283 </script> 284 285 <hbox flex="1" style="overflow: auto;"> 286 <body xmlns="http://www.w3.org/1999/xhtml"> 287 <a target="_blank" 288 href="https://bugzilla.mozilla.org/show_bug.cgi?id=630194" 289 title="Update accessible tree when opening the menu popup"> 290 Mozilla Bug 630194 291 </a> 292 <a target="_blank" 293 href="https://bugzilla.mozilla.org/show_bug.cgi?id=630486" 294 title="Don't force accessible creation for popup children."> 295 Mozilla Bug 630486 296 </a> 297 <p id="display"></p> 298 <div id="content" style="display: none"> 299 </div> 300 <pre id="test"> 301 </pre> 302 </body> 303 304 <vbox flex="1"> 305 306 <menupopup id="context"> 307 <menuitem id="item0" label="item0"/> 308 <menuitem id="item1" label="item1"/> 309 <menu id="item2" label="item2"> 310 <menupopup id="submenu2"> 311 <menu id="item2.0" label="item2.0"> 312 <menupopup id="submenu2.0"> 313 <menuitem id="item2.0.0" label="item2.0.0"/> 314 </menupopup> 315 </menu> 316 </menupopup> 317 </menu> 318 </menupopup> 319 320 <button context="context" id="button">btn</button> 321 </vbox> 322 </hbox> 323 </window>