Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Unified Diff: third_party/WebKit/LayoutTests/custom-elements/spec/parsing.html

Issue 2200613002: The HTML parser synchronously creates custom elements (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Eliminate redundant TODOs. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | third_party/WebKit/LayoutTests/custom-elements/spec/resources/custom-elements-helpers.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/LayoutTests/custom-elements/spec/parsing.html
diff --git a/third_party/WebKit/LayoutTests/custom-elements/spec/parsing.html b/third_party/WebKit/LayoutTests/custom-elements/spec/parsing.html
new file mode 100644
index 0000000000000000000000000000000000000000..e6b3842870b1a0607f3fa1db488604b4d26bccd6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/custom-elements/spec/parsing.html
@@ -0,0 +1,285 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/custom-elements-helpers.js"></script>
+<body>
+<script>
+'use strict';
+
+// Looks up the preceeding element (which should be a template
+// element) and creates a Promise test. The test name is taken from
+// the template's data-test attribute.
+//
+// The content of the template is loaded into an iframe. On load, f
+// is passed the frame's content window to run assertions.
+function test_with_content(f) {
+ let t = document.currentScript.previousElementSibling;
+ test_with_window(f, t.dataset.test, t.innerHTML);
+}
+
+// Searches the document for an iframe with the specified content window.
+function findFrameWithWindow(w) {
+ return Array.prototype.find.call(document.querySelectorAll('iframe'), (f) => {
+ return f.contentWindow === w;
+ });
+}
+
+test_with_window((w) => {
+ assert_equals(findFrameWithWindow(w).contentWindow, w,
+ 'should find the frame with this window');
+ assert_equals(findFrameWithWindow(window), undefined,
+ 'should return undefined if there is no such frame');
+}, 'sanity check the findFrameWithWindow function');
+</script>
+
+<template data-test="the parser synchronously creates elements">
+ <script>
+ 'use strict';
+
+ window.invocations = [];
+ customElements.define('a-a', class extends HTMLElement {
+ constructor() {
+ super();
+ invocations.push('constructor');
+ }
+ static get observedAttributes() { return ['x']; }
+ attributeChangedCallback(name, oldValue, newValue, nsuri) {
+ invocations.push(`${name}="${newValue}"`);
+ }
+ connectedCallback() {
+ invocations.push('connected');
+ }
+ });
+ </script>
+ <a-a x="y">
+ <script>
+ 'use strict';
+
+ invocations.push('script');
+ </script>
+ </a-a>
+</template>
+<script>
+'use strict';
+
+test_with_content((w) => {
+ assert_array_equals(w.invocations,
+ ['constructor', 'x="y"', 'connected', 'script']);
+});
+</script>
+
+<template data-test="element creation failure produces unknown element">
+ <script>
+ 'use strict';
+
+ customElements.define('a-a', class extends HTMLElement {
+ constructor() {
+ super();
+
+ // Returning this different, in-use element causes element
+ // creation to fail in
+ // https://dom.spec.whatwg.org/#concept-create-element steps
+ // 6.4-9, eg: "If result has children then then throw a
+ // NotSupportedError."
+ return document.documentElement;
+ }
+ });
+ </script>
+ <a-a>
+</template>
+<script>
+'use strict';
+
+test_with_content((w) => {
+ let e = w.document.querySelector('a-a');
+ assert_true(e.matches(':not(:defined)'));
+ assert_equals(Object.getPrototypeOf(e), w.HTMLUnknownElement.prototype);
+});
+</script>
+
+<template data-test="modify tree during creation">
+ <script>
+ 'use strict';
+
+ customElements.define('a-a', class extends HTMLElement {
+ constructor() {
+ super();
+ document.querySelector('b').remove();
+ }
+ });
+ </script>
+ <b>
+ <a-a>
+ </b>
+</template>
+<script>
+'use strict';
+
+test_with_content((w) => {
+ assert_equals(w.document.querySelectorAll('b').length, 0);
+});
+</script>
+
+<template data-test="destructive writes are blocked during construction">
+ <script>
+ // Custom element constructors do not set the insertion point, which
+ // makes document.write() "destructive." However they increment the
+ // ignore-destructive-writes counter, which blocks document.write.
+ // https://html.spec.whatwg.org/#create-an-element-for-the-token
+ // https://github.com/whatwg/html/issues/1630
+ // https://html.spec.whatwg.org/#document.write()
+ 'use strict';
+
+ window.invocations = [];
+ customElements.define('a-a', class extends HTMLElement {
+ constructor() {
+ super();
+ invocations.push('constructor');
+ document.write(
+ `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`);
+ }
+ connectedCallback() {
+ invocations.push('connected');
+ }
+ });
+ </script>
+ <a-a>
+ <script>
+ 'use strict';
+ invocations.push('parsed');
+ </script>
+</template>
+<script>
+'use strict';
+
+test_with_content((w) => {
+ assert_array_equals(
+ w.invocations,
+ ['constructor', 'connected', 'parsed'],
+ 'the destructive document.write content should have been ignored');
+});
+</script>
+
+<template data-test="non-destructive writes are not blocked">
+ <script>
+ // Script running sets the insertion point, which makes makes
+ // document.write() "non-destructive." Custom elements do not block
+ // non-destructive writes.
+ // https://html.spec.whatwg.org/#create-an-element-for-the-token
+ // https://html.spec.whatwg.org/#document.write()
+ 'use strict';
+
+ window.invocations = [];
+ customElements.define('a-a', class extends HTMLElement {
+ constructor() {
+ super();
+ invocations.push('constructor');
+ document.write(
+ `<script>'use strict'; invocations.push('written');</scr${'i'}pt>`);
+ }
+ connectedCallback() {
+ invocations.push('connected');
+ }
+ });
+ document.write('<a-a>');
+ invocations.push('post write');
+ </script>
+ <script>
+ 'use strict';
+ invocations.push('parsed');
+ </script>
+</template>
+<script>
+'use strict';
+
+test_with_content((w) => {
+ assert_array_equals(
+ w.invocations,
+ ['constructor', 'connected', 'post write', 'written', 'parsed'],
+ 'the non-destructive document.write content should have been inserted');
+});
+</script>
+
+<template data-test="innerHTML is not blocked by custom element constructors">
+ <script>
+ 'use strict';
+
+ window.invocations = [];
+ customElements.define('a-a', class extends HTMLElement {
+ constructor() {
+ super();
+ invocations.push(`construct ${this.id}`);
+ if (!this.id) {
+ // If the ID attribute is not set, this was created
+ // synchronously by the parser. Adding children at this point
+ // would cause creation to fail, so embiggen the previous
+ // element instead.
+ document.querySelector('span').innerHTML = `<a-a id="r">`;
+ }
+ }
+ connectedCallback() {
+ invocations.push(`connected ${this.parentNode.localName}/${this.id}`);
+ }
+ });
+ </script>
+ <span></span>
+ <a-a id="q"></a-a>
+ <script>
+ 'use strict';
+ invocations.push('parsed');
+ </script>
+</template>
+<script>
+'use strict';
+
+test_with_content((w) => {
+ assert_array_equals(
+ w.invocations,
+ ['construct ', 'construct r', 'connected span/r', 'connected body/q',
+ 'parsed'],
+ 'custom element constructors should not block innerHTML');
+});
+</script>
+
+
+<template data-test="parsing without a browsing context should not create custom elements">
+ <body>
+ <script>
+ 'use strict';
+
+ let f = parent.findFrameWithWindow(window);
+ f.invocations = [];
+
+ customElements.define('a-a', class extends HTMLElement {
+ constructor() {
+ super();
+ f.invocations.push(this);
+ }
+ });
+ </script>
+ <a-a></a-a>
+ <script>
+ f.detached = document.implementation.createHTMLDocument();
+ f.detached.documentElement.appendChild(document.body);
+ </script>
+ <a-a></a-a>
+</template>
+<script>
+'use strict';
+
+test_with_content((w) => {
+ let f = findFrameWithWindow(w);
+ assert_array_equals(f.invocations,
+ [f.detached.querySelector('a-a:first-of-type')],
+ 'one element should have been constructed');
+ assert_true(f.invocations[0].matches(':defined'),
+ 'the element should have been created successfully');
+
+ let elements = f.detached.querySelectorAll('a-a');
+ console.log(f.invocations[0].parentNode);
+ assert_equals(elements.length, 2,
+ 'two elements should have been created');
+ assert_equals(Object.getPrototypeOf(elements[1]), w.HTMLElement.prototype,
+ 'the second element should be un-upgraded, not failed');
+});
+</script>
« no previous file with comments | « no previous file | third_party/WebKit/LayoutTests/custom-elements/spec/resources/custom-elements-helpers.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698