Tests/LibWeb: Import some CSSOM WPT tests

This commit is contained in:
Aliaksandr Kalenik 2024-11-12 21:53:44 +02:00 committed by Andreas Kling
parent 13b7c26e9f
commit d0646236ca
Notes: github-actions[bot] 2024-11-13 10:08:08 +00:00
52 changed files with 2005 additions and 0 deletions

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Pass
Details
Result Test Name MessagePass Element getClientRects()
Pass Range getClientRects()

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass getBoundingClientRect

View file

@ -0,0 +1,17 @@
Summary
Harness status: OK
Rerun
Found 6 tests
3 Pass
3 Fail
Details
Result Test Name MessageFail calls handleEvent method of event listener
Pass looks up handleEvent method on every event dispatch
Pass doesn't look up handleEvent method on callable event listeners
Pass rethrows errors when getting handleEvent
Fail throws if handleEvent is falsy and not callable
Fail throws if handleEvent is thruthy and not callable

View file

@ -0,0 +1,19 @@
Summary
Harness status: OK
Rerun
Found 8 tests
7 Pass
1 Fail
Details
Result Test Name MessagePass EventListener parameter is optional
Fail listeners are called when <iframe> is resized
Pass listeners are called correct number of times
Pass listeners are called in order they were added
Pass listener that was added twice is called only once
Pass listeners are called in order their MQLs were created
Pass removing listener from one MQL doesn't remove it from all MQLs
Pass MediaQueryList::removeListener removes added listener

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail MediaQueryList.changed is correct for all lists in the document even during a change event handler

View file

@ -0,0 +1,18 @@
Summary
Harness status: OK
Rerun
Found 8 tests
8 Pass
Details
Result Test Name MessagePass dispatchEvent triggers listener added with addListener
Pass listener added with addListener and addEventListener is called once
Pass listener added with addListener and addEventListener (capture) is called twice
Pass removeEventListener removes listener added with addListener
Pass removeEventListener (capture) doesn't remove listener added with addListener
Pass removeListener removes listener added with addEventListener
Pass removeListener doesn't remove listener added with addEventListener (capture)
Pass capturing event listener fires before non-capturing listener at target

View file

@ -0,0 +1,18 @@
Summary
Harness status: OK
Rerun
Found 7 tests
6 Pass
1 Fail
Details
Result Test Name MessageFail onchange adds listener
Pass onchange removes listener
Pass listeners for "change" type are called
Pass listeners with different type are not called
Pass addEventListener "once" option is respected
Pass removeEventListener removes listener
Pass dispatchEvent works as expected

View file

@ -0,0 +1,17 @@
Summary
Harness status: OK
Rerun
Found 6 tests
3 Pass
3 Fail
Details
Result Test Name MessagePass type can be different from "change"
Pass init dictionary default values
Pass init dictionary overrides
Fail argument of addListener
Fail argument of onchange
Fail constructor of "change" event

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Pass
Details
Result Test Name MessagePass getBoundingClientRect() should return a DOMRect where height=bottom-top
Pass getBoundingClientRect() should return a DOMRect where width=right-left

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass getBoundingClientRect on a newly-created Element not yet inserted into the DOM should return an all-zeroes DOMRect

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Fail
Details
Result Test Name MessageFail {Element,Range}.prototype.getBoundingClientRect on SVG <tspan>, Element
Fail {Element,Range}.prototype.getBoundingClientRect on SVG <tspan>, Range

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass CSSOM View - GetClientRects().length is the same regardless source new lines

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass getClientRects on a newly-created Element not yet inserted into the DOM should return an empty DOMRectList

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail CSSOM View - 5 - extensions to the Document interface

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass Checking whether dynamic changes to visibility interact correctly with table anonymous boxes

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass Checking whether dynamic changes to visibility interact correctly with table anonymous boxes

View file

@ -0,0 +1,14 @@
Summary
Harness status: OK
Rerun
Found 4 tests
4 Pass
Details
Result Test Name MessagePass simple scroll with style: 'margin' and 'overflow: scroll'
Pass simple scroll with style: 'margin' and 'overflow: hidden'
Pass simple scroll with style: 'padding' and 'overflow: scroll'
Pass simple scroll with style: 'padding' and 'overflow: hidden'

View file

@ -0,0 +1,18 @@
Summary
Harness status: OK
Rerun
Found 8 tests
8 Pass
Details
Result Test Name MessagePass Element scrollTop/Left getter/setter test
Pass Element scroll test (two arguments)
Pass Element scroll test (one argument)
Pass Element scrollTo test (two arguments)
Pass Element scrollTo test (one argument)
Pass Element scrollBy test (two arguments)
Pass Element scrollBy test (one argument)
Pass Element scroll maximum test

View file

@ -0,0 +1,17 @@
Summary
Harness status: OK
Rerun
Found 6 tests
2 Pass
4 Fail
Details
Result Test Name MessageFail elementsFromPoint for each corner of a simple div
Fail elementsFromPoint for each corner of a div that has a pseudo-element
Fail elementsFromPoint for each corner of a div that is between another div and its pseudo-element
Fail elementsFromPoint for each corner of a div that has a margin
Pass elementsFromPoint for each corner of a div with pointer-events:none
Pass elementsFromPoint for each corner of a div with a 3d transform

View file

