1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/tests/standalone_native_menu_window.xul Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,277 @@ 1.4 +<?xml version="1.0"?> 1.5 + 1.6 +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> 1.7 + 1.8 +<window id="StandaloneNativeMenuWindow" 1.9 + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 1.10 + width="300" 1.11 + height="300" 1.12 + onload="onLoad();" 1.13 + title="nsIStandaloneNativeMenu Test"> 1.14 + 1.15 + <command id="cmd_FooItem0" oncommand="executedCommandID = 'cmd_FooItem0';"/> 1.16 + <command id="cmd_FooItem1" oncommand="executedCommandID = 'cmd_FooItem1';"/> 1.17 + <command id="cmd_BarItem0" oncommand="executedCommandID = 'cmd_BarItem0';"/> 1.18 + <command id="cmd_BarItem1" oncommand="executedCommandID = 'cmd_BarItem1';"/> 1.19 + <command id="cmd_NewItem0" oncommand="executedCommandID = 'cmd_NewItem0';"/> 1.20 + <command id="cmd_NewItem1" oncommand="executedCommandID = 'cmd_NewItem1';"/> 1.21 + <command id="cmd_NewItem2" oncommand="executedCommandID = 'cmd_NewItem2';"/> 1.22 + <command id="cmd_NewItem3" oncommand="executedCommandID = 'cmd_NewItem3';"/> 1.23 + <command id="cmd_NewItem4" oncommand="executedCommandID = 'cmd_NewItem4';"/> 1.24 + <command id="cmd_NewItem5" oncommand="executedCommandID = 'cmd_NewItem5';"/> 1.25 + 1.26 + <!-- We do not modify any menus or menu items defined here in testing. These 1.27 + serve as a baseline structure for us to test after other modifications. 1.28 + We add children to the menubar defined here and test by modifying those 1.29 + children. --> 1.30 + <popupset> 1.31 + <menupopup id="standalonenativemenu"> 1.32 + <menu id="foo" label="Foo"> 1.33 + <menupopup> 1.34 + <menuitem label="FooItem0" command="cmd_FooItem0"/> 1.35 + <menuitem label="FooItem1" command="cmd_FooItem1"/> 1.36 + <menuseparator/> 1.37 + <menu label="Bar"> 1.38 + <menupopup> 1.39 + <menuitem label="BarItem0" command="cmd_BarItem0"/> 1.40 + <menuitem label="BarItem1" command="cmd_BarItem1"/> 1.41 + </menupopup> 1.42 + </menu> 1.43 + </menupopup> 1.44 + </menu> 1.45 + </menupopup> 1.46 + </popupset> 1.47 + 1.48 + <script type="application/javascript"><![CDATA[ 1.49 + 1.50 + function ok(condition, message) { 1.51 + window.opener.wrappedJSObject.SimpleTest.ok(condition, message); 1.52 + } 1.53 + 1.54 + function todo(condition, message) { 1.55 + window.opener.wrappedJSObject.SimpleTest.todo(condition, message); 1.56 + } 1.57 + 1.58 + function onTestsFinished() { 1.59 + window.close(); 1.60 + window.opener.wrappedJSObject.SimpleTest.finish(); 1.61 + } 1.62 + 1.63 + var executedCommandID = ""; 1.64 + 1.65 + function testItem(menu, location, targetID) { 1.66 + var correctCommandHandler = false; 1.67 + try { 1.68 + menu.menuWillOpen(); 1.69 + menu.activateNativeMenuItemAt(location); 1.70 + correctCommandHandler = executedCommandID == targetID; 1.71 + } 1.72 + catch (e) { 1.73 + dump(e + "\n"); 1.74 + } 1.75 + finally { 1.76 + executedCommandID = ""; 1.77 + return correctCommandHandler; 1.78 + } 1.79 + } 1.80 + 1.81 + var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; 1.82 + 1.83 + function createXULMenuPopup() { 1.84 + return document.createElementNS(XUL_NS, "menupopup"); 1.85 + } 1.86 + 1.87 + function createXULMenu(aLabel) { 1.88 + var item = document.createElementNS(XUL_NS, "menu"); 1.89 + item.setAttribute("label", aLabel); 1.90 + return item; 1.91 + } 1.92 + 1.93 + function createXULMenuItem(aLabel, aCommandId) { 1.94 + var item = document.createElementNS(XUL_NS, "menuitem"); 1.95 + item.setAttribute("label", aLabel); 1.96 + item.setAttribute("command", aCommandId); 1.97 + return item; 1.98 + } 1.99 + 1.100 + function runBaseMenuTests(menu) { 1.101 + menu.forceUpdateNativeMenuAt("0|3"); 1.102 + return testItem(menu, "0|0", "cmd_FooItem0") && 1.103 + testItem(menu, "0|1", "cmd_FooItem1") && 1.104 + testItem(menu, "0|3|0", "cmd_BarItem0") && 1.105 + testItem(menu, "0|3|1", "cmd_BarItem1"); 1.106 + } 1.107 + 1.108 + function onLoad() { 1.109 + var _delayedOnLoad = function() { 1.110 + var Cc = Components.classes; 1.111 + var Ci = Components.interfaces; 1.112 + 1.113 + var menuNode = document.getElementById("standalonenativemenu"); 1.114 + var menu; 1.115 + try { 1.116 + menu = Cc["@mozilla.org/widget/standalonenativemenu;1"].createInstance(Ci.nsIStandaloneNativeMenu); 1.117 + menu.init(menuNode); 1.118 + } catch (e) { 1.119 + ok(false, "Create nsIStandaloneNativeMenu instance"); 1.120 + onTestsFinished(); 1.121 + return; 1.122 + } 1.123 + 1.124 + // First let's run the base menu tests. 1.125 + ok(runBaseMenuTests(menu), "base tests #1"); 1.126 + 1.127 + // Set up some nodes that we'll use. 1.128 + //var menubarNode = document.getElementById("nativemenubar"); 1.129 + var newMenu0 = createXULMenu("NewMenu0"); 1.130 + var newMenu1 = createXULMenu("NewMenu1"); 1.131 + var newMenuPopup0 = createXULMenuPopup(); 1.132 + var newMenuPopup1 = createXULMenuPopup(); 1.133 + var newMenuItem0 = createXULMenuItem("NewMenuItem0", "cmd_NewItem0"); 1.134 + var newMenuItem1 = createXULMenuItem("NewMenuItem1", "cmd_NewItem1"); 1.135 + var newMenuItem2 = createXULMenuItem("NewMenuItem2", "cmd_NewItem2"); 1.136 + var newMenuItem3 = createXULMenuItem("NewMenuItem3", "cmd_NewItem3"); 1.137 + var newMenuItem4 = createXULMenuItem("NewMenuItem4", "cmd_NewItem4"); 1.138 + var newMenuItem5 = createXULMenuItem("NewMenuItem5", "cmd_NewItem5"); 1.139 + 1.140 + // Create another submenu with hierarchy via DOM manipulation. 1.141 + // ****************** 1.142 + // * Foo * NewMenu0 * <- Menu bar 1.143 + // ****************** 1.144 + // **************** 1.145 + // * NewMenuItem0 * <- NewMenu0 submenu 1.146 + // **************** 1.147 + // * NewMenuItem1 * 1.148 + // **************** 1.149 + // * NewMenuItem2 * 1.150 + // ******************************* 1.151 + // * NewMenu1 > * NewMenuItem3 * <- NewMenu1 submenu 1.152 + // ******************************* 1.153 + // * NewMenuItem4 * 1.154 + // **************** 1.155 + // * NewMenuItem5 * 1.156 + // **************** 1.157 + newMenu0.appendChild(newMenuPopup0); 1.158 + newMenuPopup0.appendChild(newMenuItem0); 1.159 + newMenuPopup0.appendChild(newMenuItem1); 1.160 + newMenuPopup0.appendChild(newMenuItem2); 1.161 + newMenuPopup0.appendChild(newMenu1); 1.162 + newMenu1.appendChild(newMenuPopup1); 1.163 + newMenuPopup1.appendChild(newMenuItem3); 1.164 + newMenuPopup1.appendChild(newMenuItem4); 1.165 + newMenuPopup1.appendChild(newMenuItem5); 1.166 + //XXX - we have to append the menu to the top-level of the menu bar 1.167 + // only after constructing it. If we append before construction, it is 1.168 + // invalid because it has no children and we don't validate it if we add 1.169 + // children later. 1.170 + menuNode.appendChild(newMenu0); 1.171 + menu.forceUpdateNativeMenuAt("1|3"); 1.172 + // Run basic tests again. 1.173 + ok(runBaseMenuTests(menu), "base tests #2"); 1.174 + 1.175 + // Error strings. 1.176 + var sa = "Command handler(s) should have activated"; 1.177 + var sna = "Command handler(s) should not have activated"; 1.178 + 1.179 + // Test middle items. 1.180 + ok(testItem(menu, "1|1", "cmd_NewItem1"), "#1:" + sa); 1.181 + ok(testItem(menu, "1|3|1", "cmd_NewItem4"), "#2:" + sa); 1.182 + 1.183 + // Hide newMenu0. 1.184 + newMenu0.setAttribute("hidden", "true"); 1.185 + ok(runBaseMenuTests(menu), "base tests #3: " + sa); // the base menu should still be unhidden 1.186 + ok(!testItem(menu, "1|0", ""), "#3:" + sna); 1.187 + ok(!testItem(menu, "1|1", ""), "#4:" + sna); 1.188 + ok(!testItem(menu, "1|2", ""), "#5:" + sna); 1.189 + ok(!testItem(menu, "1|3|0", ""), "#6:" + sna); 1.190 + ok(!testItem(menu, "1|3|1", ""), "#7:" + sna); 1.191 + ok(!testItem(menu, "1|3|2", ""), "#8:" + sna); 1.192 + 1.193 + // Show newMenu0. 1.194 + newMenu0.setAttribute("hidden", "false"); 1.195 + menu.forceUpdateNativeMenuAt("1|3"); 1.196 + ok(runBaseMenuTests(menu), "base tests #4:" + sa); 1.197 + ok(testItem(menu, "1|0", "cmd_NewItem0"), "#9:" + sa); 1.198 + ok(testItem(menu, "1|1", "cmd_NewItem1"), "#10:" + sa); 1.199 + ok(testItem(menu, "1|2", "cmd_NewItem2"), "#11:" + sa); 1.200 + ok(testItem(menu, "1|3|0", "cmd_NewItem3"), "#12:" + sa); 1.201 + ok(testItem(menu, "1|3|1", "cmd_NewItem4"), "#13:" + sa); 1.202 + ok(testItem(menu, "1|3|2", "cmd_NewItem5"), "#14:" + sa); 1.203 + 1.204 + // Hide items. 1.205 + newMenuItem1.setAttribute("hidden", "true"); 1.206 + newMenuItem4.setAttribute("hidden", "true"); 1.207 + menu.forceUpdateNativeMenuAt("1|2"); 1.208 + ok(runBaseMenuTests(menu), "base tests #5:" + sa); 1.209 + ok(testItem(menu, "1|0", "cmd_NewItem0"), "#15:" + sa); 1.210 + ok(testItem(menu, "1|1", "cmd_NewItem2"), "#16:" + sa); 1.211 + ok(!testItem(menu, "1|2", ""), "#17:" + sna); 1.212 + ok(testItem(menu, "1|2|0", "cmd_NewItem3"), "#18:" + sa); 1.213 + ok(testItem(menu, "1|2|1", "cmd_NewItem5"), "#19:" + sa); 1.214 + ok(!testItem(menu, "1|2|2", ""), "#20:" + sna); 1.215 + 1.216 + // Show items. 1.217 + newMenuItem1.setAttribute("hidden", "false"); 1.218 + newMenuItem4.setAttribute("hidden", "false"); 1.219 + //forceUpdateNativeMenuAt("1|3"); 1.220 + ok(runBaseMenuTests(menu), "base tests #6:" + sa); 1.221 + ok(testItem(menu, "1|0", "cmd_NewItem0"), "#21:" + sa); 1.222 + ok(testItem(menu, "1|1", "cmd_NewItem1"), "#22:" + sa); 1.223 + ok(testItem(menu, "1|2", "cmd_NewItem2"), "#23:" + sa); 1.224 + ok(testItem(menu, "1|3|0", "cmd_NewItem3"), "#24:" + sa); 1.225 + ok(testItem(menu, "1|3|1", "cmd_NewItem4"), "#25:" + sa); 1.226 + ok(testItem(menu, "1|3|2", "cmd_NewItem5"), "#26:" + sa); 1.227 + 1.228 + // At this point in the tests the state of the menus has been returned 1.229 + // to the originally diagramed state. 1.230 + 1.231 + // Remove menu. 1.232 + menuNode.removeChild(newMenu0); 1.233 + ok(runBaseMenuTests(menu), "base tests #7:" + sa); 1.234 + ok(!testItem(menu, "1|0", ""), "#27:" + sna); 1.235 + ok(!testItem(menu, "1|1", ""), "#28:" + sna); 1.236 + ok(!testItem(menu, "1|2", ""), "#29:" + sna); 1.237 + ok(!testItem(menu, "1|3|0", ""), "#30:" + sna); 1.238 + ok(!testItem(menu, "1|3|1", ""), "#31:" + sna); 1.239 + ok(!testItem(menu, "1|3|2", ""), "#32:" + sna); 1.240 + // return state to original diagramed state 1.241 + menuNode.appendChild(newMenu0); 1.242 + 1.243 + // Test for bug 447042, make sure that adding a menu node with no children 1.244 + // to the menu bar and then adding another menu node with children works. 1.245 + // Menus with no children don't get their native menu items shown and that 1.246 + // caused internal arrays to get out of sync and an append crashed. 1.247 + var tmpMenu0 = createXULMenu("tmpMenu0"); 1.248 + menuNode.removeChild(newMenu0); 1.249 + menuNode.appendChild(tmpMenu0); 1.250 + menuNode.appendChild(newMenu0); 1.251 + menu.forceUpdateNativeMenuAt("1|3"); 1.252 + //todo(runBaseMenuTests(menu), "base tests #8"); 1.253 + todo(testItem(menu, "1|0", "cmd_NewItem0"), "#33:" +sa); 1.254 + todo(testItem(menu, "1|1", "cmd_NewItem1"), "#34:" +sa); 1.255 + todo(testItem(menu, "1|2", "cmd_NewItem2"), "#35:" +sa); 1.256 + todo(testItem(menu, "1|3|0", "cmd_NewItem3"), "#36:" +sa); 1.257 + todo(testItem(menu, "1|3|1", "cmd_NewItem4"), "#37:" +sa); 1.258 + todo(testItem(menu, "1|3|2", "cmd_NewItem5"), "#38:" +sa); 1.259 + // return state to original diagramed state 1.260 + menuNode.removeChild(tmpMenu0); 1.261 + delete tmpMenu0; 1.262 + 1.263 + // This test is basically a crash test for bug 433858. 1.264 + newMenuItem1.setAttribute("hidden", "true"); 1.265 + newMenuItem2.setAttribute("hidden", "true"); 1.266 + newMenu1.setAttribute("hidden", "true"); 1.267 + menu.forceUpdateNativeMenuAt("1"); 1.268 + newMenuItem1.setAttribute("hidden", "false"); 1.269 + newMenuItem2.setAttribute("hidden", "false"); 1.270 + newMenu1.setAttribute("hidden", "false"); 1.271 + menu.forceUpdateNativeMenuAt("1"); 1.272 + 1.273 + onTestsFinished(); 1.274 + } 1.275 + 1.276 + setTimeout(_delayedOnLoad, 1000); 1.277 + } 1.278 + 1.279 + ]]></script> 1.280 +</window>