<!DOCTYPE html>
<meta charset="utf-8">
<meta name="flags" content="dom">
<title>CSS Test: CSSOM View MediaQueryList::{add,remove}Listener</title>
<link rel="author" title="Rune Lillesveen" href="mailto:[email protected]">
<link rel="help" href="https://www.w3.org/TR/cssom-view-1/#the-mediaquerylist-interface">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/matchMedia.js"></script>
<div id="log"></div>
<script>
"use strict";
test(() => {
const mql = window.matchMedia("(min-width: 100px)");
mql.addListener(null);
mql.addListener(undefined);
mql.removeListener(null);
mql.removeListener(undefined);
}, "EventListener parameter is optional");
promise_test(async t => {
const iframe = await createIFrame(t, 200, 100);
const heightMQL = iframe.contentWindow.matchMedia("(max-height: 50px)");
const widthMQL = iframe.contentWindow.matchMedia("(min-width: 150px)");
let heightEvent;
let widthEvent;
heightMQL.addListener(event => {
heightEvent = event;
});
widthMQL.addListener(event => {
widthEvent = event;
});
assert_false(heightMQL.matches);
assert_true(widthMQL.matches);
iframe.height = "50"; // 200x100 => 200x50
await waitForChangesReported();
assert_equals(heightEvent.media, heightMQL.media);
assert_true(heightEvent.matches);
assert_true(heightMQL.matches);
assert_true(widthMQL.matches);
iframe.width = "100"; // 200x50 => 100x50
await waitForChangesReported();
assert_equals(widthEvent.media, widthMQL.media);
assert_false(widthEvent.matches);
assert_false(widthMQL.matches);
assert_true(heightMQL.matches);
}, "listeners are called when <iframe> is resized");
promise_test(async t => {
const mql = await createMQL(t);
let eventsCount = 0;
mql.addListener(() => {
eventsCount++;
});
for (let i = 1; i <= 10; i++) {
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(eventsCount, i);
}
}, "listeners are called correct number of times");
promise_test(async t => {
const mql = await createMQL(t);
const calls = [];
mql.addListener(() => {
calls.push("1st");
});
mql.addListener(() => {
calls.push("2nd");
});
triggerMQLEvent(mql);
await waitForChangesReported();
assert_array_equals(calls, ["1st", "2nd"]);
}, "listeners are called in order they were added");
promise_test(async t => {
const mql = await createMQL(t);
let called = 0;
const listener = () => {
called++;
};
mql.addListener(listener);
mql.addListener(listener);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(called, 1);
}, "listener that was added twice is called only once");
promise_test(async t => {
const iframe = await createIFrame(t, 100);
const media = `(min-width: 200px)`;
const mql1 = iframe.contentWindow.matchMedia(media);
const mql2 = iframe.contentWindow.matchMedia(media);
const calls = [];
mql2.addListener(() => {
calls.push("mql2");
});
mql1.addListener(() => {
calls.push("mql1");
});
iframe.width = "200"; // 100x100 => 200x100
await waitForChangesReported();
assert_array_equals(calls, ["mql1", "mql2"]);
}, "listeners are called in order their MQLs were created");
promise_test(async t => {
const iframe = await createIFrame(t, 200);
const media = `(max-height: 150px)`;
const mql1 = iframe.contentWindow.matchMedia(media);
const mql2 = iframe.contentWindow.matchMedia(media);
let calls = 0;
const listener = () => {
calls++;
};
mql1.addListener(listener);
mql2.removeListener(listener);
iframe.height = "50"; // 200x200 => 200x50
await waitForChangesReported();
assert_equals(calls, 1);
}, "removing listener from one MQL doesn't remove it from all MQLs");
promise_test(async t => {
const mql = await createMQL(t);
const listener = t.unreached_func("should not be called");
mql.addListener(listener);
mql.removeListener(listener);
triggerMQLEvent(mql);
await waitForChangesReported();
}, "MediaQueryList::removeListener removes added listener");
</script>