@ -0,0 +1,39 @@
Summary
Harness status: OK
Rerun
Found 28 tests
25 Pass
3 Fail
Details
Result Test Name MessagePass container: 0
Fail container: 1
Pass container: 2
Pass container: 3
Pass container: 4
Fail container: 5
Pass container: 6
Pass container: 7
Pass container: 8
Pass container: 9
Pass container: 10
Pass container: 11
Pass container: 12
Pass container: 13
Pass container: 14
Pass container: 15
Pass container: 16
Pass container: 17
Pass container: 18
Pass container: 19
Pass container: 20
Pass container: 21
Pass container: 22
Pass container: 23
Pass container: 24
Fail container: 25
Pass container: 26
Pass container: 27

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass resize events are not fired on the initial layout

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass resize events are not fired on the initial layout

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass scrolling an element with no CSS layout box should have no effect

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass CSSOM scrollingElement reflects the propagated scroll to viewport correctly

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass CSSOM scrollingElement reflects the propagated scroll to viewport correctly

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<title>CSSOM View APIs that return a DOMRectList</title>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<div id=x>x</div>
<script>
setup(() => {
window.element = document.getElementById('x');
});
test(() => {
const domRectList = element.getClientRects();
assert_class_string(domRectList, 'DOMRectList');
assert_class_string(domRectList.item(0), 'DOMRect');
}, 'Element getClientRects()');
test(() => {
const range = new Range();
range.selectNodeContents(element);
const domRectList = range.getClientRects();
assert_class_string(domRectList, 'DOMRectList');
assert_class_string(domRectList.item(0), 'DOMRect');
}, 'Range getClientRects()');
</script>

View file

@ -0,0 +1,31 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>getBoundingClientRect</title>
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
#foo {
margin: 0px 0px 0px 5px;
transform: translate(10px, 200px);
position: fixed;
left: 5px;
background-color: red;
}
</style>
</head>
<body>
<div id="foo">
FOO
</div>
<script>
test(function () {
var foo = document.getElementById("foo").getBoundingClientRect();
assert_equals(foo.left, 20);
});
</script>
</body>
</html>

View file

@ -0,0 +1,118 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="flags" content="dom">
<title>CSS Test: CSSOM View MediaQueryList::addListener with handleEvent</title>
<link rel="help" href="https://dom.spec.whatwg.org/#callbackdef-eventlistener">
<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";
setup({ allow_uncaught_exception: true });
promise_test(async t => {
const mql = await createMQL(t);
let _this;
let _event;
const listener = {
handleEvent(event) {
_this = this;
_event = event;
},
};
mql.addListener(listener);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(_this, listener);
assert_equals(_event.media, mql.media);
assert_equals(_event.matches, mql.matches);
}, "calls handleEvent method of event listener");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
mql.addListener({
get handleEvent() {
calls++;
return function() {};
},
});
assert_equals(calls, 0);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 2);
}, "looks up handleEvent method on every event dispatch");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
const listener = () => {
calls++;
};
Object.defineProperty(listener, "handleEvent", {
get: t.unreached_func("handleEvent method should not be looked up on functions"),
});
mql.addListener(listener);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1);
}, "doesn't look up handleEvent method on callable event listeners");
const uncaught_error_test = async (t, mql, getHandleEvent) => {
const eventWatcher = new EventWatcher(t, window, "error", waitForChangesReported);
const errorPromise = eventWatcher.wait_for("error");
let calls = 0;
const listener = {
get handleEvent() {
calls++;
return getHandleEvent();
},
};
try {
mql.addListener(listener);
triggerMQLEvent(mql);
const event = await errorPromise;
throw event.error;
} finally {
assert_equals(calls, 1, "handleEvent property was not looked up");
}
};
promise_test(async t => {
const error = { name: "test" };
const mql = await createMQL(t);
return promise_rejects_exactly(t, error,
uncaught_error_test(t, mql, () => { throw error; }));
}, "rethrows errors when getting handleEvent");
promise_test(async t => {
const mql = await createMQL(t);
const global = getWindow(mql);
return promise_rejects_js(t, global.TypeError,
uncaught_error_test(t, mql, () => false));
}, "throws if handleEvent is falsy and not callable");
promise_test(async t => {
const mql = await createMQL(t);
const global = getWindow(mql);
return promise_rejects_js(t, global.TypeError,
uncaught_error_test(t, mql, () => "str"));
}, "throws if handleEvent is thruthy and not callable");
</script>

View file

@ -0,0 +1,161 @@
<!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:rune@opera.com">
<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>

View file

@ -0,0 +1,32 @@
<!doctype html>
<title>MediaQueryList.changed is correct for all lists in the document even during a change event handler</title>
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="author" href="https://mozilla.org" title="Mozilla">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1648839">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#evaluate-media-queries-and-report-changes">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="resources/matchMedia.js"></script>
<body>
<script>
promise_test(async t => {
// Create two identical media queries.
let mql = await createMQL(t);
let mql2 = getWindow(mql).matchMedia(mql.media);
let changeEvents = 0;
let check = t.step_func(function() {
changeEvents++;
assert_equals(mql.matches, mql2.matches, "Value of .matches should match"); // No pun intended
});
mql.addListener(check);
mql2.addListener(check);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(changeEvents, 2, "Should've fired the change event in both MediaQueryLists");
});
</script>

View file

