Commit e449fc97 authored by Kyoko Muto's avatar Kyoko Muto Committed by Commit Bot

Compare <detail>/<summary> with imperative Shadow DOM Distribution API vs without

In this Cl, we reuse the "backend" of the imperative Shadow DOM Distribution API
for a new custom element, <my-detail>/<my-summary>.

In addition, we add reftest and perftests to compare the custom element,
<my-detail>/<my-summary> to built-in custom element, <detail>/<summary>.

perftest result: built-in element (ave)0.635 ms/new element (ave)1.030 ms

Bug: 869308
Change-Id: If3304c65382bc5ad57f4cfe59b1d1a623a22c471
Reviewed-on: https://chromium-review.googlesource.com/1192783
Commit-Queue: Kyoko Muto <kymuto@google.com>
Reviewed-by: default avatarHayato Ito <hayato@chromium.org>
Reviewed-by: default avatarRakina Zata Amni <rakina@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589409}
parent fed40f2c
// We reuse the "backend" of the imperative Shadow DOM Distribution API for a new custom element, <my-detail>/<my-summary>.
//TODO(crbug.com/869308):Emulate other <summary><details> features
class MySummaryElement extends HTMLElement {
constructor() {
super();
}
}
customElements.define("my-summary", MySummaryElement);
customElements.define("my-detail", class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open", slotting: "manual" });
}
connectedCallback() {
const target = this;
if (!target.shadowRoot.querySelector(':scope > slot')) {
const slot1 = document.createElement("slot");
const slot2 = document.createElement("slot");
const shadowRoot = target.shadowRoot;
shadowRoot.appendChild(slot1);
shadowRoot.appendChild(slot2);
slot1.style.display = "block";
slot1.style.backgroundColor = "red";
const observer = new MutationObserver(function(mutations) {
//Get the first <my-summary> element from <my-detail>'s direct children
slot1.assign([target.querySelector(':scope > my-summary')]);
slot2.assign(target.childNodes);
});
observer.observe(this, {childList: true});
}
}
});
<html>
<body>
<p style="display: block; background-color: red;">added-summary</p>
<p>another test</p>
<p>summary first-summary</p>
</body>
</html>
<!DOCTYPE html>
<script src="custom-detail-summary.js"></script>
<my-detail id="my-detail">
<p>another test</p>
<my-summary id="my-summary">summary</my-summary>
<my-summary>first-summary</my-summary>
</my-detail>
<my-summary id="my-summary1">added-summary</my-summary>
<script>
const host = document.querySelector("#my-detail");
const sum = document.querySelector("#my-summary");
const sum1 = document.querySelector("#my-summary1");
host.insertBefore(sum1, sum);
</script>
// We reuse the "backend" of the imperative Shadow DOM Distribution API for a new custom element, <my-detail>/<my-summary>.
//TODO(crbug.com/869308):Emulate other <summary><details> features
class MySummaryElement extends HTMLElement {
constructor() {
super();
}
}
customElements.define("my-summary", MySummaryElement);
customElements.define("my-detail", class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open", slotting: "manual" });
}
connectedCallback() {
const target = this;
if (!target.shadowRoot.querySelector(':scope > slot')) {
const slot1 = document.createElement("slot");
const slot2 = document.createElement("slot");
const shadowRoot = target.shadowRoot;
shadowRoot.appendChild(slot1);
shadowRoot.appendChild(slot2);
slot1.style.display = "block";
slot1.style.backgroundColor = "red";
const observer = new MutationObserver(function(mutations) {
//Get the first <my-summary> element from <my-detail>'s direct children
slot1.assign(target.querySelector(':scope > my-summary'));
slot2.assign(target.childNodes);
});
observer.observe(this, {childList: true});
}
}
});
<!DOCTYPE html>
<script src="../resources/runner.js"></script>
<script src="custom-detail-summary.js"></script>
<my-detail id="my-detail">
<my-summary id="my-summary">summary</my-summary>
</my-detail>
<my-summary id="my-summary1">added-summary1</my-summary>
<my-summary id="my-summary2">added-summary2</my-summary>
<script>
const host = document.querySelector("#my-detail");
const sum = document.querySelector("#my-summary");
const sum1 = document.querySelector("#my-summary1");
const sum2 = document.querySelector("#my-summary2");
window.onload = function() {
PerfTestRunner.measureTime({
description: "Measure performance of my-detail element in manual-slotting mode in shadow root when my-summary element is inserted.",
run: function() {
const start = PerfTestRunner.now();
for (let i = 0; i < 100; i++) {
host.appendChild(sum1);
host.insertBefore(sum2, sum);
PerfTestRunner.forceLayout();
sum1.remove();
sum2.remove();
PerfTestRunner.forceLayout();
}
return PerfTestRunner.now() - start;
}
});
}
</script>
<!doctype html>
<script src="../resources/runner.js"></script>
<detail id="detail">
<summary id="summary">summary</summary>
</detail>
<summary id="summary1">added-summary1</summary>
<summary id="summary2">added-summary2</summary>
<script>
const host = document.querySelector("#detail");
const sum = document.querySelector("#summary");
const sum1 = document.querySelector("#summary1");
const sum2 = document.querySelector("#summary2");
window.onload = function() {
PerfTestRunner.measureTime({
description: "Measure performance of built-in detail element when summary element is inserted.",
run: function() {
const start = PerfTestRunner.now();
for (let i = 0; i < 100; i++) {
host.appendChild(sum1);
host.insertBefore(sum2, sum);
PerfTestRunner.forceLayout();
sum1.remove();
sum2.remove();
PerfTestRunner.forceLayout();
}
return PerfTestRunner.now() - start;
}
});
}
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment