Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1802215 - Allow <panel-list> to be anchored to shadow DOM nodes</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="./panel-list.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
<link rel="stylesheet" href="./panel-list.css"/>
<link rel="stylesheet" href="./panel-item.css"/>
<script>
/**
* Define a simple custom element that includes a <button> in its
* shadow DOM to anchor a panel-list on. The TestElement is slotted,
* putting any direct descendents right after a 400px tall <div>
* with a red border.
*/
class TestElement extends HTMLElement {
static get fragment() {
const MARKUP = `
<template>
<div style="height: 100px; border: 1px solid red;">
<button id="anchor">Anchor</button>
</div>
<slot></slot>
</template>
`;
let parser = new DOMParser();
let doc = parser.parseFromString(MARKUP, "text/html");
TestElement.template = document.importNode(
doc.querySelector("template"),
true
);
let fragment = TestElement.template.content.cloneNode(true);
return fragment;
}
connectedCallback() {
this.shadow = this.attachShadow({ mode: "closed" });
this.shadow.appendChild(TestElement.fragment);
this.anchor = this.shadow.querySelector("#anchor");
this.anchor.addEventListener("click", event => {
let panelList = this.querySelector("panel-list");
panelList.toggle(event);
});
}
doClick() {
this.anchor.click();
}
}
customElements.define("test-element", TestElement);
/**
* Tests that if a <panel-list> is anchored on a node within a custom
* element shadow DOM, that it anchors properly to that shadow node.
*/
add_task(async function test_panel_list_anchor_on_shadow_node() {
let testElement = document.getElementById("test-element");
let panelList = document.getElementById("test-list");
let openPromise = new Promise(resolve => {
panelList.addEventListener("shown", resolve, { once: true });
});
testElement.doClick();
await openPromise;
let panelRect = panelList.getBoundingClientRect();
let anchorRect = testElement.anchor.getBoundingClientRect();
// Recalculate the <panel-list> rect top value relative to the top-left
// of the anchorRect. We expect the <panel-list> to be tightly anchored
// to the bottom of the <button>, so we expect this new value to be 0.
let panelTopLeftRelativeToAnchorTopLeft = panelRect.top - anchorRect.top - anchorRect.height;
is(
panelTopLeftRelativeToAnchorTopLeft,
0,
"Panel should be tightly anchored to the bottom of the button shadow node."
);
});
</script>
</head>
<body>
<p id="display"></p>
<div id="content">
<test-element id="test-element">
<panel-list id="test-list">
<panel-item>An item</panel-item>
<panel-item>Another item</panel-item>
</panel-list>
</test-element>
</div>
<pre id="test"></pre>
</body>
</html>