blob: 3a843f91e0d847c65af7cdda4e4a746bede06449 [file] [log] [blame]
<!DOCTYPE html>
<html is="my-html">
<head>
<meta charset="utf-8">
<meta name="help" content="https://html.spec.whatwg.org/multipage/custom-elements.html#element-definition">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body is="my-body">
<div id="container"></div>
<script>
class MyA extends HTMLAnchorElement {
constructor() {
super();
}
}
class MyAbbr extends HTMLElement {
constructor() {
super();
}
}
class MyAddress extends HTMLElement {
constructor() {
super();
}
}
class MyArea extends HTMLAreaElement {
constructor() {
super();
}
}
class MyArticle extends HTMLElement {
constructor() {
super();
}
}
class MyAside extends HTMLElement {
constructor() {
super();
}
}
class MyAudio extends HTMLAudioElement {
constructor() {
super();
}
}
class MyB extends HTMLElement {
constructor() {
super();
}
}
class MyBase extends HTMLBaseElement {
constructor() {
super();
}
}
class MyBdi extends HTMLElement {
constructor() {
super();
}
}
class MyBdo extends HTMLElement {
constructor() {
super();
}
}
class MyBlockquote extends HTMLQuoteElement {
constructor() {
super();
}
}
class MyBody extends HTMLBodyElement {
constructor() {
super();
}
}
class MyBr extends HTMLBRElement {
constructor() {
super();
}
}
class MyButton extends HTMLButtonElement {
constructor() {
super();
}
}
class MyCanvas extends HTMLCanvasElement {
constructor() {
super();
}
}
class MyCaption extends HTMLTableCaptionElement {
constructor() {
super();
}
}
class MyCite extends HTMLElement {
constructor() {
super();
}
}
class MyCode extends HTMLElement {
constructor() {
super();
}
}
class MyCol extends HTMLTableColElement {
constructor() {
super();
}
}
class MyColgroup extends HTMLTableColElement {
constructor() {
super();
}
}
class MyData extends HTMLDataElement {
constructor() {
super();
}
}
class MyDd extends HTMLElement {
constructor() {
super();
}
}
class MyDel extends HTMLModElement {
constructor() {
super();
}
}
class MyDetails extends HTMLDetailsElement {
constructor() {
super();
}
}
class MyDfn extends HTMLElement {
constructor() {
super();
}
}
class MyDiv extends HTMLDivElement {
constructor() {
super();
}
}
class MyDl extends HTMLDListElement {
constructor() {
super();
}
}
class MyDt extends HTMLElement {
constructor() {
super();
}
}
class MyEm extends HTMLElement {
constructor() {
super();
}
}
class MyEmbed extends HTMLEmbedElement {
constructor() {
super();
}
}
class MyFieldset extends HTMLFieldSetElement {
constructor() {
super();
}
}
class MyFigcaption extends HTMLElement {
constructor() {
super();
}
}
class MyFigure extends HTMLElement {
constructor() {
super();
}
}
class MyFooter extends HTMLElement {
constructor() {
super();
}
}
class MyForm extends HTMLFormElement {
constructor() {
super();
}
}
class MyH1 extends HTMLHeadingElement {
constructor() {
super();
}
}
class MyH2 extends HTMLHeadingElement {
constructor() {
super();
}
}
class MyH3 extends HTMLHeadingElement {
constructor() {
super();
}
}
class MyH4 extends HTMLHeadingElement {
constructor() {
super();
}
}
class MyH5 extends HTMLHeadingElement {
constructor() {
super();
}
}
class MyH6 extends HTMLHeadingElement {
constructor() {
super();
}
}
class MyHeader extends HTMLElement {
constructor() {
super();
}
}
class MyHgroup extends HTMLElement {
constructor() {
super();
}
}
class MyHr extends HTMLHRElement {
constructor() {
super();
}
}
class MyHtml extends HTMLHtmlElement {
constructor() {
super();
}
}
class MyI extends HTMLElement {
constructor() {
super();
}
}
class MyIframe extends HTMLIFrameElement {
constructor() {
super();
}
}
class MyImg extends HTMLImageElement {
constructor() {
super();
}
}
class MyInput extends HTMLInputElement {
constructor() {
super();
}
}
class MyIns extends HTMLModElement {
constructor() {
super();
}
}
class MyKbd extends HTMLElement {
constructor() {
super();
}
}
class MyLabel extends HTMLLabelElement {
constructor() {
super();
}
}
class MyLegend extends HTMLLegendElement {
constructor() {
super();
}
}
class MyLi extends HTMLLIElement {
constructor() {
super();
}
}
class MyLink extends HTMLLinkElement {
constructor() {
super();
}
}
class MyMain extends HTMLElement {
constructor() {
super();
}
}
class MyMap extends HTMLMapElement {
constructor() {
super();
}
}
class MyMark extends HTMLElement {
constructor() {
super();
}
}
class MyMenu extends HTMLMenuElement {
constructor() {
super();
}
}
class MyMeta extends HTMLMetaElement {
constructor() {
super();
}
}
class MyMeter extends HTMLMeterElement {
constructor() {
super();
}
}
class MyNav extends HTMLElement {
constructor() {
super();
}
}
class MyNoscript extends HTMLElement {
constructor() {
super();
}
}
class MyObject extends HTMLObjectElement {
constructor() {
super();
}
}
class MyOl extends HTMLOListElement {
constructor() {
super();
}
}
class MyOptgroup extends HTMLOptGroupElement {
constructor() {
super();
}
}
class MyOption extends HTMLOptionElement {
constructor() {
super();
}
}
class MyOutput extends HTMLOutputElement {
constructor() {
super();
}
}
class MyP extends HTMLParagraphElement {
constructor() {
super();
}
}
class MyParam extends HTMLParamElement {
constructor() {
super();
}
}
class MyPicture extends HTMLPictureElement {
constructor() {
super();
}
}
class MyPre extends HTMLPreElement {
constructor() {
super();
}
}
class MyProgress extends HTMLProgressElement {
constructor() {
super();
}
}
class MyQ extends HTMLQuoteElement {
constructor() {
super();
}
}
class MyRp extends HTMLElement {
constructor() {
super();
}
}
class MyRt extends HTMLElement {
constructor() {
super();
}
}
class MyRuby extends HTMLElement {
constructor() {
super();
}
}
class MyS extends HTMLElement {
constructor() {
super();
}
}
class MySamp extends HTMLElement {
constructor() {
super();
}
}
class MyScript extends HTMLScriptElement {
constructor() {
super();
}
}
class MySection extends HTMLElement {
constructor() {
super();
}
}
class MySelect extends HTMLSelectElement {
constructor() {
super();
}
}
class MySmall extends HTMLElement {
constructor() {
super();
}
}
class MySource extends HTMLSourceElement {
constructor() {
super();
}
}
class MySpan extends HTMLSpanElement {
constructor() {
super();
}
}
class MyStrong extends HTMLElement {
constructor() {
super();
}
}
class MyStyle extends HTMLStyleElement {
constructor() {
super();
}
}
class MySub extends HTMLElement {
constructor() {
super();
}
}
class MySummary extends HTMLElement {
constructor() {
super();
}
}
class MySup extends HTMLElement {
constructor() {
super();
}
}
class MyTable extends HTMLTableElement {
constructor() {
super();
}
}
class MyTbody extends HTMLTableSectionElement {
constructor() {
super();
}
}
class MyTd extends HTMLTableCellElement {
constructor() {
super();
}
}
class MyTemplate extends HTMLTemplateElement {
constructor() {
super();
}
}
class MyTextarea extends HTMLTextAreaElement {
constructor() {
super();
}
}
class MyTfoot extends HTMLTableSectionElement {
constructor() {
super();
}
}
class MyTh extends HTMLTableCellElement {
constructor() {
super();
}
}
class MyThead extends HTMLTableSectionElement {
constructor() {
super();
}
}
class MyTime extends HTMLTimeElement {
constructor() {
super();
}
}
class MyTitle extends HTMLTitleElement {
constructor() {
super();
}
}
class MyTr extends HTMLTableRowElement {
constructor() {
super();
}
}
class MyTrack extends HTMLTrackElement {
constructor() {
super();
}
}
class MyU extends HTMLElement {
constructor() {
super();
}
}
class MyUl extends HTMLUListElement {
constructor() {
super();
}
}
class MyVar extends HTMLElement {
constructor() {
super();
}
}
class MyVideo extends HTMLVideoElement {
constructor() {
super();
}
}
class MyWbr extends HTMLElement {
constructor() {
super();
}
}
let testData = [
{tag: 'a', klass: MyA},
{tag: 'abbr', klass: MyAbbr},
{tag: 'address', klass: MyAddress},
{tag: 'area', klass: MyArea},
{tag: 'article', klass: MyArticle},
{tag: 'aside', klass: MyAside},
{tag: 'audio', klass: MyAudio},
{tag: 'b', klass: MyB},
{tag: 'base', klass: MyBase},
{tag: 'bdi', klass: MyBdi},
{tag: 'bdo', klass: MyBdo},
{tag: 'blockquote', klass: MyBlockquote},
{tag: 'body', klass: MyBody, parsing: 'document'},
{tag: 'br', klass: MyBr},
{tag: 'button', klass: MyButton},
{tag: 'canvas', klass: MyCanvas},
{tag: 'caption', klass: MyCaption, parsing: 'table'},
{tag: 'cite', klass: MyCite},
{tag: 'code', klass: MyCode},
{tag: 'col', klass: MyCol, parsing: 'table'},
{tag: 'colgroup', klass: MyColgroup, parsing: 'table'},
{tag: 'data', klass: MyData},
{tag: 'dd', klass: MyDd},
{tag: 'del', klass: MyDel},
{tag: 'details', klass: MyDetails},
{tag: 'dfn', klass: MyDfn},
{tag: 'div', klass: MyDiv},
{tag: 'dl', klass: MyDl},
{tag: 'dt', klass: MyDt},
{tag: 'em', klass: MyEm},
{tag: 'embed', klass: MyEmbed},
{tag: 'fieldset', klass: MyFieldset},
{tag: 'figcaption', klass: MyFigcaption},
{tag: 'figure', klass: MyFigure},
{tag: 'footer', klass: MyFooter},
{tag: 'form', klass: MyForm},
{tag: 'h1', klass: MyH1},
{tag: 'h2', klass: MyH2},
{tag: 'h3', klass: MyH3},
{tag: 'h4', klass: MyH4},
{tag: 'h5', klass: MyH5},
{tag: 'h6', klass: MyH6},
{tag: 'header', klass: MyHeader},
{tag: 'hgroup', klass: MyHgroup},
{tag: 'hr', klass: MyHr},
{tag: 'html', klass: MyHtml, parsing: 'document'},
{tag: 'i', klass: MyI},
{tag: 'iframe', klass: MyIframe},
{tag: 'img', klass: MyImg},
{tag: 'input', klass: MyInput},
{tag: 'ins', klass: MyIns},
{tag: 'kbd', klass: MyKbd},
{tag: 'label', klass: MyLabel},
{tag: 'legend', klass: MyLegend},
{tag: 'li', klass: MyLi},
{tag: 'link', klass: MyLink},
{tag: 'main', klass: MyMain},
{tag: 'map', klass: MyMap},
{tag: 'mark', klass: MyMark},
{tag: 'menu', klass: MyMenu},
{tag: 'meta', klass: MyMeta},
{tag: 'meter', klass: MyMeter},
{tag: 'nav', klass: MyNav},
{tag: 'noscript', klass: MyNoscript},
{tag: 'object', klass: MyObject},
{tag: 'ol', klass: MyOl},
{tag: 'optgroup', klass: MyOptgroup},
{tag: 'option', klass: MyOption},
{tag: 'output', klass: MyOutput},
{tag: 'p', klass: MyP},
{tag: 'param', klass: MyParam},
{tag: 'picture', klass: MyPicture},
{tag: 'pre', klass: MyPre},
{tag: 'progress', klass: MyProgress},
{tag: 'q', klass: MyQ},
{tag: 'rp', klass: MyRp},
{tag: 'rt', klass: MyRt},
{tag: 'ruby', klass: MyRuby},
{tag: 's', klass: MyS},
{tag: 'samp', klass: MySamp},
{tag: 'script', klass: MyScript},
{tag: 'section', klass: MySection},
{tag: 'select', klass: MySelect},
{tag: 'small', klass: MySmall},
{tag: 'source', klass: MySource},
{tag: 'span', klass: MySpan},
{tag: 'strong', klass: MyStrong},
{tag: 'style', klass: MyStyle},
{tag: 'sub', klass: MySub},
{tag: 'summary', klass: MySummary},
{tag: 'sup', klass: MySup},
{tag: 'table', klass: MyTable},
{tag: 'tbody', klass: MyTbody, parsing: 'table'},
{tag: 'td', klass: MyTd, parsing: 'table'},
{tag: 'template', klass: MyTemplate},
{tag: 'textarea', klass: MyTextarea},
{tag: 'tfoot', klass: MyTfoot, parsing: 'table'},
{tag: 'th', klass: MyTh, parsing: 'table'},
{tag: 'thead', klass: MyThead, parsing: 'table'},
{tag: 'time', klass: MyTime},
{tag: 'title', klass: MyTitle},
{tag: 'tr', klass: MyTr, parsing: 'table'},
{tag: 'track', klass: MyTrack},
{tag: 'u', klass: MyU},
{tag: 'ul', klass: MyUl},
{tag: 'var', klass: MyVar},
{tag: 'video', klass: MyVideo},
{tag: 'wbr', klass: MyWbr},
];
// HTMLDataListElement isn't implemented by all major browsers yet.
if (window.HTMLDataListElement) {
testData.push({tag: 'datalist', klass: class extends HTMLDataListElement {
constructor() {
super();
}
}});
}
// HTMLDialogElement isn't implemented by all major browsers yet.
if (window.HTMLDialogElement) {
testData.push({tag: 'dialog', klass: class MyDialog extends HTMLDialogElement {
constructor() {
super();
}
}});
}
// HTMLSlotElement isn't implemented by all major browsers yet.
if (window.HTMLSlotElement) {
testData.push({tag: 'slot', klass: class extends HTMLSlotElement {
constructor() {
super();
}
}});
}
for (const t of testData) {
test(() => {
let name = 'my-' + t.tag;
customElements.define(name, t.klass, { extends: t.tag });
test(() => {
let customized = new t.klass();
assert_equals(customized.constructor, t.klass);
// cloneNode() won't create a customized built-in element due to no
// 'is' attribute. https://github.com/whatwg/html/issues/3402
assert_not_equals(customized.cloneNode().constructor, t.klass,
'Cloning a customized built-in element should NOT succeed.');
}, `${t.tag}: Operator 'new' should instantiate a customized built-in element`);
test(() => {
let customized = document.createElement(t.tag, { is: name });
assert_equals(customized.constructor, t.klass);
assert_equals(customized.cloneNode().constructor, t.klass,
'Cloning a customized built-in element should succeed.');
}, `${t.tag}: document.createElement() should instantiate a customized built-in element`);
if (t.parsing == 'document') {
let test = async_test(`${t.tag}: document parser should instantiate a customized built-in element`);
window.addEventListener('load', test.step_func_done(() => {
let customized = document.querySelector(t.tag);
assert_equals(customized.constructor, t.klass);
assert_equals(customized.cloneNode().constructor, t.klass,
'Cloning a customized built-in element should succeed.');
}));
return;
}
test(() => {
let container = document.getElementById('container');
if (t.parsing == 'table') {
container.innerHTML = `<table><${t.tag} is="${name}" id="${name}">`;
} else {
container.innerHTML = `<${t.tag} is="${name}" id="${name}">`;
}
let customized = document.getElementById(name);
assert_equals(customized.constructor, t.klass);
assert_equals(customized.cloneNode().constructor, t.klass,
'Cloning a customized built-in element should succeed.');
}, `${t.tag}: innerHTML should instantiate a customized built-in element`);
}, `${t.tag}: Define a customized built-in element`);
}
</script>
</body>
</html>