@ -0,0 +1,172 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="flags" content="dom">
<title>CSS Test: CSSOM View MediaQueryList extends EventTarget (interop)</title>
<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("all");
let receivedEvent;
mql.addListener(event => {
receivedEvent = event;
});
const dispatchedEvent = new Event("change");
mql.dispatchEvent(dispatchedEvent);
assert_equals(receivedEvent, dispatchedEvent);
}, "dispatchEvent triggers listener added with addListener");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
const listener = {
handleEvent() {
calls++;
},
};
mql.addListener(listener);
mql.addEventListener("change", listener);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1, "triggerMQLEvent");
mql.dispatchEvent(new Event("change"));
assert_equals(calls, 2, "dispatchEvent");
}, "listener added with addListener and addEventListener is called once");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
const listener = () => {
calls++;
};
mql.addListener(listener);
mql.addEventListener("change", listener, true);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 2, "triggerMQLEvent");
mql.dispatchEvent(new Event("change"));
assert_equals(calls, 4, "dispatchEvent");
}, "listener added with addListener and addEventListener (capture) is called twice");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
const listener = {
handleEvent() {
calls++;
},
};
mql.addListener(listener);
mql.removeEventListener("change", listener);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 0, "triggerMQLEvent");
mql.dispatchEvent(new Event("change"));
assert_equals(calls, 0, "dispatchEvent");
}, "removeEventListener removes listener added with addListener");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
const listener = () => {
calls++;
};
mql.addListener(listener);
mql.removeEventListener("change", listener, true);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1, "triggerMQLEvent");
mql.dispatchEvent(new Event("change"));
assert_equals(calls, 2, "dispatchEvent");
}, "removeEventListener (capture) doesn't remove listener added with addListener");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
const listener = {
handleEvent() {
calls++;
},
};
mql.addEventListener("change", listener);
mql.removeListener(listener);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 0, "triggerMQLEvent");
mql.dispatchEvent(new Event("change"));
assert_equals(calls, 0, "dispatchEvent");
}, "removeListener removes listener added with addEventListener");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
const listener = () => {
calls++;
};
mql.addEventListener("change", listener, true);
mql.removeListener(listener);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1, "triggerMQLEvent");
mql.dispatchEvent(new Event("change"));
assert_equals(calls, 2, "dispatchEvent");
}, "removeListener doesn't remove listener added with addEventListener (capture)");
// See:
// * https://github.com/whatwg/dom/issues/746
// * https://bugzilla.mozilla.org/show_bug.cgi?id=1492446
// * https://bugs.chromium.org/p/chromium/issues/detail?id=949432
promise_test(async t => {
const mql = await createMQL(t);
let calls = [];
mql.addListener(() => {
calls.push("addListener");
});
mql.addEventListener("change", {
handleEvent() {
calls.push("addEventListener");
},
}, true);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_array_equals(calls, ["addEventListener", "addListener"], "triggerMQLEvent");
calls = [];
mql.dispatchEvent(new Event("change"));
assert_array_equals(calls, ["addEventListener", "addListener"], "dispatchEvent");
}, "capturing event listener fires before non-capturing listener at target");
</script>

View file

@ -0,0 +1,118 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="flags" content="dom">
<title>CSS Test: CSSOM View MediaQueryList extends EventTarget</title>
<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";
promise_test(async t => {
const mql = await createMQL(t);
let _event;
mql.onchange = event => {
_event = event;
};
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(_event.media, mql.media);
assert_equals(_event.matches, mql.matches);
}, "onchange adds listener");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
mql.onchange = () => {
calls++;
};
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1);
mql.onchange = null;
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1);
}, "onchange removes listener");
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
mql.addEventListener("change", {
handleEvent() {
calls++;
},
});
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1);
}, 'listeners for "change" type are called');
promise_test(async t => {
const mql = await createMQL(t);
mql.addEventListener("matches", t.unreached_func("should not be called"));
triggerMQLEvent(mql);
await waitForChangesReported();
}, 'listeners with different type are not called');
promise_test(async t => {
const mql = await createMQL(t);
let calls = 0;
mql.addEventListener("change", {
handleEvent() {
calls++;
},
}, {once: true});
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1);
triggerMQLEvent(mql);
await waitForChangesReported();
assert_equals(calls, 1);
}, 'addEventListener "once" option is respected');
promise_test(async t => {
const mql = await createMQL(t);
const listener = t.unreached_func("should not be called");
mql.addEventListener("change", listener);
mql.removeEventListener("change", listener);
triggerMQLEvent(mql);
await waitForChangesReported();
}, "removeEventListener removes listener");
test(() => {
const mql = window.matchMedia("all");
let receivedEvent;
mql.addEventListener("custom", event => {
receivedEvent = event;
event.preventDefault();
}, true);
const dispatchedEvent = new CustomEvent("custom", {
cancelable: true,
detail: {},
});
const defaultAction = mql.dispatchEvent(dispatchedEvent);
assert_equals(receivedEvent, dispatchedEvent);
assert_false(defaultAction);
}, "dispatchEvent works as expected");
</script>

View file

