<!DOCTYPE html>
This test passes if it doesn't crash.
<script>
if (window.testRunner)
testRunner.dumpAsText();
</script>
<script>
class CustomDetails extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open', slotAssignment: 'manual'});
this.summarySlot = document.createElement('slot');
this.summarySlot.id = 'details-summary';
shadowRoot.appendChild(this.summarySlot);
const defaultSummary = document.createElement('summary');
defaultSummary.textContent = 'Details';
this.summarySlot.appendChild(defaultSummary);
this.contentSlot = document.createElement('slot');
this.contentSlot.id = 'details-content';
this.contentSlot.style = `content-visibility:hidden; display:block;`;
shadowRoot.appendChild(this.contentSlot);
const style = document.createElement('style');
style.textContent = `
:host summary {
display: list-item;
counter-increment: list-item 0;
list-style: disclosure-closed inside;
}
:host([open]) summary {
list-style-type: disclosure-open;
}
`;
shadowRoot.appendChild(style);
}
connectedCallback() {
this.updateOpen();
this.updateAssignment();
this.addEventListener('DOMNodeInserted', this.updateAssignment);
this.addEventListener('DOMNodeRemoved', this.updateAssignment);
}
disconnectedCallback() {
this.removeEventListener('DOMNodeInserted', this.updateAssignment);
this.removeEventListener('DOMNodeRemoved', this.updateAssignment);
}
attributeChangedCallback(name, oldValue, newValue) {
this.updateOpen();
}
static get observedAttributes() {
return ['open'];
}
updateOpen() {
if (this.hasAttribute('open')) {
this.contentSlot.style = ``;
} else {
this.contentSlot.style = `content-visibility: hidden; display:block`;
}
}
updateAssignment() {
let summary = null;
const content = [];
for (let child = this.firstChild; child; child = child.nextSibling) {
if (!summary && child.tagName === 'SUMMARY') {
summary = child;
} else {
content.push(child);
}
}
if (summary)
this.summarySlot.assign(summary);
if (content.length)
this.contentSlot.assign(...content);
}
};
customElements.define('x-details', CustomDetails);
</script>
<script>
function clickOn(element, x, y) {
const rect = element.getBoundingClientRect();
return new Promise((resolve, reject) => {
chrome.gpuBenchmarking.pointerActionSequence([
{source: 'mouse',
actions: [
{name: 'pointerMove', x: rect.x + x, y: rect.y + y},
{name: 'pointerDown', x: rect.x + x, y: rect.y + y, button: 0},
{name: 'pointerUp', button: 0}]
}], resolve);
});
}
const $ = document.querySelector.bind(document);
async function runTests() {
$('#dt1').removeChild($('#dt1 > summary'));
$('#dt1c').removeChild($('#dt1c > summary'));
await clickOn($('#dt1c'), 2, 2);
$('#dt2').removeChild($('#dt2 > summary'));
$('#dt2c').removeChild($('#dt2c > summary'));
await clickOn($('#dt2c'), 2, 2);
$('#dt3').removeChild($('#dt3 > summary:last-of-type'));
$('#dt3c').removeChild($('#dt3c > summary:last-of-type'));
await clickOn($('#dt3c'), 2, 2);
$('#dt4').removeChild($('#dt4 > summary'));
$('#dt4c').removeChild($('#dt4c > summary'));
await clickOn($('#dt4c'), 2, 2);
$('#dt5').removeChild($('#dt5 > summary'));
$('#dt5c').removeChild($('#dt5c > summary'));
await clickOn($('#dt5c'), 2, 2);
$('#dt6').removeChild($('#dt6 > summary:last-of-type'));
$('#dt6c').removeChild($('#dt6c > summary:last-of-type'));
await clickOn($('#dt6c'), 2, 2);
testRunner.notifyDone();
}
testRunner.waitUntilDone();
</script>
<body onload="runTests()">
<x-details id="dt1"><summary>summary</summary></x-details>
<x-details id="dt1c"><summary>summary</summary></x-details>
<x-details id="dt2"><summary>summary 1</summary><summary>summary 2</summary></x-details>
<x-details id="dt2c"><summary>summary 1</summary><summary>summary 2</summary></x-details>
<x-details id="dt3"><summary>summary 1</summary><summary>summary 2</summary></x-details>
<x-details id="dt3c"><summary>summary 1</summary><summary>summary 2</summary></x-details>
<x-details id="dt4" open><summary>summary</summary></x-details>
<x-details id="dt4c" open><summary>summary</summary></x-details>
<x-details id="dt5" open><summary>summary 1</summary><summary>summary 2</summary></x-details>
<x-details id="dt5c" open><summary>summary 1</summary><summary>summary 2</summary></x-details>
<x-details id="dt6" open><summary>summary 1</summary><summary>summary 2</summary></x-details>
<x-details id="dt6c" open><summary>summary 1</summary><summary>summary 2</summary></x-details>
</body>