gecko-dev/testing/web-platform/tests/custom-elements/pseudo-class-defined.html
Kent Tamura 678b56240c Bug 1440517 [wpt PR 9640] - custom-elements: An element created with 0-length 'is' should be 'undefined' state., a=testonly
Automatic update from web-platform-testscustom-elements: An element created with 0-length 'is' should be 'undefined' state.

createElement() should accept 0-length 'is' string though
window.customElements.define() doesn't accept it and web authors
can't define such custom elements.

createElement() never finds custom element definition for 0-length 'is'.
So the state of the created elements should be 'undefined'.

https://dom.spec.whatwg.org/#dom-document-createelement
> 3. Let is be the value of the is member of options, or null if no such
> member exists.

https://dom.spec.whatwg.org/#concept-create-element
> 7.3. If namespace is the HTML namespace, and either localName is a
> valid custom element name or is is non-null, then set result’s custom
> element state to "undefined".

The code before this CL incorrectly rejected 0-length 'is' value, and
made the element state 'uncustomized'.
IsEmpty() checks for "is" values should be IsNull().

Bug: 814644
Change-Id: I273f4aa07dd029e483365a9b31586297862a7140
Reviewed-on: https://chromium-review.googlesource.com/930941
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#538692}

wpt-commits: 8ec6c8a8bea25fcefbbc176534ad274ff67a3eef
wpt-pr: 9640
wpt-commits: 8ec6c8a8bea25fcefbbc176534ad274ff67a3eef
wpt-pr: 9640
2018-03-31 22:25:46 +01:00

93 lines
4.1 KiB
HTML

<!DOCTYPE html>
<link rel="help" href="https://html.spec.whatwg.org/multipage/semantics-other.html#selector-defined">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<iframe id="iframe"></iframe>
<script>
const testList = [
{ tag_name: 'div', defined: true },
{ tag_name: 'a-a', defined: false },
{ tag_name: 'font-face', defined: true },
{ tag_name: 'abbr', is: 'my-abbr', defined: false },
{ tag_name: 'p', is: '', defined: false },
];
// Setup iframe to test the parser.
const neither = 'rgb(255, 0, 0)';
const defined = 'rgb(255, 165, 0)';
const not_defined = 'rgb(0, 0, 255)';
iframe.srcdoc = `<style>
* { color:${neither}; }
:defined { color:${defined}; }
:not(:defined) { color:${not_defined}; }
</style>`
+ testList.map(d => `<${d.tag_name}${d.is !== undefined ? ' is=' + d.is : ''}></${d.tag_name}>`).join('');
setup({ explicit_done: true });
iframe.onload = () => {
const doc = iframe.contentDocument;
const doc_without_browsing_context = doc.implementation.createHTMLDocument();
for (const data of testList) {
// Test elements inserted by parser.
test_defined(data.defined, doc.getElementsByTagName(data.tag_name)[0],
`<${data.tag_name}${data.is ? ' is=' + data.is : ''}>`);
// Test DOM createElement() methods.
let try_upgrade = !data.defined && (data.is === undefined || data.is.length > 0);
test_defined_for_createElement(data.defined, try_upgrade, doc, data.tag_name, data.is);
// Documents without browsing context should behave the same.
test_defined_for_createElement(data.defined, false, doc_without_browsing_context, data.tag_name, data.is, 'Without browsing context: ');
}
done();
};
function test_defined_for_createElement(defined, should_test_change, doc, tag_name, is, description = '') {
let has_is = is !== undefined;
let is_desc = has_is ? `, { is: "${is}" }` : '';
// Test document.createElement().
let element = has_is ? doc.createElement(tag_name, { is: is }) : doc.createElement(tag_name);
doc.body.appendChild(element);
test_defined(defined, element, `${description}createElement("${tag_name}"${is_desc})`);
// Test document.createElementNS().
let html_element = has_is ? doc.createElementNS('http://www.w3.org/1999/xhtml', tag_name, { is: is })
: doc.createElementNS('http://www.w3.org/1999/xhtml', tag_name);
doc.body.appendChild(html_element);
test_defined(defined, html_element, `${description}createElementNS("http://www.w3.org/1999/xhtml", "${tag_name}"${is_desc})`);
// If the element namespace is not HTML, it should be "uncustomized"; i.e., "defined".
let svg_element = has_is ? doc.createElementNS('http://www.w3.org/2000/svg', tag_name, { is: is })
: doc.createElementNS('http://www.w3.org/2000/svg', tag_name);
doc.body.appendChild(svg_element);
test_defined(true, svg_element, `${description}createElementNS("http://www.w3.org/2000/svg", "${tag_name}"${is_desc})`);
// Test ":defined" changes when the custom element was defined.
if (should_test_change) {
let w = doc.defaultView;
assert_false(!w, 'defaultView required to test change');
if (is) {
w.customElements.define(is, class extends w.HTMLElement {}, { extends: tag_name });
} else {
w.customElements.define(tag_name, class extends w.HTMLElement {
constructor() { super(); }
});
}
test_defined(true, element, `Upgraded ${description}createElement("${tag_name}"${is_desc})`);
test_defined(true, html_element, `Upgraded ${description}createElementNS("http://www.w3.org/1999/xhtml", "${tag_name}"${is_desc})`);
}
}
function test_defined(expected, element, description) {
test(() => {
assert_equals(element.matches(':defined'), expected, 'matches(":defined")');
assert_equals(element.matches(':not(:defined)'), !expected, 'matches(":not(:defined")');
const view = element.ownerDocument.defaultView;
if (!view)
return;
const style = view.getComputedStyle(element);
assert_equals(style.color, expected ? defined : not_defined, 'getComputedStyle');
}, `${description} should ${expected ? 'be' : 'not be'} :defined`);
}
</script>