1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/content/tests/chrome/test_popupremoving.xul Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,165 @@ 1.4 +<?xml version="1.0"?> 1.5 +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> 1.6 +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> 1.7 + 1.8 +<window title="Popup Removing Tests" 1.9 + onload="setTimeout(nextTest, 0)" 1.10 + onDOMAttrModified="modified(event)" 1.11 + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 1.12 + 1.13 +<!-- 1.14 + This test checks that popup elements can be removed in various ways without 1.15 + crashing. It tests two situations, one with menus that are 'separate', and 1.16 + one with menus that are 'nested'. In each case, there are four levels of menu. 1.17 + 1.18 + The nextTest function starts the process by opening the first menu. A set of 1.19 + popupshown event listeners are used to open the next menu until all four are 1.20 + showing. This last one calls removePopup to remove the menu node from the 1.21 + tree. This should hide the popups as they are no longer in a document. 1.22 + 1.23 + A mutation listener is triggered when the fourth menu closes by having its 1.24 + open attribute cleared. This listener hides the third popup which causes 1.25 + its frame to be removed. Naturally, we want to ensure that this doesn't 1.26 + crash when the third menu is removed. 1.27 + --> 1.28 + 1.29 + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 1.30 + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> 1.31 + 1.32 +<hbox> 1.33 + 1.34 +<menu id="nestedmenu1" label="1"> 1.35 + <menupopup id="nestedpopup1" onpopupshown="if (event.target == this) this.firstChild.open = true"> 1.36 + <menu id="nestedmenu2" label="2"> 1.37 + <menupopup id="nestedpopup2" onpopupshown="if (event.target == this) this.firstChild.open = true"> 1.38 + <menu id="nestedmenu3" label="3"> 1.39 + <menupopup id="nestedpopup3" onpopupshown="if (event.target == this) this.firstChild.open = true"> 1.40 + <menu id="nestedmenu4" label="4" onpopupshown="removePopups()"> 1.41 + <menupopup id="nestedpopup4"> 1.42 + <menuitem label="Nested 1"/> 1.43 + <menuitem label="Nested 2"/> 1.44 + <menuitem label="Nested 3"/> 1.45 + </menupopup> 1.46 + </menu> 1.47 + </menupopup> 1.48 + </menu> 1.49 + </menupopup> 1.50 + </menu> 1.51 + </menupopup> 1.52 +</menu> 1.53 + 1.54 +<menu id="separatemenu1" label="1"> 1.55 + <menupopup id="separatepopup1" onpopupshown="$('separatemenu2').open = true"> 1.56 + <menuitem label="L1 One"/> 1.57 + <menuitem label="L1 Two"/> 1.58 + <menuitem label="L1 Three"/> 1.59 + </menupopup> 1.60 +</menu> 1.61 + 1.62 +<menu id="separatemenu2" label="2"> 1.63 + <menupopup id="separatepopup2" onpopupshown="$('separatemenu3').open = true" 1.64 + onpopuphidden="popup2Hidden()"> 1.65 + <menuitem label="L2 One"/> 1.66 + <menuitem label="L2 Two"/> 1.67 + <menuitem label="L2 Three"/> 1.68 + </menupopup> 1.69 +</menu> 1.70 + 1.71 +<menu id="separatemenu3" label="3" onpopupshown="$('separatemenu4').open = true"> 1.72 + <menupopup id="separatepopup3"> 1.73 + <menuitem label="L3 One"/> 1.74 + <menuitem label="L3 Two"/> 1.75 + <menuitem label="L3 Three"/> 1.76 + </menupopup> 1.77 +</menu> 1.78 + 1.79 +<menu id="separatemenu4" label="4" onpopupshown="removePopups()" 1.80 + onpopuphidden="$('separatemenu2').open = false"> 1.81 + <menupopup id="separatepopup3"> 1.82 + <menuitem label="L4 One"/> 1.83 + <menuitem label="L4 Two"/> 1.84 + <menuitem label="L4 Three"/> 1.85 + </menupopup> 1.86 +</menu> 1.87 + 1.88 +</hbox> 1.89 + 1.90 +<script class="testbody" type="application/javascript"> 1.91 +<![CDATA[ 1.92 + 1.93 +SimpleTest.waitForExplicitFinish(); 1.94 + 1.95 +var gKey = ""; 1.96 +gTriggerMutation = null; 1.97 +gChangeMutation = null; 1.98 + 1.99 +function nextTest() 1.100 +{ 1.101 + if (gKey == "") { 1.102 + gKey = "separate"; 1.103 + } 1.104 + else if (gKey == "separate") { 1.105 + gKey = "nested"; 1.106 + } 1.107 + else { 1.108 + SimpleTest.finish(); 1.109 + return; 1.110 + } 1.111 + 1.112 + $(gKey + "menu1").open = true; 1.113 +} 1.114 + 1.115 +function modified(event) 1.116 +{ 1.117 + // use this mutation listener to hide the third popup, destroying its frame. 1.118 + // It gets triggered when the open attribute is cleared on the fourth menu. 1.119 + 1.120 + if (event.target == gTriggerMutation && 1.121 + event.attrName == "open") { 1.122 + gChangeMutation.hidden = true; 1.123 + // force a layout flush 1.124 + document.documentElement.boxObject.width; 1.125 + gTriggerMutation = null; 1.126 + gChangeMutation = null; 1.127 + } 1.128 +} 1.129 + 1.130 +function removePopups() 1.131 +{ 1.132 + var menu2 = $(gKey + "menu2"); 1.133 + var menu3 = $(gKey + "menu3"); 1.134 + is(menu2.getAttribute("open"), "true", gKey + " menu 2 open before"); 1.135 + is(menu3.getAttribute("open"), "true", gKey + " menu 3 open before"); 1.136 + 1.137 + gTriggerMutation = menu3; 1.138 + gChangeMutation = $(gKey + "menu4"); 1.139 + var menu = $(gKey + "menu1"); 1.140 + menu.parentNode.removeChild(menu); 1.141 + 1.142 + if (gKey == "nested") { 1.143 + // the 'separate' test checks this during the popup2 hidden event handler 1.144 + is(menu2.hasAttribute("open"), false, gKey + " menu 2 open after"); 1.145 + is(menu3.hasAttribute("open"), false, gKey + " menu 3 open after"); 1.146 + nextTest(); 1.147 + } 1.148 +} 1.149 + 1.150 +function popup2Hidden() 1.151 +{ 1.152 + is($(gKey + "menu2").hasAttribute("open"), false, gKey + " menu 2 open after"); 1.153 + nextTest(); 1.154 +} 1.155 + 1.156 +]]> 1.157 +</script> 1.158 + 1.159 +<body xmlns="http://www.w3.org/1999/xhtml"> 1.160 +<p id="display"> 1.161 +</p> 1.162 +<div id="content" style="display: none"> 1.163 +</div> 1.164 +<pre id="test"> 1.165 +</pre> 1.166 +</body> 1.167 + 1.168 +</window>