|
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" type="text/css"?> |
|
4 |
|
5 <window title="Popup Removing Tests" |
|
6 onload="setTimeout(nextTest, 0)" |
|
7 onDOMAttrModified="modified(event)" |
|
8 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> |
|
9 |
|
10 <!-- |
|
11 This test checks that popup elements can be removed in various ways without |
|
12 crashing. It tests two situations, one with menus that are 'separate', and |
|
13 one with menus that are 'nested'. In each case, there are four levels of menu. |
|
14 |
|
15 The nextTest function starts the process by opening the first menu. A set of |
|
16 popupshown event listeners are used to open the next menu until all four are |
|
17 showing. This last one calls removePopup to remove the menu node from the |
|
18 tree. This should hide the popups as they are no longer in a document. |
|
19 |
|
20 A mutation listener is triggered when the fourth menu closes by having its |
|
21 open attribute cleared. This listener hides the third popup which causes |
|
22 its frame to be removed. Naturally, we want to ensure that this doesn't |
|
23 crash when the third menu is removed. |
|
24 --> |
|
25 |
|
26 <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> |
|
27 <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> |
|
28 |
|
29 <hbox> |
|
30 |
|
31 <menu id="nestedmenu1" label="1"> |
|
32 <menupopup id="nestedpopup1" onpopupshown="if (event.target == this) this.firstChild.open = true"> |
|
33 <menu id="nestedmenu2" label="2"> |
|
34 <menupopup id="nestedpopup2" onpopupshown="if (event.target == this) this.firstChild.open = true"> |
|
35 <menu id="nestedmenu3" label="3"> |
|
36 <menupopup id="nestedpopup3" onpopupshown="if (event.target == this) this.firstChild.open = true"> |
|
37 <menu id="nestedmenu4" label="4" onpopupshown="removePopups()"> |
|
38 <menupopup id="nestedpopup4"> |
|
39 <menuitem label="Nested 1"/> |
|
40 <menuitem label="Nested 2"/> |
|
41 <menuitem label="Nested 3"/> |
|
42 </menupopup> |
|
43 </menu> |
|
44 </menupopup> |
|
45 </menu> |
|
46 </menupopup> |
|
47 </menu> |
|
48 </menupopup> |
|
49 </menu> |
|
50 |
|
51 <menu id="separatemenu1" label="1"> |
|
52 <menupopup id="separatepopup1" onpopupshown="$('separatemenu2').open = true"> |
|
53 <menuitem label="L1 One"/> |
|
54 <menuitem label="L1 Two"/> |
|
55 <menuitem label="L1 Three"/> |
|
56 </menupopup> |
|
57 </menu> |
|
58 |
|
59 <menu id="separatemenu2" label="2"> |
|
60 <menupopup id="separatepopup2" onpopupshown="$('separatemenu3').open = true" |
|
61 onpopuphidden="popup2Hidden()"> |
|
62 <menuitem label="L2 One"/> |
|
63 <menuitem label="L2 Two"/> |
|
64 <menuitem label="L2 Three"/> |
|
65 </menupopup> |
|
66 </menu> |
|
67 |
|
68 <menu id="separatemenu3" label="3" onpopupshown="$('separatemenu4').open = true"> |
|
69 <menupopup id="separatepopup3"> |
|
70 <menuitem label="L3 One"/> |
|
71 <menuitem label="L3 Two"/> |
|
72 <menuitem label="L3 Three"/> |
|
73 </menupopup> |
|
74 </menu> |
|
75 |
|
76 <menu id="separatemenu4" label="4" onpopupshown="removePopups()" |
|
77 onpopuphidden="$('separatemenu2').open = false"> |
|
78 <menupopup id="separatepopup3"> |
|
79 <menuitem label="L4 One"/> |
|
80 <menuitem label="L4 Two"/> |
|
81 <menuitem label="L4 Three"/> |
|
82 </menupopup> |
|
83 </menu> |
|
84 |
|
85 </hbox> |
|
86 |
|
87 <script class="testbody" type="application/javascript"> |
|
88 <![CDATA[ |
|
89 |
|
90 SimpleTest.waitForExplicitFinish(); |
|
91 |
|
92 var gKey = ""; |
|
93 gTriggerMutation = null; |
|
94 gChangeMutation = null; |
|
95 |
|
96 function nextTest() |
|
97 { |
|
98 if (gKey == "") { |
|
99 gKey = "separate"; |
|
100 } |
|
101 else if (gKey == "separate") { |
|
102 gKey = "nested"; |
|
103 } |
|
104 else { |
|
105 SimpleTest.finish(); |
|
106 return; |
|
107 } |
|
108 |
|
109 $(gKey + "menu1").open = true; |
|
110 } |
|
111 |
|
112 function modified(event) |
|
113 { |
|
114 // use this mutation listener to hide the third popup, destroying its frame. |
|
115 // It gets triggered when the open attribute is cleared on the fourth menu. |
|
116 |
|
117 if (event.target == gTriggerMutation && |
|
118 event.attrName == "open") { |
|
119 gChangeMutation.hidden = true; |
|
120 // force a layout flush |
|
121 document.documentElement.boxObject.width; |
|
122 gTriggerMutation = null; |
|
123 gChangeMutation = null; |
|
124 } |
|
125 } |
|
126 |
|
127 function removePopups() |
|
128 { |
|
129 var menu2 = $(gKey + "menu2"); |
|
130 var menu3 = $(gKey + "menu3"); |
|
131 is(menu2.getAttribute("open"), "true", gKey + " menu 2 open before"); |
|
132 is(menu3.getAttribute("open"), "true", gKey + " menu 3 open before"); |
|
133 |
|
134 gTriggerMutation = menu3; |
|
135 gChangeMutation = $(gKey + "menu4"); |
|
136 var menu = $(gKey + "menu1"); |
|
137 menu.parentNode.removeChild(menu); |
|
138 |
|
139 if (gKey == "nested") { |
|
140 // the 'separate' test checks this during the popup2 hidden event handler |
|
141 is(menu2.hasAttribute("open"), false, gKey + " menu 2 open after"); |
|
142 is(menu3.hasAttribute("open"), false, gKey + " menu 3 open after"); |
|
143 nextTest(); |
|
144 } |
|
145 } |
|
146 |
|
147 function popup2Hidden() |
|
148 { |
|
149 is($(gKey + "menu2").hasAttribute("open"), false, gKey + " menu 2 open after"); |
|
150 nextTest(); |
|
151 } |
|
152 |
|
153 ]]> |
|
154 </script> |
|
155 |
|
156 <body xmlns="http://www.w3.org/1999/xhtml"> |
|
157 <p id="display"> |
|
158 </p> |
|
159 <div id="content" style="display: none"> |
|
160 </div> |
|
161 <pre id="test"> |
|
162 </pre> |
|
163 </body> |
|
164 |
|
165 </window> |