Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=542058
5 -->
6 <head>
7 <title>Test for MediaQueryList (Bug 542058)</title>
8 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
10 </head>
11 <body onload="run()">
12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=542058">Mozilla Bug 542058</a>
13 <iframe id="subdoc" src="about:blank"></iframe>
14 <div id="content" style="display:none"></div>
15 <pre id="test">
16 <script type="application/javascript">
18 /** Test for MediaQueryList (Bug 542058) **/
20 SimpleTest.waitForExplicitFinish();
22 function run() {
23 var iframe = document.getElementById("subdoc");
24 var subdoc = iframe.contentDocument;
25 var subwin = iframe.contentWindow;
26 var subroot = subdoc.documentElement;
28 var content_div = document.getElementById("content");
29 content_div.style.font = "initial";
30 var em_size =
31 getComputedStyle(content_div, "").fontSize.match(/^(\d+)px$/)[1];
33 var w = Math.floor(em_size * 9.3);
34 var h = Math.floor(em_size * 4.2);
35 iframe.style.width = w + "px";
36 iframe.style.height = h + "px";
37 subroot.offsetWidth; // flush layout
39 function setup_mql(str) {
40 var obj = {
41 str: str,
42 mql: subwin.matchMedia(str),
43 notifyCount: 0,
44 listener: function(mql) {
45 is(mql, obj.mql,
46 "correct argument to listener: " + obj.str);
47 ++obj.notifyCount;
48 // Test the last match result only on odd
49 // notifications.
50 if (obj.notifyCount & 1) {
51 obj.lastOddMatchResult = mql.matches;
52 }
53 }
54 }
55 obj.mql.addListener(obj.listener);
56 return obj;
57 }
59 function finish_mql(obj) {
60 obj.mql.removeListener(obj.listener);
61 }
63 var w_exact_w = setup_mql("(width: " + w + "px)");
64 var w_min_9em = setup_mql("(min-width : 9em)");
65 var w_min_10em = setup_mql("( min-width: 10em ) ");
66 var w_max_9em = setup_mql("(max-width: 9em)");
67 var w_max_10em = setup_mql("(max-width: 10em)");
69 is(w_exact_w.mql.media, "(width: " + w + "px)", "serialization");
70 is(w_min_9em.mql.media, "(min-width: 9em)", "serialization");
71 is(w_min_10em.mql.media, "(min-width: 10em)", "serialization");
72 is(w_max_9em.mql.media, "(max-width: 9em)", "serialization");
73 is(w_max_10em.mql.media, "(max-width: 10em)", "serialization");
75 function check_match(obj, expected, desc) {
76 is(obj.mql.matches, expected,
77 obj.str + " media query list .matches " + desc);
78 if (obj.notifyCount & 1) { // odd notifications only
79 is(obj.lastOddMatchResult, expected,
80 obj.str + " media query list last notify result " + desc);
81 }
82 }
83 function check_notify(obj, expected, desc) {
84 is(obj.notifyCount, expected,
85 obj.str + " media query list .notify count " + desc);
86 }
87 check_match(w_exact_w, true, "initially");
88 check_notify(w_exact_w, 0, "initially");
89 check_match(w_min_9em, true, "initially");
90 check_notify(w_min_9em, 0, "initially");
91 check_match(w_min_10em, false, "initially");
92 check_notify(w_min_10em, 0, "initially");
93 check_match(w_max_9em, false, "initially");
94 check_notify(w_max_9em, 0, "initially");
95 check_match(w_max_10em, true, "initially");
96 check_notify(w_max_10em, 0, "initially");
98 var w2 = Math.floor(em_size * 10.3);
99 iframe.style.width = w2 + "px";
100 subroot.offsetWidth; // flush layout
102 check_match(w_exact_w, false, "after width increase to around 10.3em");
103 check_notify(w_exact_w, 1, "after width increase to around 10.3em");
104 check_match(w_min_9em, true, "after width increase to around 10.3em");
105 check_notify(w_min_9em, 0, "after width increase to around 10.3em");
106 check_match(w_min_10em, true, "after width increase to around 10.3em");
107 check_notify(w_min_10em, 1, "after width increase to around 10.3em");
108 check_match(w_max_9em, false, "after width increase to around 10.3em");
109 check_notify(w_max_9em, 0, "after width increase to around 10.3em");
110 check_match(w_max_10em, false, "after width increase to around 10.3em");
111 check_notify(w_max_10em, 1, "after width increase to around 10.3em");
113 var w3 = w * 2;
114 iframe.style.width = w3 + "px";
115 subroot.offsetWidth; // flush layout
117 check_match(w_exact_w, false, "after width double from original");
118 check_notify(w_exact_w, 1, "after width double from original");
119 check_match(w_min_9em, true, "after width double from original");
120 check_notify(w_min_9em, 0, "after width double from original");
121 check_match(w_min_10em, true, "after width double from original");
122 check_notify(w_min_10em, 1, "after width double from original");
123 check_match(w_max_9em, false, "after width double from original");
124 check_notify(w_max_9em, 0, "after width double from original");
125 check_match(w_max_10em, false, "after width double from original");
126 check_notify(w_max_10em, 1, "after width double from original");
128 SpecialPowers.setFullZoom(subwin, 2.0);
129 subroot.offsetWidth; // flush layout
131 check_match(w_exact_w, true, "after zoom");
132 check_notify(w_exact_w, 2, "after zoom");
133 check_match(w_min_9em, true, "after zoom");
134 check_notify(w_min_9em, 0, "after zoom");
135 check_match(w_min_10em, false, "after zoom");
136 check_notify(w_min_10em, 2, "after zoom");
137 check_match(w_max_9em, false, "after zoom");
138 check_notify(w_max_9em, 0, "after zoom");
139 check_match(w_max_10em, true, "after zoom");
140 check_notify(w_max_10em, 2, "after zoom");
142 SpecialPowers.setFullZoom(subwin, 1.0);
144 finish_mql(w_exact_w);
145 finish_mql(w_min_9em);
146 finish_mql(w_min_10em);
147 finish_mql(w_max_9em);
148 finish_mql(w_max_10em);
150 // Additional tests of listener mutation.
151 (function() {
152 var received = [];
153 var received_mql = [];
154 function listener1(mql) {
155 received.push(1);
156 received_mql.push(mql);
157 }
158 function listener2(mql) {
159 received.push(2);
160 received_mql.push(mql);
161 }
163 iframe.style.width = "200px";
164 subroot.offsetWidth; // flush layout
166 var mql = subwin.matchMedia("(min-width: 150px)");
167 mql.addListener(listener1);
168 mql.addListener(listener1);
169 mql.addListener(listener2);
170 is(JSON.stringify(received), "[]", "listeners before notification");
172 iframe.style.width = "100px";
173 subroot.offsetWidth; // flush layout
175 is(JSON.stringify(received), "[1,2]", "duplicate listeners removed");
176 received = [];
177 mql.removeListener(listener1);
179 iframe.style.width = "200px";
180 subroot.offsetWidth; // flush layout
182 is(JSON.stringify(received), "[2]", "listener removal");
183 received = [];
184 mql.addListener(listener1);
186 iframe.style.width = "100px";
187 subroot.offsetWidth; // flush layout
189 is(JSON.stringify(received), "[2,1]", "listeners notified in order");
190 received = [];
191 mql.addListener(listener2);
193 iframe.style.width = "200px";
194 subroot.offsetWidth; // flush layout
196 is(JSON.stringify(received), "[2,1]", "add of existing listener is no-op");
197 received = [];
198 mql.addListener(listener1);
200 iframe.style.width = "100px";
201 subroot.offsetWidth; // flush layout
203 is(JSON.stringify(received), "[2,1]", "add of existing listener is no-op");
204 mql.removeListener(listener2);
205 received = [];
206 received_mql = [];
208 var mql2 = subwin.matchMedia("(min-width: 160px)");
209 mql2.addListener(listener1);
210 mql.addListener(listener2);
212 iframe.style.width = "200px";
213 subroot.offsetWidth; // flush layout
215 // mql (1, 2), mql2 (1)
216 is(JSON.stringify(received), "[1,2,1]",
217 "notification of lists in order created");
218 is(received_mql[0], mql,
219 "notification of lists in order created");
220 is(received_mql[1], mql,
221 "notification of lists in order created");
222 is(received_mql[2], mql2,
223 "notification of lists in order created");
224 received = [];
225 received_mql = [];
227 function removing_listener(mql) {
228 received.push(3);
229 received_mql.push(mql);
230 mql.removeListener(listener2);
231 mql2.removeListener(listener1);
232 }
234 mql.addListener(removing_listener);
235 mql.removeListener(listener2);
236 mql.addListener(listener2); // after removing_listener (3)
238 iframe.style.width = "100px";
239 subroot.offsetWidth; // flush layout
241 // mql(1, 3, 2) mql2(1)
242 is(JSON.stringify(received), "[1,3,2,1]",
243 "listeners still notified after removed if change was before");
244 is(received_mql[0], mql,
245 "notification order (removal tests)");
246 is(received_mql[1], mql,
247 "notification order (removal tests)");
248 is(received_mql[2], mql,
249 "notification order (removal tests)");
250 is(received_mql[3], mql2,
251 "notification order (removal tests)");
252 received = [];
253 received_mql = [];
255 iframe.style.width = "200px";
256 subroot.offsetWidth; // flush layout
258 // mql(1, 3)
259 is(JSON.stringify(received), "[1,3]",
260 "listeners not notified for changes after their removal");
261 is(received_mql[0], mql,
262 "notification order (removal tests)");
263 is(received_mql[1], mql,
264 "notification order (removal tests)");
265 })();
267 /* Bug 716751: null-dereference crash */
268 (function() {
269 iframe.style.width = "200px";
270 subroot.offsetWidth; // flush layout
272 var mql = subwin.matchMedia("(min-width: 150px)");
273 SimpleTest.doesThrow(function() {
274 mql.addListener(null);
275 }, "expected an exception");
277 iframe.style.width = "100px";
278 subroot.offsetWidth; // flush layout
279 // With the bug, we crash here. No need for test assertions.
281 SimpleTest.doesThrow(function() {
282 mql.removeListener(null);
283 }, "expected an exception");
284 SimpleTest.doesThrow(function() {
285 mql.removeListener(null);
286 }, "expected an exception");
287 })();
289 /* Bug 753777: test that things work in a freshly-created iframe */
290 (function() {
291 var iframe = document.createElement("iframe");
292 document.body.appendChild(iframe);
294 is(iframe.contentWindow.matchMedia("(min-width: 1px)").matches, true,
295 "(min-width: 1px) should match in newly-created iframe");
296 is(iframe.contentWindow.matchMedia("(max-width: 1px)").matches, false,
297 "(max-width: 1px) should not match in newly-created iframe");
299 document.body.removeChild(iframe);
300 })();
302 /* Bug 716751: listeners lost due to GC */
303 var gc_received = [];
304 (function() {
305 var received = [];
306 var listener1 = function(mql) {
307 gc_received.push(1);
308 }
310 iframe.style.width = "200px";
311 subroot.offsetWidth; // flush layout
313 var mql = subwin.matchMedia("(min-width: 150px)");
314 mql.addListener(listener1);
315 is(JSON.stringify(gc_received), "[]", "GC test: before notification");
317 iframe.style.width = "100px";
318 subroot.offsetWidth; // flush layout
320 is(JSON.stringify(gc_received), "[1]", "GC test: after notification 1");
322 // Because of conservative GC, we need to go back to the event loop
323 // to GC properly.
324 setTimeout(step2, 0);
325 })();
327 function step2() {
328 SpecialPowers.DOMWindowUtils.garbageCollect();
330 iframe.style.width = "200px";
331 subroot.offsetWidth; // flush layout
333 is(JSON.stringify(gc_received), "[1,1]", "GC test: after notification 2");
335 SimpleTest.finish();
336 }
337 }
339 </script>
340 </pre>
341 </body>
342 </html>