widget/tests/native_menus_window.xul

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:db181a908c1d
1 <?xml version="1.0"?>
2
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/. -->
6
7 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
8
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">
15
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';"/>
26
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>
46
47 <script type="application/javascript"><![CDATA[
48
49 function ok(condition, message) {
50 window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
51 }
52
53 function onTestsFinished() {
54 window.close();
55 window.opener.wrappedJSObject.SimpleTest.finish();
56 }
57
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.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
62 getInterface(Components.interfaces.nsIDOMWindowUtils);
63 try {
64 utils.forceUpdateNativeMenuAt(location);
65 }
66 catch (e) {
67 dump(e + "\n");
68 }
69 }
70
71 var executedCommandID = "";
72
73 function testItem(location, targetID) {
74 var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
75 getInterface(Components.interfaces.nsIDOMWindowUtils);
76 var correctCommandHandler = false;
77 try {
78 utils.activateNativeMenuItemAt(location);
79 correctCommandHandler = executedCommandID == targetID;
80 }
81 catch (e) {
82 dump(e + "\n");
83 }
84 finally {
85 executedCommandID = "";
86 return correctCommandHandler;
87 }
88 }
89
90 function createXULMenuPopup() {
91 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
92 var item = document.createElementNS(XUL_NS, "menupopup");
93 return item;
94 }
95
96 function createXULMenu(aLabel) {
97 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
98 var item = document.createElementNS(XUL_NS, "menu");
99 item.setAttribute("label", aLabel);
100 return item;
101 }
102
103 function createXULMenuItem(aLabel, aCommandId) {
104 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
105 var item = document.createElementNS(XUL_NS, "menuitem");
106 item.setAttribute("label", aLabel);
107 item.setAttribute("command", aCommandId);
108 return item;
109 }
110
111 function runBaseMenuTests() {
112 forceUpdateNativeMenuAt("0|3");
113 return testItem("0|0", "cmd_FooItem0") &&
114 testItem("0|1", "cmd_FooItem1") &&
115 testItem("0|3|0", "cmd_BarItem0") &&
116 testItem("0|3|1", "cmd_BarItem1");
117 }
118
119 function onLoad() {
120 var _delayedOnLoad = function() {
121 // First let's run the base menu tests.
122 ok(runBaseMenuTests());
123
124 // Set up some nodes that we'll use.
125 var menubarNode = document.getElementById("nativemenubar");
126 var newMenu0 = createXULMenu("NewMenu0");
127 var newMenu1 = createXULMenu("NewMenu1");
128 var newMenuPopup0 = createXULMenuPopup();
129 var newMenuPopup1 = createXULMenuPopup();
130 var newMenuItem0 = createXULMenuItem("NewMenuItem0", "cmd_NewItem0");
131 var newMenuItem1 = createXULMenuItem("NewMenuItem1", "cmd_NewItem1");
132 var newMenuItem2 = createXULMenuItem("NewMenuItem2", "cmd_NewItem2");
133 var newMenuItem3 = createXULMenuItem("NewMenuItem3", "cmd_NewItem3");
134 var newMenuItem4 = createXULMenuItem("NewMenuItem4", "cmd_NewItem4");
135 var newMenuItem5 = createXULMenuItem("NewMenuItem5", "cmd_NewItem5");
136
137 // Create another submenu with hierarchy via DOM manipulation.
138 // ******************
139 // * Foo * NewMenu0 * <- Menu bar
140 // ******************
141 // ****************
142 // * NewMenuItem0 * <- NewMenu0 submenu
143 // ****************
144 // * NewMenuItem1 *
145 // ****************
146 // * NewMenuItem2 *
147 // *******************************
148 // * NewMenu1 > * NewMenuItem3 * <- NewMenu1 submenu
149 // *******************************
150 // * NewMenuItem4 *
151 // ****************
152 // * NewMenuItem5 *
153 // ****************
154 newMenu0.appendChild(newMenuPopup0);
155 newMenuPopup0.appendChild(newMenuItem0);
156 newMenuPopup0.appendChild(newMenuItem1);
157 newMenuPopup0.appendChild(newMenuItem2);
158 newMenuPopup0.appendChild(newMenu1);
159 newMenu1.appendChild(newMenuPopup1);
160 newMenuPopup1.appendChild(newMenuItem3);
161 newMenuPopup1.appendChild(newMenuItem4);
162 newMenuPopup1.appendChild(newMenuItem5);
163 //XXX - we have to append the menu to the top-level of the menu bar
164 // only after constructing it. If we append before construction, it is
165 // invalid because it has no children and we don't validate it if we add
166 // children later.
167 menubarNode.appendChild(newMenu0);
168 forceUpdateNativeMenuAt("1|3");
169 // Run basic tests again.
170 ok(runBaseMenuTests());
171
172 // Error strings.
173 var sa = "Command handler(s) should have activated";
174 var sna = "Command handler(s) should not have activated";
175
176 // Test middle items.
177 ok(testItem("1|1", "cmd_NewItem1"), sa);
178 ok(testItem("1|3|1", "cmd_NewItem4"), sa);
179
180 // Hide newMenu0.
181 newMenu0.setAttribute("hidden", "true");
182 ok(runBaseMenuTests(), sa); // the base menu should still be unhidden
183 ok(!testItem("1|0", ""), sna);
184 ok(!testItem("1|1", ""), sna);
185 ok(!testItem("1|2", ""), sna);
186 ok(!testItem("1|3|0", ""), sna);
187 ok(!testItem("1|3|1", ""), sna);
188 ok(!testItem("1|3|2", ""), sna);
189
190 // Show newMenu0.
191 newMenu0.setAttribute("hidden", "false");
192 forceUpdateNativeMenuAt("1|3");
193 ok(runBaseMenuTests(), sa);
194 ok(testItem("1|0", "cmd_NewItem0"), sa);
195 ok(testItem("1|1", "cmd_NewItem1"), sa);
196 ok(testItem("1|2", "cmd_NewItem2"), sa);
197 ok(testItem("1|3|0", "cmd_NewItem3"), sa);
198 ok(testItem("1|3|1", "cmd_NewItem4"), sa);
199 ok(testItem("1|3|2", "cmd_NewItem5"), sa);
200
201 // Hide items.
202 newMenuItem1.setAttribute("hidden", "true");
203 newMenuItem4.setAttribute("hidden", "true");
204 forceUpdateNativeMenuAt("1|2");
205 ok(runBaseMenuTests(), sa);
206 ok(testItem("1|0", "cmd_NewItem0"), sa);
207 ok(testItem("1|1", "cmd_NewItem2"), sa);
208 ok(!testItem("1|2", ""), sna);
209 ok(testItem("1|2|0", "cmd_NewItem3"), sa);
210 ok(testItem("1|2|1", "cmd_NewItem5"), sa);
211 ok(!testItem("1|2|2", ""), sna);
212
213 // Show items.
214 newMenuItem1.setAttribute("hidden", "false");
215 newMenuItem4.setAttribute("hidden", "false");
216 forceUpdateNativeMenuAt("1|3");
217 ok(runBaseMenuTests(), sa);
218 ok(testItem("1|0", "cmd_NewItem0"), sa);
219 ok(testItem("1|1", "cmd_NewItem1"), sa);
220 ok(testItem("1|2", "cmd_NewItem2"), sa);
221 ok(testItem("1|3|0", "cmd_NewItem3"), sa);
222 ok(testItem("1|3|1", "cmd_NewItem4"), sa);
223 ok(testItem("1|3|2", "cmd_NewItem5"), sa);
224
225 // At this point in the tests the state of the menus has been returned
226 // to the originally diagramed state.
227
228 // Remove menu.
229 menubarNode.removeChild(newMenu0);
230 ok(runBaseMenuTests(), sa);
231 ok(!testItem("1|0", ""), sna);
232 ok(!testItem("1|1", ""), sna);
233 ok(!testItem("1|2", ""), sna);
234 ok(!testItem("1|3|0", ""), sna);
235 ok(!testItem("1|3|1", ""), sna);
236 ok(!testItem("1|3|2", ""), sna);
237 // return state to original diagramed state
238 menubarNode.appendChild(newMenu0);
239
240 // Test for bug 447042, make sure that adding a menu node with no children
241 // to the menu bar and then adding another menu node with children works.
242 // Menus with no children don't get their native menu items shown and that
243 // caused internal arrays to get out of sync and an append crashed.
244 var tmpMenu0 = createXULMenu("tmpMenu0");
245 menubarNode.removeChild(newMenu0);
246 menubarNode.appendChild(tmpMenu0);
247 menubarNode.appendChild(newMenu0);
248 forceUpdateNativeMenuAt("1|3");
249 ok(runBaseMenuTests());
250 ok(testItem("1|0", "cmd_NewItem0"), sa);
251 ok(testItem("1|1", "cmd_NewItem1"), sa);
252 ok(testItem("1|2", "cmd_NewItem2"), sa);
253 ok(testItem("1|3|0", "cmd_NewItem3"), sa);
254 ok(testItem("1|3|1", "cmd_NewItem4"), sa);
255 ok(testItem("1|3|2", "cmd_NewItem5"), sa);
256 // return state to original diagramed state
257 menubarNode.removeChild(tmpMenu0);
258 delete tmpMenu0;
259
260 // This test is basically a crash test for bug 433858.
261 newMenuItem1.setAttribute("hidden", "true");
262 newMenuItem2.setAttribute("hidden", "true");
263 newMenu1.setAttribute("hidden", "true");
264 forceUpdateNativeMenuAt("1");
265 newMenuItem1.setAttribute("hidden", "false");
266 newMenuItem2.setAttribute("hidden", "false");
267 newMenu1.setAttribute("hidden", "false");
268 forceUpdateNativeMenuAt("1");
269
270 onTestsFinished();
271 }
272
273 setTimeout(_delayedOnLoad, 1000);
274 }
275
276 ]]></script>
277 </window>

mercurial