Merge mozilla-central to autoland on a CLOSED TREE
[gecko.git] / widget / tests / native_menus_window.xhtml
blob2b3d3f2aa3231533f66f8c8490fb15d0c99446db
1 <?xml version="1.0"?>
3 <!-- This Source Code Form is subject to the terms of the Mozilla Public
4 - License, v. 2.0. If a copy of the MPL was not distributed with this
5 - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
7 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
9 <window id="NativeMenuWindow"
10 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
11 width="300"
12 height="300"
13 onload="onLoad();"
14 title="Native Menu Test">
16 <command id="cmd_FooItem0" oncommand="executedCommandID = 'cmd_FooItem0';"/>
17 <command id="cmd_FooItem1" oncommand="executedCommandID = 'cmd_FooItem1';"/>
18 <command id="cmd_BarItem0" oncommand="executedCommandID = 'cmd_BarItem0';"/>
19 <command id="cmd_BarItem1" oncommand="executedCommandID = 'cmd_BarItem1';"/>
20 <command id="cmd_NewItem0" oncommand="executedCommandID = 'cmd_NewItem0';"/>
21 <command id="cmd_NewItem1" oncommand="executedCommandID = 'cmd_NewItem1';"/>
22 <command id="cmd_NewItem2" oncommand="executedCommandID = 'cmd_NewItem2';"/>
23 <command id="cmd_NewItem3" oncommand="executedCommandID = 'cmd_NewItem3';"/>
24 <command id="cmd_NewItem4" oncommand="executedCommandID = 'cmd_NewItem4';"/>
25 <command id="cmd_NewItem5" oncommand="executedCommandID = 'cmd_NewItem5';"/>
27 <!-- We do not modify any menus or menu items defined here in testing. These
28 serve as a baseline structure for us to test after other modifications.
29 We add children to the menubar defined here and test by modifying those
30 children. -->
31 <menubar id="nativemenubar">
32 <menu id="foo" label="Foo">
33 <menupopup>
34 <menuitem label="FooItem0" command="cmd_FooItem0"/>
35 <menuitem label="FooItem1" command="cmd_FooItem1"/>
36 <menuseparator/>
37 <menu label="Bar">
38 <menupopup>
39 <menuitem label="BarItem0" command="cmd_BarItem0"/>
40 <menuitem label="BarItem1" command="cmd_BarItem1"/>
41 </menupopup>
42 </menu>
43 </menupopup>
44 </menu>
45 </menubar>
47 <script type="application/javascript"><![CDATA[
49 function ok(condition, message) {
50 window.arguments[0].SimpleTest.ok(condition, message);
53 function onTestsFinished() {
54 window.close();
55 window.arguments[0].SimpleTest.finish();
58 // Force a menu to update itself. All of the menus parents will be updated
59 // as well. An empty string will force a complete menu system reload.
60 function forceUpdateNativeMenuAt(location) {
61 var utils = window.windowUtils;
62 try {
63 utils.forceUpdateNativeMenuAt(location);
65 catch (e) {
66 dump(e + "\n");
70 var executedCommandID = "";
72 function testItem(location, targetID) {
73 var utils = window.windowUtils;
74 var correctCommandHandler = false;
75 try {
76 utils.activateNativeMenuItemAt(location);
77 correctCommandHandler = executedCommandID == targetID;
79 catch (e) {
80 dump(e + "\n");
82 finally {
83 executedCommandID = "";
85 return correctCommandHandler;
88 function createXULMenuPopup() {
89 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
90 var item = document.createElementNS(XUL_NS, "menupopup");
91 return item;
94 function createXULMenu(aLabel) {
95 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
96 var item = document.createElementNS(XUL_NS, "menu");
97 item.setAttribute("label", aLabel);
98 return item;
101 function createXULMenuItem(aLabel, aCommandId) {
102 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
103 var item = document.createElementNS(XUL_NS, "menuitem");
104 item.setAttribute("label", aLabel);
105 item.setAttribute("command", aCommandId);
106 return item;
109 function runBaseMenuTests() {
110 forceUpdateNativeMenuAt("0|3");
111 return testItem("0|0", "cmd_FooItem0") &&
112 testItem("0|1", "cmd_FooItem1") &&
113 testItem("0|3|0", "cmd_BarItem0") &&
114 testItem("0|3|1", "cmd_BarItem1");
117 function onLoad() {
118 var _delayedOnLoad = function() {
119 // First let's run the base menu tests.
120 ok(runBaseMenuTests());
122 // Set up some nodes that we'll use.
123 var menubarNode = document.getElementById("nativemenubar");
124 var newMenu0 = createXULMenu("NewMenu0");
125 var newMenu1 = createXULMenu("NewMenu1");
126 var newMenuPopup0 = createXULMenuPopup();
127 var newMenuPopup1 = createXULMenuPopup();
128 var newMenuItem0 = createXULMenuItem("NewMenuItem0", "cmd_NewItem0");
129 var newMenuItem1 = createXULMenuItem("NewMenuItem1", "cmd_NewItem1");
130 var newMenuItem2 = createXULMenuItem("NewMenuItem2", "cmd_NewItem2");
131 var newMenuItem3 = createXULMenuItem("NewMenuItem3", "cmd_NewItem3");
132 var newMenuItem4 = createXULMenuItem("NewMenuItem4", "cmd_NewItem4");
133 var newMenuItem5 = createXULMenuItem("NewMenuItem5", "cmd_NewItem5");
135 // Create another submenu with hierarchy via DOM manipulation.
136 // ******************
137 // * Foo * NewMenu0 * <- Menu bar
138 // ******************
139 // ****************
140 // * NewMenuItem0 * <- NewMenu0 submenu
141 // ****************
142 // * NewMenuItem1 *
143 // ****************
144 // * NewMenuItem2 *
145 // *******************************
146 // * NewMenu1 > * NewMenuItem3 * <- NewMenu1 submenu
147 // *******************************
148 // * NewMenuItem4 *
149 // ****************
150 // * NewMenuItem5 *
151 // ****************
152 newMenu0.appendChild(newMenuPopup0);
153 newMenuPopup0.appendChild(newMenuItem0);
154 newMenuPopup0.appendChild(newMenuItem1);
155 newMenuPopup0.appendChild(newMenuItem2);
156 newMenuPopup0.appendChild(newMenu1);
157 newMenu1.appendChild(newMenuPopup1);
158 newMenuPopup1.appendChild(newMenuItem3);
159 newMenuPopup1.appendChild(newMenuItem4);
160 newMenuPopup1.appendChild(newMenuItem5);
161 //XXX - we have to append the menu to the top-level of the menu bar
162 // only after constructing it. If we append before construction, it is
163 // invalid because it has no children and we don't validate it if we add
164 // children later.
165 menubarNode.appendChild(newMenu0);
166 forceUpdateNativeMenuAt("1|3");
167 // Run basic tests again.
168 ok(runBaseMenuTests());
170 // Error strings.
171 var sa = "Command handler(s) should have activated";
172 var sna = "Command handler(s) should not have activated";
174 // Test middle items.
175 ok(testItem("1|1", "cmd_NewItem1"), sa);
176 ok(testItem("1|3|1", "cmd_NewItem4"), sa);
178 // Hide newMenu0.
179 newMenu0.setAttribute("hidden", "true");
180 ok(runBaseMenuTests(), sa); // the base menu should still be unhidden
181 ok(!testItem("1|0", ""), sna);
182 ok(!testItem("1|1", ""), sna);
183 ok(!testItem("1|2", ""), sna);
184 ok(!testItem("1|3|0", ""), sna);
185 ok(!testItem("1|3|1", ""), sna);
186 ok(!testItem("1|3|2", ""), sna);
188 // Show newMenu0.
189 newMenu0.setAttribute("hidden", "false");
190 forceUpdateNativeMenuAt("1|3");
191 ok(runBaseMenuTests(), sa);
192 ok(testItem("1|0", "cmd_NewItem0"), sa);
193 ok(testItem("1|1", "cmd_NewItem1"), sa);
194 ok(testItem("1|2", "cmd_NewItem2"), sa);
195 ok(testItem("1|3|0", "cmd_NewItem3"), sa);
196 ok(testItem("1|3|1", "cmd_NewItem4"), sa);
197 ok(testItem("1|3|2", "cmd_NewItem5"), sa);
199 // Hide items.
200 newMenuItem1.setAttribute("hidden", "true");
201 newMenuItem4.setAttribute("hidden", "true");
202 forceUpdateNativeMenuAt("1|2");
203 ok(runBaseMenuTests(), sa);
204 ok(testItem("1|0", "cmd_NewItem0"), sa);
205 ok(testItem("1|1", "cmd_NewItem2"), sa);
206 ok(!testItem("1|2", ""), sna);
207 ok(testItem("1|2|0", "cmd_NewItem3"), sa);
208 ok(testItem("1|2|1", "cmd_NewItem5"), sa);
209 ok(!testItem("1|2|2", ""), sna);
211 // Show items.
212 newMenuItem1.setAttribute("hidden", "false");
213 newMenuItem4.setAttribute("hidden", "false");
214 forceUpdateNativeMenuAt("1|3");
215 ok(runBaseMenuTests(), sa);
216 ok(testItem("1|0", "cmd_NewItem0"), sa);
217 ok(testItem("1|1", "cmd_NewItem1"), sa);
218 ok(testItem("1|2", "cmd_NewItem2"), sa);
219 ok(testItem("1|3|0", "cmd_NewItem3"), sa);
220 ok(testItem("1|3|1", "cmd_NewItem4"), sa);
221 ok(testItem("1|3|2", "cmd_NewItem5"), sa);
223 // At this point in the tests the state of the menus has been returned
224 // to the originally diagramed state.
226 // Test command disabling
227 var cmd_NewItem0 = document.getElementById("cmd_NewItem0");
228 ok(testItem("1|0", "cmd_NewItem0"), sa);
229 cmd_NewItem0.setAttribute("disabled", "true");
230 ok(!testItem("1|0", "cmd_NewItem0"), sna);
231 cmd_NewItem0.removeAttribute("disabled");
232 ok(testItem("1|0", "cmd_NewItem0"), sa);
234 // Remove menu.
235 menubarNode.removeChild(newMenu0);
236 ok(runBaseMenuTests(), sa);
237 ok(!testItem("1|0", ""), sna);
238 ok(!testItem("1|1", ""), sna);
239 ok(!testItem("1|2", ""), sna);
240 ok(!testItem("1|3|0", ""), sna);
241 ok(!testItem("1|3|1", ""), sna);
242 ok(!testItem("1|3|2", ""), sna);
243 // return state to original diagramed state
244 menubarNode.appendChild(newMenu0);
246 // Test for bug 447042, make sure that adding a menu node with no children
247 // to the menu bar and then adding another menu node with children works.
248 // Menus with no children don't get their native menu items shown and that
249 // caused internal arrays to get out of sync and an append crashed.
250 var tmpMenu0 = createXULMenu("tmpMenu0");
251 menubarNode.removeChild(newMenu0);
252 menubarNode.appendChild(tmpMenu0);
253 menubarNode.appendChild(newMenu0);
254 forceUpdateNativeMenuAt("1|3");
255 ok(runBaseMenuTests());
256 ok(testItem("1|0", "cmd_NewItem0"), sa);
257 ok(testItem("1|1", "cmd_NewItem1"), sa);
258 ok(testItem("1|2", "cmd_NewItem2"), sa);
259 ok(testItem("1|3|0", "cmd_NewItem3"), sa);
260 ok(testItem("1|3|1", "cmd_NewItem4"), sa);
261 ok(testItem("1|3|2", "cmd_NewItem5"), sa);
262 // return state to original diagramed state
263 menubarNode.removeChild(tmpMenu0);
265 // This test is basically a crash test for bug 433858.
266 newMenuItem1.setAttribute("hidden", "true");
267 newMenuItem2.setAttribute("hidden", "true");
268 newMenu1.setAttribute("hidden", "true");
269 forceUpdateNativeMenuAt("1");
270 newMenuItem1.setAttribute("hidden", "false");
271 newMenuItem2.setAttribute("hidden", "false");
272 newMenu1.setAttribute("hidden", "false");
273 forceUpdateNativeMenuAt("1");
275 onTestsFinished();
278 setTimeout(_delayedOnLoad, 1000);
281 ]]></script>
282 </window>