2 * Copyright 2016 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 ok(performance.timing.navigationStart > 0, "navigationStart <= 0");
23 ok(performance.timing.fetchStart == performance.timing.navigationStart, "fetchStart != navigationStart");
24 ok(performance.timing.domainLookupStart >= performance.timing.fetchStart, "domainLookupStart < fetchStart");
25 ok(performance.timing.domainLookupEnd >= performance.timing.domainLookupStart, "domainLookupEnd < domainLookupStart");
26 ok(performance.timing.connectStart >= performance.timing.domainLookupEnd, "connectStart < domainLookupEnd");
27 ok(performance.timing.connectEnd >= performance.timing.connectStart, "connectEnd < connectStart");
28 ok(performance.timing.requestStart >= performance.timing.connectEnd, "requestStart < connectEnd");
29 ok(performance.timing.responseStart >= performance.timing.requestStart, "responseStart < requestStart");
30 ok(performance.timing.responseEnd >= performance.timing.responseStart, "responseEnd < responseStart");
31 ok(performance.timing.domLoading >= performance.timing.responseEnd, "domLoading < responseEnd");
32 ok(performance.timing.domInteractive === 0, "domInteractive != 0");
33 ok(performance.timing.domComplete === 0, "domComplete != 0");
34 ok(performance.timing.domContentLoadedEventStart === 0, "domContentLoadedEventStart != 0");
35 ok(performance.timing.domContentLoadedEventEnd === 0, "domContentLoadedEventEnd != 0");
36 ok(performance.timing.loadEventStart === 0, "loadEventStart != 0");
37 ok(performance.timing.loadEventEnd === 0, "loadEventEnd != 0");
38 ok(performance.timing.unloadEventStart === 0, "unloadEventStart != 0");
39 ok(performance.timing.unloadEventEnd === 0, "unloadEventEnd != 0");
40 ok(performance.timing.redirectStart === 0, "redirectStart != 0");
41 ok(performance.timing.redirectEnd === 0, "redirectEnd != 0");
42 ok(performance.timing.msFirstPaint === 0, "msFirstPaint != 0");
44 var pageshow_fired = false, pagehide_fired = false;
45 document.doc_unload_events_called = false;
46 window.onbeforeunload = function() { ok(false, "beforeunload fired"); };
47 window.onunload = function() {
48 document.doc_unload_events_called = true;
49 ok(document.readyState === "complete", "unload readyState = " + document.readyState);
50 if(document.documentMode < 11)
51 ok(pagehide_fired === false, "pagehide fired before unload");
53 ok(pagehide_fired === true, "pagehide not fired before unload");
56 if(window.addEventListener) {
57 window.addEventListener("pageshow", function(e) {
58 pageshow_fired = true;
60 var r = Object.prototype.toString.call(e);
61 ok(r === "[object PageTransitionEvent]", "pageshow toString = " + r);
62 ok("persisted" in e, "'persisted' not in pageshow event");
63 ok(document.readyState === "complete", "pageshow readyState = " + document.readyState);
64 ok(performance.timing.loadEventEnd > 0, "loadEventEnd <= 0 in pageshow handler");
67 window.addEventListener("pagehide", function(e) {
68 pagehide_fired = true;
69 ok(document.documentMode >= 11, "pagehide fired");
71 var r = Object.prototype.toString.call(e);
72 ok(r === "[object PageTransitionEvent]", "pagehide toString = " + r);
73 ok("persisted" in e, "'persisted' not in pagehide event");
76 document.addEventListener("visibilitychange", function() { ok(false, "visibilitychange fired"); });
77 document.addEventListener("beforeunload", function() { ok(false, "beforeunload fired on document"); });
78 document.addEventListener("unload", function() { ok(false, "unload fired on document"); });
80 document.attachEvent("onbeforeunload", function() { ok(false, "beforeunload fired on document"); });
81 document.attachEvent("onunload", function() { ok(false, "unload fired on document"); });
84 sync_test("performance timing", function() {
85 ok(performance.timing.domInteractive >= performance.timing.domLoading, "domInteractive < domLoading");
86 ok(performance.timing.domContentLoadedEventStart >= performance.timing.domInteractive, "domContentLoadedEventStart < domInteractive");
87 ok(performance.timing.domContentLoadedEventEnd >= performance.timing.domContentLoadedEventStart, "domContentLoadedEventEnd < domContentLoadedEventStart");
88 ok(performance.timing.domComplete >= performance.timing.domContentLoadedEventEnd, "domComplete < domContentLoadedEventEnd");
89 ok(performance.timing.loadEventStart >= performance.timing.domComplete, "loadEventStart < domComplete");
90 ok(performance.timing.loadEventEnd >= performance.timing.loadEventStart, "loadEventEnd < loadEventStart");
91 ok(performance.navigation.type === 0, "navigation type = " + performance.navigation.type);
92 ok(performance.navigation.redirectCount === 0, "redirectCount = " + performance.navigation.redirectCount);
95 sync_test("page transition events", function() {
96 if(document.documentMode < 11)
97 ok(pageshow_fired === false, "pageshow fired");
99 ok(pageshow_fired === true, "pageshow not fired");
100 ok(pagehide_fired === false, "pagehide fired");
102 if(document.body.addEventListener)
103 document.body.addEventListener("unload", function() { ok(false, "unload fired on document.body"); });
105 document.body.attachEvent("onunload", function() { ok(false, "unload fired on document.body"); });
108 sync_test("builtin_toString", function() {
110 [ "abbr", "Phrase", -1 ],
111 [ "acronym", "Phrase", -1 ],
112 [ "address", "Block", -1 ],
113 // [ "applet", "Applet" ], // makes Windows pop up a dialog box
116 [ "audio", "Audio", -1 ],
117 [ "b", "Phrase", -1 ],
118 [ "base", "Base", -1 ],
119 [ "basefont", "BaseFont", -1 ],
120 [ "bdi", "Unknown" ],
121 [ "bdo", "Phrase", -1 ],
122 [ "big", "Phrase", -1 ],
123 [ "blockquote", "Block", -1 ],
126 [ "button", "Button" ],
127 [ "canvas", "Canvas", -1 ],
128 [ "caption", "TableCaption", -1 ],
129 [ "center", "Block", -1 ],
130 [ "cite", "Phrase", -1 ],
131 [ "code", "Phrase", -1 ],
132 [ "col", "TableCol", -1 ],
133 [ "colgroup", "TableCol", -1 ],
134 [ "data", "Unknown" ],
135 [ "datalist", "DataList", 10 ],
137 [ "del", "Mod", -1 ],
138 [ "details", "Unknown" ],
139 [ "dfn", "Phrase", -1 ],
140 [ "dialog", "Unknown" ],
141 [ "dir", "Directory", -1 ],
142 [ "div", "Div", -1 ],
143 [ "dl", "DList", -1 ],
145 [ "em", "Phrase", -1 ],
146 [ "embed", "Embed" ],
147 [ "fieldset", "FieldSet", -1 ],
148 [ "figcaption", "" ],
150 [ "font", "Font", -1 ],
152 [ "form", "Form", -1 ],
153 [ "frame", "Frame", -1 ],
154 [ "frameset", "FrameSet", -1 ],
155 [ "h1", "Heading", -1 ],
156 [ "h2", "Heading", -1 ],
157 [ "h3", "Heading", -1 ],
158 [ "h4", "Heading", -1 ],
159 [ "h5", "Heading", -1 ],
160 [ "h6", "Heading", -1 ],
166 [ "i", "Phrase", -1 ],
167 [ "iframe", "IFrame", -1 ],
169 [ "input", "Input" ],
170 [ "ins", "Mod", -1 ],
171 [ "kbd", "Phrase", -1 ],
172 [ "label", "Label" ],
173 [ "legend", "Legend", -1 ],
176 [ "main", "Unknown" ],
177 [ "map", "Map", -1 ],
180 [ "meter", "Unknown" ],
184 [ "object", "Object", -1 ],
185 [ "ol", "OList", -1 ],
186 [ "optgroup", "OptGroup", -1 ],
187 [ "option", "Option" ],
188 [ "output", "Unknown" ],
189 [ "p", "Paragraph", -1 ],
190 [ "param", "Param", -1 ],
191 [ "picture", "Unknown" ],
192 [ "pre", "Pre", -1 ],
193 [ "progress", "Progress", 10 ],
194 [ "q", "Quote", -1 ],
195 [ "rp", "Phrase", -1 ],
196 [ "rt", "Phrase", -1 ],
197 [ "ruby", "Phrase", -1 ],
198 [ "s", "Phrase", -1 ],
199 [ "samp", "Phrase", -1 ],
200 [ "script", "Script" ],
202 [ "select", "Select", -1 ],
203 [ "small", "Phrase", -1 ],
204 [ "source", "Source", -1 ],
205 [ "span", "Span", -1 ],
206 [ "strike", "Phrase", -1 ],
207 [ "strong", "Phrase", -1 ],
208 [ "style", "Style" ],
209 [ "sub", "Phrase", -1 ],
210 [ "summary", "Unknown" ],
211 [ "sup", "Phrase", -1 ],
212 [ "svg", "Unknown" ],
213 [ "table", "Table" ],
214 [ "tbody", "TableSection", -1 ],
215 [ "td", "TableDataCell" ],
216 [ "template", "Unknown" ],
217 [ "textarea", "TextArea" ],
218 [ "tfoot", "TableSection", -1 ],
219 [ "th", "TableHeaderCell", -1 ],
220 [ "thead", "TableSection", -1 ],
221 [ "time", "Unknown" ],
222 [ "title", "Title" ],
223 [ "tr", "TableRow" ],
224 [ "track", "Track", 10 ],
225 [ "tt", "Phrase", -1 ],
226 [ "u", "Phrase", -1 ],
227 [ "ul", "UList", -1 ],
228 [ "var", "Phrase", -1 ],
229 [ "video", "Video", -1 ],
231 [ "winetest", "Unknown" ]
233 var v = document.documentMode, e;
235 function test(msg, obj, name, tostr, is_todo) {
239 todo_wine_if(name !== "HTMLElement" && s === "[object HTMLElement]").
240 ok(s === (tostr ? tostr : (v < 9 ? "[object]" : "[object " + name + "]")), msg + " toString returned " + s);
242 s = Object.prototype.toString.call(obj);
243 todo_wine_if(v >= 9 && is_todo).
244 ok(s === (v < 9 ? "[object Object]" : "[object " + name + "]"), msg + " Object.toString returned " + s);
247 for(var i = 0; i < tags.length; i++)
248 if(tags[i].length < 3 || v >= tags[i][2])
249 test("tag '" + tags[i][0] + "'", document.createElement(tags[i][0]), "HTML" + tags[i][1] + "Element", null, tags[i].length > 2);
251 e = document.createElement("a");
252 ok(e.toString() === "", "tag 'a' (without href) toString returned " + e.toString());
253 e.href = "https://www.winehq.org/";
254 test("tag 'a'", e, "HTMLAnchorElement", "https://www.winehq.org/");
256 e = document.createElement("area");
257 ok(e.toString() === "", "tag 'area' (without href) toString returned " + e.toString());
258 e.href = "https://www.winehq.org/";
259 test("tag 'area'", e, "HTMLAreaElement", "https://www.winehq.org/");
261 e = document.createElement("style");
262 document.body.appendChild(e);
263 var sheet = v >= 9 ? e.sheet : e.styleSheet;
265 sheet.insertRule("div { border: none }", 0);
267 sheet.addRule("div", "border: none", 0);
269 e = document.createElement("p");
270 e.className = "testclass another ";
271 e.textContent = "Test content";
272 e.style.border = "1px solid black";
273 document.body.appendChild(e);
275 var txtRange = document.body.createTextRange();
276 txtRange.moveToElementText(e);
278 var clientRects = e.getClientRects();
279 if(!clientRects) win_skip("getClientRects() is buggy and not available, skipping");
281 var currentStyle = e.currentStyle;
282 if(!currentStyle) win_skip("currentStyle is buggy and not available, skipping");
284 // w10pro64 testbot VM throws WININET_E_INTERNAL_ERROR for some reason
287 localStorage = window.localStorage;
289 ok(e.number === 0x72ee4 - 0x80000000, "localStorage threw " + e.number + ": " + e);
291 if(!localStorage) win_skip("localStorage is buggy and not available, skipping");
293 test("attribute", document.createAttribute("class"), "Attr");
294 if(false /* todo_wine */) test("attributes", e.attributes, "NamedNodeMap");
295 test("childNodes", document.body.childNodes, "NodeList", null, true);
296 if(clientRects) test("clientRect", clientRects[0], "ClientRect", null, true);
297 if(clientRects) test("clientRects", clientRects, "ClientRectList", null, true);
298 if(currentStyle) test("currentStyle", currentStyle, "MSCurrentStyleCSSProperties", null, true);
299 if(v >= 11 /* todo_wine */) test("document", document, v < 11 ? "Document" : "HTMLDocument", null, true);
300 test("elements", document.getElementsByTagName("body"), "HTMLCollection", null, true);
301 test("history", window.history, "History");
302 test("implementation", document.implementation, "DOMImplementation");
303 if(localStorage) test("localStorage", localStorage, "Storage", null, true);
304 test("location", window.location, "Object", window.location.href, null, true);
305 if(v >= 11 /* todo_wine */) test("mimeTypes", window.navigator.mimeTypes, v < 11 ? "MSMimeTypesCollection" : "MimeTypeArray");
306 test("navigator", window.navigator, "Navigator");
307 test("performance", window.performance, "Performance");
308 test("performanceNavigation", window.performance.navigation, "PerformanceNavigation");
309 test("performanceTiming", window.performance.timing, "PerformanceTiming");
310 if(v >= 11 /* todo_wine */) test("plugins", window.navigator.plugins, v < 11 ? "MSPluginsCollection" : "PluginArray");
311 test("screen", window.screen, "Screen");
312 test("sessionStorage", window.sessionStorage, "Storage", null, true);
313 test("style", document.body.style, "MSStyleCSSProperties", null, true);
314 test("styleSheet", sheet, "CSSStyleSheet", null, true);
315 test("styleSheetRule", sheet.rules[0], "CSSStyleRule", null, true);
316 test("styleSheetRules", sheet.rules, "MSCSSRuleList", null, true);
317 test("styleSheets", document.styleSheets, "StyleSheetList", null, true);
318 test("textNode", document.createTextNode("testNode"), "Text", v < 9 ? "testNode" : null);
319 test("textRange", txtRange, "TextRange");
320 test("window", window, "Window", "[object Window]", true);
321 test("xmlHttpRequest", new XMLHttpRequest(), "XMLHttpRequest");
323 test("namespaces", document.namespaces, "MSNamespaceInfoCollection");
326 test("eventObject", document.createEventObject(), "MSEventObj");
327 test("selection", document.selection, "MSSelection");
330 test("computedStyle", window.getComputedStyle(e), "CSSStyleDeclaration", null, true);
331 test("doctype", document.doctype, "DocumentType");
333 test("Event", document.createEvent("Event"), "Event");
334 test("CustomEvent", document.createEvent("CustomEvent"), "CustomEvent");
335 test("KeyboardEvent", document.createEvent("KeyboardEvent"), "KeyboardEvent");
336 test("MouseEvent", document.createEvent("MouseEvent"), "MouseEvent");
337 test("UIEvent", document.createEvent("UIEvent"), "UIEvent");
340 test("classList", e.classList, "DOMTokenList", "testclass another ", true);
341 test("console", window.console, "Console");
342 test("mediaQueryList", window.matchMedia("(hover:hover)"), "MediaQueryList");
345 test("MutationObserver", new window.MutationObserver(function() {}), "MutationObserver", null, true);
348 document.body.innerHTML = "<!--...-->";
349 test("comment", document.body.firstChild, "Comment");
353 sync_test("builtin_obj", function() {
354 var v = document.documentMode;
355 var f = document.createElement;
359 ok(!(window instanceof Object), "window instance of Object");
360 ok(!(document instanceof Object), "document instance of Object");
361 ok(!("arguments" in f), "arguments in f");
362 ok(!("length" in f), "length in f");
369 ok(e === 0xa01b6 - 0x80000000, "[f.toString] e = " + e);
371 window.toString.call(null);
372 ok(false, "expected exception calling window.toString with null context");
378 f.call(Object, "div");
382 todo_wine_if(v >= 9).
383 ok(e === (v < 9 ? 0xa0005 : 0x0ffff) - 0x80000000, "[f.call(Object, 'div')] e = " + e);
391 todo_wine_if(v >= 9).
392 ok(e === (v < 9 ? 0xa0005 : 0x0ffff) - 0x80000000, "[f.call(null, 'div')] e = " + e);
394 var elem1 = f.call(document, "div");
395 var elem2 = f.call(document, "br");
396 document.body.appendChild(elem1);
397 document.body.appendChild(elem2);
398 elem1.onclick = function() { ok(false, "unexpected elem1.onclick"); };
400 elem2.onclick = function() { clicked = true; };
401 elem1.click.call(elem2);
402 ok(clicked === true, "elem2.onclick not called");
404 elem1 = f.apply(document, ["div"]);
405 elem2 = f.apply(document, ["br"]);
406 document.body.appendChild(elem1);
407 document.body.appendChild(elem2);
408 elem1.onclick = function() { ok(false, "unexpected elem1.onclick"); };
410 elem2.onclick = function() { clicked = true; };
411 elem1.click.apply(elem2);
412 ok(clicked === true, "elem2.onclick not called");
415 elem1.click.apply(elem2, { length: -1 });
416 ok(false, "exception expected");
420 sync_test("elem_props", function() {
421 var elem = document.documentElement;
423 function test_exposed(prop, expect, is_todo) {
424 var ok_ = is_todo ? todo_wine.ok : ok;
426 ok_(prop in elem, prop + " not found in element.");
428 ok_(!(prop in elem), prop + " found in element.");
431 var v = document.documentMode;
433 test_exposed("attachEvent", v < 11);
434 test_exposed("detachEvent", v < 11);
435 test_exposed("doScroll", v < 11);
436 test_exposed("readyState", v < 11);
437 test_exposed("clientTop", true);
438 test_exposed("title", true);
439 test_exposed("querySelectorAll", v >= 8);
440 test_exposed("textContent", v >= 9);
441 test_exposed("prefix", v >= 9);
442 test_exposed("firstElementChild", v >= 9);
443 test_exposed("onsubmit", v >= 9);
444 test_exposed("getElementsByClassName", v >= 9);
445 test_exposed("removeAttributeNS", v >= 9);
446 test_exposed("addEventListener", v >= 9);
447 test_exposed("hasAttribute", v >= 8, v === 8);
448 test_exposed("removeEventListener", v >= 9);
449 test_exposed("dispatchEvent", v >= 9);
450 test_exposed("msSetPointerCapture", v >= 10);
451 if (v >= 9) test_exposed("spellcheck", v >= 10);
453 elem = document.createElement("style");
454 test_exposed("media", true);
455 test_exposed("type", true);
456 test_exposed("disabled", true);
457 test_exposed("media", true);
458 test_exposed("sheet", v >= 9);
459 test_exposed("readyState", v < 11);
460 test_exposed("styleSheet", v < 11);
461 test_exposed("classList", v >= 10);
463 elem = document.createElement("img");
464 test_exposed("fileSize", v < 11);
467 sync_test("doc_props", function() {
468 function test_exposed(prop, expect, is_todo) {
469 var ok_ = is_todo ? todo_wine.ok : ok;
471 ok_(prop in document, prop + " not found in document.");
473 ok_(!(prop in document), prop + " found in document.");
476 var v = document.documentMode;
477 ok(document.mimeType === external.getExpectedMimeType("text/html"), "mimeType = " + document.mimeType);
479 test_exposed("attachEvent", v < 11);
480 test_exposed("detachEvent", v < 11);
481 test_exposed("createStyleSheet",v < 11);
482 test_exposed("fileSize", v < 11);
483 test_exposed("selection", v < 11);
484 test_exposed("onstorage", v < 9);
485 test_exposed("textContent", v >= 9);
486 test_exposed("prefix", v >= 9);
487 test_exposed("defaultView", v >= 9);
488 test_exposed("head", v >= 9);
489 test_exposed("addEventListener", v >= 9);
490 test_exposed("removeEventListener", v >= 9);
491 test_exposed("dispatchEvent", v >= 9);
492 test_exposed("createEvent", v >= 9);
494 test_exposed("parentWindow", true);
495 if(v >= 9) ok(document.defaultView === document.parentWindow, "defaultView != parentWindow");
498 sync_test("docfrag_props", function() {
499 var docfrag = document.createDocumentFragment();
501 function test_exposed(prop, expect) {
503 ok(prop in docfrag, prop + " not found in document fragent.");
505 ok(!(prop in docfrag), prop + " found in document fragent.");
508 var v = document.documentMode;
510 test_exposed("compareDocumentPosition", v >= 9);
513 sync_test("window_props", function() {
514 function test_exposed(prop, expect, is_todo) {
515 var ok_ = is_todo ? todo_wine.ok : ok;
517 ok_(prop in window, prop + " not found in window.");
519 ok_(!(prop in window), prop + " found in window.");
522 var v = document.documentMode;
524 test_exposed("attachEvent", v < 11);
525 test_exposed("detachEvent", v < 11);
526 test_exposed("execScript", v < 11);
527 test_exposed("createPopup", v < 11);
528 test_exposed("postMessage", true);
529 test_exposed("sessionStorage", true);
530 test_exposed("localStorage", true);
531 test_exposed("addEventListener", v >= 9);
532 test_exposed("removeEventListener", v >= 9);
533 test_exposed("dispatchEvent", v >= 9);
534 test_exposed("getSelection", v >= 9);
535 test_exposed("onfocusout", v >= 9);
536 test_exposed("getComputedStyle", v >= 9);
537 test_exposed("cancelAnimationFrame", v >= 10);
538 test_exposed("requestAnimationFrame", v >= 10);
539 test_exposed("Map", v >= 11);
540 test_exposed("Set", v >= 11);
541 test_exposed("WeakMap", v >= 11);
542 test_exposed("WeakSet", false);
543 test_exposed("performance", true);
544 test_exposed("console", v >= 10);
545 test_exposed("matchMedia", v >= 10);
546 test_exposed("MutationObserver", v >= 11);
549 sync_test("domimpl_props", function() {
550 var domimpl = document.implementation;
551 function test_exposed(prop, expect) {
553 ok(prop in domimpl, prop + " not found in DOMImplementation.");
555 ok(!(prop in domimpl), prop + " found in DOMImplementation.");
558 var v = document.documentMode;
560 test_exposed("hasFeature", true);
561 test_exposed("createDocument", v >= 9);
562 test_exposed("createDocumentType", v >= 9);
563 test_exposed("createHTMLDocument", v >= 9);
566 sync_test("xhr_props", function() {
567 var xhr = new XMLHttpRequest();
569 function test_exposed(prop, expect) {
571 ok(prop in xhr, prop + " not found in XMLHttpRequest.");
573 ok(!(prop in xhr), prop + " found in XMLHttpRequest.");
576 var v = document.documentMode;
578 test_exposed("addEventListener", v >= 9);
579 test_exposed("removeEventListener", v >= 9);
580 test_exposed("dispatchEvent", v >= 9);
581 test_exposed("onabort", v >= 10);
582 test_exposed("onerror", v >= 10);
583 test_exposed("onloadend", v >= 10);
584 test_exposed("onloadstart", v >= 10);
585 test_exposed("onprogress", v >= 10);
586 test_exposed("ontimeout", true);
587 test_exposed("overrideMimeType", v >= 11);
588 test_exposed("response", v >= 10);
589 test_exposed("responseType", v >= 10);
590 test_exposed("timeout", true);
591 test_exposed("upload", v >= 10);
592 test_exposed("withCredentials", v >= 10);
595 sync_test("stylesheet_props", function() {
596 var v = document.documentMode;
597 var elem = document.createElement("style");
598 document.body.appendChild(elem);
599 var sheet = v >= 9 ? elem.sheet : elem.styleSheet;
601 function test_exposed(prop, expect) {
603 ok(prop in sheet, prop + " not found in style sheet.");
605 ok(!(prop in sheet), prop + " found in style sheet.");
608 test_exposed("href", true);
609 test_exposed("title", true);
610 test_exposed("type", true);
611 test_exposed("media", true);
612 test_exposed("ownerNode", v >= 9);
613 test_exposed("ownerRule", v >= 9);
614 test_exposed("cssRules", v >= 9);
615 test_exposed("insertRule", v >= 9);
616 test_exposed("deleteRule", v >= 9);
617 test_exposed("disabled", true);
618 test_exposed("parentStyleSheet", true);
619 test_exposed("owningElement", true);
620 test_exposed("readOnly", true);
621 test_exposed("imports", true);
622 test_exposed("id", true);
623 test_exposed("addImport", true);
624 test_exposed("addRule", true);
625 test_exposed("removeImport", true);
626 test_exposed("removeRule", true);
627 test_exposed("cssText", true);
628 test_exposed("rules", true);
631 sync_test("rect_props", function() {
632 document.body.innerHTML = '<div>test</div>';
633 var elem = document.body.firstChild;
634 var rect = elem.getBoundingClientRect();
635 function test_exposed(prop, expect) {
637 ok(prop in rect, prop + " not found in rect object.");
639 ok(!(prop in rect), prop + " found in rect object.");
642 var v = document.documentMode;
644 test_exposed("width", v >= 9);
645 test_exposed("height", v >= 9);
648 sync_test("xhr open", function() {
651 (new XMLHttpRequest()).open("GET", "https://www.winehq.org/");
656 if(document.documentMode < 10)
657 ok(e, "expected exception");
659 ok(!e, "unexpected exception");
662 sync_test("style_props", function() {
663 var style = document.body.style;
665 function test_exposed(prop, expect) {
667 ok(prop in style, prop + " not found in style object.");
669 ok(!(prop in style), prop + " found in style object.");
672 var v = document.documentMode;
674 test_exposed("removeAttribute", true);
675 test_exposed("zIndex", true);
676 test_exposed("z-index", true);
677 test_exposed("filter", true);
678 test_exposed("pixelTop", true);
679 test_exposed("float", true);
680 test_exposed("css-float", false);
681 test_exposed("style-float", false);
682 test_exposed("setProperty", v >= 9);
683 test_exposed("removeProperty", v >= 9);
684 test_exposed("background-clip", v >= 9);
685 test_exposed("msTransform", v >= 9);
686 test_exposed("transform", v >= 10);
688 style = document.body.currentStyle;
690 test_exposed("zIndex", true);
691 test_exposed("z-index", true);
692 test_exposed("filter", true);
693 test_exposed("pixelTop", false);
694 test_exposed("float", true);
695 test_exposed("css-float", false);
696 test_exposed("style-float", false);
697 test_exposed("setProperty", v >= 9);
698 test_exposed("removeProperty", v >= 9);
699 test_exposed("background-clip", v >= 9);
700 test_exposed("transform", v >= 10);
702 if(window.getComputedStyle) {
703 style = window.getComputedStyle(document.body);
705 test_exposed("removeAttribute", false);
706 test_exposed("zIndex", true);
707 test_exposed("z-index", true);
708 test_exposed("pixelTop", false);
709 test_exposed("float", true);
710 test_exposed("css-float", false);
711 test_exposed("style-float", false);
712 test_exposed("setProperty", v >= 9);
713 test_exposed("removeProperty", v >= 9);
714 test_exposed("background-clip", v >= 9);
715 test_exposed("transform", v >= 10);
719 sync_test("createElement_inline_attr", function() {
720 var v = document.documentMode, e, s;
723 s = document.createElement("<div>").tagName;
724 ok(s === "DIV", "<div>.tagName returned " + s);
725 s = document.createElement("<div >").tagName;
726 ok(s === "DIV", "<div >.tagName returned " + s);
727 s = document.createElement("<div/>").tagName;
728 ok(s === "DIV", "<div/>.tagName returned " + s);
731 document.createElement("<div");
735 ok(e === 0x4005 - 0x80000000, "<div e = " + e);
738 document.createElement("<div test=1");
742 ok(e === 0x4005 - 0x80000000, "<div test=1 e = " + e);
744 var tags = [ "div", "head", "body", "title", "html" ];
746 for(var i = 0; i < tags.length; i++) {
747 e = document.createElement("<" + tags[i] + " test='a\"' abcd=\""b"\">");
748 ok(e.tagName === tags[i].toUpperCase(), "<" + tags[i] + " test=\"a\" abcd=\"b\">.tagName returned " + e.tagName);
749 ok(e.test === "a\"", "<" + tags[i] + " test='a\"' abcd=\""b"\">.test returned " + e.test);
750 ok(e.abcd === "\"b\"", "<" + tags[i] + " test='a\"' abcd=\""b"\">.abcd returned " + e.abcd);
756 document.createElement("<div>");
762 ok(e === undefined, "<div> e = " + e);
764 ok(s === "InvalidCharacterError", "<div> s = " + s);
768 document.createElement("<div test=\"a\">");
774 ok(e === undefined, "<div test=\"a\"> e = " + e);
776 ok(s === "InvalidCharacterError", "<div test=\"a\"> s = " + s);
780 sync_test("JS objs", function() {
783 function test_exposed(func, obj, expect, is_todo) {
784 var ok_ = is_todo ? todo_wine.ok : ok;
786 ok_(func in obj, func + " not found in " + obj);
788 ok_(!(func in obj), func + " found in " + obj);
791 function test_parses(code, expect) {
800 ok(success === true, code + " did not parse");
802 ok(success === false, code + " parsed");
805 var v = document.documentMode;
807 test_exposed("ScriptEngineMajorVersion", g, true);
809 test_exposed("JSON", g, v >= 8);
810 test_exposed("now", Date, true);
811 test_exposed("toISOString", Date.prototype, v >= 9);
812 test_exposed("isArray", Array, v >= 9);
813 test_exposed("forEach", Array.prototype, v >= 9);
814 test_exposed("indexOf", Array.prototype, v >= 9);
815 test_exposed("trim", String.prototype, v >= 9);
816 test_exposed("map", Array.prototype, v >= 9);
818 /* FIXME: IE8 implements weird semi-functional property descriptors. */
819 test_exposed("getOwnPropertyDescriptor", Object, v >= 8, v === 8);
820 test_exposed("defineProperty", Object, v >= 8, v === 8);
821 test_exposed("defineProperties", Object, v >= 9);
823 test_exposed("getPrototypeOf", Object, v >= 9);
825 test_parses("if(false) { o.default; }", v >= 9);
826 test_parses("if(false) { o.with; }", v >= 9);
827 test_parses("if(false) { o.if; }", v >= 9);
830 sync_test("eval", function() {
831 var i, context, code = "this.foobar = 1234", v = document.documentMode;
834 function() { eval(code); },
835 function() { (eval)(code); },
836 function() { (function(eval) { eval(code); }).call(this, eval); },
837 function() { eval("eval(" + code + ")"); }
840 for(i = 0; i < direct.length; i++) {
842 direct[i].call(context);
843 ok(context.foobar === 1234, "direct[" + i + "] context foobar = " + context.foobar);
847 function() { (true, eval)(code); },
848 function() { (eval, eval)(code); },
849 function() { (true ? eval : false)(code); },
850 function() { [eval][0](code); },
851 function() { eval.call(this, code); },
852 function() { var f; (f = eval)(code); },
853 function() { var f = eval; f(code); },
854 function() { (function(f) { f(code); }).call(this, eval); },
855 function() { (function(f) { return f; }).call(this, eval)(code); },
856 function() { (function() { arguments[0](code) }).call(this, eval); },
857 function() { window.eval(code); },
858 function() { window["eval"](code); },
859 function() { eval("eval")(code); }
862 for(i = 0; i < indirect.length; i++) {
864 ok(!("foobar" in window), "indirect[" + i + "] has global foobar before call");
865 indirect[i].call(context);
867 ok(context.foobar === 1234, "indirect[" + i + "] context foobar = " + context.foobar);
868 ok(!("foobar" in window), "indirect[" + i + "] has global foobar");
870 ok(!("foobar" in context), "indirect[" + i + "] has foobar");
871 ok(window.foobar === 1234, "indirect[" + i + "] global foobar = " + context.foobar);
872 delete window.foobar;
877 (function(eval) { eval(code); })(function() { context.barfoo = 4321; });
878 ok(context.barfoo === 4321, "context.barfoo = " + context.barfoo);
881 sync_test("for..in", function() {
882 var v = document.documentMode, found = 0, r;
885 ctor.prototype.test2 = true;
887 var arr = new Array(), obj = new ctor(), i, r;
892 ctor.prototype.test3 = true;
897 ok(i === 3, "enum did " + i + " iterations");
898 ok(arr["test1"] === true, "arr[test1] !== true");
899 ok(arr["test2"] === true, "arr[test2] !== true");
900 ok(arr["test3"] === true, "arr[test3] !== true");
903 if(r === "ondragstart")
905 ok(found === 1, "ondragstart enumerated " + found + " times in document");
906 document.ondragstart = "";
909 if(r === "ondragstart")
911 ok(found === 1, "ondragstart enumerated " + found + " times in document after set to empty string");
914 sync_test("function caller", function() {
915 ok(Function.prototype.hasOwnProperty("caller"), "caller not prop of Function.prototype");
917 function test_caller(expected_caller, stop) {
918 ok(test_caller.caller === expected_caller, "caller = " + test_caller.caller);
921 ok(nested.caller === test_caller, "nested caller = " + nested.caller);
922 test_caller(nested, true);
923 ok(test_caller.caller === expected_caller, "caller within nested = " + test_caller.caller);
926 ok(test_caller.caller === expected_caller, "caller after nested = " + test_caller.caller);
928 ok(test_caller.hasOwnProperty("caller"), "caller not prop of test_caller");
929 ok(test_caller.caller === null, "test_caller.caller = " + test_caller.caller);
931 function f1() { test_caller(f1); } f1();
932 function f2() { test_caller(f2); } f2();
935 sync_test("elem_by_id", function() {
936 document.body.innerHTML = '<form id="testid" name="testname"></form>';
937 var v = document.documentMode, found, i;
939 var id_elem = document.getElementById("testid");
940 ok(id_elem.tagName === "FORM", "id_elem.tagName = " + id_elem.tagName);
942 var name_elem = document.getElementById("testname");
944 ok(id_elem === name_elem, "id_elem != id_elem");
946 ok(name_elem === null, "name_elem != null");
948 id_elem = window.testid;
949 ok(id_elem.tagName === "FORM", "window.testid = " + id_elem);
951 name_elem = document.testname;
952 ok(name_elem.tagName === "FORM", "document.testname = " + name_elem);
954 for(id_elem in window)
955 ok(id_elem !== "testid" && id_elem != "testname", id_elem + " was enumerated in window");
958 for(id_elem in window) {
959 ok(id_elem != "testname", id_elem + " was enumerated in window after set to 137");
960 if(id_elem === "testid")
963 ok(found, "testid was not enumerated in window after set to 137");
966 for(id_elem in document) {
967 ok(id_elem !== "testid", "testid was enumerated in document");
968 if(id_elem === "testname")
971 ok(found, "testname was not enumerated in document");
975 ok(false, "document.testname() did not throw exception");
977 ok(e.number === 0xa01b6 - 0x80000000, "document.testname() threw = " + e.number);
981 document.testname = "foo";
982 ok(v >= 9, "Setting document.testname did not throw exception");
984 id_elem = document.testid;
985 ok(id_elem.tagName === "FORM", "document.testid after set = " + id_elem);
986 name_elem = document.testname;
987 ok(name_elem === "foo", "document.testname after set = " + name_elem);
989 todo_wine_if(v >= 9).
990 ok(v < 9 && e.number === 0xa01b6 - 0x80000000, "Setting document.testname threw = " + e.number);
994 document.testid = "bar";
995 ok(v >= 9, "Setting document.testid did not throw exception");
997 id_elem = document.testid;
998 ok(id_elem === "bar", "document.testid after both set = " + id_elem);
999 name_elem = document.testname;
1000 ok(name_elem === "foo", "document.testname after both set = " + name_elem);
1002 found = false, name_elem = false;
1003 for(id_elem in document) {
1004 if(id_elem === "testid")
1006 if(id_elem === "testname")
1009 ok(found, "testid was not enumerated in document after both set");
1010 ok(name_elem, "testname was not enumerated in document after both set");
1011 delete document.testid;
1012 delete document.testname;
1014 todo_wine_if(v >= 9).
1015 ok(v < 9 && e.number === 0xa01b6 - 0x80000000, "Setting document.testid threw = " + e.number);
1019 document.testid2 = 2;
1020 document.body.innerHTML = '<form id="testid2" name="testname"></form>';
1021 ok(window.testid2 == 1, "window.testid2 = " + window.testid2);
1022 id_elem = document.body.firstChild;
1023 ok(document.testid2 == (v < 9 ? id_elem : 2), "document.testid2 = " + document.testid2);
1024 document.body.innerHTML = '';
1025 ok(window.testid2 == 1, "window.testid2 = " + window.testid2);
1026 ok(document.testid2 == 2, "document.testid2 = " + document.testid2 + " expected 2");
1028 ok(document.title === "", "document.title = " + document.title);
1029 document.body.innerHTML = '<form id="title" name="testname"></form>';
1030 id_elem = document.body.firstChild;
1031 todo_wine_if(v < 9).
1032 ok(document.title === (v < 9 ? id_elem : ""), "document.title = " + document.title);
1033 document.body.innerHTML = '';
1034 ok(document.title === "", "document.title = " + document.title);
1036 ok(window.closed === false, "window.closed = " + window.closed);
1037 document.body.innerHTML = '<form id="closed" name="testname"></form>';
1038 id_elem = document.body.firstChild;
1039 ok(window.closed === false, "window.closed = " + window.closed);
1041 // these tags expose name as props, and id only if they have a name
1042 var tags = [ "embed", "form", "iframe", "img" ];
1045 document.body.innerHTML = '<' + tag + ' id="testid" name="testname"></' + tag + '><' + tag + ' id="foobar"></' + tag + '>';
1046 ok("testname" in document, tag + " did not expose testname");
1047 ok("testid" in document, tag + " did not expose testid");
1048 ok(!("foobar" in document), tag + " exposed foobar");
1051 // these tags always expose their id as well as name (we don't test applet because it makes Windows pop up a dialog box)
1052 tags = [ "object" ];
1055 document.body.innerHTML = '<' + tag + ' id="testid" name="testname"></' + tag + '><' + tag + ' id="foobar"></' + tag + '>';
1056 ok("testname" in document, tag + " did not expose testname");
1057 ok("testid" in document, tag + " did not expose testid");
1058 ok("foobar" in document, tag + " did not expose foobar");
1061 // all other tags don't expose props for either id or name, test a few of them here
1062 tags = [ "a", "b", "body", "center", "div", "frame", "h2", "head", "html", "input", "meta", "p", "span", "style", "table", "winetest" ];
1065 document.body.innerHTML = '<' + tag + ' id="testid" name="testname"></' + tag + '><' + tag + ' id="foobar"></' + tag + '>';
1066 ok(!("testname" in document), tag + " exposed testname");
1067 ok(!("testid" in document), tag + " exposed testid");
1068 ok(!("foobar" in document), tag + " exposed foobar");
1072 sync_test("doc_mode", function() {
1073 compat_version = parseInt(document.location.search.substring(1));
1075 trace("Testing compatibility mode " + compat_version);
1077 if(compat_version > 6 && compat_version > document.documentMode) {
1078 win_skip("Document mode not supported (expected " + compat_version + " got " + document.documentMode + ")");
1083 ok(Math.max(compat_version, 5) === document.documentMode, "documentMode = " + document.documentMode);
1085 if(document.documentMode > 5)
1086 ok(document.compatMode === "CSS1Compat", "document.compatMode = " + document.compatMode);
1088 ok(document.compatMode === "BackCompat", "document.compatMode = " + document.compatMode);
1091 sync_test("doctype", function() {
1092 var doctype = document.doctype;
1094 if(document.documentMode < 9) {
1095 ok(doctype === null, "doctype = " + document.doctype);
1099 ok(doctype.name === "html", "doctype.name = " + doctype.name);
1102 async_test("iframe_doc_mode", function() {
1103 var iframe = document.createElement("iframe");
1105 iframe.onload = function() {
1106 var iframe_mode = iframe.contentWindow.document.documentMode;
1107 if(document.documentMode < 9)
1108 ok(iframe_mode === 5, "iframe_mode = " + iframe_mode);
1110 ok(iframe_mode === document.documentMode, "iframe_mode = " + iframe_mode);
1114 iframe.src = "about:blank";
1115 document.body.appendChild(iframe);
1118 sync_test("conditional_comments", function() {
1119 var div = document.createElement("div");
1120 document.body.appendChild(div);
1122 function test_version(v) {
1123 var version = compat_version ? compat_version : 7;
1125 div.innerHTML = "<!--[if lte IE " + v + "]>true<![endif]-->";
1126 ok(div.innerText === (version <= v ? "true" : ""),
1127 "div.innerText = " + div.innerText + " for version (<=) " + v);
1129 div.innerHTML = "<!--[if lt IE " + v + "]>true<![endif]-->";
1130 ok(div.innerText === (version < v ? "true" : ""),
1131 "div.innerText = " + div.innerText + " for version (<) " + v);
1133 div.innerHTML = "<!--[if gte IE " + v + "]>true<![endif]-->";
1134 ok(div.innerText === (version >= v && version < 10 ? "true" : ""),
1135 "div.innerText = " + div.innerText + " for version (>=) " + v);
1137 div.innerHTML = "<!--[if gt IE " + v + "]>true<![endif]-->";
1138 ok(div.innerText === (version > v && version < 10 ? "true" : ""),
1139 "div.innerText = " + div.innerText + " for version (>) " + v);
1150 async_test("script_load", function() {
1151 var v = document.documentMode;
1157 var elem = document.createElement("script");
1160 elem.onreadystatechange = guard(function() {
1161 ok(v < 11, "unexpected onreadystatechange call");
1162 ready_states += elem.readyState + ",";
1165 elem.onload = guard(function() {
1168 ok(ready_states === "loading,exec,loaded,", "ready_states = " + ready_states);
1171 ok(ready_states === "loading,exec,", "ready_states = " + ready_states);
1174 ok(ready_states === "exec,", "ready_states = " + ready_states);
1180 document.body.appendChild(elem);
1181 elem.src = "jsstream.php?simple";
1182 external.writeStream("simple", "ready_states += 'exec,';");
1185 sync_test("location", function() {
1186 document.body.innerHTML = '<a name="testanchor">test</a>';
1188 ok(location.hash === "", "initial location.hash = " + location.hash);
1189 location.hash = "TestAnchor";
1190 ok(location.hash === "#TestAnchor", "location.hash after set to TestAnchor = " + location.hash);
1191 location.hash = "##foo";
1192 ok(location.hash === "##foo", "location.hash after set to ##foo = " + location.hash);
1193 location.hash = "#testanchor";
1194 ok(location.hash === "#testanchor", "location.hash after set to #testanchor = " + location.hash);
1197 sync_test("navigator", function() {
1198 var v = document.documentMode, re;
1199 var app = navigator.appVersion;
1200 ok(navigator.userAgent === "Mozilla/" + app,
1201 "userAgent = " + navigator.userAgent + " appVersion = " + app);
1204 ? "^" + (v < 9 ? "4" : "5") + "\\.0 \\(compatible; MSIE " + (v < 7 ? 7 : v) +
1205 "\\.0; Windows NT [0-9].[0-9]; .*Trident/[678]\\.0.*\\)$"
1206 : "^5.0 \\(Windows NT [0-9].[0-9]; .*Trident/[678]\\.0.*rv:11.0\\) like Gecko$";
1207 ok(new RegExp(re).test(app), "appVersion = " + app);
1209 ok(navigator.appCodeName === "Mozilla", "appCodeName = " + navigator.appCodeName);
1210 ok(navigator.appName === (v < 11 ? "Microsoft Internet Explorer" : "Netscape"),
1211 "appName = " + navigator.appName);
1212 ok(navigator.toString() === (v < 9 ? "[object]" : "[object Navigator]"),
1213 "navigator.toString() = " + navigator.toString());
1216 sync_test("delete_prop", function() {
1217 var v = document.documentMode;
1218 var obj = document.createElement("div"), r, obj2;
1228 ok(r, "did not get an expected exception");
1231 ok(!r, "got an unexpected exception");
1232 ok(!("prop1" in obj), "prop1 is still in obj");
1234 /* again, this time prop1 does not exist */
1242 ok(r, "did not get an expected exception");
1245 ok(!r, "got an unexpected exception");
1246 ok(!("prop1" in obj), "prop1 is still in obj");
1249 r = (delete obj.className);
1250 ok(r, "delete returned " + r);
1251 ok("className" in obj, "className deleted from obj");
1252 ok(obj.className === "", "className = " + obj.className);
1254 /* builtin propertiles don't throw any exception, but are not really deleted */
1255 r = (delete obj.tagName);
1256 ok(r, "delete returned " + r);
1257 ok("tagName" in obj, "tagName deleted from obj");
1258 ok(obj.tagName === "DIV", "tagName = " + obj.tagName);
1260 obj = document.querySelectorAll("*");
1261 ok("0" in obj, "0 is not in obj");
1263 r = (delete obj[0]);
1264 ok("0" in obj, "0 is not in obj");
1265 ok(obj[0] === obj2, "obj[0] != obj2");
1267 /* test window object and its global scope handling */
1270 obj.globalprop1 = true;
1271 ok(globalprop1, "globalprop1 = " + globalprop1);
1274 delete obj.globalprop1;
1279 ok(r, "did not get an expected exception");
1281 ok(!r, "got an unexpected globalprop1 exception");
1282 ok(!("globalprop1" in obj), "globalprop1 is still in obj");
1286 ok(obj.globalprop2, "globalprop2 = " + globalprop2);
1289 delete obj.globalprop2;
1294 ok(r, "did not get an expected globalprop2 exception");
1296 ok(!r, "got an unexpected exception");
1298 ok(!("globalprop2" in obj), "globalprop2 is still in obj");
1301 obj.globalprop3 = true;
1302 ok(globalprop3, "globalprop3 = " + globalprop3);
1310 ok(r, "did not get an expected exception");
1311 ok("globalprop3" in obj, "globalprop3 is not in obj");
1313 ok(!r, "got an unexpected globalprop3 exception");
1314 ok(!("globalprop3" in obj), "globalprop3 is still in obj");
1318 ok(obj.globalprop4, "globalprop4 = " + globalprop4);
1319 r = (delete globalprop4);
1320 ok(r, "delete returned " + r);
1322 ok(!("globalprop4" in obj), "globalprop4 is still in obj");
1325 sync_test("detached arguments", function() {
1326 var args, get_a, set_a, get_x, set_x;
1328 function test_args() {
1329 ok(args[0] === 1, "args[0] = " + args[0]);
1331 ok(args[0] === 2, "args[0] = " + args[0]);
1333 ok(get_x() === 3, "get_x() = " + get_x());
1334 ok(args[0] === 3, "args[0] = " + args[0]);
1339 get_x = function() { return x; };
1340 set_x = function(v) { x = v; };
1347 (function(a, a, b, c) {
1348 get_a = function() { return a; }
1349 set_a = function(v) { a = v; }
1350 ok(get_a() === 2, "get_a() = " + get_a());
1351 ok(a === 2, "a = " + a);
1352 ok(b === 3, "b = " + b);
1353 ok(c === 4, "c = " + c);
1355 ok(arguments[0] === 1, "arguments[0] = " + arguments[0]);
1356 ok(arguments[1] === 42, "arguments[1] = " + arguments[1]);
1357 ok(get_a() === 42, "get_a() after assign = " + get_a());
1361 ok(get_a() === 42, "get_a() after detach = " + get_a());
1363 ok(get_a() === 100, "get_a() after set_a() = " + get_a());
1364 ok(args[0] === 1, "detached args[0] = " + args[0]);
1365 ok(args[1] === 100, "detached args[1] = " + args[1]);
1369 ok(a === 7, "function(a, a) a = " + a);
1370 ok(arguments[0] === 5, "function(a, a) arguments[0] = " + arguments[0]);
1371 ok(arguments[1] === 7, "function(a, a) arguments[1] = " + arguments[1]);
1375 var func_scope_val = 1;
1376 var func_scope_val2 = 2;
1378 sync_test("func_scope", function() {
1379 var func_scope_val = 2;
1381 var f = function func_scope_val() {
1382 return func_scope_val;
1386 if(document.documentMode < 9) {
1387 ok(f() === 3, "f() = " + f());
1390 ok(f === f(), "f() = " + f());
1392 f = function func_scope_val(a) {
1394 return func_scope_val;
1398 ok(f === f(), "f() = " + f());
1399 ok(func_scope_val === 3, "func_scope_val = " + func_scope_val);
1400 ok(window.func_scope_val === 1, "window.func_scope_val = " + window.func_scope_val);
1402 f = function func_scope_val(a) {
1403 return (function() { return a ? func_scope_val(false) : func_scope_val; })();
1406 ok(f === f(true), "f(true) = " + f(true));
1409 ok(window === window.self, "window = " + window);
1411 ! function func_scope_val2() {};
1412 ok(window.func_scope_val2 === 2, "window.func_scope_val2 = " + window.func_scope_val2);
1416 ok(x === o, "x = " + x);
1418 ok(x === o, "x != o");
1422 ok(x === o, "x = " + x);
1424 ok(x === o, "x != o");
1431 ok(false, "expected exception");
1436 sync_test("set_obj", function() {
1437 if(!("Set" in window)) return;
1441 ok(false, "expected exception calling constructor as method");
1443 ok(e.number === 0xa13fc - 0x80000000, "calling constructor as method threw " + e.number);
1447 ok(Object.getPrototypeOf(s) === Set.prototype, "unexpected Set prototype");
1449 function test_length(name, len) {
1450 ok(Set.prototype[name].length === len, "Set.prototype." + name + " = " + Set.prototype[name].length);
1452 Set.prototype[name].call({}, 0);
1453 ok(false, "expected exception calling Set.prototype." + name + "(object)");
1455 ok(e.number === 0xa13fc - 0x80000000, "Set.prototype." + name + "(object) threw " + e.number);
1458 test_length("add", 1);
1459 test_length("clear", 0);
1460 test_length("delete", 1);
1461 test_length("forEach", 1);
1462 test_length("has", 1);
1463 ok(!("entries" in s), "entries are in Set");
1464 ok(!("keys" in s), "keys are in Set");
1465 ok(!("values" in s), "values are in Set");
1467 r = Object.prototype.toString.call(s);
1468 ok(r === "[object Object]", "toString returned " + r);
1471 ok(r === false, "has(-0) returned " + r);
1472 ok(s.size === 0, "size = " + s.size);
1475 ok(r === undefined, "add(42) returned " + r);
1477 ok(r === undefined, "add(42) returned " + r);
1479 ok(r === undefined, "add(0) returned " + r);
1481 ok(r === false, "has(-0) returned " + r);
1483 ok(r === undefined, "add(-0) returned " + r);
1485 ok(r === true, "has(-0) after add returned " + r);
1487 ok(r === undefined, "add(test) returned " + r);
1489 ok(r === undefined, "add(13) returned " + r);
1491 ok(r === undefined, "add(s) returned " + r);
1493 r = s["delete"]("test"); /* using s.delete() would break parsing in quirks mode */
1494 ok(r === true, "delete(test) returned " + r);
1495 r = s["delete"]("test");
1496 ok(r === false, "delete(test) returned " + r);
1498 ok(s.size === 5, "size = " + s.size);
1500 ok(s.size === 5, "size (after set) = " + s.size);
1503 r = s.forEach(function(value, key, obj) {
1504 var t = s["delete"](key);
1505 ok(t === true, "delete(" + key + ") returned " + r);
1506 ok(value === key, "value = " + value + ", key = " + key);
1507 ok(obj === s, "set = " + obj);
1508 ok(this === a, "this = " + this);
1511 ok(r === undefined, "forEach returned " + r);
1512 ok(a.length === 5, "a.length = " + a.length);
1513 for(var i = 0; i < a.length; i++)
1514 ok(a[i] === [42, 0, -0, 13, s][i], "a[" + i + "] = " + a[i]);
1515 ok(s.size === 0, "size = " + s.size);
1518 ok(s.size === 0, "size = " + s.size);
1521 ok(s.size === 2, "size = " + s.size);
1523 ok(r === undefined, "clear returned " + r);
1524 ok(s.size === 0, "size = " + s.size);
1526 s = new Set([1, 2, 3]);
1527 ok(s.size === 0, "size = " + s.size);
1534 s.forEach(function(value, key, obj) {
1537 ok(s.size === 0, "size = " + s.size);
1538 ok(this.valueOf() === 42, "this.valueOf() = " + this.valueOf());
1540 ok(r === 1, "r = " + r);
1543 sync_test("map_obj", function() {
1544 if(!("Map" in window)) return;
1548 ok(false, "expected exception calling constructor as method");
1550 ok(e.number === 0xa13fc - 0x80000000, "calling constructor as method threw " + e.number);
1553 var s = new Map, r, i;
1554 ok(Object.getPrototypeOf(s) === Map.prototype, "unexpected Map prototype");
1556 function test_length(name, len) {
1557 ok(Map.prototype[name].length === len, "Map.prototype." + name + " = " + Map.prototype[name].length);
1559 test_length("clear", 0);
1560 test_length("delete", 1);
1561 test_length("forEach", 1);
1562 test_length("get", 1);
1563 test_length("has", 1);
1564 test_length("set", 2);
1565 ok(!("entries" in s), "entries are in Map");
1566 ok(!("keys" in s), "keys are in Map");
1567 ok(!("values" in s), "values are in Map");
1569 ok("size" in Map.prototype, "size is not in Map.prototype");
1571 r = Object.prototype.toString.call(s);
1572 ok(r === "[object Object]", "toString returned " + r);
1575 ok(r === undefined, "get(test) returned " + r);
1577 ok(r === false, "has(test) returned " + r);
1578 ok(s.size === 0, "size = " + s.size + " expected 0");
1580 r = s.set("test", 1);
1581 ok(r === undefined, "set returned " + r);
1582 ok(s.size === 1, "size = " + s.size + " expected 1");
1584 ok(r === 1, "get(test) returned " + r);
1586 ok(r === true, "has(test) returned " + r);
1589 ok(s.size === 1, "size = " + s.size + " expected 1");
1593 ok(r === 2, "get(test) returned " + r);
1595 ok(r === true, "has(test) returned " + r);
1597 r = s["delete"]("test"); /* using s.delete() would break parsing in quirks mode */
1598 ok(r === true, "delete(test) returned " + r);
1599 ok(s.size === 0, "size = " + s.size + " expected 0");
1600 r = s["delete"]("test");
1601 ok(r === false, "delete(test) returned " + r);
1603 var test_keys = [undefined, null, NaN, 3, "str", false, true, {}];
1604 for(i in test_keys) {
1605 r = s.set(test_keys[i], test_keys[i] + 1);
1606 ok(r === undefined, "set(test) returned " + r);
1608 ok(s.size === test_keys.length, "size = " + s.size + " expected " + test_keys.length);
1609 for(i in test_keys) {
1610 r = s.get(test_keys[i]);
1611 if(isNaN(test_keys[i]))
1612 ok(isNaN(r), "get(" + test_keys[i] + ") returned " + r);
1614 ok(r === test_keys[i] + 1, "get(" + test_keys[i] + ") returned " + r);
1619 r = s.forEach(function(value, key, map) {
1620 if(isNaN(test_keys[i])) {
1621 ok(isNaN(key), "key = " + key + " expected NaN");
1622 ok(isNaN(value), "value = " + value + " expected NaN");
1624 ok(key === test_keys[i], "key = " + key + " expected " + test_keys[i]);
1625 ok(value === key + 1, "value = " + value);
1627 ok(map === s, "map = " + map);
1628 ok(this === test_keys, "this = " + this);
1631 ok(i === test_keys.length, "i = " + i);
1632 ok(r === undefined, "forEach returned " + r);
1637 s.forEach(function(value, key) {
1638 if(isNaN(test_keys[i]))
1639 ok(isNaN(key), "key = " + key + " expected " + test_keys[i]);
1641 ok(key === test_keys[i], "key = " + key + " expected " + test_keys[i]);
1644 ok(i === test_keys.length, "i = " + i);
1647 ok(r === undefined, "clear returned " + r);
1648 ok(s.size === 0, "size = " + s.size + " expected 0");
1649 r = s.get(test_keys[0]);
1650 ok(r === undefined, "get returned " + r);
1657 s.forEach(function() {
1658 ok(i, "unexpected call");
1668 s.forEach(function(value, key) {
1670 r = s["delete"](key);
1671 ok(r === true, "delete returned " + r);
1673 ok(i === 66, "i = " + i);
1678 ok(s.size === 2, "size = " + s.size + " expected 2");
1680 ok(r === 20, "get(-0) returned " + r);
1682 ok(r === 10, "get(0) returned " + r);
1685 Map.prototype.set.call({}, 1, 2);
1686 ok(false, "expected exception");
1688 ok(e.number === 0xa13fc - 0x80000000, "e.number = " + e.number);
1696 s.forEach(function(value, key) {
1699 ok(s.size === 0, "size = " + s.size);
1700 ok(this.valueOf() === 42, "this.valueOf() = " + this.valueOf());
1702 ok(r === 1, "r = " + r);
1705 async_test("weakmap_obj", function() {
1706 if(!("WeakMap" in window)) { next_test(); return; }
1710 ok(false, "expected exception calling constructor as method");
1712 ok(e.number === 0xa13fc - 0x80000000, "calling constructor as method threw " + e.number);
1715 var s = new WeakMap, r, o, o2;
1716 ok(Object.getPrototypeOf(s) === WeakMap.prototype, "unexpected WeakMap prototype");
1718 function test_length(name, len) {
1719 ok(WeakMap.prototype[name].length === len, "WeakMap.prototype." + name + " = " + WeakMap.prototype[name].length);
1721 test_length("clear", 0);
1722 test_length("delete", 1);
1723 test_length("get", 1);
1724 test_length("has", 1);
1725 test_length("set", 2);
1726 ok(!("entries" in s), "entries is in WeakMap");
1727 ok(!("forEach" in s), "forEach is in WeakMap");
1728 ok(!("keys" in s), "keys is in WeakMap");
1729 ok(!("size" in s), "size is in WeakMap");
1730 ok(!("values" in s), "values is in WeakMap");
1732 r = Object.prototype.toString.call(s);
1733 ok(r === "[object Object]", "toString returned " + r);
1736 ok(r === undefined, "get('test') returned " + r);
1738 ok(r === false, "has('test') returned " + r);
1741 r = s.set("test", 1);
1742 ok(false, "set('test') did not throw");
1744 ok(e.number === 0xa13fd - 0x80000000, "set('test') threw " + e.number);
1747 r = s.set(external.testHostContext(true), 1);
1748 ok(false, "set(host_obj) did not throw");
1750 ok(e.number === 0xa13fd - 0x80000000, "set(host_obj) threw " + e.number);
1754 ok(r === undefined, "set({}, 1) returned " + r);
1758 ok(r === undefined, "get({}) returned " + r);
1760 ok(r === false, "has({}) returned " + r);
1763 ok(r === undefined, "set(o, 2) returned " + r);
1765 ok(r === 2, "get(o) returned " + r);
1767 ok(r === true, "has(o) returned " + r);
1769 ok(r === undefined, "get(o2) before set returned " + r);
1771 ok(r === false, "has(o2) before set returned " + r);
1772 r = s.set(o2, "test");
1773 ok(r === undefined, "set(o2, 'test') returned " + r);
1775 ok(r === "test", "get(o2) returned " + r);
1777 ok(r === true, "has(o2) returned " + r);
1779 r = s["delete"]("test"); /* using s.delete() would break parsing in quirks mode */
1780 ok(r === false, "delete('test') returned " + r);
1781 r = s["delete"]({});
1782 ok(r === false, "delete({}) returned " + r);
1784 ok(r === true, "delete(o) returned " + r);
1787 ok(r === undefined, "get(o) after delete returned " + r);
1789 ok(r === false, "has(o) after delete returned " + r);
1791 ok(r === "test", "get(o2) after delete returned " + r);
1793 ok(r === true, "has(o2) after delete returned " + r);
1795 r = s.set(o, undefined);
1796 ok(r === undefined, "set(o, undefined) returned " + r);
1798 ok(r === undefined, "get(o) after re-set returned " + r);
1800 ok(r === true, "has(o) after re-set returned " + r);
1803 ok(r === undefined, "clear() returned " + r);
1805 ok(r === undefined, "get(o) after clear returned " + r);
1807 ok(r === false, "has(o) after clear returned " + r);
1809 ok(r === undefined, "get(o2) after clear returned " + r);
1811 ok(r === false, "has(o2) after clear returned " + r);
1813 r = external.newRefTest();
1814 ok(r.ref === 1, "wrong ref after newRefTest: " + r.ref);
1815 o = { val: r.get(), map: s };
1817 ok(r.ref > 1, "map entry released");
1822 if(r.ref > 1 && Date.now() - o < 5000) {
1824 window.setTimeout(retry);
1827 ok(r.ref === 1, "map entry not released");
1830 window.setTimeout(retry);
1833 sync_test("storage", function() {
1834 var v = document.documentMode, i, r, list;
1836 sessionStorage["add-at-end"] = 0;
1837 sessionStorage.removeItem("add-at-end");
1839 sessionStorage.setItem("foobar", "1234");
1840 ok("foobar" in sessionStorage, "foobar not in sessionStorage");
1841 r = sessionStorage.foobar;
1842 ok(r === "1234", "sessionStorage.foobar = " + r);
1843 sessionStorage.barfoo = 4321;
1844 r = sessionStorage.getItem("barfoo");
1845 ok(r === "4321", "sessionStorage.barfoo = " + r);
1846 sessionStorage.setItem("abcd", "blah");
1847 sessionStorage.dcba = "test";
1849 // Order isn't consistent, but changes are reflected during the enumeration.
1850 // Elements that were already traversed in DISPID (even if removed before
1851 // the enumeration) are not enumerated, even if re-added during the enum.
1852 i = 0; list = [ "foobar", "barfoo", "abcd", "dcba" ];
1853 for(r in sessionStorage) {
1854 for(var j = 0; j < list.length; j++)
1857 ok(j < list.length, "got '" + r + "' enumerating");
1860 sessionStorage.removeItem(list[0]);
1861 sessionStorage.setItem("new", "new");
1862 list.splice(0, 1, "new");
1865 sessionStorage.setItem("add-at-end", "0");
1868 ok(i === 4, "enum did " + i + " iterations");
1871 delete sessionStorage.foobar;
1872 ok(v >= 8, "expected exception deleting sessionStorage.foobar");
1873 ok(!("foobar" in sessionStorage), "foobar in sessionStorage after deletion");
1874 r = sessionStorage.getItem("foobar");
1875 ok(r === null, "sessionStorage.foobar after deletion = " + r);
1877 ok(v < 8, "did not expect exception deleting sessionStorage.foobar");
1878 ok(e.number === 0xa01bd - 0x80000000, "deleting sessionStorage.foobar threw = " + e.number);
1881 sessionStorage.clear();
1884 async_test("storage events", function() {
1885 var iframe = document.createElement("iframe"), iframe2 = document.createElement("iframe");
1886 var local = false, storage, storage2, v = document.documentMode, i = 0;
1891 storage.removeItem("foobar");
1894 expect(0, "foobar", "", "test");
1895 storage.setItem("foobar", "test");
1898 expect(1, "foobar", "test", "TEST", true);
1899 storage2.setItem("foobar", "TEST");
1902 expect(0, "foobar", "TEST", "");
1903 storage.removeItem("foobar");
1906 expect(1, "winetest", "", "WineTest");
1907 storage2.setItem("winetest", "WineTest");
1910 expect(0, "", "", "");
1916 if(++i < tests.length)
1921 // w10pro64 testbot VM throws WININET_E_INTERNAL_ERROR for some reason
1922 storage = null, storage2 = null;
1924 storage = window.localStorage, storage2 = iframe.contentWindow.localStorage;
1926 ok(e.number === 0x72ee4 - 0x80000000, "localStorage threw " + e.number + ": " + e);
1928 if(!storage || !storage2) {
1929 win_skip("localStorage is buggy and not available, skipping");
1933 i = 0, local = true;
1936 setTimeout(function() { tests[0](); });
1938 // Get rid of any entries first, since native doesn't update immediately
1939 var w = [ window, iframe.contentWindow ];
1940 for(var j = 0; j < w.length; j++)
1941 w[j].onstorage = w[j].document.onstorage = w[j].document.onstoragecommit = null;
1942 document.onstoragecommit = function() {
1944 setTimeout(function() { tests[0](); });
1953 function test_event(e, idx, key, oldValue, newValue) {
1955 ok(e === undefined, "event not undefined in legacy mode: " + e);
1958 var s = Object.prototype.toString.call(e);
1959 todo_wine_if(e.target != window && e.target != document).
1960 ok(s === "[object StorageEvent]", "Object.toString = " + s);
1961 ok(e.key === key, "key = " + e.key + ", expected " + key);
1962 ok(e.oldValue === oldValue, "oldValue = " + e.oldValue + ", expected " + oldValue);
1963 ok(e.newValue === newValue, "newValue = " + e.newValue + ", expected " + newValue);
1964 s = (idx ? iframe.contentWindow : window)["location"]["href"].split('#', 1)[0];
1965 ok(e.url === s, "url = " + e.url + ", expected " + s);
1968 function expect(idx, key, oldValue, newValue, quirk) {
1969 var window2 = iframe.contentWindow, document2 = window2.document;
1970 window.onstorage = function() { ok(false, "window.onstorage called"); };
1971 document.onstorage = function() { ok(false, "doc.onstorage called"); };
1972 document.onstoragecommit = function() { ok(false, "doc.onstoragecommit called"); };
1973 window2.onstorage = function() { ok(false, "iframe window.onstorage called"); };
1974 document2.onstorage = function() { ok(false, "iframe doc.onstorage called"); };
1975 document2.onstoragecommit = function() { ok(false, "iframe doc.onstoragecommit called"); };
1977 if(idx === undefined) {
1978 setTimeout(function() { next(); });
1980 // Native sometimes calls this for some reason
1981 if(local && quirk) document.onstoragecommit = null;
1983 (v < 9 ? document2 : window2)["onstorage"] = function(e) {
1984 (local && idx ? document2 : (local || v < 9 ? document : window))[local ? "onstoragecommit" : "onstorage"] = function(e) {
1985 test_event(e, idx, local ? "" : key, local ? "" : oldValue, local ? "" : newValue);
1988 test_event(e, idx, key, oldValue, newValue);
1993 iframe.onload = function() {
1994 iframe2.onload = function() {
1995 var w = iframe2.contentWindow;
1996 w.onstorage = function() { ok(false, "about:blank window.onstorage called"); };
1997 w.document.onstorage = function() { ok(false, "about:blank document.onstorage called"); };
1998 w.document.onstoragecommit = function() { ok(false, "about:blank document.onstoragecommit called"); };
2000 storage = window.sessionStorage, storage2 = iframe.contentWindow.sessionStorage;
2003 iframe2.src = "about:blank";
2004 document.body.appendChild(iframe2);
2006 iframe.src = "blank.html";
2007 document.body.appendChild(iframe);
2010 sync_test("elem_attr", function() {
2011 var v = document.documentMode;
2012 var elem = document.createElement("div"), r;
2014 function test_exposed(prop, expect) {
2016 ok(prop in elem, prop + " is not exposed from elem");
2018 ok(!(prop in elem), prop + " is exposed from elem");
2021 r = elem.getAttribute("class");
2022 ok(r === null, "class attr = " + r);
2023 r = elem.getAttribute("className");
2024 ok(r === (v < 8 ? "" : null), "className attr = " + r);
2026 elem.className = "cls";
2027 r = elem.getAttribute("class");
2028 ok(r === (v < 8 ? null : "cls"), "class attr = " + r);
2029 r = elem.getAttribute("className");
2030 ok(r === (v < 8 ? "cls" : null), "className attr = " + r);
2032 elem.setAttribute("class", "cls2");
2033 ok(elem.className === (v < 8 ? "cls" : "cls2"), "elem.className = " + elem.className);
2034 r = elem.getAttribute("class");
2035 ok(r === "cls2", "class attr = " + r);
2036 r = elem.getAttribute("className");
2037 ok(r === (v < 8 ? "cls" : null), "className attr = " + r);
2039 elem.setAttribute("className", "cls3");
2040 ok(elem.className === (v < 8 ? "cls3" : "cls2"), "elem.className = " + elem.className);
2041 r = elem.getAttribute("class");
2042 ok(r === "cls2", "class attr = " + r);
2043 r = elem.getAttribute("className");
2044 ok(r === "cls3", "className attr = " + r);
2046 elem.htmlFor = "for";
2047 r = elem.getAttribute("for");
2048 ok(r === null, "for attr = " + r);
2049 r = elem.getAttribute("htmlFor");
2050 ok(r === (v < 9 ? "for" : null), "htmlFor attr = " + r);
2052 elem.setAttribute("for", "for2");
2053 ok(elem.htmlFor === "for", "elem.htmlFor = " + elem.htmlFor);
2054 r = elem.getAttribute("for");
2055 ok(r === "for2", "for attr = " + r);
2056 r = elem.getAttribute("htmlFor");
2057 ok(r === (v < 9 ? "for" : null), "htmlFor attr = " + r);
2059 elem.setAttribute("htmlFor", "for3");
2060 ok(elem.htmlFor === (v < 9 ? "for3" : "for"), "elem.htmlFor = " + elem.htmlFor);
2061 r = elem.getAttribute("for");
2062 ok(r === "for2", "for attr = " + r);
2063 r = elem.getAttribute("htmlFor");
2064 ok(r === "for3", "htmlFor attr = " + r);
2066 elem.setAttribute("testattr", "test", 0, "extra arg", 0xdeadbeef);
2067 test_exposed("class", v < 8);
2068 test_exposed("className", true);
2069 test_exposed("for", v < 9);
2070 test_exposed("htmlFor", true);
2071 test_exposed("testattr", v < 9);
2074 elem.setAttribute("testattr", arr);
2075 r = elem.getAttribute("testattr");
2076 ok(r === (v < 8 ? arr : "3"), "testattr = " + r);
2077 ok(elem.testattr === (v < 9 ? arr : undefined), "elem.testattr = " + elem.testattr);
2078 r = elem.removeAttribute("testattr");
2079 ok(r === (v < 9 ? true : undefined), "testattr removeAttribute returned " + r);
2080 ok(elem.testattr === undefined, "removed testattr = " + elem.testattr);
2083 elem.setAttribute("testattr", "string");
2084 elem.testattr = arr;
2085 r = elem.getAttribute("testattr");
2086 ok(r === (v < 8 ? arr : (v < 9 ? "9" : "string")), "testattr = " + r);
2087 ok(elem.testattr === arr, "elem.testattr = " + elem.testattr);
2089 r = elem.getAttribute("testattr");
2090 ok(r === (v < 8 ? arr : (v < 9 ? "3" : "string")), "testattr = " + r);
2091 ok(elem.testattr === arr, "elem.testattr = " + elem.testattr);
2092 r = elem.removeAttribute("testattr");
2093 ok(r === (v < 9 ? true : undefined), "testattr removeAttribute returned " + r);
2094 ok(elem.testattr === (v < 9 ? undefined : arr), "removed testattr = " + elem.testattr);
2096 arr.toString = function() { return 42; }
2097 elem.testattr = arr;
2098 r = elem.getAttribute("testattr");
2099 ok(r === (v < 8 ? arr : (v < 9 ? "42" : null)), "testattr with custom toString = " + r);
2100 elem.setAttribute("testattr", arr);
2101 r = elem.getAttribute("testattr");
2102 ok(r === (v < 8 ? arr : "42"), "testattr after setAttribute with custom toString = " + r);
2103 ok(elem.testattr === arr, "elem.testattr after setAttribute with custom toString = " + elem.testattr);
2104 r = elem.removeAttribute("testattr");
2105 ok(r === (v < 9 ? true : undefined), "testattr removeAttribute with custom toString returned " + r);
2106 ok(elem.testattr === (v < 9 ? undefined : arr), "removed testattr with custom toString = " + elem.testattr);
2108 arr.valueOf = function() { return "arrval"; }
2109 elem.testattr = arr;
2110 r = elem.getAttribute("testattr");
2111 ok(r === (v < 8 ? arr : (v < 9 ? "arrval" : null)), "testattr with custom valueOf = " + r);
2112 elem.setAttribute("testattr", arr);
2113 r = elem.getAttribute("testattr");
2114 ok(r === (v < 8 ? arr : (v < 10 ? "arrval" : "42")), "testattr after setAttribute with custom valueOf = " + r);
2115 ok(elem.testattr === arr, "elem.testattr after setAttribute with custom valueOf = " + elem.testattr);
2116 r = elem.removeAttribute("testattr");
2117 ok(r === (v < 9 ? true : undefined), "testattr removeAttribute with custom valueOf returned " + r);
2118 ok(elem.testattr === (v < 9 ? undefined : arr), "removed testattr with custom valueOf = " + elem.testattr);
2120 var func = elem.setAttribute;
2122 func("testattr", arr);
2123 todo_wine_if(v >= 9).
2124 ok(v < 9, "expected exception setting testattr via func");
2126 ok(v >= 9, "did not expect exception setting testattr via func");
2127 elem.setAttribute("testattr", arr);
2129 r = elem.getAttribute("testattr");
2130 ok(r === (v < 8 ? arr : (v < 10 ? "arrval" : "42")), "testattr after setAttribute (as func) = " + r);
2132 delete arr.toString;
2134 elem.setAttribute("id", arr);
2135 r = elem.getAttribute("id");
2136 todo_wine_if(v >= 8 && v < 10).
2137 ok(r === (v < 8 || v >= 10 ? "3" : "[object]"), "id = " + r);
2138 r = elem.removeAttribute("id");
2139 ok(r === (v < 9 ? true : undefined), "id removeAttribute returned " + r);
2140 ok(elem.id === "", "removed id = " + elem.id);
2142 func = function() { };
2143 elem.onclick = func;
2144 ok(elem.onclick === func, "onclick = " + elem.onclick);
2145 r = elem.getAttribute("onclick");
2146 todo_wine_if(v === 8).
2147 ok(r === (v < 8 ? func : null), "onclick attr = " + r);
2148 r = elem.removeAttribute("onclick");
2149 ok(r === (v < 9 ? false : undefined), "removeAttribute returned " + r);
2150 todo_wine_if(v === 8).
2151 ok(elem.onclick === (v != 8 ? func : null), "removed onclick = " + elem.onclick);
2153 elem.onclick_test = func;
2154 ok(elem.onclick_test === func, "onclick_test = " + elem.onclick_test);
2155 r = elem.getAttribute("onclick_test");
2156 ok(r === (v < 8 ? func : (v < 9 ? func.toString() : null)), "onclick_test attr = " + r);
2158 elem.setAttribute("onclick", "test");
2159 r = elem.getAttribute("onclick");
2160 ok(r === "test", "onclick attr after setAttribute = " + r);
2161 r = elem.removeAttribute("onclick");
2162 ok(r === (v < 9 ? true : undefined), "removeAttribute after setAttribute returned " + r);
2164 /* IE11 returns an empty function, which we can't check directly */
2165 todo_wine_if(v >= 9).
2166 ok((v < 11) ? (elem.onclick === null) : (elem.onclick !== func), "removed onclick after setAttribute = " + elem.onclick);
2168 r = Object.prototype.toString.call(elem.onclick);
2169 todo_wine_if(v >= 9 && v < 11).
2170 ok(r === (v < 9 ? "[object Object]" : (v < 11 ? "[object Null]" : "[object Function]")),
2171 "removed onclick after setAttribute Object.toString returned " + r);
2173 elem.setAttribute("onclick", "string");
2174 r = elem.getAttribute("onclick");
2175 ok(r === "string", "onclick attr after setAttribute = " + r);
2176 elem.onclick = func;
2177 ok(elem.onclick === func, "onclick = " + elem.onclick);
2178 r = elem.getAttribute("onclick");
2179 todo_wine_if(v === 8).
2180 ok(r === (v < 8 ? func : (v < 9 ? null : "string")), "onclick attr = " + r);
2181 elem.onclick = "test";
2182 r = elem.getAttribute("onclick");
2183 ok(r === (v < 9 ? "test" : "string"), "onclick attr = " + r);
2184 r = elem.removeAttribute("onclick");
2185 ok(r === (v < 9 ? true : undefined), "removeAttribute returned " + r);
2186 todo_wine_if(v >= 9).
2187 ok(elem.onclick === null, "removed onclick = " + elem.onclick);
2189 elem.setAttribute("ondblclick", arr);
2190 r = elem.getAttribute("ondblclick");
2191 todo_wine_if(v >= 8 && v < 10).
2192 ok(r === (v < 8 ? arr : (v < 10 ? "[object]" : "3")), "ondblclick = " + r);
2193 r = elem.removeAttribute("ondblclick");
2194 ok(r === (v < 8 ? false : (v < 9 ? true : undefined)), "ondblclick removeAttribute returned " + r);
2195 r = Object.prototype.toString.call(elem.ondblclick);
2196 todo_wine_if(v >= 11).
2197 ok(r === (v < 8 ? "[object Array]" : (v < 9 ? "[object Object]" : (v < 11 ? "[object Null]" : "[object Function]"))),
2198 "removed ondblclick Object.toString returned " + r);
2200 elem.setAttribute("ondblclick", "string");
2201 r = elem.getAttribute("ondblclick");
2202 ok(r === "string", "ondblclick string = " + r);
2203 r = elem.removeAttribute("ondblclick");
2204 ok(r === (v < 9 ? true : undefined), "ondblclick string removeAttribute returned " + r);
2205 ok(elem.ondblclick === null, "removed ondblclick string = " + elem.ondblclick);
2208 /* style is a special case */
2210 elem.style = "opacity: 1.0";
2211 ok(false, "expected exception setting elem.style");
2214 var style = elem.style;
2215 r = elem.getAttribute("style");
2216 ok(r === (v < 8 ? style : null), "style attr = " + r);
2217 r = elem.removeAttribute("style");
2218 ok(r === true, "removeAttribute('style') returned " + r);
2220 ok(r === style, "removed elem.style = " + r);
2221 r = elem.getAttribute("style");
2222 ok(r === (v < 8 ? style : null), "style attr after removal = " + r);
2223 elem.setAttribute("style", "opacity: 1.0");
2224 r = elem.getAttribute("style");
2225 ok(r === (v < 8 ? style : "opacity: 1.0"), "style attr after setAttribute = " + r);
2227 ok(r === style, "elem.style after setAttribute = " + r);
2231 sync_test("elem_attrNS", function() {
2232 var v = document.documentMode;
2233 if(v < 9) return; /* not available */
2235 var specialspace_ns = "http://www.mozilla.org/ns/specialspace";
2236 var svg_ns = "http://www.w3.org/2000/svg";
2238 var elem = document.createElement("div"), r;
2240 elem.setAttributeNS(specialspace_ns, "spec:align", "left");
2241 r = elem.hasAttribute("spec:align");
2242 ok(r === true, "spec:align does not exist");
2243 r = elem.getAttribute("spec:align");
2244 ok(r === "left", "spec:align = " + r);
2245 r = elem.hasAttribute("align");
2246 ok(r === false, "align exists");
2247 r = elem.getAttribute("align");
2248 ok(r === null, "align = " + r);
2249 r = elem.hasAttributeNS(null, "spec:align");
2250 ok(r === false, "null spec:align exists");
2251 r = elem.getAttributeNS(null, "spec:align");
2252 ok(r === "", "null spec:align = " + r);
2253 r = elem.hasAttributeNS(null, "spec:align");
2254 ok(r === false, "null align exists");
2255 r = elem.getAttributeNS(null, "align");
2256 ok(r === "", "null align = " + r);
2257 r = elem.hasAttributeNS(svg_ns, "spec:align");
2258 ok(r === false, "svg spec:align exists");
2259 r = elem.getAttributeNS(svg_ns, "spec:align");
2260 ok(r === "", "svg spec:align = " + r);
2261 r = elem.hasAttributeNS(svg_ns, "align");
2262 ok(r === false, "svg align exists");
2263 r = elem.getAttributeNS(svg_ns, "align");
2264 ok(r === "", "svg align = " + r);
2265 r = elem.hasAttributeNS(specialspace_ns, "spec:align");
2266 ok(r === false, "specialspace spec:align exists");
2267 r = elem.getAttributeNS(specialspace_ns, "spec:align");
2268 ok(r === "", "specialspace spec:align = " + r);
2269 r = elem.hasAttributeNS(specialspace_ns, "align");
2270 ok(r === true, "specialspace align does not exist");
2271 r = elem.getAttributeNS(specialspace_ns, "align");
2272 ok(r === "left", "specialspace align = " + r);
2275 elem.setAttributeNS(null, "spec:align", "right");
2276 ok(false, "expected exception setting qualified attr with null ns");
2279 ok(ex.message === "NamespaceError", "setAttributeNS(null, 'spec:align', 'right') threw " + ex.message);
2282 elem.setAttributeNS("", "spec:align", "right");
2283 ok(false, "expected exception setting qualified attr with empty ns");
2286 ok(ex.message === "NamespaceError", "setAttributeNS('', 'spec:align', 'right') threw " + ex.message);
2288 elem.setAttributeNS(null, "align", "right");
2289 r = elem.getAttribute("spec:align");
2290 ok(r === "left", "spec:align (null) = " + r);
2291 r = elem.hasAttribute("align");
2292 ok(r === true, "align (null) does not exist");
2293 r = elem.getAttribute("align");
2294 ok(r === "right", "align (null) = " + r);
2295 r = elem.hasAttributeNS(null, "spec:align");
2296 ok(r === false, "null spec:align exists");
2297 r = elem.getAttributeNS(null, "spec:align");
2298 ok(r === "", "null spec:align (null) = " + r);
2299 r = elem.hasAttributeNS(null, "align");
2300 ok(r === true, "null align does not exist");
2301 r = elem.getAttributeNS(null, "align");
2302 ok(r === "right", "null align (null) = " + r);
2303 r = elem.hasAttributeNS(svg_ns, "spec:align");
2304 ok(r === false, "svg spec:align (null) exists");
2305 r = elem.getAttributeNS(svg_ns, "spec:align");
2306 ok(r === "", "svg spec:align (null) = " + r);
2307 r = elem.hasAttributeNS(svg_ns, "align");
2308 ok(r === false, "svg align (null) exists");
2309 r = elem.getAttributeNS(svg_ns, "align");
2310 ok(r === "", "svg align (null) = " + r);
2311 r = elem.hasAttributeNS(specialspace_ns, "spec:align");
2312 ok(r === false, "specialspace_ns spec:align (null) exists");
2313 r = elem.getAttributeNS(specialspace_ns, "spec:align");
2314 ok(r === "", "specialspace spec:align (null) = " + r);
2315 r = elem.hasAttributeNS(specialspace_ns, "align");
2316 ok(r === true, "specialspace align (null) does not exist");
2317 r = elem.getAttributeNS(specialspace_ns, "align");
2318 ok(r === "left", "specialspace align (null) = " + r);
2320 elem.setAttribute("align", "center");
2321 r = elem.hasAttributeNS(null, "spec:align");
2322 ok(r === false, "null spec:align (non-NS) exists");
2323 r = elem.getAttributeNS(null, "spec:align");
2324 ok(r === "", "null spec:align (non-NS) = " + r);
2325 r = elem.hasAttributeNS(null, "align");
2326 ok(r === true, "null align (non-NS) does not exist");
2327 r = elem.getAttributeNS(null, "align");
2328 ok(r === "center", "null align (non-NS) = " + r);
2329 r = elem.hasAttributeNS(svg_ns, "spec:align");
2330 ok(r === false, "svg spec:align (non-NS) exists");
2331 r = elem.getAttributeNS(svg_ns, "spec:align");
2332 ok(r === "", "svg spec:align (non-NS) = " + r);
2333 r = elem.hasAttributeNS(svg_ns, "align");
2334 ok(r === false, "svg align (non-NS) exists");
2335 r = elem.getAttributeNS(svg_ns, "align");
2336 ok(r === "", "svg align (non-NS) = " + r);
2337 r = elem.hasAttributeNS(specialspace_ns, "spec:align");
2338 ok(r === false, "specialspace spec:align (non-NS) exists");
2339 r = elem.getAttributeNS(specialspace_ns, "spec:align");
2340 ok(r === "", "specialspace spec:align (non-NS) = " + r);
2341 r = elem.hasAttributeNS(specialspace_ns, "align");
2342 ok(r === true, "specialspace align (non-NS) does not exist");
2343 r = elem.getAttributeNS(specialspace_ns, "align");
2344 ok(r === "left", "specialspace align (non-NS) = " + r);
2345 elem.removeAttributeNS(null, "spec:align");
2347 elem.setAttribute("emptynsattr", "none");
2348 elem.setAttributeNS("", "emptynsattr", "test");
2349 r = elem.hasAttribute("emptynsattr");
2350 ok(r === true, "emptynsattr without NS does not exist");
2351 r = elem.getAttribute("emptynsattr");
2352 ok(r === "test", "emptynsattr without NS = " + r);
2353 elem.setAttributeNS(null, "emptynsattr", "wine");
2354 r = elem.hasAttribute("emptynsattr");
2355 ok(r === true, "emptynsattr without NS does not exist");
2356 r = elem.getAttribute("emptynsattr");
2357 ok(r === "wine", "emptynsattr without NS = " + r);
2358 elem.setAttributeNS(specialspace_ns, "emptynsattr", "ns");
2359 r = elem.hasAttribute("emptynsattr");
2360 ok(r === true, "emptynsattr without NS does not exist");
2361 r = elem.getAttribute("emptynsattr");
2362 ok(r === "wine", "emptynsattr without NS = " + r);
2363 r = elem.hasAttributeNS("", "emptynsattr");
2364 ok(r === true, "emptynsattr empty ns does not exist");
2365 r = elem.getAttributeNS("", "emptynsattr");
2366 ok(r === "wine", "emptynsattr empty ns = " + r);
2367 r = elem.hasAttributeNS(null, "emptynsattr");
2368 ok(r === true, "emptynsattr null ns does not exist");
2369 r = elem.getAttributeNS(null, "emptynsattr");
2370 ok(r === "wine", "emptynsattr null ns = " + r);
2371 r = elem.hasAttributeNS(specialspace_ns, "emptynsattr");
2372 ok(r === true, "emptynsattr specialspace ns does not exist");
2373 r = elem.getAttributeNS(specialspace_ns, "emptynsattr");
2374 ok(r === "ns", "emptynsattr specialspace ns = " + r);
2376 elem.removeAttributeNS("", "emptynsattr");
2377 r = elem.hasAttribute("emptynsattr");
2378 ok(r === true, "emptynsattr without NS after remove does not exist");
2379 r = elem.getAttribute("emptynsattr");
2380 ok(r === "ns", "emptynsattr without NS after remove = " + r);
2381 r = elem.hasAttributeNS(specialspace_ns, "emptynsattr");
2382 ok(r === true, "emptynsattr specialspace ns after empty remove does not exist");
2383 r = elem.getAttributeNS(specialspace_ns, "emptynsattr");
2384 ok(r === "ns", "emptynsattr specialspace ns after empty remove = " + r);
2385 elem.setAttribute("emptynsattr", "test");
2386 r = elem.getAttribute("emptynsattr");
2387 ok(r === "test", "emptynsattr without NS after re-set = " + r);
2388 r = elem.getAttributeNS(specialspace_ns, "emptynsattr");
2389 ok(r === "test", "emptynsattr specialspace ns after empty re-set = " + r);
2391 elem.removeAttribute("emptynsattr");
2392 r = elem.hasAttribute("emptynsattr");
2393 ok(r === false, "emptynsattr without NS after non-NS remove exists");
2394 r = elem.getAttribute("emptynsattr");
2395 ok(r === null, "emptynsattr without NS after non-NS remove = " + r);
2396 r = elem.hasAttributeNS(specialspace_ns, "emptynsattr");
2397 ok(r === false, "emptynsattr specialspace ns after non-NS remove exists");
2398 r = elem.getAttributeNS(specialspace_ns, "emptynsattr");
2399 ok(r === "", "emptynsattr specialspace ns after non-NS remove = " + r);
2401 elem.setAttributeNS(specialspace_ns, "emptynsattr", "ns");
2402 elem.removeAttributeNS(svg_ns, "emptynsattr");
2403 r = elem.hasAttributeNS(specialspace_ns, "emptynsattr");
2404 ok(r === true, "emptynsattr specialspace ns after wrong NS remove does not exist");
2405 r = elem.getAttributeNS(specialspace_ns, "emptynsattr");
2406 ok(r === "ns", "emptynsattr specialspace ns after wrong NS remove = " + r);
2407 r = elem.hasAttributeNS(specialspace_ns, "emptynsattr");
2408 ok(r === true, "emptynsattr specialspace ns after remove does not exist");
2409 r = elem.getAttributeNS(specialspace_ns, "emptynsattr");
2410 ok(r === "ns", "emptynsattr specialspace ns after remove = " + r);
2413 ns.toString = function() { return "toString namespace"; }
2414 ns.valueOf = function() { return "valueOf namespace"; }
2415 elem.setAttributeNS(ns, "foobar", "test");
2416 r = elem.hasAttribute("foobar");
2417 ok(r === true, "foobar without NS does not exist");
2418 r = elem.getAttribute("foobar");
2419 ok(r === "test", "foobar without NS = " + r);
2420 r = elem.hasAttributeNS(ns, "foobar");
2421 ok(r === true, "foobar does not exist");
2422 r = elem.getAttributeNS(ns, "foobar");
2423 ok(r === "test", "foobar = " + r);
2424 r = elem.hasAttributeNS("toString namespace", "foobar");
2425 ok(r === (v < 10 ? false : true), "foobar (toString namespace) " + (v < 10 ? "exists" : "does not exist"));
2426 r = elem.getAttributeNS("toString namespace", "foobar");
2427 ok(r === (v < 10 ? "" : "test"), "foobar (toString namespace) = " + r);
2428 r = elem.hasAttributeNS("valueOf namespace", "foobar");
2429 ok(r === (v < 10 ? true : false), "foobar (valueOf namespace) = " + (v < 10 ? "does not exist" : "exists"));
2430 r = elem.getAttributeNS("valueOf namespace", "foobar");
2431 ok(r === (v < 10 ? "test" : ""), "foobar (valueOf namespace) = " + r);
2434 elem.setAttributeNS(svg_ns, "testattr", arr);
2435 r = elem.getAttributeNS(svg_ns, "testattr");
2436 ok(r === "3", "testattr = " + r);
2437 ok(elem.testattr === undefined, "elem.testattr = " + elem.testattr);
2438 elem.removeAttributeNS(svg_ns, "testattr");
2439 r = elem.getAttributeNS(svg_ns, "testattr");
2440 ok(r === "", "testattr after remove = " + r);
2442 arr.toString = function() { return 42; }
2443 elem.setAttributeNS(svg_ns, "testattr", arr);
2444 r = elem.getAttributeNS(svg_ns, "testattr");
2445 ok(r === "42", "testattr with custom toString = " + r);
2446 elem.removeAttributeNS(svg_ns, "testattr");
2447 r = elem.getAttributeNS(svg_ns, "testattr");
2448 ok(r === "", "testattr with custom toString after remove = " + r);
2450 arr.valueOf = function() { return "arrval"; }
2451 elem.setAttributeNS(svg_ns, "testattr", arr);
2452 r = elem.getAttributeNS(svg_ns, "testattr");
2453 ok(r === "42", "testattr with custom valueOf = " + r);
2454 elem.removeAttributeNS(svg_ns, "testattr");
2456 elem.setAttributeNS(svg_ns, "boolattr", true);
2457 r = elem.getAttributeNS(svg_ns, "boolattr");
2458 ok(r === "true", "boolattr = " + r);
2460 elem.setAttributeNS(svg_ns, "numattr", 13);
2461 r = elem.getAttributeNS(svg_ns, "numattr");
2462 ok(r === "13", "numattr = " + r);
2465 sync_test("builtins_diffs", function() {
2466 var v = document.documentMode;
2468 /* despite what spec says for ES6, IE still throws */
2476 "preventExtensions",
2479 for(var i = 0; i < props.length; i++) {
2481 Object[props[i]]("test");
2482 ok(false, "Object." + props[i] + " with non-object: expected exception");
2484 ok(e.number === (v < 9 ? 0xa01b6 : 0xa138f) - 0x80000000, "Object." + props[i] + " with non-object: exception = " + e.number);
2489 RegExp.prototype.toString.call({source: "foo", flags: "g"});
2490 ok(false, "RegExp.toString with non-regexp: expected exception");
2492 ok(e.number === 0xa1398 - 0x80000000, "RegExp.toString with non-regexp: exception = " + e.number);
2495 RegExp.prototype.toString.call({source: "abc", global: true, ignoreCase: true, multiline: true});
2496 ok(false, "RegExp.toString with non-regexp 2: expected exception");
2498 ok(e.number === 0xa1398 - 0x80000000, "RegExp.toString with non-regexp 2: exception = " + e.number);
2503 ok(false, "/a/.lastIndex(): expected exception");
2505 ok(e.number === 0xa138a - 0x80000000, "/a/.lastIndex(): exception = " + e.number);
2509 ok(false, "\"a\".length(): expected exception");
2511 ok(e.number === 0xa138a - 0x80000000, "\"a\".length(): exception = " + e.number);
2515 sync_test("nullDisp", function() {
2516 var v = document.documentMode, nullDisp = external.nullDisp, r;
2518 ok(external.getVT(nullDisp) === "VT_NULL", "getVT(nullDisp) is not VT_NULL");
2519 ok(typeof(nullDisp) === "object", "typeof(nullDisp) = " + typeof(nullDisp));
2520 ok(nullDisp === nullDisp, "nullDisp !== nullDisp");
2521 ok(nullDisp === null, "nullDisp === null");
2522 ok(nullDisp == null, "nullDisp == null");
2523 ok(!nullDisp === true, "!nullDisp = " + !nullDisp);
2524 ok(String(nullDisp) === "null", "String(nullDisp) = " + String(nullDisp));
2525 ok(+nullDisp === 0, "+nullDisp !== 0");
2526 ok(''+nullDisp === "null", "''+nullDisp !== null");
2527 ok(nullDisp != new Object(), "nullDisp == new Object()");
2528 ok(new Object() != nullDisp, "new Object() == nullDisp");
2529 ok((typeof Object(nullDisp)) === "object", "typeof Object(nullDisp) !== 'object'");
2530 r = Object(nullDisp).toString();
2531 ok(r === "[object Object]", "Object(nullDisp).toString() = " + r);
2532 ok(Object(nullDisp) != nullDisp, "Object(nullDisp) == nullDisp");
2533 ok(new Object(nullDisp) != nullDisp, "new Object(nullDisp) == nullDisp");
2534 r = (nullDisp instanceof Object);
2535 ok(r === false, "nullDisp instance of Object");
2538 r = JSON.stringify.call(null, nullDisp);
2539 ok(r === "null", "JSON.stringify(nullDisp) returned " + r);
2543 (new Object()) instanceof nullDisp;
2544 ok(false, "expected exception on (new Object()) instanceof nullDisp");
2546 ok(e.number === 0xa138a - 0x80000000, "(new Object()) instanceof nullDisp threw " + e.number);
2550 Function.prototype.apply.call(nullDisp, Object, []);
2551 ok(false, "expected exception calling Function.apply on nullDisp");
2553 ok(e.number === 0xa138a - 0x80000000, "Function.apply on nullDisp threw " + e.number);
2556 Function.prototype.call.call(nullDisp, Object);
2557 ok(false, "expected exception calling Function.call on nullDisp");
2559 ok(e.number === 0xa138a - 0x80000000, "Function.call on nullDisp threw " + e.number);
2564 ok(false, "expected exception for new nullDisp");
2566 ok(e.number === 0xa138f - 0x80000000, "new nullDisp threw " + e.number);
2570 sync_test("invalid selectors", function() {
2571 var v = document.documentMode, body = document.body, i;
2585 for(i = 0; i < selectors.length; i++) {
2587 body.querySelector(selectors[i]);
2588 ok(false, "body.querySelector(\"" + selectors[i] + "\" did not throw exception");
2591 ok(e.number === 0x70057 - 0x80000000, "body.querySelector(\"" + selectors[i] + "\" threw " + e.number);
2594 ok(e.name === (v < 10 ? undefined : "SyntaxError"), "body.querySelector(\"" + selectors[i] + "\" threw " + e.name);
2598 body.querySelectorAll(selectors[i]);
2599 ok(false, "body.querySelectorAll(\"" + selectors[i] + "\" did not throw exception");
2602 ok(e.number === 0x70057 - 0x80000000, "body.querySelectorAll(\"" + selectors[i] + "\" threw " + e.number);
2605 ok(e.name === (v < 10 ? undefined : "SyntaxError"), "body.querySelectorAll(\"" + selectors[i] + "\" threw " + e.name);
2610 if(!body.msMatchesSelector)
2613 for(i = 0; i < selectors.length; i++) {
2615 body.msMatchesSelector(selectors[i]);
2616 ok(false, "body.msMatchesSelector(\"" + selectors[i] + "\" did not throw exception");
2619 ok(e.number === 0x70057 - 0x80000000, "body.msMatchesSelector(\"" + selectors[i] + "\" threw " + e.number);
2622 ok(e.name === (v < 10 ? undefined : "SyntaxError"), "body.msMatchesSelector(\"" + selectors[i] + "\" threw " + e.name);
2628 sync_test("__proto__", function() {
2629 var v = document.documentMode;
2633 ok(x.__proto__ === undefined, "x.__proto__ = " + x.__proto__);
2634 ok(!("__proto__" in Object), "Object.__proto__ = " + Object.__proto__);
2638 ok(x.__proto__ === Number.prototype, "x.__proto__ = " + x.__proto__);
2639 ok(Object.__proto__ === Function.prototype, "Object.__proto__ = " + Object.__proto__);
2640 ok(Object.prototype.__proto__ === null, "Object.prototype.__proto__ = " + Object.prototype.__proto__);
2641 ok(Object.prototype.hasOwnProperty("__proto__"), "__proto__ is not a property of Object.prototype");
2642 ok(!Object.prototype.hasOwnProperty.call(x, "__proto__"), "__proto__ is a property of x");
2644 x.__proto__ = Object.prototype;
2645 ok(x.__proto__ === Number.prototype, "x.__proto__ set to Object.prototype = " + x.__proto__);
2646 ok(!Object.prototype.hasOwnProperty.call(x, "__proto__"), "__proto__ is a property of x after set to Object.prototype");
2649 r = Object.getPrototypeOf(x);
2650 ok(x.__proto__ === undefined, "x.__proto__ after set to null = " + x.__proto__);
2651 ok(r === null, "getPrototypeOf(x) after set to null = " + r);
2653 function check(expect, msg) {
2654 var r = Object.getPrototypeOf(x);
2655 ok(x.__proto__ === expect, "x.__proto__ " + msg + " = " + x.__proto__);
2656 ok(r === expect, "getPrototypeOf(x) " + msg + " = " + r);
2657 ok(!Object.prototype.hasOwnProperty.call(x, "__proto__"), "__proto__ is a property of x " + msg);
2661 check(Object.prototype, "after x set to {}");
2662 x.__proto__ = Number.prototype;
2663 check(Number.prototype, "after set to Number.prototype");
2664 x.__proto__ = Object.prototype;
2665 check(Object.prototype, "after re-set to Object.prototype");
2668 var obj = new ctor();
2670 check(obj, "after set to obj");
2671 x.__proto__ = ctor.prototype;
2672 check(obj.__proto__, "after set to ctor.prototype");
2673 ok(obj.__proto__ === ctor.prototype, "obj.__proto__ !== ctor.prototype");
2675 r = (delete x.__proto__);
2676 ok(r, "delete x.__proto__ returned " + r);
2677 ok(Object.prototype.hasOwnProperty("__proto__"), "__proto__ is not a property of Object.prototype after delete");
2678 r = Object.getPrototypeOf(x);
2679 ok(r === ctor.prototype, "x.__proto__ after delete = " + r);
2681 var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
2682 ok(desc.value === undefined, "__proto__ value = " + desc.value);
2683 ok(Object.getPrototypeOf(desc.get) === Function.prototype, "__proto__ getter not a function");
2684 ok(Object.getPrototypeOf(desc.set) === Function.prototype, "__proto__ setter not a function");
2685 ok(desc.get.length === 0, "__proto__ getter length = " + desc.get.length);
2686 ok(desc.set.length === 1, "__proto__ setter length = " + desc.set.length);
2688 r = desc.get.call(x, 1, 2, 3, 4);
2689 ok(r === x.__proto__, "calling __proto__ getter on x returned " + r);
2691 r = desc.set.call(x, obj);
2692 ok(r === obj, "calling __proto__ setter(obj) on x returned " + r);
2693 check(obj, "after set to obj via calling setter");
2694 r = desc.set.call(x, 42);
2695 ok(r === 42, "calling __proto__ setter(42) on x returned " + r);
2696 check(obj, "after set to obj via calling setter(42)");
2697 r = desc.set.call(x, "foo");
2698 ok(r === "foo", "calling __proto__ setter('foo') on x returned " + r);
2699 check(obj, "after set to obj via calling setter('foo')");
2700 r = desc.set.call(x);
2701 ok(r === undefined, "calling __proto__ setter() on x returned " + r);
2702 r = desc.set.call(true, obj);
2703 ok(r === obj, "calling __proto__ setter(obj) on true value returned " + r);
2705 r = desc.set.call(x, obj);
2706 ok(r === obj, "calling __proto__ setter(obj) on x set to true returned " + r);
2707 ok(x.__proto__ === Boolean.prototype, "true value __proto__ after set to obj = " + x.__proto__);
2708 x = new Boolean(true);
2709 r = desc.set.call(x, obj);
2710 ok(r === obj, "calling __proto__ setter(obj) on x set to Boolean(true) returned " + r);
2711 ok(x.__proto__ === obj, "Boolean(true) __proto__ after set to obj = " + x.__proto__);
2713 r = desc.get.call(13);
2714 ok(r === Number.prototype, "calling __proto__ getter on 13 returned " + r);
2716 r = desc.get.call(undefined);
2717 ok(false, "expected exception calling __proto__ getter on undefined");
2719 ok(e.number === 0xa138f - 0x80000000, "calling __proto__ getter on undefined threw exception " + e.number);
2722 r = desc.get.call(null);
2723 ok(false, "expected exception calling __proto__ getter on null");
2725 ok(e.number === 0xa138f - 0x80000000, "calling __proto__ getter on null threw exception " + e.number);
2729 r = desc.set.call(undefined, obj);
2730 ok(false, "expected exception calling __proto__ setter on undefined");
2732 ok(e.number === 0xa138f - 0x80000000, "calling __proto__ setter on undefined threw exception " + e.number);
2735 r = desc.set.call(null, obj);
2736 ok(false, "expected exception calling __proto__ setter on null");
2738 ok(e.number === 0xa138f - 0x80000000, "calling __proto__ setter on null threw exception " + e.number);
2742 r = Object.create(x);
2743 ok(r.__proto__ === x, "r.__proto__ = " + r.__proto__);
2744 r = Object.create(r);
2745 ok(r.__proto__.__proto__ === x, "r.__proto__.__proto__ = " + r.__proto__.__proto__);
2748 ok(false, "expected exception setting circular proto chain");
2750 ok(e.number === 0xa13b0 - 0x80000000 && e.name === "TypeError",
2751 "setting circular proto chain threw exception " + e.number + " (" + e.name + ")");
2754 Object.preventExtensions(x);
2755 x.__proto__ = Object.prototype; /* same prototype */
2757 x.__proto__ = Number.prototype;
2758 ok(false, "expected exception changing __proto__ on non-extensible object");
2760 ok(e.number === 0xa13b6 - 0x80000000 && e.name === "TypeError",
2761 "changing __proto__ on non-extensible object threw exception " + e.number + " (" + e.name + ")");
2765 sync_test("__defineGetter__", function() {
2766 var v = document.documentMode;
2770 ok(x.__defineGetter__ === undefined, "x.__defineGetter__ = " + x.__defineGetter__);
2771 ok(!("__defineGetter__" in Object), "Object.__defineGetter__ = " + Object.__defineGetter__);
2774 ok(Object.prototype.hasOwnProperty("__defineGetter__"), "__defineGetter__ is not a property of Object.prototype");
2775 ok(Object.prototype.__defineGetter__.length === 2, "__defineGetter__.length = " + Object.prototype.__defineGetter__.length);
2777 function getter() { return "wine"; }
2778 function setter(val) { }
2780 r = x.__defineGetter__("foo", getter);
2781 ok(r === undefined, "__defineGetter__ on 42 returned " + r);
2782 ok(x.foo === undefined, "42.foo = " + x.foo);
2785 r = x.__defineGetter__("foo", getter);
2786 ok(r === undefined, "__defineGetter__ returned " + r);
2787 ok(x.foo === "wine", "x.foo = " + x.foo);
2788 r = Object.getOwnPropertyDescriptor(x, "foo");
2789 ok(r.value === undefined, "x.foo value = " + r.value);
2790 ok(r.get === getter, "x.foo get = " + r.get);
2791 ok(r.set === undefined, "x.foo set = " + r.set);
2792 ok(r.writable === undefined, "x.foo writable = " + r.writable);
2793 ok(r.enumerable === true, "x.foo enumerable = " + r.enumerable);
2794 ok(r.configurable === true, "x.foo configurable = " + r.configurable);
2796 Object.defineProperty(x, "foo", { get: undefined, set: setter, configurable: false });
2797 r = Object.getOwnPropertyDescriptor(x, "foo");
2798 ok(r.value === undefined, "x.foo setter value = " + r.value);
2799 ok(r.get === undefined, "x.foo setter get = " + r.get);
2800 ok(r.set === setter, "x.foo setter set = " + r.set);
2801 ok(r.writable === undefined, "x.foo setter writable = " + r.writable);
2802 ok(r.enumerable === true, "x.foo setter enumerable = " + r.enumerable);
2803 ok(r.configurable === false, "x.foo setter configurable = " + r.configurable);
2805 x.__defineGetter__("foo", getter);
2806 ok(false, "expected exception calling __defineGetter__ on non-configurable property");
2808 ok(e.number === 0xa13d6 - 0x80000000, "__defineGetter__ on non-configurable property threw exception " + e.number);
2811 r = Object.prototype.__defineGetter__.call(undefined, "bar", getter);
2812 ok(r === undefined, "__defineGetter__ on undefined returned " + r);
2813 r = Object.prototype.__defineGetter__.call(null, "bar", getter);
2814 ok(r === undefined, "__defineGetter__ on null returned " + r);
2815 r = x.__defineGetter__(undefined, getter);
2816 ok(r === undefined, "__defineGetter__ undefined prop returned " + r);
2817 ok(x["undefined"] === "wine", "x.undefined = " + x["undefined"]);
2818 r = x.__defineGetter__(false, getter);
2819 ok(r === undefined, "__defineGetter__ undefined prop returned " + r);
2820 ok(x["false"] === "wine", "x.false = " + x["false"]);
2823 x.__defineGetter__("bar", "string");
2824 ok(false, "expected exception calling __defineGetter__ with string");
2826 ok(e.number === 0xa138a - 0x80000000, "__defineGetter__ with string threw exception " + e.number);
2829 x.__defineGetter__("bar", undefined);
2830 ok(false, "expected exception calling __defineGetter__ with undefined");
2832 ok(e.number === 0xa138a - 0x80000000, "__defineGetter__ with undefined threw exception " + e.number);
2835 x.__defineGetter__("bar", null);
2836 ok(false, "expected exception calling __defineGetter__ with null");
2838 ok(e.number === 0xa138a - 0x80000000, "__defineGetter__ with null threw exception " + e.number);
2841 Object.prototype.__defineGetter__.call(x, "bar");
2842 ok(false, "expected exception calling __defineGetter__ with only one arg");
2844 ok(e.number === 0xa138a - 0x80000000, "__defineGetter__ with only one arg threw exception " + e.number);
2848 ok(x.bar === "test", "x.bar = " + x.bar);
2849 x.__defineGetter__("bar", getter);
2850 ok(x.bar === "wine", "x.bar with getter = " + x.bar);
2853 sync_test("__defineSetter__", function() {
2854 var v = document.documentMode;
2858 ok(x.__defineSetter__ === undefined, "x.__defineSetter__ = " + x.__defineSetter__);
2859 ok(!("__defineSetter__" in Object), "Object.__defineSetter__ = " + Object.__defineSetter__);
2862 ok(Object.prototype.hasOwnProperty("__defineSetter__"), "__defineSetter__ is not a property of Object.prototype");
2863 ok(Object.prototype.__defineSetter__.length === 2, "__defineSetter__.length = " + Object.prototype.__defineSetter__.length);
2865 function getter() { return "wine"; }
2866 function setter(val) { this.setterVal = val - 1; }
2868 r = x.__defineSetter__("foo", setter);
2869 ok(r === undefined, "__defineSetter__ on 42 returned " + r);
2870 ok(x.foo === undefined, "42.foo = " + x.foo);
2873 r = x.__defineSetter__("foo", setter);
2874 ok(r === undefined, "__defineSetter__ returned " + r);
2875 ok(x.setterVal === undefined, "x.setterVal = " + x.setterVal);
2877 ok(x.setterVal === 12, "x.setterVal = " + x.setterVal);
2878 r = Object.getOwnPropertyDescriptor(x, "foo");
2879 ok(r.value === undefined, "x.foo value = " + r.value);
2880 ok(r.get === undefined, "x.foo get = " + r.get);
2881 ok(r.set === setter, "x.foo set = " + r.set);
2882 ok(r.writable === undefined, "x.foo writable = " + r.writable);
2883 ok(r.enumerable === true, "x.foo enumerable = " + r.enumerable);
2884 ok(r.configurable === true, "x.foo configurable = " + r.configurable);
2886 Object.defineProperty(x, "foo", { get: getter, set: undefined, configurable: false });
2887 r = Object.getOwnPropertyDescriptor(x, "foo");
2888 ok(r.value === undefined, "x.foo getter value = " + r.value);
2889 ok(r.get === getter, "x.foo getter get = " + r.get);
2890 ok(r.set === undefined, "x.foo getter set = " + r.set);
2891 ok(r.writable === undefined, "x.foo getter writable = " + r.writable);
2892 ok(r.enumerable === true, "x.foo getter enumerable = " + r.enumerable);
2893 ok(r.configurable === false, "x.foo getter configurable = " + r.configurable);
2895 x.__defineSetter__("foo", setter);
2896 ok(false, "expected exception calling __defineSetter__ on non-configurable property");
2898 ok(e.number === 0xa13d6 - 0x80000000, "__defineSetter__ on non-configurable property threw exception " + e.number);
2901 r = Object.prototype.__defineSetter__.call(undefined, "bar", setter);
2902 ok(r === undefined, "__defineSetter__ on undefined returned " + r);
2903 r = Object.prototype.__defineSetter__.call(null, "bar", setter);
2904 ok(r === undefined, "__defineSetter__ on null returned " + r);
2905 r = x.__defineSetter__(null, setter);
2906 ok(r === undefined, "__defineSetter__ null prop returned " + r);
2908 ok(x.setterVal === 99, "x.setterVal after setting x.null = " + x.setterVal);
2909 r = x.__defineSetter__(50, setter);
2910 ok(r === undefined, "__defineSetter__ 50 prop returned " + r);
2912 ok(x.setterVal === 32, "x.setterVal after setting x.50 = " + x.setterVal);
2915 x.__defineSetter__("bar", true);
2916 ok(false, "expected exception calling __defineSetter__ with bool");
2918 ok(e.number === 0xa138a - 0x80000000, "__defineSetter__ with bool threw exception " + e.number);
2921 x.__defineSetter__("bar", undefined);
2922 ok(false, "expected exception calling __defineSetter__ with undefined");
2924 ok(e.number === 0xa138a - 0x80000000, "__defineSetter__ with undefined threw exception " + e.number);
2927 x.__defineSetter__("bar", null);
2928 ok(false, "expected exception calling __defineSetter__ with null");
2930 ok(e.number === 0xa138a - 0x80000000, "__defineSetter__ with null threw exception " + e.number);
2933 Object.prototype.__defineSetter__.call(x, "bar");
2934 ok(false, "expected exception calling __defineSetter__ with only one arg");
2936 ok(e.number === 0xa138a - 0x80000000, "__defineSetter__ with only one arg threw exception " + e.number);
2940 ok(x.bar === "test", "x.bar = " + x.bar);
2941 x.__defineSetter__("bar", setter);
2942 ok(x.bar === undefined, "x.bar with setter = " + x.bar);
2944 ok(x.bar === undefined, "x.bar with setter = " + x.bar);
2945 ok(x.setterVal === 9, "x.setterVal after setting bar = " + x.setterVal);
2948 sync_test("MutationObserver", function() {
2949 if (!window.MutationObserver) {
2954 window.MutationObserver();
2955 ok(false, "MutationObserver without args should fail");
2957 ok(e.number == 0xffff - 0x80000000, "MutationObserver without new threw exception " + e.number);
2961 window.MutationObserver(42);
2962 ok(false, "MutationObserver with non-function should fail");
2965 ok(e.name == "TypeMismatchError", "MutationObserver with non-function arg threw exception " + e.name);
2969 window.MutationObserver(function() {});
2971 ok(false, "MutationObserver without new threw exception " + e.number);
2975 new window.MutationObserver();
2976 ok(false, "MutationObserver with no args should fail");
2978 ok(e.number == 0xffff - 0x80000000, "MutationObserver with no args threw exception " + e.number);
2982 new window.MutationObserver(1);
2983 ok(false, "MutationObserver with non-function arg should fail");
2986 ok(e.name == "TypeMismatchError", "MutationObserver with non-function arg threw exception " + e.name);
2990 new window.MutationObserver(function() {});
2992 ok(false, "MutationObserver threw exception " + e.number);
2996 new window.MutationObserver(function() {}, 1);
2998 ok(false, "MutationObserver with extra args threw exception " + e.number);
3001 var mutation_observer = new MutationObserver(function() {});
3002 function test_exposed(prop) {
3003 ok(prop in mutation_observer, prop + " not found in MutationObserver.");
3005 test_exposed("observe");
3006 test_exposed("disconnect");
3007 test_exposed("takeRecords");
3010 sync_test("initMessageEvent", function() {
3011 var e, v = document.documentMode;
3012 if(!document.createEvent)
3014 e = document.createEvent("MessageEvent");
3015 ok(e.data === (v < 10 ? "" : undefined), "e.data = " + e.data);
3016 ok(e.bubbles === false, "bubbles = " + e.bubbles);
3017 ok(e.cancelable === false, "cancelable = " + e.cancelable);
3018 ok(e.source === null, "e.source = " + e.source);
3019 ok(e.origin === "", "e.origin = " + e.origin);
3021 e.initMessageEvent("blah", true, true, 137, "wine", 1234, window);
3022 ok(e.data === "137", "e.data = " + e.data);
3023 ok(e.bubbles === true, "bubbles = " + e.bubbles);
3024 ok(e.cancelable === true, "cancelable = " + e.cancelable);
3025 ok(e.source === window, "e.source = " + e.source);
3026 ok(e.origin === "wine", "e.origin = " + e.origin);
3028 e.initMessageEvent("abcd", false, false, "testdata", "origin", 42, null);
3029 ok(e.data === "testdata", "e.data = " + e.data);
3030 ok(e.bubbles === false, "bubbles = " + e.bubbles);
3031 ok(e.cancelable === false, "cancelable = " + e.cancelable);
3032 ok(e.source === null, "e.source = " + e.source);
3033 ok(e.origin === "origin", "e.origin = " + e.origin);
3036 async_test("postMessage", function() {
3037 var v = document.documentMode;
3038 var onmessage_called = false;
3039 window.onmessage = function(e) {
3040 onmessage_called = true;
3042 ok(e === undefined, "e = " + e);
3044 ok(e.data === (v < 10 ? "10" : 10), "e.data = " + e.data);
3045 ok(e.source === window, "e.source = " + e.source);
3046 ok(e.origin === "http://winetest.example.org", "e.origin = " + e.origin);
3048 e = document.createEvent("MessageEvent");
3049 ok(e.data === (v < 10 ? "" : undefined), "created e.data = " + e.data);
3055 v < 10 ? { toString: function() { return "http://winetest.example.org"; } } : null,
3056 (function() { return "http://winetest.example.org"; }),
3057 "winetest.example.org",
3061 for(var i = 0; i < invalid.length; i++) {
3063 window.postMessage("invalid " + i, invalid[i]);
3064 ok(false, "expected exception with targetOrigin " + invalid[i]);
3066 var n = ex.number >>> 0;
3067 todo_wine_if(v >= 10).
3068 ok(n === (v < 10 ? 0x80070057 : 0), "postMessage with targetOrigin " + invalid[i] + " threw " + n);
3071 ok(ex.name === "SyntaxError", "postMessage with targetOrigin " + invalid[i] + " threw " + ex.name);
3075 window.postMessage("invalid empty", "");
3076 ok(false, "expected exception with empty targetOrigin");
3078 var n = ex.number >>> 0;
3079 ok(n === 0x80070057, "postMessage with empty targetOrigin threw " + n);
3082 window.postMessage("wrong port", "http://winetest.example.org:1234");
3083 ok(onmessage_called == (v < 9 ? true : false), "onmessage not called with wrong port");
3084 onmessage_called = false;
3087 "http://winetest.example.com",
3088 "ftp://winetest.example.org",
3089 "http://wine.example.org",
3090 "http://example.org"
3092 for(var i = 0; i < not_sent.length; i++) {
3093 window.postMessage("not_sent " + i, not_sent[i]);
3094 ok(onmessage_called == false, "onmessage called with targetOrigin " + not_sent[i]);
3095 onmessage_called = false;
3098 window.postMessage(10, (v < 10 ? "*" : { toString: function() { return "*"; } }));
3099 ok(onmessage_called == (v < 9 ? true : false), "onmessage not called");
3100 if(v < 9) next_test();
3103 sync_test("form", function() {
3104 document.body.innerHTML = "";
3105 var form = document.createElement("form");
3106 document.body.appendChild(form);
3109 form.innerHTML = "<input type=\"text\" id = \"i1\" /><input type=\"text\" id = \"i2\" />";
3110 ok(form.length === 2, "form.length = " + form.length);
3111 ok(typeof(form[0]) === "object", "form[0] = " + form[0]);
3112 ok(typeof(form[1]) === "object", "form[1] = " + form[1]);
3113 form.innerHTML = "";
3114 ok(form[0] === "test", "form[0] = " + form[0]);