@ -0,0 +1,90 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="flags" content="dom">
<title>CSS Test: CSSOM View MediaQueryListEvent</title>
<link rel="help" href="https://www.w3.org/TR/cssom-view-1/#mediaquerylistevent">
<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(() => {
assert_equals(new MediaQueryListEvent("test").type, "test");
}, 'type can be different from "change"');
test(() => {
const event = new MediaQueryListEvent("change");
assert_equals(event.media, "");
assert_false(event.matches);
assert_false(event.bubbles);
assert_false(event.cancelable);
}, "init dictionary default values");
test(() => {
const event = new MediaQueryListEvent("change", {
media: "test",
matches: true,
bubbles: true,
cancelable: true,
});
assert_equals(event.media, "test");
assert_true(event.matches);
assert_true(event.bubbles);
assert_true(event.cancelable);
}, "init dictionary overrides");
promise_test(async t => {
const mql = await createMQL(t);
let _event;
mql.addListener(event => {
_event = event;
});
triggerMQLEvent(mql);
await waitForChangesReported();
assert_true(_event instanceof getWindow(mql).MediaQueryListEvent);
assert_equals(_event.type, "change");
assert_false(_event.bubbles);
assert_false(_event.cancelable);
}, "argument of addListener");
promise_test(async t => {
const mql = await createMQL(t);
let _event;
mql.onchange = event => {
_event = event;
};
triggerMQLEvent(mql);
await waitForChangesReported();
assert_true(_event instanceof getWindow(mql).MediaQueryListEvent);
assert_equals(_event.type, "change");
assert_false(_event.bubbles);
assert_false(_event.cancelable);
}, "argument of onchange");
promise_test(async t => {
const mql = await createMQL(t);
let _event;
mql.addEventListener("change", event => {
_event = event;
});
triggerMQLEvent(mql);
await waitForChangesReported();
assert_true(_event instanceof getWindow(mql).MediaQueryListEvent);
assert_equals(_event.type, "change");
assert_false(_event.bubbles);
assert_false(_event.cancelable);
}, 'constructor of "change" event');
</script>

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<title>CSSOM View - 6.1 - getBoundingClientRect tests</title>
<meta charset="utf-8">
<link rel="author" title="Chris Wu" href="mailto:pwx.frontend@gmail.com">
<link rel="help" href="http://www.w3.org/TR/cssom-view/#dom-element-getboundingclientrect">
<meta name="flags" content="dom">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style type="text/css">
#testItem {
width: 279px;
height: 188px;
margin: 100px 0 0 178px;
background-color: purple;
font-size: 26px;
font-weight: bold;
text-align: center;
line-height: 188px;
}
</style>
</head>
<body>
<div id="testItem">test item</div>
<div id="log"></div>
<script>
var titem = document.getElementById('testItem').getBoundingClientRect();
test(
function(){
assert_equals(titem.bottom - titem.top, titem.height, "height should equal bottom minus top")
}, "getBoundingClientRect() should return a DOMRect where height=bottom-top"
);
test(
function(){
assert_equals(titem.right - titem.left, titem.width, "width should equal right minus left")
}, "getBoundingClientRect() should return a DOMRect where width=right-left"
)
</script>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test (CSSOM View): getBoundingClientRect of element outside DOM</title>
<link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
<link rel="help" href="http://www.w3.org/TR/cssom-view/#dom-element-getclientrects">
<link rel="help" href="http://www.w3.org/TR/cssom-view/#dom-element-getboundingclientrect">
<meta name="flags" content="dom">
<meta name="assert" content="Calling getBoundingClientRect on an element that is outside of the DOM (and therefore does not have an associated layout box) should result in an all-zeroes DOMRect and should definitely not throw an error.">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
test(
function () {
var rect = document.createElement('div').getBoundingClientRect();
assert_equals(rect.x, 0, "DOMRect's x should be zero");
assert_equals(rect.y, 0, "DOMRect's y should be zero");
assert_equals(rect.width, 0, "DOMRect's width should be zero");
assert_equals(rect.height, 0, "DOMRect's height should be zero");
},
"getBoundingClientRect on a newly-created Element not yet inserted into the DOM should return an all-zeroes DOMRect"
);
</script>
</head>
<body></body>
</html>

View file

@ -0,0 +1,34 @@
<!doctype html>
<title>{Element,Range}.prototype.getBoundingClientRect on SVG &lt;tspan&gt;</title>
<link rel="stylesheet" type="text/css" href="../../fonts/ahem.css">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-getboundingclientrect">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-range-getboundingclientrect">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<svg>
<text y="180" font-size="100" font-family="Ahem"
fill="lightblue">X<tspan fill="blue">XX</tspan></text>
</svg>
<script>
function check(object) {
let rect = object.getBoundingClientRect();
assert_equals(rect.left, 108, 'left');
assert_equals(rect.top, 108, 'top');
assert_equals(rect.width, 200, 'width');
assert_equals(rect.height, 100, 'height');
}
async_test(t => {
window.addEventListener("load", t.step_func_done(() => {
let tspan = document.querySelector('tspan');
check(tspan);
}));
}, document.title + ', Element');
async_test(t => {
window.addEventListener("load", t.step_func_done(() => {
let tspan = document.querySelector('tspan');
let range = new Range();
range.selectNode(tspan);
check(range);
}));
}, document.title + ', Range');
</script>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<title>CSSOM View - GetClientRects().length is the same regardless source new lines</title>
<link rel="help" href="https://drafts.csswg.org/cssom-view-1/#dom-element-getclientrects">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<span id="single">
test test
</span><br/>
<span id="multiple">
test
test
</span>
<script>
test(function () {
const count = document.querySelector("#single").getClientRects().length;
const count2 = document.querySelector("#multiple").getClientRects().length;
assert_equals(count, 1, "count");
assert_equals(count2, 1, "count2");
});
</script>
</body>
</html>

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test (CSSOM View): getClientRects of element outside DOM</title>
<link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
<link rel="help" href="http://www.w3.org/TR/cssom-view/#dom-element-getclientrects">
<meta name="flags" content="dom">
<meta name="assert" content="Calling getClientRects on an element that is outside of the DOM (and therefore does not have an associated layout box) should result in an empty DOMRectList and should definitely not throw an error.">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
test(
function () {
var rectList = document.createElement('div').getClientRects();
assert_equals(rectList.length, 0, "DOMRectList should be empty");
},
"getClientRects on a newly-created Element not yet inserted into the DOM should return an empty DOMRectList"
);
</script>
</head>
<body></body>
</html>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<title>CSSOM View - 5 - extensions to the Document interface</title>
<link rel="author" title="Neils Christoffersen" href="mailto:neils.christoffersen@gmail.com">
<link rel="help" href="http://www.w3.org/TR/cssom-view/#extensions-to-the-document-interface">
<meta name="flags" content="dom">
<meta name="assert" content="elementFromPoint returns correct element">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
#targetDiv {
position: absolute;
top: 10;
left: 10;
height: 100px;
width: 100px;
}
</style>
</head>
<body>
<div id="myDiv"></div>
<div id="log"></div>
<div id="targetDiv">
</div>
<script>
var element = document.elementFromPoint(15, 15);
test ( function() {
assert_equals(element.id, "targetDiv", "elementFromPoint didn't return the correct element");
});
</script>
</body>
</html>

