[ // [TagName, InterfaceName] ['a', 'Anchor'], ['abbr', ''], ['acronym', ''], ['address', ''], ['area', 'Area'], ['article', ''], ['aside', ''], ['audio', 'Audio'], ['b', ''], ['base', 'Base'], ['basefont', ''], ['bdo', ''], ['big', ''], ['blockquote', 'Quote'], ['body', 'Body'], ['br', 'BR'], ['button', 'Button'], ['canvas', 'Canvas'], ['caption', 'TableCaption'], ['center', ''], ['cite', ''], ['code', ''], ['col', 'TableCol'], ['colgroup', 'TableCol'], ['data', 'Data'], ['datalist', 'DataList'], ['dd', ''], ['del', 'Mod'], ['details', 'Details'], ['dfn', ''], ['dir', 'Directory'], ['div', 'Div'], ['dl', 'DList'], ['dt', ''], ['em', ''], ['embed', 'Embed'], ['fieldset', 'FieldSet'], ['figcaption', ''], ['figure', ''], ['font', 'Font'], ['footer', ''], ['form', 'Form'], ['frame', 'Frame'], ['frameset', 'FrameSet'], ['h1', 'Heading'], ['h2', 'Heading'], ['h3', 'Heading'], ['h4', 'Heading'], ['h5', 'Heading'], ['h6', 'Heading'], ['head', 'Head'], ['header', ''], ['hgroup', ''], ['hr', 'HR'], ['html', 'Html'], ['i', ''], ['iframe', 'IFrame'], ['image', ''], ['img', 'Image'], ['input', 'Input'], ['ins', 'Mod'], ['kbd', ''], ['label', 'Label'], ['legend', 'Legend'], ['li', 'LI'], ['link', 'Link'], ['listing', 'Pre'], ['main', ''], ['map', 'Map'], ['mark', ''], ['menu', 'Menu'], ['meta', 'Meta'], ['meter', 'Meter'], ['nav', ''], ['nobr', ''], ['noembed', ''], ['noframes', ''], ['noscript', ''], ['object', 'Object'], ['ol', 'OList'], ['optgroup', 'OptGroup'], ['option', 'Option'], ['output', 'Output'], ['p', 'Paragraph'], ['param', 'Param'], ['picture', 'Picture'], ['plaintext', ''], ['pre', 'Pre'], ['progress', 'Progress'], ['q', 'Quote'], ['rb', ''], ['rp', ''], ['rt', ''], ['rtc', ''], ['ruby', ''], ['s', ''], ['samp', ''], ['script', 'Script'], ['section', ''], ['select', 'Select'], ['small', ''], ['source', 'Source'], ['span', 'Span'], ['strike', ''], ['strong', ''], ['style', 'Style'], ['sub', ''], ['summary', ''], ['sup', ''], ['table', 'Table'], ['tbody', 'TableSection'], ['td', 'TableCell'], ['textarea', 'TextArea'], ['tfoot', 'TableSection'], ['th', 'TableCell'], ['thead', 'TableSection'], ['template', 'Template'], ['time', 'Time'], ['title', 'Title'], ['tr', 'TableRow'], ['track', 'Track'], ['tt', ''], ['u', ''], ['ul', 'UList'], ['var', ''], ['video', 'Video'], ['wbr', ''], ['xmp', 'Pre'], ].forEach((e) => { let tagName = e[0]; let interfaceName = 'HTML' + e[1] + 'Element'; promises.push(test_with_new_window((testWindow) => { // Use window from iframe to isolate the test. // Test calling the HTML*Element constructor. (() => { SimpleTest.doesThrow(() => { testWindow[interfaceName](); }, 'calling the ' + interfaceName + ' constructor should throw a TypeError'); })(); // Test constructing a HTML*ELement. (() => { SimpleTest.doesThrow(() => { new testWindow[interfaceName](); }, 'constructing a ' + interfaceName + ' should throw a TypeError'); })(); // Test constructing a custom element with defining HTML*Element as entry. (() => { testWindow.customElements.define('x-defining-' + tagName, testWindow[interfaceName]); SimpleTest.doesThrow(() => { new testWindow[interfaceName](); }, 'constructing a custom element with defining ' + interfaceName + ' as registry entry should throw a TypeError'); })(); // Since HTMLElement can be registered without specifying "extends", skip // testing HTMLElement tags. if (interfaceName !== "HTMLElement") { // Test constructing a customized HTML*Element with defining a registry entry // without specifying "extends". (() => { class X extends testWindow[interfaceName] {} testWindow.customElements.define('x-defining-invalid-' + tagName, X); SimpleTest.doesThrow(() => { new X(); }, 'constructing a customized ' + interfaceName + ' with defining a ' + 'registry entry without specifying "extends" should throw a TypeError'); })(); } // Test constructing a built-in custom element with defining a registry entry // with incorrect "extends" information. (() => { class X extends testWindow[interfaceName] {} testWindow.customElements.define('x-defining-incorrect-' + tagName, X, { extends: tagName === 'img' ? 'p' : 'img' }); SimpleTest.doesThrow(() => { new X(); }, 'constructing a customized ' + interfaceName + ' with defining a ' + 'registry entry with incorrect "extends" should throw a TypeError'); })(); // Test calling a custom element constructor and constructing a built-in // custom element. (() => { let num_constructor_invocations = 0; class X extends testWindow[interfaceName] { constructor() { super(); num_constructor_invocations++; } } testWindow.customElements.define('x-' + tagName, X, { extends: tagName }); SimpleTest.doesThrow(() => { X(); }, 'calling a customized ' + interfaceName + ' constructor should throw a TypeError'); let element = new X(); SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(element)), X.prototype, 'constructing a customized ' + interfaceName + '; the element should be a registered constructor'); SimpleTest.is(element.localName, tagName, 'constructing a customized ' + interfaceName + '; the element tag name should be "' + tagName + '"'); SimpleTest.is(element.namespaceURI, 'http://www.w3.org/1999/xhtml', 'constructing a customized ' + interfaceName + '; the element should be in the HTML namespace'); SimpleTest.is(element.prefix, null, 'constructing a customized ' + interfaceName + '; the element name should not have a prefix'); SimpleTest.is(element.ownerDocument, testWindow.document, 'constructing a customized ' + interfaceName + '; the element should be owned by the registry\'s associated ' + 'document'); SimpleTest.is(num_constructor_invocations, 1, 'constructing a customized ' + interfaceName + '; the constructor should have been invoked once'); })(); // Test if prototype is no an object. (() => { function ElementWithNonObjectPrototype() { let o = Reflect.construct(testWindow[interfaceName], [], new.target); SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(o)), window[interfaceName].prototype, 'constructing a customized ' + interfaceName + '; if prototype is not object, fallback from NewTarget\'s realm'); } // Prototype have to be an object during define(), otherwise define will // throw an TypeError exception. ElementWithNonObjectPrototype.prototype = {}; testWindow.customElements.define('x-non-object-prototype-' + tagName, ElementWithNonObjectPrototype, { extends: tagName }); ElementWithNonObjectPrototype.prototype = "string"; new ElementWithNonObjectPrototype(); })(); })); });