зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1599630 [wpt PR 20465] - Disallow recursive custom element constructions, a=testonly
Automatic update from web-platform-tests Disallow recursive custom element constructions With this CL, recursive custom element constructions are no longer allowed. I.e. this will now only run the constructor once: class extends HTMLElement { constructor() { super(); customElements.upgrade(this); } } Previously, the code and spec had a bug which caused the above code snippet to infinitely recurse. In [1] the spec has changed, to set the custom element state to "failed" before the constructor is called. With this change in place, recursive calls will early-out at step #2 (of [2]), and avoid the recursion. [1] https://github.com/whatwg/html/pull/5126 [2] https://html.spec.whatwg.org/multipage/custom-elements.html#upgrades Bug: 966472 Change-Id: I76e88c0b70132eee2482c304ef9e727ae1fe8fc7 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1931644 Reviewed-by: Kent Tamura <tkent@chromium.org> Commit-Queue: Mason Freed <masonfreed@chromium.org> Auto-Submit: Mason Freed <masonfreed@chromium.org> Cr-Commit-Position: refs/heads/master@{#727841} -- wpt-commits: 4f24cabbe1f503f3daf8cf0834f4fb1a032f31bc wpt-pr: 20465
This commit is contained in:
Родитель
3f1f90850c
Коммит
100fe4df0b
|
@ -90,4 +90,22 @@ function test_defined(expected, element, description) {
|
|||
assert_equals(style.color, expected ? defined : not_defined, 'getComputedStyle');
|
||||
}, `${description} should ${expected ? 'be' : 'not be'} :defined`);
|
||||
}
|
||||
|
||||
test(function () {
|
||||
var log = [];
|
||||
var instance = document.createElement('my-custom-element-2');
|
||||
document.body.appendChild(instance);
|
||||
customElements.define('my-custom-element-2',class extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
log.push([this, 'begin']);
|
||||
assert_false(this.matches(":defined"), "During construction, this should not match :defined");
|
||||
log.push([this, 'end']);
|
||||
}
|
||||
});
|
||||
assert_equals(log.length, 2);
|
||||
assert_array_equals(log[0], [instance, 'begin']);
|
||||
assert_array_equals(log[1], [instance, 'end']);
|
||||
}, 'this.matches(:defined) should not match during an upgrade');
|
||||
|
||||
</script>
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
<script src="resources/custom-elements-helpers.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<infinite-cloning-element-1></infinite-cloning-element-1>
|
||||
<infinite-cloning-element-2 id="a"></infinite-cloning-element-2>
|
||||
<infinite-cloning-element-2 id="b"></infinite-cloning-element-2>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
setup({allow_uncaught_exception:true});
|
||||
|
@ -203,6 +206,53 @@ test(() => {
|
|||
}, 'If definition\'s disable shadow is true and element\'s shadow root is ' +
|
||||
'non-null, then throw a "NotSupportedError" DOMException.');
|
||||
|
||||
test(() => {
|
||||
var log = [];
|
||||
|
||||
customElements.define('infinite-cloning-element-1',class extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
log.push([this, 'begin']);
|
||||
// Potential infinite recursion:
|
||||
customElements.upgrade(this);
|
||||
log.push([this, 'end']);
|
||||
}
|
||||
});
|
||||
|
||||
assert_equals(log.length, 2);
|
||||
const instance = document.querySelector("infinite-cloning-element-1");
|
||||
assert_array_equals(log[0], [instance, 'begin']);
|
||||
assert_array_equals(log[1], [instance, 'end']);
|
||||
}, 'Infinite constructor recursion with upgrade(this) should not be possible');
|
||||
|
||||
test(() => {
|
||||
var log = [];
|
||||
|
||||
customElements.define('infinite-cloning-element-2',class extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
log.push([this, 'begin']);
|
||||
const b = document.querySelector("#b");
|
||||
b.remove();
|
||||
// While this constructor is running for "a", "b" is still
|
||||
// undefined, and so inserting it into the document will enqueue a
|
||||
// second upgrade reaction for "b" in addition to the one enqueued
|
||||
// by defining x-foo.
|
||||
document.body.appendChild(b);
|
||||
log.push([this, 'end']);
|
||||
}
|
||||
});
|
||||
|
||||
assert_equals(log.length, 4);
|
||||
const instanceA = document.querySelector("#a");
|
||||
const instanceB = document.querySelector("#b");
|
||||
assert_array_equals(log[0], [instanceA, 'begin']);
|
||||
assert_array_equals(log[1], [instanceB, 'begin']);
|
||||
assert_array_equals(log[2], [instanceB, 'end']);
|
||||
assert_array_equals(log[3], [instanceA, 'end']);
|
||||
}, 'Infinite constructor recursion with appendChild should not be possible');
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Загрузка…
Ссылка в новой задаче