View file

@ -0,0 +1,40 @@
<!doctype html>
<meta charset=utf-8>
<title>Checking whether dynamic changes to visibility interact correctly with
table anonymous boxes</title>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<style>
#overlay {
display: table;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: white;
z-index: 999
}
#wrapper { position: relative; }
</style>
<div id=log></div>
<div id="wrapper">
<div id="overlay"><div></div></div>
<div id="target">Some text</div>
</div>
<script>
test(function() {
var t = document.querySelector("#target");
var rect = t.getBoundingClientRect();
var hit = document.elementFromPoint(rect.x + rect.width/2,
rect.y + rect.height/2);
assert_equals(hit, t.previousElementSibling,
"Should hit the overlay first.");
t.previousElementSibling.style.visibility = "hidden";
hit = document.elementFromPoint(rect.x + rect.width/2,
rect.y + rect.height/2);
assert_equals(hit, t,
"Should hit our target now that the overlay is hidden.");
});
</script>

View file

@ -0,0 +1,48 @@
<!doctype html>
<meta charset=utf-8>
<title>Checking whether dynamic changes to visibility interact correctly with
table anonymous boxes</title>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<style>
#overlay {
display: table;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: white;
z-index: 999
}
#wrapper { position: relative; }
</style>
<div id=log></div>
<div id="wrapper">
<div id="overlay"><div></div></div>
<div id="target">Some text</div>
</div>
<script>
test(function() {
// Make sure we have boxes constructed already.
document.body.offsetWidth;
var overlay = document.querySelector("#overlay");
overlay.insertBefore(document.createElement("div"), overlay.firstChild);
overlay.appendChild(document.createElement("div"));
// Make sure we have boxes constructed for those inserts/appends
document.body.offsetWidth;
overlay.firstChild.nextSibling.remove();
var t = document.querySelector("#target");
var rect = t.getBoundingClientRect();
var hit = document.elementFromPoint(rect.x + rect.width/2,
rect.y + rect.height/2);
assert_equals(hit, t.previousElementSibling,
"Should hit the overlay first.");
t.previousElementSibling.style.visibility = "hidden";
hit = document.elementFromPoint(rect.x + rect.width/2,
rect.y + rect.height/2);
assert_equals(hit, t,
"Should hit our target now that the overlay is hidden.");
});
</script>

View file

@ -0,0 +1,58 @@
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>cssom-view - elementScroll - 002</title>
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrolltop">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollleft">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="scroller1" style="height: 100px; width: 100px; overflow: scroll; background: red;">
<div style="background: green; margin-top: 100px; margin-left: 100px; width: 100px; height: 100px;"></div>
</div>
<div id="scroller2" style="height: 100px; width: 100px; overflow: hidden; background: red;">
<div style="background: green; margin-top: 100px; padding-left: 100px; width: 100px; height: 100px;"></div>
</div>
<div id="scroller3" style="height: 100px; width: 100px; overflow: scroll; background: red;">
<div style="background: green; padding-top: 100px; margin-left: 100px; width: 100px; height: 100px;"></div>
</div>
<div id="scroller4" style="height: 100px; width: 100px; overflow: hidden; background: red;">
<div style="background: green; padding-top: 100px; padding-left: 100px; width: 100px; height: 100px;"></div>
</div>
<script>
test(function () {
var scroller1 = document.getElementById("scroller1");
scroller1.scrollTop = 100;
scroller1.scrollLeft = 100;
assert_equals(scroller1.scrollTop, 100, "changed scrollTop should be 100");
assert_equals(scroller1.scrollLeft, 100, "changed scrollLeft should be 100");
}, "simple scroll with style: 'margin' and 'overflow: scroll'");
test(function () {
var scroller2 = document.getElementById("scroller2");
scroller2.scrollTop = 100;
scroller2.scrollLeft = 100;
assert_equals(scroller2.scrollTop, 100, "changed scrollTop should be 100");
assert_equals(scroller2.scrollLeft, 100, "changed scrollLeft should be 100");
}, "simple scroll with style: 'margin' and 'overflow: hidden'");
test(function () {
var scroller3 = document.getElementById("scroller3");
scroller3.scrollTop = 100;
scroller3.scrollLeft = 100;
assert_equals(scroller3.scrollTop, 100, "changed scrollTop should be 100");
assert_equals(scroller3.scrollLeft, 100, "changed scrollLeft should be 100");
}, "simple scroll with style: 'padding' and 'overflow: scroll'");
test(function () {
var scroller4 = document.getElementById("scroller4");
scroller4.scrollTop = 100;
scroller4.scrollLeft = 100;
assert_equals(scroller4.scrollTop, 100, "changed scrollTop should be 100");
assert_equals(scroller4.scrollLeft, 100, "changed scrollLeft should be 100");
}, "simple scroll with style: 'padding' and 'overflow: hidden'");
</script>

View file

