haikuwebkit/LayoutTests/fast/shadow-dom/offsetParent-across-shadow-...

191 lines
9.3 KiB
HTML
Raw Permalink Normal View History

offsetLeft and offsetParent should adjust across shadow boundaries https://bugs.webkit.org/show_bug.cgi?id=157437 <rdar://problem/26154021> Reviewed by Simon Fraser. Source/WebCore: Update the WebKit's treatment of shadow boundaries in offsetLeft, offsetTop, and offsetParent to match the latest discussion in CSS WG. See https://github.com/w3c/webcomponents/issues/497 and https://github.com/w3c/webcomponents/issues/763 The latest consensus is to use the retargeting algorithm (https://dom.spec.whatwg.org/#retarget). In practice, this would mean that we need to keep walking up the offset parent ancestors until we find the one which is in the same tree as a shadow-inclusive ancestor of the context object. For example, if a node (the context object of offsetTop, offsetLeft, offsetParent) was assigned to a slot inside a shadow tree and its offset parent was in the shadow tree, we need to walk up to its offset parent, then its offset parent, etc... until we find the offset parent in the same tree as the context object. Note it's possible that the context object is inside a shadow tree which does not have its own offset parent. (e.g. all elements have position: static) For this reason, we need to consider not just offset parent in the same tree as the context object but as well as any offset parent which is in its ancestor trees. Test: fast/shadow-dom/offsetParent-across-shadow-boundaries.html * dom/Element.cpp: (WebCore::adjustOffsetForZoomAndSubpixelLayout): Extracted to share code between offsetLeft and offsetTop. (WebCore::collectAncestorTreeScopeAsHashSet): Added. (WebCore::Element::offsetLeftForBindings): Added. Sums up offsetLeft's until it finds the first offset parent which is a shadow-including ancestor (https://dom.spec.whatwg.org/#concept-shadow-including-ancestor). (WebCore::Element::offsetLeft): Now uses adjustOffsetForZoomAndSubpixelLayout. (WebCore::Element::offsetTopForBindings): Added. Like offsetLeftForBindings, this function sums up offsetTop's until it finds the first offset parent which is a shadow-including ancestor. (WebCore::Element::offsetTop): Now uses adjustOffsetForZoomAndSubpixelLayout. (WebCore::Element::offsetParentForBindings): Renamed from bindingsOffsetParent to be consistent with other functions meant to be used for bindings code. * dom/Element.h: * html/HTMLElement.idl: Source/WebKit: Use *forBindings variants of offsetLeft, offsetTop, and offsetParent. * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMElementGtk.cpp: (webkit_dom_element_get_offset_left): (webkit_dom_element_get_offset_top): (webkit_dom_element_get_offset_parent): Source/WebKitLegacy/mac: Use *forBindings variants of offsetLeft, offsetTop, and offsetParent. * DOM/DOMElement.mm: (-[DOMElement offsetLeft]): (-[DOMElement offsetTop]): (-[DOMElement offsetParent]): LayoutTests: Added a W3C style testharness.js test. * fast/shadow-dom/offsetParent-across-shadow-boundaries-expected.txt: Added. * fast/shadow-dom/offsetParent-across-shadow-boundaries.html: Added. Canonical link: https://commits.webkit.org/207360@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-12-18 03:52:53 +00:00
<!DOCTYPE html>
<html>
<head>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<meta name="assert" content="offsetParent should only return nodes that are shadow including ancestor">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-ancestor">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="resources/event-path-test-helpers.js"></script>
</head>
<body>
<div id="log"></div>
<div id="container" style="position: relative"></div>
<script>
const container = document.getElementById('container');
function testOffsetParentInShadowTree(mode) {
test(function () {
const host = document.createElement('div');
container.appendChild(host);
this.add_cleanup(() => host.remove());
const shadowRoot = host.attachShadow({mode});
shadowRoot.innerHTML = '<div id="relativeParent" style="position: relative; padding-left: 100px; padding-top: 70px;"><div id="target"></div></div>';
const relativeParent = shadowRoot.getElementById('relativeParent');
assert_true(relativeParent instanceof HTMLDivElement);
const target = shadowRoot.getElementById('target');
assert_equals(target.offsetParent, relativeParent);
assert_equals(target.offsetLeft, 100);
assert_equals(target.offsetTop, 70);
}, `offsetParent must return the offset parent in the same shadow tree of ${mode} mode`);
}
testOffsetParentInShadowTree('open');
testOffsetParentInShadowTree('closed');
function testOffsetParentInNestedShadowTrees(mode) {
test(function () {
const outerHost = document.createElement('section');
container.appendChild(outerHost);
this.add_cleanup(() => outerHost.remove());
const outerShadow = outerHost.attachShadow({mode});
outerShadow.innerHTML = '<section id="outerParent" style="position: absolute; top: 50px; left: 50px;"></section>';
const innerHost = document.createElement('div');
outerShadow.firstChild.appendChild(innerHost);
const innerShadow = innerHost.attachShadow({mode});
innerShadow.innerHTML = '<div id="innerParent" style="position: relative; padding-left: 60px; padding-top: 40px;"><div id="target"></div></div>';
const innerParent = innerShadow.getElementById('innerParent');
const target = innerShadow.getElementById('target');
assert_true(innerParent instanceof HTMLDivElement);
assert_equals(target.offsetParent, innerParent);
assert_equals(target.offsetLeft, 60);
assert_equals(target.offsetTop, 40);
outerHost.remove();
}, `offsetParent must return the offset parent in the same shadow tree of ${mode} mode even when nested`);
}
testOffsetParentInNestedShadowTrees('open');
testOffsetParentInNestedShadowTrees('closed');
function testOffsetParentOnElementAssignedToSlotInsideOffsetParent(mode) {
test(function () {
const host = document.createElement('div');
host.innerHTML = '<div id="target"></div>'
container.appendChild(host);
this.add_cleanup(() => host.remove());
const shadowRoot = host.attachShadow({mode});
shadowRoot.innerHTML = '<div style="position: relative; padding-left: 85px; padding-top: 45px;"><slot></slot></div>';
const target = host.querySelector('#target');
assert_equals(target.offsetParent, container);
assert_equals(target.offsetLeft, 85);
assert_equals(target.offsetTop, 45);
}, `offsetParent must skip offset parents of an element when the context object is assigned to a slot in a shadow tree of ${mode} mode`);
}
testOffsetParentOnElementAssignedToSlotInsideOffsetParent('open');
testOffsetParentOnElementAssignedToSlotInsideOffsetParent('closed');
function testOffsetParentOnElementAssignedToSlotInsideNestedOffsetParents(mode) {
test(function () {
const host = document.createElement('div');
host.innerHTML = '<div id="target" style="border:solid 1px blue;">hi</div>';
const previousBlock = document.createElement('div');
previousBlock.style.height = '12px';
container.append(previousBlock, host);
Update testharness.js from upstream https://bugs.webkit.org/show_bug.cgi?id=201808 Reviewed by Darin Adler. LayoutTests/imported/w3c: Update existing layout tests so that they are compatible with this new version of testharness.js. * IndexedDB-private-browsing/idbdatabase_createObjectStore9-invalidparameters.html: * IndexedDB-private-browsing/idbobjectstore_deleted.html: * web-platform-tests/custom-elements/resources/custom-elements-helpers.js: (create_window_in_test): LayoutTests: Update testharness.js from upstream 6fd5e1e086ce590a4780a30d12968. Update existing layout tests so that they are compatible with this new version of testharness.js. * TestExpectations: * css-custom-properties-api/length-expected.txt: * css-custom-properties-api/length.html: * css-custom-properties-api/registerProperty.html: * css-dark-mode/older-systems/color-scheme-css-expected.txt: * css-dark-mode/older-systems/color-scheme-css.html: * css-dark-mode/older-systems/color-scheme-meta-expected.txt: * css-dark-mode/older-systems/color-scheme-meta.html: * css3/flexbox/style-change-expected.txt: * fast/css/DOMQuad-serialization.html: * fast/css/Element-style.html: * fast/css/parse-justify-self-expected.txt: * fast/css/parse-justify-self.html: * fast/events/clipboard-event-constructor-expected.txt: * fast/events/clipboard-event-constructor.html: * fast/media/mq-js-update-media-expected.txt: * fast/media/mq-js-update-media.html: * fast/mediacapturefromelement/CanvasCaptureMediaStream-offscreencanvas-expected.txt: * fast/mediastream/captureStream/canvas2d-expected.txt: * fast/mediastream/captureStream/canvas2d-heavy-drawing.html: * fast/mediastream/captureStream/canvas2d.html: * fast/shadow-dom/event-path-with-window-expected.txt: * fast/shadow-dom/event-path-with-window.html: * fast/shadow-dom/offsetParent-across-shadow-boundaries-expected.txt: * fast/shadow-dom/offsetParent-across-shadow-boundaries.html: * fast/shadow-dom/slotchange-for-slot-mutation-expected.txt: * fast/shadow-dom/slotchange-for-slot-mutation.html: * fast/shadow-dom/stylesheet-title-in-shadow-tree-expected.txt: * fast/shadow-dom/stylesheet-title-in-shadow-tree.html: * http/tests/fetch/redirectmode-and-preload-expected.txt: * http/tests/fetch/redirectmode-and-preload.html: * imported/blink/editing/selection/selectstart-event-crash-expected.txt: * js/promises-tests/promises-in-workers-expected.txt: * js/promises-tests/promises-in-workers.js: * resources/check-layout-th.js: (window.checkLayout): * resources/testharness.js: (WindowTestEnvironment): (WindowTestEnvironment.prototype._dispatch): (WindowTestEnvironment.prototype._forEach_windows): (WindowTestEnvironment.prototype.next_default_test_name): (WorkerTestEnvironment.prototype.next_default_test_name): (ServiceWorkerTestEnvironment.on_all_loaded): (ServiceWorkerTestEnvironment): (ShellTestEnvironment): (ShellTestEnvironment.prototype.next_default_test_name): (ShellTestEnvironment.prototype.on_new_harness_properties): (ShellTestEnvironment.prototype.on_tests_ready): (ShellTestEnvironment.prototype.add_on_loaded_callback): (ShellTestEnvironment.prototype.test_timeout): (create_test_environment): (is_shared_worker): (is_service_worker): (test): (promise_test): (this.wait_for): (EventWatcher): (done): * streams/readable-byte-stream-controller-expected.txt: * streams/readable-byte-stream-controller-worker-expected.txt: Added. * streams/readable-byte-stream-controller-worker.html: Copied from LayoutTests/streams/readable-byte-stream-controller.html. * streams/readable-byte-stream-controller.html: * streams/readable-stream-byob-reader-expected.txt: * streams/readable-stream-byob-reader-worker-expected.txt: Added. * streams/readable-stream-byob-reader-worker.html: Copied from LayoutTests/streams/readable-stream-byob-reader.html. * streams/readable-stream-byob-reader.html: * streams/readable-stream-byob-request-expected.txt: * streams/readable-stream-byob-request-worker-expected.txt: Copied from LayoutTests/streams/readable-stream-byob-request-expected.txt. * streams/readable-stream-byob-request-worker.html: Copied from LayoutTests/streams/readable-stream-byob-request.html. * streams/readable-stream-byob-request.html: * streams/reference-implementation/readable-stream-templated-expected.txt: * streams/reference-implementation/readable-stream-templated.html: * streams/reference-implementation/writable-stream-abort-expected.txt: * streams/reference-implementation/writable-stream-expected.txt: * webrtc/datachannel/basic-expected.txt: * webrtc/datachannel/basic.html: * webrtc/datachannel/mdns-ice-candidates-expected.txt: * webrtc/datachannel/mdns-ice-candidates.html: * webrtc/pc-detached-document-expected.txt: * webrtc/pc-detached-document.html: * webrtc/video-mute-expected.txt: * webrtc/video-mute-vp8-expected.txt: * webrtc/video-mute-vp8.html: * webrtc/video-mute.html: Canonical link: https://commits.webkit.org/215471@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249918 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-09-16 21:04:08 +00:00
this.add_cleanup(() => { container.innerHTML = ''; });
offsetLeft and offsetParent should adjust across shadow boundaries https://bugs.webkit.org/show_bug.cgi?id=157437 <rdar://problem/26154021> Reviewed by Simon Fraser. Source/WebCore: Update the WebKit's treatment of shadow boundaries in offsetLeft, offsetTop, and offsetParent to match the latest discussion in CSS WG. See https://github.com/w3c/webcomponents/issues/497 and https://github.com/w3c/webcomponents/issues/763 The latest consensus is to use the retargeting algorithm (https://dom.spec.whatwg.org/#retarget). In practice, this would mean that we need to keep walking up the offset parent ancestors until we find the one which is in the same tree as a shadow-inclusive ancestor of the context object. For example, if a node (the context object of offsetTop, offsetLeft, offsetParent) was assigned to a slot inside a shadow tree and its offset parent was in the shadow tree, we need to walk up to its offset parent, then its offset parent, etc... until we find the offset parent in the same tree as the context object. Note it's possible that the context object is inside a shadow tree which does not have its own offset parent. (e.g. all elements have position: static) For this reason, we need to consider not just offset parent in the same tree as the context object but as well as any offset parent which is in its ancestor trees. Test: fast/shadow-dom/offsetParent-across-shadow-boundaries.html * dom/Element.cpp: (WebCore::adjustOffsetForZoomAndSubpixelLayout): Extracted to share code between offsetLeft and offsetTop. (WebCore::collectAncestorTreeScopeAsHashSet): Added. (WebCore::Element::offsetLeftForBindings): Added. Sums up offsetLeft's until it finds the first offset parent which is a shadow-including ancestor (https://dom.spec.whatwg.org/#concept-shadow-including-ancestor). (WebCore::Element::offsetLeft): Now uses adjustOffsetForZoomAndSubpixelLayout. (WebCore::Element::offsetTopForBindings): Added. Like offsetLeftForBindings, this function sums up offsetTop's until it finds the first offset parent which is a shadow-including ancestor. (WebCore::Element::offsetTop): Now uses adjustOffsetForZoomAndSubpixelLayout. (WebCore::Element::offsetParentForBindings): Renamed from bindingsOffsetParent to be consistent with other functions meant to be used for bindings code. * dom/Element.h: * html/HTMLElement.idl: Source/WebKit: Use *forBindings variants of offsetLeft, offsetTop, and offsetParent. * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMElementGtk.cpp: (webkit_dom_element_get_offset_left): (webkit_dom_element_get_offset_top): (webkit_dom_element_get_offset_parent): Source/WebKitLegacy/mac: Use *forBindings variants of offsetLeft, offsetTop, and offsetParent. * DOM/DOMElement.mm: (-[DOMElement offsetLeft]): (-[DOMElement offsetTop]): (-[DOMElement offsetParent]): LayoutTests: Added a W3C style testharness.js test. * fast/shadow-dom/offsetParent-across-shadow-boundaries-expected.txt: Added. * fast/shadow-dom/offsetParent-across-shadow-boundaries.html: Added. Canonical link: https://commits.webkit.org/207360@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-12-18 03:52:53 +00:00
const shadowRoot = host.attachShadow({mode});
shadowRoot.innerHTML = '<section style="position: relative; margin-left: 20px; margin-top: 100px; background: #ccc"><div style="position: absolute; top: 10px; left: 10px;"><slot></slot></div></section>';
const target = host.querySelector('#target');
assert_equals(target.offsetParent, container);
assert_equals(target.offsetLeft, 30);
assert_equals(target.offsetTop, 122);
Update testharness.js from upstream https://bugs.webkit.org/show_bug.cgi?id=201808 Reviewed by Darin Adler. LayoutTests/imported/w3c: Update existing layout tests so that they are compatible with this new version of testharness.js. * IndexedDB-private-browsing/idbdatabase_createObjectStore9-invalidparameters.html: * IndexedDB-private-browsing/idbobjectstore_deleted.html: * web-platform-tests/custom-elements/resources/custom-elements-helpers.js: (create_window_in_test): LayoutTests: Update testharness.js from upstream 6fd5e1e086ce590a4780a30d12968. Update existing layout tests so that they are compatible with this new version of testharness.js. * TestExpectations: * css-custom-properties-api/length-expected.txt: * css-custom-properties-api/length.html: * css-custom-properties-api/registerProperty.html: * css-dark-mode/older-systems/color-scheme-css-expected.txt: * css-dark-mode/older-systems/color-scheme-css.html: * css-dark-mode/older-systems/color-scheme-meta-expected.txt: * css-dark-mode/older-systems/color-scheme-meta.html: * css3/flexbox/style-change-expected.txt: * fast/css/DOMQuad-serialization.html: * fast/css/Element-style.html: * fast/css/parse-justify-self-expected.txt: * fast/css/parse-justify-self.html: * fast/events/clipboard-event-constructor-expected.txt: * fast/events/clipboard-event-constructor.html: * fast/media/mq-js-update-media-expected.txt: * fast/media/mq-js-update-media.html: * fast/mediacapturefromelement/CanvasCaptureMediaStream-offscreencanvas-expected.txt: * fast/mediastream/captureStream/canvas2d-expected.txt: * fast/mediastream/captureStream/canvas2d-heavy-drawing.html: * fast/mediastream/captureStream/canvas2d.html: * fast/shadow-dom/event-path-with-window-expected.txt: * fast/shadow-dom/event-path-with-window.html: * fast/shadow-dom/offsetParent-across-shadow-boundaries-expected.txt: * fast/shadow-dom/offsetParent-across-shadow-boundaries.html: * fast/shadow-dom/slotchange-for-slot-mutation-expected.txt: * fast/shadow-dom/slotchange-for-slot-mutation.html: * fast/shadow-dom/stylesheet-title-in-shadow-tree-expected.txt: * fast/shadow-dom/stylesheet-title-in-shadow-tree.html: * http/tests/fetch/redirectmode-and-preload-expected.txt: * http/tests/fetch/redirectmode-and-preload.html: * imported/blink/editing/selection/selectstart-event-crash-expected.txt: * js/promises-tests/promises-in-workers-expected.txt: * js/promises-tests/promises-in-workers.js: * resources/check-layout-th.js: (window.checkLayout): * resources/testharness.js: (WindowTestEnvironment): (WindowTestEnvironment.prototype._dispatch): (WindowTestEnvironment.prototype._forEach_windows): (WindowTestEnvironment.prototype.next_default_test_name): (WorkerTestEnvironment.prototype.next_default_test_name): (ServiceWorkerTestEnvironment.on_all_loaded): (ServiceWorkerTestEnvironment): (ShellTestEnvironment): (ShellTestEnvironment.prototype.next_default_test_name): (ShellTestEnvironment.prototype.on_new_harness_properties): (ShellTestEnvironment.prototype.on_tests_ready): (ShellTestEnvironment.prototype.add_on_loaded_callback): (ShellTestEnvironment.prototype.test_timeout): (create_test_environment): (is_shared_worker): (is_service_worker): (test): (promise_test): (this.wait_for): (EventWatcher): (done): * streams/readable-byte-stream-controller-expected.txt: * streams/readable-byte-stream-controller-worker-expected.txt: Added. * streams/readable-byte-stream-controller-worker.html: Copied from LayoutTests/streams/readable-byte-stream-controller.html. * streams/readable-byte-stream-controller.html: * streams/readable-stream-byob-reader-expected.txt: * streams/readable-stream-byob-reader-worker-expected.txt: Added. * streams/readable-stream-byob-reader-worker.html: Copied from LayoutTests/streams/readable-stream-byob-reader.html. * streams/readable-stream-byob-reader.html: * streams/readable-stream-byob-request-expected.txt: * streams/readable-stream-byob-request-worker-expected.txt: Copied from LayoutTests/streams/readable-stream-byob-request-expected.txt. * streams/readable-stream-byob-request-worker.html: Copied from LayoutTests/streams/readable-stream-byob-request.html. * streams/readable-stream-byob-request.html: * streams/reference-implementation/readable-stream-templated-expected.txt: * streams/reference-implementation/readable-stream-templated.html: * streams/reference-implementation/writable-stream-abort-expected.txt: * streams/reference-implementation/writable-stream-expected.txt: * webrtc/datachannel/basic-expected.txt: * webrtc/datachannel/basic.html: * webrtc/datachannel/mdns-ice-candidates-expected.txt: * webrtc/datachannel/mdns-ice-candidates.html: * webrtc/pc-detached-document-expected.txt: * webrtc/pc-detached-document.html: * webrtc/video-mute-expected.txt: * webrtc/video-mute-vp8-expected.txt: * webrtc/video-mute-vp8.html: * webrtc/video-mute.html: Canonical link: https://commits.webkit.org/215471@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249918 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-09-16 21:04:08 +00:00
}, `offsetParent must skip multiple offset parents of an element when the context object is assigned to a slot in a shadow tree of ${mode} mode`);
offsetLeft and offsetParent should adjust across shadow boundaries https://bugs.webkit.org/show_bug.cgi?id=157437 <rdar://problem/26154021> Reviewed by Simon Fraser. Source/WebCore: Update the WebKit's treatment of shadow boundaries in offsetLeft, offsetTop, and offsetParent to match the latest discussion in CSS WG. See https://github.com/w3c/webcomponents/issues/497 and https://github.com/w3c/webcomponents/issues/763 The latest consensus is to use the retargeting algorithm (https://dom.spec.whatwg.org/#retarget). In practice, this would mean that we need to keep walking up the offset parent ancestors until we find the one which is in the same tree as a shadow-inclusive ancestor of the context object. For example, if a node (the context object of offsetTop, offsetLeft, offsetParent) was assigned to a slot inside a shadow tree and its offset parent was in the shadow tree, we need to walk up to its offset parent, then its offset parent, etc... until we find the offset parent in the same tree as the context object. Note it's possible that the context object is inside a shadow tree which does not have its own offset parent. (e.g. all elements have position: static) For this reason, we need to consider not just offset parent in the same tree as the context object but as well as any offset parent which is in its ancestor trees. Test: fast/shadow-dom/offsetParent-across-shadow-boundaries.html * dom/Element.cpp: (WebCore::adjustOffsetForZoomAndSubpixelLayout): Extracted to share code between offsetLeft and offsetTop. (WebCore::collectAncestorTreeScopeAsHashSet): Added. (WebCore::Element::offsetLeftForBindings): Added. Sums up offsetLeft's until it finds the first offset parent which is a shadow-including ancestor (https://dom.spec.whatwg.org/#concept-shadow-including-ancestor). (WebCore::Element::offsetLeft): Now uses adjustOffsetForZoomAndSubpixelLayout. (WebCore::Element::offsetTopForBindings): Added. Like offsetLeftForBindings, this function sums up offsetTop's until it finds the first offset parent which is a shadow-including ancestor. (WebCore::Element::offsetTop): Now uses adjustOffsetForZoomAndSubpixelLayout. (WebCore::Element::offsetParentForBindings): Renamed from bindingsOffsetParent to be consistent with other functions meant to be used for bindings code. * dom/Element.h: * html/HTMLElement.idl: Source/WebKit: Use *forBindings variants of offsetLeft, offsetTop, and offsetParent. * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMElementGtk.cpp: (webkit_dom_element_get_offset_left): (webkit_dom_element_get_offset_top): (webkit_dom_element_get_offset_parent): Source/WebKitLegacy/mac: Use *forBindings variants of offsetLeft, offsetTop, and offsetParent. * DOM/DOMElement.mm: (-[DOMElement offsetLeft]): (-[DOMElement offsetTop]): (-[DOMElement offsetParent]): LayoutTests: Added a W3C style testharness.js test. * fast/shadow-dom/offsetParent-across-shadow-boundaries-expected.txt: Added. * fast/shadow-dom/offsetParent-across-shadow-boundaries.html: Added. Canonical link: https://commits.webkit.org/207360@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239313 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-12-18 03:52:53 +00:00
}
testOffsetParentOnElementAssignedToSlotInsideNestedOffsetParents('open');
testOffsetParentOnElementAssignedToSlotInsideNestedOffsetParents('closed');
function testOffsetParentOnElementAssignedToSlotInsideNestedShadowTrees(mode) {
test(function () {
const outerHost = document.createElement('section');
outerHost.innerHTML = '<div id="target"></div>';
container.appendChild(outerHost);
this.add_cleanup(() => outerHost.remove());
const outerShadow = outerHost.attachShadow({mode});
outerShadow.innerHTML = '<section style="position: absolute; top: 40px; left: 50px;"><div id="innerHost"><slot></slot></div></section>';
const innerShadow = outerShadow.getElementById('innerHost').attachShadow({mode});
innerShadow.innerHTML = '<div style="position: absolute; top: 200px; margin-left: 100px;"><slot></slot></div>';
const target = outerHost.querySelector('#target');
assert_equals(target.offsetParent, container);
assert_equals(target.offsetLeft, 150);
assert_equals(target.offsetTop, 240);
outerHost.remove();
}, `offsetParent must skip offset parents of an element when the context object is assigned to a slot in nested shadow trees of ${mode} mode`);
}
testOffsetParentOnElementAssignedToSlotInsideNestedShadowTrees('open');
testOffsetParentOnElementAssignedToSlotInsideNestedShadowTrees('closed');
function testOffsetParentOnElementInsideShadowTreeWithoutOffsetParent(mode) {
test(function () {
const outerHost = document.createElement('section');
container.appendChild(outerHost);
this.add_cleanup(() => outerHost.remove());
const outerShadow = outerHost.attachShadow({mode});
outerShadow.innerHTML = '<div id="innerHost"><div id="target"></div></div>';
const innerShadow = outerShadow.getElementById('innerHost').attachShadow({mode});
innerShadow.innerHTML = '<div style="position: absolute; top: 23px; left: 24px;"><slot></slot></div>';
const target = outerShadow.querySelector('#target');
assert_equals(target.offsetParent, container);
assert_equals(target.offsetLeft, 24);
assert_equals(target.offsetTop, 23);
}, `offsetParent must find the first offset parent which is a shadow-including ancestor of the context object even some shadow tree of ${mode} mode did not have any offset parent`);
}
testOffsetParentOnElementInsideShadowTreeWithoutOffsetParent('open');
testOffsetParentOnElementInsideShadowTreeWithoutOffsetParent('closed');
function testOffsetParentOnUnassignedChild(mode) {
test(function () {
const host = document.createElement('section');
host.innerHTML = '<div id="target"></div>';
this.add_cleanup(() => host.remove());
container.appendChild(host);
const shadowRoot = host.attachShadow({mode});
shadowRoot.innerHTML = '<section style="position: absolute; top: 50px; left: 50px;">content</section>';
const target = host.querySelector('#target');
assert_equals(target.offsetParent, null);
assert_equals(target.offsetLeft, 0);
assert_equals(target.offsetTop, 0);
}, `offsetParent must return null on a child element of a shadow host for the shadow tree in ${mode} mode which is not assigned to any slot`);
}
testOffsetParentOnUnassignedChild('open');
testOffsetParentOnUnassignedChild('closed');
function testOffsetParentOnAssignedChildNotInFlatTree(mode) {
test(function () {
const outerHost = document.createElement('section');
outerHost.innerHTML = '<div id="target"></div>';
container.appendChild(outerHost);
this.add_cleanup(() => outerHost.remove());
const outerShadow = outerHost.attachShadow({mode});
outerShadow.innerHTML = '<div id="innerHost"><div style="position: absolute; top: 50px; left: 50px;"><slot></slot></div></div>';
const innerShadow = outerShadow.getElementById('innerHost').attachShadow({mode});
innerShadow.innerHTML = '<div>content</div>';
const target = outerHost.querySelector('#target');
assert_equals(target.offsetParent, null);
assert_equals(target.offsetLeft, 0);
assert_equals(target.offsetTop, 0);
}, `offsetParent must return null on a child element of a shadow host for the shadow tree in ${mode} mode which is not in the flat tree`);
}
testOffsetParentOnAssignedChildNotInFlatTree('open');
testOffsetParentOnAssignedChildNotInFlatTree('closed');
</script>
</body>
</html>