diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /layout/style/test/test_media_query_list.html | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/style/test/test_media_query_list.html')
-rw-r--r-- | layout/style/test/test_media_query_list.html | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/layout/style/test/test_media_query_list.html b/layout/style/test/test_media_query_list.html new file mode 100644 index 0000000000..5f213117e5 --- /dev/null +++ b/layout/style/test/test_media_query_list.html @@ -0,0 +1,373 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=542058 +--> +<head> + <title>Test for MediaQueryList (Bug 542058)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="run()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=542058">Mozilla Bug 542058</a> +<iframe id="subdoc" src="about:blank"></iframe> +<div id="content" style="display:none"></div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for MediaQueryList (Bug 542058) **/ + +SimpleTest.waitForExplicitFinish(); + +function tick() { + // MediaQueryList events are guaranteed to run before requestAnimationFrame + // per spec. + return new Promise(r => requestAnimationFrame(r)); +} + +async function run() { + var iframe = document.getElementById("subdoc"); + var subdoc = iframe.contentDocument; + var subwin = iframe.contentWindow; + var subroot = subdoc.documentElement; + + var content_div = document.getElementById("content"); + content_div.style.font = "initial"; + var em_size = + getComputedStyle(content_div).fontSize.match(/^(\d+)px$/)[1]; + + var w = Math.floor(em_size * 9.3); + var h = Math.floor(em_size * 4.2); + iframe.style.width = w + "px"; + iframe.style.height = h + "px"; + subroot.offsetWidth; // flush layout + await tick(); + + function setup_mql(str) { + var obj = { + str: str, + mql: subwin.matchMedia(str), + notifyCount: 0, + listener: function(event) { + ok(event instanceof subwin.MediaQueryListEvent, + "correct argument to listener: " + obj.str); + is(event.media, obj.mql.media, + "correct media in the event: " + obj.str); + is(event.target, obj.mql, + "correct target in the event: " + obj.str); + ++obj.notifyCount; + // Test the last match result only on odd + // notifications. + if (obj.notifyCount & 1) { + obj.lastOddMatchResult = event.target.matches; + } + } + } + obj.mql.addListener(obj.listener); + return obj; + } + + function finish_mql(obj) { + obj.mql.removeListener(obj.listener); + } + + var w_exact_w = setup_mql("(width: " + w + "px)"); + var w_min_9em = setup_mql("(min-width : 9em)"); + var w_min_10em = setup_mql("( min-width: 10em ) "); + var w_max_9em = setup_mql("(max-width: 9em)"); + var w_max_10em = setup_mql("(max-width: 10em)"); + + is(w_exact_w.mql.media, "(width: " + w + "px)", "serialization"); + is(w_min_9em.mql.media, "(min-width: 9em)", "serialization"); + is(w_min_10em.mql.media, "(min-width: 10em)", "serialization"); + is(w_max_9em.mql.media, "(max-width: 9em)", "serialization"); + is(w_max_10em.mql.media, "(max-width: 10em)", "serialization"); + + function check_match(obj, expected, desc) { + is(obj.mql.matches, expected, + obj.str + " media query list .matches " + desc); + if (obj.notifyCount & 1) { // odd notifications only + is(obj.lastOddMatchResult, expected, + obj.str + " media query list last notify result " + desc); + } + } + function check_notify(obj, expected, desc) { + is(obj.notifyCount, expected, + obj.str + " media query list .notify count " + desc); + } + check_match(w_exact_w, true, "initially"); + check_notify(w_exact_w, 0, "initially"); + check_match(w_min_9em, true, "initially"); + check_notify(w_min_9em, 0, "initially"); + check_match(w_min_10em, false, "initially"); + check_notify(w_min_10em, 0, "initially"); + check_match(w_max_9em, false, "initially"); + check_notify(w_max_9em, 0, "initially"); + check_match(w_max_10em, true, "initially"); + check_notify(w_max_10em, 0, "initially"); + + var w2 = Math.floor(em_size * 10.3); + iframe.style.width = w2 + "px"; + subroot.offsetWidth; // flush layout + await tick(); + + check_match(w_exact_w, false, "after width increase to around 10.3em"); + check_notify(w_exact_w, 1, "after width increase to around 10.3em"); + check_match(w_min_9em, true, "after width increase to around 10.3em"); + check_notify(w_min_9em, 0, "after width increase to around 10.3em"); + check_match(w_min_10em, true, "after width increase to around 10.3em"); + check_notify(w_min_10em, 1, "after width increase to around 10.3em"); + check_match(w_max_9em, false, "after width increase to around 10.3em"); + check_notify(w_max_9em, 0, "after width increase to around 10.3em"); + check_match(w_max_10em, false, "after width increase to around 10.3em"); + check_notify(w_max_10em, 1, "after width increase to around 10.3em"); + + var w3 = w * 2; + iframe.style.width = w3 + "px"; + subroot.offsetWidth; // flush layout + await tick(); + + check_match(w_exact_w, false, "after width double from original"); + check_notify(w_exact_w, 1, "after width double from original"); + check_match(w_min_9em, true, "after width double from original"); + check_notify(w_min_9em, 0, "after width double from original"); + check_match(w_min_10em, true, "after width double from original"); + check_notify(w_min_10em, 1, "after width double from original"); + check_match(w_max_9em, false, "after width double from original"); + check_notify(w_max_9em, 0, "after width double from original"); + check_match(w_max_10em, false, "after width double from original"); + check_notify(w_max_10em, 1, "after width double from original"); + + SpecialPowers.setFullZoom(subwin, 2.0); + subroot.offsetWidth; // flush layout + await tick(); + + check_match(w_exact_w, true, "after zoom"); + check_notify(w_exact_w, 2, "after zoom"); + check_match(w_min_9em, true, "after zoom"); + check_notify(w_min_9em, 0, "after zoom"); + check_match(w_min_10em, false, "after zoom"); + check_notify(w_min_10em, 2, "after zoom"); + check_match(w_max_9em, false, "after zoom"); + check_notify(w_max_9em, 0, "after zoom"); + check_match(w_max_10em, true, "after zoom"); + check_notify(w_max_10em, 2, "after zoom"); + + SpecialPowers.setFullZoom(subwin, 1.0); + + await tick(); + + finish_mql(w_exact_w); + finish_mql(w_min_9em); + finish_mql(w_min_10em); + finish_mql(w_max_9em); + finish_mql(w_max_10em); + + // Additional tests of listener mutation. + { + let received = []; + let received_mql = []; + function listener1(event) { + received.push(1); + received_mql.push(event.target); + } + function listener2(event) { + received.push(2); + received_mql.push(event.target); + } + + iframe.style.width = "200px"; + subroot.offsetWidth; // flush layout + await tick(); + + let mql = subwin.matchMedia("(min-width: 150px)"); + mql.addListener(listener1); + mql.addListener(listener1); + mql.addListener(listener2); + is(JSON.stringify(received), "[]", "listeners before notification"); + + iframe.style.width = "100px"; + subroot.offsetWidth; // flush layout + await tick(); + + is(JSON.stringify(received), "[1,2]", "duplicate listeners removed"); + received = []; + mql.removeListener(listener1); + + iframe.style.width = "200px"; + subroot.offsetWidth; // flush layout + await tick(); + + is(JSON.stringify(received), "[2]", "listener removal"); + received = []; + mql.addListener(listener1); + + iframe.style.width = "100px"; + subroot.offsetWidth; // flush layout + await tick(); + + is(JSON.stringify(received), "[2,1]", "listeners notified in order"); + received = []; + mql.addListener(listener2); + + iframe.style.width = "200px"; + subroot.offsetWidth; // flush layout + await tick(); + + is(JSON.stringify(received), "[2,1]", "add of existing listener is no-op"); + received = []; + mql.addListener(listener1); + + iframe.style.width = "100px"; + subroot.offsetWidth; // flush layout + await tick(); + + is(JSON.stringify(received), "[2,1]", "add of existing listener is no-op"); + mql.removeListener(listener2); + received = []; + received_mql = []; + + var mql2 = subwin.matchMedia("(min-width: 160px)"); + mql2.addListener(listener1); + mql.addListener(listener2); + + iframe.style.width = "200px"; + subroot.offsetWidth; // flush layout + await tick(); + + // mql (1, 2), mql2 (1) + is(JSON.stringify(received), "[1,2,1]", + "notification of lists in order created"); + is(received_mql[0], mql, + "notification of lists in order created"); + is(received_mql[1], mql, + "notification of lists in order created"); + is(received_mql[2], mql2, + "notification of lists in order created"); + received = []; + received_mql = []; + + function removing_listener(event) { + received.push(3); + received_mql.push(event.target); + event.target.removeListener(listener2); + mql2.removeListener(listener1); + } + + mql.addListener(removing_listener); + mql.removeListener(listener2); + mql.addListener(listener2); // after removing_listener (3) + + iframe.style.width = "100px"; + subroot.offsetWidth; // flush layout + await tick(); + + // mql(1, 3) + is(JSON.stringify(received), "[1,3]", + "listeners still notified after removed if change was before"); + is(received_mql[0], mql, + "notification order (removal tests)"); + is(received_mql[1], mql, + "notification order (removal tests)"); + received = []; + received_mql = []; + + iframe.style.width = "200px"; + subroot.offsetWidth; // flush layout + await tick(); + + // mql(1, 3) + is(JSON.stringify(received), "[1,3]", + "listeners not notified for changes after their removal"); + is(received_mql[0], mql, + "notification order (removal tests)"); + is(received_mql[1], mql, + "notification order (removal tests)"); + } + + /* Bug 753777: test that things work in a freshly-created iframe */ + { + let newIframe = document.createElement("iframe"); + document.body.appendChild(newIframe); + + is(newIframe.contentWindow.matchMedia("all").matches, true, + "matchMedia should work in newly-created iframe"); + is(newIframe.contentWindow.matchMedia("(min-width: 1px)").matches, true, + "(min-width: 1px) should match in newly-created iframe"); + is(newIframe.contentWindow.matchMedia("(max-width: 1px)").matches, false, + "(max-width: 1px) should not match in newly-created iframe"); + + document.body.removeChild(newIframe); + } + + /* Bug 716751: listeners lost due to GC */ + var gc_received = []; + { + let received = []; + let listener1 = function(event) { + gc_received.push(1); + } + + iframe.style.width = "200px"; + subroot.offsetWidth; // flush layout + await tick(); + + let mql = subwin.matchMedia("(min-width: 150px)"); + mql.addListener(listener1); + is(JSON.stringify(gc_received), "[]", "GC test: before notification"); + + iframe.style.width = "100px"; + subroot.offsetWidth; // flush layout + await tick(); + + is(JSON.stringify(gc_received), "[1]", "GC test: after notification 1"); + + // Because of conservative GC, we need to go back to the event loop + // to GC properly. + setTimeout(step2, 0); + } + + async function step2() { + SpecialPowers.DOMWindowUtils.garbageCollect(); + + iframe.style.width = "200px"; + subroot.offsetWidth; // flush layout + await tick(); + + is(JSON.stringify(gc_received), "[1,1]", "GC test: after notification 2"); + + bug1270626(); + } + + /* Bug 1270626: listeners that throw exceptions */ + async function bug1270626() { + var throwingListener = function(event) { + throw "error"; + } + + iframe.style.width = "200px"; + subroot.offsetWidth; // flush layout + await tick(); + + var mql = subwin.matchMedia("(min-width: 150px)"); + mql.addListener(throwingListener); + + SimpleTest.expectUncaughtException(true); + is(SimpleTest.isExpectingUncaughtException(), true, + "should be waiting for an uncaught exception"); + + iframe.style.width = "100px"; + subroot.offsetWidth; // flush layout + await tick(); + + is(SimpleTest.isExpectingUncaughtException(), false, + "should have gotten an uncaught exception"); + + SimpleTest.finish(); + } +} + +</script> +</pre> +</body> +</html> |