@ -0,0 +1,173 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>cssom-view - elementScroll</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
#section {
width: 300px;
height: 500px;
/*position: absolute;*/
top: 16px;
left: 16px;
border: inset gray 3px;
overflow: hidden;
background: white;
}
#scrollable {
width: 400px;
height: 700px;
background: linear-gradient(135deg, red, blue);
}
</style>
<section id="section">
<div id="scrollable"></div>
<div id="unrelated"></div>
</section>
<script>
setup({explicit_done:true});
window.onload = function () {
var section = document.getElementById("section");
var unrelated = document.getElementById("unrelated");
test(function () {
assert_equals(section.scrollTop, 0, "initial scrollTop should be 0");
assert_equals(section.scrollLeft, 0, "initial scrollLeft should be 0");
section.scrollTop = 30;
section.scrollLeft = 40;
assert_equals(section.scrollTop, 30, "changed scrollTop should be 40");
assert_equals(section.scrollLeft, 40, "changed scrollLeft should be 40");
assert_equals(unrelated.scrollTop, 0, "unrelated element should not scroll");
assert_equals(unrelated.scrollLeft, 0, "unrelated element should not scroll");
}, "Element scrollTop/Left getter/setter test");
test(function () {
section.scroll(50, 60);
assert_equals(section.scrollLeft, 50, "changed scrollLeft should be 50");
assert_equals(section.scrollTop, 60, "changed scrollTop should be 60");
}, "Element scroll test (two arguments)");
test(function () {
section.scroll({left: 55, top: 65});
assert_equals(section.scrollLeft, 55, "changed scrollLeft should be 55");
assert_equals(section.scrollTop, 65, "changed scrollTop should be 65");
section.scroll({left: 85});
assert_equals(section.scrollLeft, 85, "changed scrollLeft should be 85");
assert_equals(section.scrollTop, 65, "scrollTop should stay at 65");
section.scroll({top: 75});
assert_equals(section.scrollLeft, 85, "scrollLeft should stay at 85");
assert_equals(section.scrollTop, 75, "changed scrollTop should be 75");
section.scroll({});
assert_equals(section.scrollLeft, 85, "scrollLeft should stay at 85");
assert_equals(section.scrollTop, 75, "scrollTop should stay at 75");
section.scroll();
assert_equals(section.scrollLeft, 85, "scrollLeft should stay at 85");
assert_equals(section.scrollTop, 75, "scrollTop should stay at 75");
}, "Element scroll test (one argument)");
test(function () {
section.scrollTo(80, 70);
assert_equals(section.scrollLeft, 80, "changed scrollLeft should be 70");
assert_equals(section.scrollTop, 70, "changed scrollTop should be 80");
}, "Element scrollTo test (two arguments)");
test(function () {
section.scrollTo({left: 75, top: 85});
assert_equals(section.scrollLeft, 75, "changed scrollLeft should be 75");
assert_equals(section.scrollTop, 85, "changed scrollTop should be 85");
section.scrollTo({left: 65});
assert_equals(section.scrollLeft, 65, "changed scrollLeft should be 65");
assert_equals(section.scrollTop, 85, "scrollTop should stay at 85");
section.scrollTo({top: 55});
assert_equals(section.scrollLeft, 65, "scrollLeft should stay at 65");
assert_equals(section.scrollTop, 55, "changed scrollTop should be 55");
section.scrollTo({});
assert_equals(section.scrollLeft, 65, "scrollLeft should stay at 65");
assert_equals(section.scrollTop, 55, "scrollTop should stay at 55");
section.scrollTo();
assert_equals(section.scrollLeft, 65, "scrollLeft should stay at 55");
assert_equals(section.scrollTop, 55, "scrollTop should stay at 55");
}, "Element scrollTo test (one argument)");
test(function () {
var left = section.scrollLeft;
var top = section.scrollTop;
section.scrollBy(10, 20);
assert_equals(section.scrollLeft, left + 10, "increment of scrollLeft should be 10")
assert_equals(section.scrollTop, top + 20, "increment of scrollTop should be 20")
}, "Element scrollBy test (two arguments)");
test(function () {
var left = section.scrollLeft;
var top = section.scrollTop;
section.scrollBy({left: 5, top: 15});
left += 5
top += 15
assert_equals(section.scrollLeft, left, "increment of scrollLeft should be 5")
assert_equals(section.scrollTop, top, "increment of scrollTop should be 15")
section.scrollBy({left: -15});
left -= 15
assert_equals(section.scrollLeft, left, "decrement of scrollLeft should be 15")
assert_equals(section.scrollTop, top, "scrollTop should not be modified")
section.scrollBy({top: -5});
top -= 5;
assert_equals(section.scrollLeft, left, "scrollLeft should not be modified")
assert_equals(section.scrollTop, top, "decrement of scrollTop should be 5")
section.scrollBy({});
assert_equals(section.scrollLeft, left, "scrollLeft should not be modified")
assert_equals(section.scrollTop, top, "scrollTop should not be modified")
section.scrollBy();
assert_equals(section.scrollLeft, left, "scrollLeft should not be modified")
assert_equals(section.scrollTop, top, "scrollTop should not be modified")
}, "Element scrollBy test (one argument)");
test(function () {
section.scrollTop = 1000;
section.scrollLeft = 1000;
assert_equals(section.scrollTop, 700 - 500, "changed scrollTop should be 200");
assert_equals(section.scrollLeft, 400 - 300, "changed scrollLeft should be 100");
}, "Element scroll maximum test");
done();
};
</script>

View file

