htmlconstructor_builtin_tests.js (8327B)
1 [ 2 // [TagName, InterfaceName] 3 ["a", "Anchor"], 4 ["abbr", ""], 5 ["acronym", ""], 6 ["address", ""], 7 ["area", "Area"], 8 ["article", ""], 9 ["aside", ""], 10 ["audio", "Audio"], 11 ["b", ""], 12 ["base", "Base"], 13 ["basefont", ""], 14 ["bdo", ""], 15 ["big", ""], 16 ["blockquote", "Quote"], 17 ["body", "Body"], 18 ["br", "BR"], 19 ["button", "Button"], 20 ["canvas", "Canvas"], 21 ["caption", "TableCaption"], 22 ["center", ""], 23 ["cite", ""], 24 ["code", ""], 25 ["col", "TableCol"], 26 ["colgroup", "TableCol"], 27 ["data", "Data"], 28 ["datalist", "DataList"], 29 ["dd", ""], 30 ["del", "Mod"], 31 ["details", "Details"], 32 ["dfn", ""], 33 ["dir", "Directory"], 34 ["div", "Div"], 35 ["dl", "DList"], 36 ["dt", ""], 37 ["em", ""], 38 ["embed", "Embed"], 39 ["fieldset", "FieldSet"], 40 ["figcaption", ""], 41 ["figure", ""], 42 ["font", "Font"], 43 ["footer", ""], 44 ["form", "Form"], 45 ["frame", "Frame"], 46 ["frameset", "FrameSet"], 47 ["h1", "Heading"], 48 ["h2", "Heading"], 49 ["h3", "Heading"], 50 ["h4", "Heading"], 51 ["h5", "Heading"], 52 ["h6", "Heading"], 53 ["head", "Head"], 54 ["header", ""], 55 ["hgroup", ""], 56 ["hr", "HR"], 57 ["html", "Html"], 58 ["i", ""], 59 ["iframe", "IFrame"], 60 ["image", ""], 61 ["img", "Image"], 62 ["input", "Input"], 63 ["ins", "Mod"], 64 ["kbd", ""], 65 ["label", "Label"], 66 ["legend", "Legend"], 67 ["li", "LI"], 68 ["link", "Link"], 69 ["listing", "Pre"], 70 ["main", ""], 71 ["map", "Map"], 72 ["mark", ""], 73 ["marquee", "Marquee"], 74 ["menu", "Menu"], 75 ["meta", "Meta"], 76 ["meter", "Meter"], 77 ["nav", ""], 78 ["nobr", ""], 79 ["noembed", ""], 80 ["noframes", ""], 81 ["noscript", ""], 82 ["object", "Object"], 83 ["ol", "OList"], 84 ["optgroup", "OptGroup"], 85 ["option", "Option"], 86 ["output", "Output"], 87 ["p", "Paragraph"], 88 ["param", "Param"], 89 ["picture", "Picture"], 90 ["plaintext", ""], 91 ["pre", "Pre"], 92 ["progress", "Progress"], 93 ["q", "Quote"], 94 ["rb", ""], 95 ["rp", ""], 96 ["rt", ""], 97 ["rtc", ""], 98 ["ruby", ""], 99 ["s", ""], 100 ["samp", ""], 101 ["script", "Script"], 102 ["section", ""], 103 ["select", "Select"], 104 ["small", ""], 105 ["source", "Source"], 106 ["span", "Span"], 107 ["strike", ""], 108 ["strong", ""], 109 ["style", "Style"], 110 ["sub", ""], 111 ["summary", ""], 112 ["sup", ""], 113 ["table", "Table"], 114 ["tbody", "TableSection"], 115 ["td", "TableCell"], 116 ["textarea", "TextArea"], 117 ["tfoot", "TableSection"], 118 ["th", "TableCell"], 119 ["thead", "TableSection"], 120 ["template", "Template"], 121 ["time", "Time"], 122 ["title", "Title"], 123 ["tr", "TableRow"], 124 ["track", "Track"], 125 ["tt", ""], 126 ["u", ""], 127 ["ul", "UList"], 128 ["var", ""], 129 ["video", "Video"], 130 ["wbr", ""], 131 ["xmp", "Pre"], 132 ].forEach(e => { 133 let tagName = e[0]; 134 let interfaceName = "HTML" + e[1] + "Element"; 135 promises.push( 136 test_with_new_window(testWindow => { 137 // Use window from iframe to isolate the test. 138 // Test calling the HTML*Element constructor. 139 (() => { 140 SimpleTest.doesThrow( 141 () => { 142 testWindow[interfaceName](); 143 }, 144 "calling the " + 145 interfaceName + 146 " constructor should throw a TypeError" 147 ); 148 })(); 149 150 // Test constructing a HTML*ELement. 151 (() => { 152 SimpleTest.doesThrow( 153 () => { 154 new testWindow[interfaceName](); 155 }, 156 "constructing a " + interfaceName + " should throw a TypeError" 157 ); 158 })(); 159 160 // Test constructing a custom element with defining HTML*Element as entry. 161 (() => { 162 testWindow.customElements.define( 163 "x-defining-" + tagName, 164 testWindow[interfaceName] 165 ); 166 SimpleTest.doesThrow( 167 () => { 168 new testWindow[interfaceName](); 169 }, 170 "constructing a custom element with defining " + 171 interfaceName + 172 " as registry entry should throw a TypeError" 173 ); 174 })(); 175 176 // Since HTMLElement can be registered without specifying "extends", skip 177 // testing HTMLElement tags. 178 if (interfaceName !== "HTMLElement") { 179 // Test constructing a customized HTML*Element with defining a registry entry 180 // without specifying "extends". 181 (() => { 182 class X extends testWindow[interfaceName] {} 183 testWindow.customElements.define("x-defining-invalid-" + tagName, X); 184 SimpleTest.doesThrow( 185 () => { 186 new X(); 187 }, 188 "constructing a customized " + 189 interfaceName + 190 " with defining a " + 191 'registry entry without specifying "extends" should throw a TypeError' 192 ); 193 })(); 194 } 195 196 // Test constructing a built-in custom element with defining a registry entry 197 // with incorrect "extends" information. 198 (() => { 199 class X extends testWindow[interfaceName] {} 200 testWindow.customElements.define("x-defining-incorrect-" + tagName, X, { 201 extends: tagName === "img" ? "p" : "img", 202 }); 203 SimpleTest.doesThrow( 204 () => { 205 new X(); 206 }, 207 "constructing a customized " + 208 interfaceName + 209 " with defining a " + 210 'registry entry with incorrect "extends" should throw a TypeError' 211 ); 212 })(); 213 214 // Test calling a custom element constructor and constructing a built-in 215 // custom element. 216 (() => { 217 let num_constructor_invocations = 0; 218 class X extends testWindow[interfaceName] { 219 constructor() { 220 super(); 221 num_constructor_invocations++; 222 } 223 } 224 testWindow.customElements.define("x-" + tagName, X, { 225 extends: tagName, 226 }); 227 SimpleTest.doesThrow( 228 () => { 229 X(); 230 }, 231 "calling a customized " + 232 interfaceName + 233 " constructor should throw a TypeError" 234 ); 235 236 let element = new X(); 237 238 SimpleTest.is( 239 Object.getPrototypeOf(Cu.waiveXrays(element)), 240 X.prototype, 241 "constructing a customized " + 242 interfaceName + 243 "; the element should be a registered constructor" 244 ); 245 SimpleTest.is( 246 element.localName, 247 tagName, 248 "constructing a customized " + 249 interfaceName + 250 '; the element tag name should be "' + 251 tagName + 252 '"' 253 ); 254 SimpleTest.is( 255 element.namespaceURI, 256 "http://www.w3.org/1999/xhtml", 257 "constructing a customized " + 258 interfaceName + 259 "; the element should be in the HTML namespace" 260 ); 261 SimpleTest.is( 262 element.prefix, 263 null, 264 "constructing a customized " + 265 interfaceName + 266 "; the element name should not have a prefix" 267 ); 268 SimpleTest.is( 269 element.ownerDocument, 270 testWindow.document, 271 "constructing a customized " + 272 interfaceName + 273 "; the element should be owned by the registry's associated " + 274 "document" 275 ); 276 SimpleTest.is( 277 num_constructor_invocations, 278 1, 279 "constructing a customized " + 280 interfaceName + 281 "; the constructor should have been invoked once" 282 ); 283 })(); 284 285 // Test if prototype is no an object. 286 (() => { 287 function ElementWithNonObjectPrototype() { 288 let o = Reflect.construct(testWindow[interfaceName], [], new.target); 289 SimpleTest.is( 290 Object.getPrototypeOf(Cu.waiveXrays(o)), 291 window[interfaceName].prototype, 292 "constructing a customized " + 293 interfaceName + 294 "; if prototype is not object, fallback from NewTarget's realm" 295 ); 296 } 297 298 // Prototype have to be an object during define(), otherwise define will 299 // throw an TypeError exception. 300 ElementWithNonObjectPrototype.prototype = {}; 301 testWindow.customElements.define( 302 "x-non-object-prototype-" + tagName, 303 ElementWithNonObjectPrototype, 304 { extends: tagName } 305 ); 306 307 ElementWithNonObjectPrototype.prototype = "string"; 308 new ElementWithNonObjectPrototype(); 309 })(); 310 }) 311 ); 312 });