@ -0,0 +1,131 @@
<!DOCTYPE HTML>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="resources/elementsFromPoint.js"></script>
<style>
html, body {
margin: 0;
padding: 0;
}
body {
height: 500px;
}
#simpleDiv {
width: 200px;
height: 200px;
background-color: rgba(0,0,255,0.5);
}
#divWithPseudo {
position: absolute;
left: 50px;
top: 50px;
width: 100px;
height: 100px;
background-color: rgba(255,0,0,0.5);
}
#divWithPseudo::before {
position: absolute;
left: 20px;
top: 20px;
width: 100px;
height: 100px;
content: "::before";
background-color: rgba(255,0,0,0.5);
z-index: 9999;
}
#divBetweenPseudo {
position: absolute;
left: 100px;
top: 100px;
width: 100px;
height: 100px;
background-color: rgba(0,255,0,0.5);
}
#withMargin {
margin-top: -15px;
width: 200px;
height: 200px;
background-color: rgba(0,0,0,0.5);
}
#inlineSpan {
float: right;
background-color: yellow;
width: 100px;
height: 1em;
}
#noPointerEvents {
position: absolute;
left: 50px;
top: 50px;
width: 100px;
height: 300px;
background-color: rgba(0,0,0,0.1);
pointer-events: none;
}
#threeD {
position: absolute;
transform: translate3d(-100px, -100px, 10px);
left: 140px;
top: 140px;
width: 200px;
height: 50px;
background-color: rgba(255,255,255,0.5);
}
</style>
<div id="simpleDiv"></div>
<div id="divWithPseudo"></div>
<div id="divBetweenPseudo"></div>
<div id="withMargin"><span id="inlineSpan"></span></div>
<div id="noPointerEvents"></div>
<div id="threeD"></div>
<script>
var body = document.body;
var html = document.documentElement;
test(function() {
checkElementsFromPointFourCorners('document', 'simpleDiv',
[simpleDiv, body, html],
[simpleDiv, body, html],
[withMargin, simpleDiv, body, html],
[divBetweenPseudo, inlineSpan, withMargin, simpleDiv, body, html]);
}, "elementsFromPoint for each corner of a simple div");
test(function() {
checkElementsFromPointFourCorners('document', 'divWithPseudo',
[threeD, divWithPseudo, simpleDiv, body, html],
[threeD, divWithPseudo, simpleDiv, body, html],
[divWithPseudo, simpleDiv, body, html],
[divWithPseudo, divBetweenPseudo, divWithPseudo, simpleDiv, body, html]);
}, "elementsFromPoint for each corner of a div that has a pseudo-element");
test(function() {
checkElementsFromPointFourCorners('document', 'divBetweenPseudo',
[divWithPseudo, divBetweenPseudo, divWithPseudo, simpleDiv, body, html],
[divBetweenPseudo, simpleDiv, body, html],
[divBetweenPseudo, inlineSpan, withMargin, simpleDiv, body, html],
[divBetweenPseudo, inlineSpan, withMargin, simpleDiv, body, html]);
}, "elementsFromPoint for each corner of a div that is between another div and its pseudo-element");
test(function() {
checkElementsFromPointFourCorners('document', 'withMargin',
[withMargin, simpleDiv, body, html],
[divBetweenPseudo, inlineSpan, withMargin, simpleDiv, body, html],
[withMargin, body, html],
[withMargin, body, html]);
}, "elementsFromPoint for each corner of a div that has a margin");
test(function() {
checkElementsFromPointFourCorners('document', 'noPointerEvents',
[threeD, divWithPseudo, simpleDiv, body, html],
[threeD, divWithPseudo, simpleDiv, body, html],
[withMargin, body, html],
[withMargin, body, html]);
}, "elementsFromPoint for each corner of a div with pointer-events:none");
test(function() {
checkElementsFromPointFourCorners('document', 'threeD',
[threeD, simpleDiv, body, html],
[threeD, body, html],
[threeD, simpleDiv, body, html],
[threeD, body, html]);
}, "elementsFromPoint for each corner of a div with a 3d transform");
</script>

View file

@ -0,0 +1,61 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface">
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<link rel="stylesheet" type="text/css" href="../../fonts/ahem.css" />
<style>
.container {
position: relative;
font: 20px/1 Ahem;
width: 150px;
height: 100px;
padding: 2px 10px;
border-width: 3px 6px;
border-style: solid;
box-sizing: border-box;
}
.target { background: grey; }
.hl { writing-mode:horizontal-tb; }
.vlr { writing-mode:vertical-lr; }
</style>
<div id=tests>
<div class="container hl">
<span class="target">x</span>
</div>
<div class="container vlr">
<span class="target">x</span>
</div>
<div class="container hl">
<div class="target">x</div>
</div>
<div class="container vlr">
<div class="target">x</div>
</div>
</div>
<script>
setup({explicit_done: true});
onload = () => {
// Clone the above tests for the following 'display' types:
let display = ['inline-block', 'grid', 'inline-grid', 'flex', 'inline-flex', 'flow-root' ];
let tests = document.querySelector('#tests');
display.forEach((display) => {
let t = tests.cloneNode(true);
[...t.children].forEach((child) => {
child.setAttribute("style", "display:"+display);
});
document.body.appendChild(t);
});
// Check that all of them return an offset relative the padding edge.
var i = 0;
document.querySelectorAll('.target').forEach((target) => {
test(() => {
assert_equals(target.offsetLeft, 10, 'offsetLeft');
assert_equals(target.offsetTop, 2, 'offsetTop');
}, 'container: ' + i);
i++;
});
done();
};
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#run-the-resize-steps"/>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<script>
promise_test(async t => {
let gotResizeEvent = false;
on_event(window, 'resize', () => gotResizeEvent = true);
await new Promise(resolve => requestAnimationFrame(resolve));
await new Promise(resolve => requestAnimationFrame(resolve));
assert_false(gotResizeEvent, 'resize event should not be fired');
}, 'resize events are not fired on the initial layout');
</script>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<meta charset=utf-8>
<link rel="help" href="https://drafts.csswg.org/cssom-view/#run-the-resize-steps"/>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<script>
promise_test(async t => {
let gotResizeEvent = false;
on_event(window, 'resize', () => gotResizeEvent = true);
await new Promise(resolve => requestAnimationFrame(resolve));
await new Promise(resolve => requestAnimationFrame(resolve));
assert_false(gotResizeEvent, 'resize event should not be fired');
}, 'resize events are not fired on the initial layout');
</script>

View file

@ -0,0 +1,48 @@
function nodeToString(node) {
var str = '';
if (node.nodeType == Node.ELEMENT_NODE) {
str += node.nodeName;
if (node.id)
str += '#' + node.id;
else if (node.class)
str += '.' + node.class;
} else if (node.nodeType == Node.TEXT_NODE) {
str += '\'' + node.data + '\'';
} else if (node.nodeType == Node.DOCUMENT_NODE) {
str += '#document';
}
return str;
}
function nodeListToString(nodes) {
var nodeString = '';
for (var i = 0; i < nodes.length; i++) {
var str = nodeToString(nodes[i]);
if (!str)
continue;
nodeString += str;
if (i + 1 < nodes.length)
nodeString += ', ';
}
return nodeString;
}
function assertElementsFromPoint(doc, x, y, expected) {
var query = doc + '.elementsFromPoint(' + x + ',' + y + ')';
var sequence = eval(query);
assert_equals(nodeListToString(sequence), nodeListToString(expected), query);
}
function checkElementsFromPointFourCorners(doc, element, expectedTopLeft, expectedTopRight, expectedBottomLeft, expectedBottomRight) {
var rect = eval(doc + '.getElementById(\'' + element + '\')').getBoundingClientRect();
var topLeft = {x: rect.left + 1, y: rect.top + 1};
var topRight = {x: rect.right - 1, y: rect.top + 1};
var bottomLeft = {x: rect.left + 1, y: rect.bottom - 1};
var bottomRight = {x: rect.right - 1, y: rect.bottom - 1};
assertElementsFromPoint(doc, topLeft.x, topLeft.y, expectedTopLeft);
assertElementsFromPoint(doc, topRight.x, topRight.y, expectedTopRight);
assertElementsFromPoint(doc, bottomLeft.x, bottomLeft.y, expectedBottomLeft);
assertElementsFromPoint(doc, bottomRight.x, bottomRight.y, expectedBottomRight);
}

View file

@ -0,0 +1,60 @@
"use strict";
{
// private variables are defined with `const` so they don't leak outside this block statement
const IFRAME_DEFAULT_SIZE = "200";
const iframes = new WeakMap();
// helpers are defined with `var` so they are globally accessible
var createMQL = async t => {
const iframe = await createIFrame(t);
const mql = iframe.contentWindow.matchMedia(`(max-width: ${IFRAME_DEFAULT_SIZE}px)`);
assert_true(mql.matches, "MQL should match on newly created <iframe>");
iframes.set(mql, iframe);
return mql;
};
var createIFrame = (t, width = IFRAME_DEFAULT_SIZE, height = width) => {
assert_not_equals(document.body, null, "<body> element is missing");
const iframe = document.createElement("iframe");
iframe.srcdoc = "";
iframe.width = String(width);
iframe.height = String(height);
iframe.style.border = "none";
t.add_cleanup(() => {
document.body.removeChild(iframe);
});
return new Promise(resolve => {
iframe.addEventListener("load", () => {
iframe.contentDocument.body.offsetWidth; // reflow
resolve(iframe);
});
document.body.appendChild(iframe);
});
};
var triggerMQLEvent = mql => {
const iframe = iframes.get(mql);
assert_not_equals(iframe, undefined, "Passed MQL instance was not created with createMQL");
iframe.width = iframe.width === IFRAME_DEFAULT_SIZE ? "250" : IFRAME_DEFAULT_SIZE;
};
var getWindow = mql => {
const iframe = iframes.get(mql);
assert_not_equals(iframe, undefined, "Passed MQL instance was not created with createMQL");
return iframe.contentWindow;
};
var waitForChangesReported = () => {
return new Promise(resolve => {
requestAnimationFrame(() => {
requestAnimationFrame(resolve);
});
});
};
}

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>cssom-view - Scrolling element with no layout box</title>
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scroll">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#css-layout-box">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div style="display: none">
<div id="elem"></div>
</div>
<script>
test(() => {
const elem = document.getElementById('elem');
elem.scroll(1, 2);
assert_equals(elem.scrollTop, 0, "scrollTop should be unchanged");
assert_equals(elem.scrollLeft, 0, "scrollLeft should be unchanged");
}, "scrolling an element with no CSS layout box should have no effect");
</script>

View file

@ -0,0 +1,23 @@
<!-- quirks -->
<title>CSSOM scrollingElement reflects the propagated scroll to viewport correctly</title>
<meta charset="utf-8">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<link rel="help" href="https://drafts.csswg.org/css-overflow/#overflow-propagation">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-document-scrollingelement">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5601">
<style>
:root {
overflow: clip;
}
body {
overflow: scroll;
}
</style>
<script>
test(function() {
assert_equals(document.scrollingElement, null);
});
</script>

View file

@ -0,0 +1,20 @@
<!-- quirks -->
<title>CSSOM scrollingElement reflects the propagated scroll to viewport correctly</title>
<meta charset="utf-8">
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
<link rel="author" title="Mozilla" href="https://mozilla.org">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<link rel="help" href="https://drafts.csswg.org/css-overflow/#overflow-propagation">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-document-scrollingelement">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5601">
<style>
body {
overflow: clip;
}
</style>
<script>
test(function() {
assert_equals(document.scrollingElement, document.body);
});
</script>