diff options
Diffstat (limited to '')
27 files changed, 1154 insertions, 0 deletions
diff --git a/dom/xul/test/398289-resource.xhtml b/dom/xul/test/398289-resource.xhtml new file mode 100644 index 0000000000..6702027ef1 --- /dev/null +++ b/dom/xul/test/398289-resource.xhtml @@ -0,0 +1,49 @@ +<?xml version="1.0"?> + +<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<dialog buttonlabelaccept="OK" + buttonlabelcancel="Cancel"> + <style xmlns="http://www.w3.org/1999/xhtml"> + .tab-middle { outline: none !important } + </style> + + <script> + document.addEventListener("dialogaccept", function() { alert('OK') }); + document.addEventListener("dialogcancel", function() { alert('Cancel') }); + </script> + + <tabbox id="test" flex="1" persist="selectedIndex"> + + <tabs> + <tab label="One"/> + <tab label="Two"/> + </tabs> + + <tabpanels flex="1"> + + <vbox flex="1"> + <description>Text for tab ONE</description> + <description class="text-link" + onclick="window.open('https://bugzilla.mozilla.org/show_bug.cgi?id=398289');">(test case for bug 398289)</description> + <tree> + <treecols> + <treecol label="Header" flex="1"/> + </treecols> + </tree> + </vbox> + + <vbox flex="1"> + <description>Text for tab TWO</description> + <description>(When the document is reloaded, this content gets replaced by the one from the first tab.)</description> + </vbox> + + </tabpanels> + + </tabbox> + + <box height="1000"/> <!-- Push dialog buttons out of sight so that the animated default button isn't part of the snapshot --> + +</dialog> +</window> diff --git a/dom/xul/test/chrome.ini b/dom/xul/test/chrome.ini new file mode 100644 index 0000000000..a1313d269e --- /dev/null +++ b/dom/xul/test/chrome.ini @@ -0,0 +1,26 @@ +[DEFAULT] +support-files = + 398289-resource.xhtml + window_bug583948.xhtml + window_bug757137.xhtml + +[test_bug199692.xhtml] +[test_bug311681.xhtml] +[test_bug391002.xhtml] +[test_bug398289.html] +[test_bug403868.xhtml] +[test_bug418216.xhtml] +[test_bug445177.xhtml] +[test_bug468176.xhtml] +[test_bug583948.xhtml] +[test_bug757137.xhtml] +[test_bug775972.xhtml] +[test_bug1070049_throw_from_script.xhtml] +[test_html_template.xhtml] +[test_import_xul_to_content.xhtml] +[test_bug1290965.xhtml] +[test_bug749367.xhtml] +[test_xul_tabindex_focus.xhtml] +[test_bug1686822.xhtml] + support-files = window_bug1686822.xhtml +[test_accesskey.xhtml] diff --git a/dom/xul/test/file_bug236853.rdf b/dom/xul/test/file_bug236853.rdf new file mode 100644 index 0000000000..8d17bf6912 --- /dev/null +++ b/dom/xul/test/file_bug236853.rdf @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:ex="http://www.ex.org/ex-rdf#"> + + <rdf:Description about="urn:root"> + <ex:nodes> + <rdf:Bag about="http://www.ex.org/nodes"> + <rdf:li> + <rdf:Description about="http://www.ex.org/nodes/A"/> + </rdf:li> + </rdf:Bag> + </ex:nodes> + </rdf:Description> +</rdf:RDF> diff --git a/dom/xul/test/mochitest.ini b/dom/xul/test/mochitest.ini new file mode 100644 index 0000000000..9ec3128ab6 --- /dev/null +++ b/dom/xul/test/mochitest.ini @@ -0,0 +1,3 @@ +[DEFAULT] + +[test_disable_scroll_frame_plain.html] diff --git a/dom/xul/test/test_accesskey.xhtml b/dom/xul/test/test_accesskey.xhtml new file mode 100644 index 0000000000..c71fcf78a0 --- /dev/null +++ b/dom/xul/test/test_accesskey.xhtml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1699284 +--> +<window title="Mozilla Bug 1699284" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> +<body> +<label id="label1" accesskey="a">Label 1</label><button id="button1" accesskey="a">Button 1</button> +<label id="label2" accesskey="a" tabindex="0">Label 2</label><button id="button2">Button 2</button> +<label id="label3">Label 3</label><button id="button3" accesskey="a">Button 3</button> +<label id="label4" accesskey="a" control="button4">Label 4</label><button id="button4" disabled="true">Button 4</button> +<label id="label5" accesskey="a" control="button5">Label 5</label><button id="button5">Button 5</button> +<!-- Tests code --> +<script type="application/javascript"> +<![CDATA[ + +/** Test for Bug 1699284 **/ + +function PerformAccessKey(aKey) { + synthesizeKey(aKey, navigator.platform.includes("Mac") ? { altKey: true, ctrlKey: true } + : { altKey: true, shiftKey: true }); +}; + +add_task(async function test_accesskey() { + let [label1, label2, label3, label4, label5] = document.querySelectorAll("label"); + let [button1, button2, button3, button4, button5] = document.querySelectorAll("button"); + + [ + label1, label2, label3, label4, label5, button1, button2, button3, button4, button5 + ].forEach(function(ele) { + ele.addEventListener("click", function(e) { + ok(false, `${e.target.id} should not receive click event`); + }); + }); + + PerformAccessKey("a"); + is(document.activeElement.id, button1.id, `focus should move to ${button1.id}`); + + PerformAccessKey("a"); + is(document.activeElement.id, button3.id, `focus should move to ${button3.id}`); + + PerformAccessKey("a"); + is(document.activeElement.id, button5.id, `focus should move to ${button5.id}`); + + // Cycle back to first element + PerformAccessKey("a"); + is(document.activeElement.id, button1.id, `focus should move to ${button1.id}`); +}); + +]]> +</script> +</body> +</window> diff --git a/dom/xul/test/test_bug1070049_throw_from_script.xhtml b/dom/xul/test/test_bug1070049_throw_from_script.xhtml new file mode 100644 index 0000000000..b9c635efd6 --- /dev/null +++ b/dom/xul/test/test_bug1070049_throw_from_script.xhtml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1070049 +--> +<window title="Mozilla Bug 1070049" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 1070049 **/ + SimpleTest.waitForExplicitFinish(); + addLoadEvent(function() { + // Prevent the test from failing when the exception hits onerror. + SimpleTest.expectUncaughtException(); + + // Tell the test to expect exactly one console error with the given parameters, + // with SimpleTest.finish as a continuation function. + SimpleTest.monitorConsole(SimpleTest.finish, [{errorMessage: new RegExp('flimfniffle')}]); + + // Schedule the console accounting (and continuation) to run next, right + // after we throw (below). + SimpleTest.executeSoon(SimpleTest.endMonitorConsole); + + // Throw. + throw "flimfniffle"; + }); + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1070049" + target="_blank">Mozilla Bug 1070049</a> + </body> +</window> diff --git a/dom/xul/test/test_bug1290965.xhtml b/dom/xul/test/test_bug1290965.xhtml new file mode 100644 index 0000000000..ce1f7a8522 --- /dev/null +++ b/dom/xul/test/test_bug1290965.xhtml @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:h="http://www.w3.org/1999/xhtml"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <toolbarbutton oncommand="++countera;" id="a">A</toolbarbutton> + <toolbarbutton oncommand="++counterb;" id="b">B</toolbarbutton> + <script type="text/javascript"> + <![CDATA[ + let aEl = document.getElementById('a'); + let bEl = document.getElementById('b'); + let countera = 0; + let counterb = 0; + + aEl.addEventListener('click', function (aEvent) { + aEvent.preventDefault(); + let cmdEvent = document.createEvent("xulcommandevent"); + cmdEvent.initCommandEvent("command", true, true, window, 0, + aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey, + aEvent.metaKey, 0, null, aEvent.mozInputSource); + aEvent.currentTarget.dispatchEvent(cmdEvent); + }); + + bEl.addEventListener('click', function (aEvent) { + let cmdEvent = document.createEvent("xulcommandevent"); + cmdEvent.initCommandEvent("command", true, true, window, 0, + aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey, + aEvent.metaKey, 0, null, aEvent.mozInputSource); + aEvent.currentTarget.dispatchEvent(cmdEvent); + }); + + bEl.click(); + aEl.click(); + + is(countera, 1, "Counter should be one as event fires once"); + is(counterb, 2, "Counter should be two as event fires twice"); + ]]> + </script> +</window> diff --git a/dom/xul/test/test_bug1686822.xhtml b/dom/xul/test/test_bug1686822.xhtml new file mode 100644 index 0000000000..cdad585d00 --- /dev/null +++ b/dom/xul/test/test_bug1686822.xhtml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <html:script><![CDATA[ + SimpleTest.waitForExplicitFinish(); + let chromeWindow = browsingContext.topChromeWindow; + + let resolve; + let i = 0; + chromeWindow.moduleScriptRan = function() { + ok(true, "Module script executed: " + ++i) + resolve(); + resolve = null; + } + + function testOnce() { + let currentWin; + return new Promise(r => { + currentWin = chromeWindow.open("window_bug1686822.xhtml", "", "chrome"); + resolve = r; + }).then(function() { + currentWin.close(); + }); + } + + (async function() { + // The first and second loads are different so make sure we test both code paths. + await testOnce(); + await testOnce(); + delete chromeWindow.moduleScriptRan; + SimpleTest.finish(); + }()); + ]]></html:script> +</window> diff --git a/dom/xul/test/test_bug199692.xhtml b/dom/xul/test/test_bug199692.xhtml new file mode 100644 index 0000000000..6d8b9efe4e --- /dev/null +++ b/dom/xul/test/test_bug199692.xhtml @@ -0,0 +1,102 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=199692 +--> +<window title="Test for Bug 199692" + id="test_bug199692.xhtml" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript"> + <![CDATA[ + customElements.define("test-xul-element", class CustomElement extends XULElement { + constructor() { + super(); + const template = document.getElementById("template"); + this.attachShadow({mode: "open"}) + .appendChild(template.content.cloneNode(true)); + } + }); + ]]> + </script> +<body id="body" xmlns="http://www.w3.org/1999/xhtml"> +<template id="template"> + <xul:label id="anon-label" value="ANON"/> +</template> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=199692">Mozilla Bug 199692</a> + +<vbox id="content" style="position: relative;" +xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <xul:label id="non-anon-label" value="a textbox!:" control="textbox"/> + <html:textarea id="textbox" rows="4"/> + <xul:radiogroup style="outline: 2px solid orange;"> + <xul:radio id="unselected-radio" label="Orange" style="outline: 2px solid red;"/> + <xul:radio id="selected-radio" label="Violet" selected="true"/> + <xul:radio id="disabled-radio" label="Yellow" disabled="true"/> + </xul:radiogroup> + <test-xul-element id="bound" style="border: 2px solid green;"></test-xul-element> +</vbox> +<pre id="test"> + <script class="testbody" type="text/javascript"> +<![CDATA[ + SimpleTest.waitForExplicitFinish(); + + // Before onload, XUL docs have no root frame. + is(document.elementFromPoint(10,10), null, + "Calls to elementFromPoint before onload should return null"); + + var d = 10; + function middle(e) { + return { "x": e.getBoundingClientRect().x + e.getBoundingClientRect().width/2, + "y": e.getBoundingClientRect().y + e.getBoundingClientRect().height/2 }; + } + function lower_right(e) { + return { "x": e.getBoundingClientRect().x + e.getBoundingClientRect().width - d, + "y": e.getBoundingClientRect().y + e.getBoundingClientRect().height - d }; + } + function upper_left(e) { + return { "x": e.getBoundingClientRect().x + d, + "y": e.getBoundingClientRect().y + d }; + } + function scrollbar_button(e) { // a bit down from upper right + return { "x": e.getBoundingClientRect().x + e.getBoundingClientRect().width - d, + "y": e.getBoundingClientRect().y + d + 15 }; + } + + function test(ptFunc, id, message) { + var pt = ptFunc($(id)); + var e = document.elementFromPoint(pt.x, pt.y); + ok(e != null, message + " (returned null)"); + is(e.id, id, message); + } + + function do_test() { + // Avoid hardcoding x,y pixel values, to better deal with differing default + // font sizes or other layout defaults. + + test(middle, 'textbox', "Point within textbox should return textbox element"); + test(lower_right, 'textbox', "Point on textbox's scrollbar should return textbox element"); + test(scrollbar_button, 'textbox', "Point on textbox's scrollbar button should return textbox element"); + test(middle, 'non-anon-label', "Point on label should return label"); + test(upper_left, 'bound', "Point on custom element content should return custom element"); + + SimpleTest.finish(); + } + $("textbox").setAttribute("value", + "lorem ipsum dolor sit amet " + + "lorem ipsum dolor sit amet " + + "lorem ipsum dolor sit amet " + + "lorem ipsum dolor sit amet " + + "lorem ipsum dolor sit amet " + + "lorem ipsum dolor sit amet " + + "lorem ipsum dolor sit amet "); // force scrollbars to appear + addLoadEvent(do_test); +]]> + </script> +</pre> +</body> +</window> diff --git a/dom/xul/test/test_bug311681.xhtml b/dom/xul/test/test_bug311681.xhtml new file mode 100644 index 0000000000..8caef2ca5b --- /dev/null +++ b/dom/xul/test/test_bug311681.xhtml @@ -0,0 +1,107 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=311681 +--> +<window title="Mozilla Bug 311681" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=311681">Mozilla Bug 311681</a> +<script class="testbody" type="text/javascript"> +<![CDATA[ + // Setup script + SimpleTest.waitForExplicitFinish(); + + // Make sure to trigger the hashtable case by asking for enough elements + // by ID. + for (var i = 0; i < 256; ++i) { + var x = document.getElementById(i); + } + + // save off the document.getElementById function, since getting it as a + // property off the document it causes a content flush. + var fun = document.getElementById; + + // Slot for our initial element with id "content" + var testNode; + + function getCont() { + return fun.call(document, "content"); + } + + function testClone() { + // Test to make sure that if we have multiple nodes with the same ID in + // a document we don't forget about one of them when the other is + // removed. + var newParent = $("display"); + var node = testNode.cloneNode(true); + isnot(node, testNode, "Clone should be a different node"); + + newParent.appendChild(node); + + // Check what getElementById returns, no flushing + is(getCont(), node, "Should be getting new node pre-flush 1") + + // Trigger a layout flush, just in case. + let itemHeight = newParent.offsetHeight/10; + + // Check what getElementById returns now. + is(getCont(), node, "Should be getting new node post-flush 1") + + clear(newParent); + + // Check what getElementById returns, no flushing + is(getCont(), testNode, "Should be getting orig node pre-flush 2"); + + // Trigger a layout flush, just in case. + itemHeight = newParent.offsetHeight/10; + + // Check what getElementById returns now. + is(getCont(), testNode, "Should be getting orig node post-flush 2"); + + node = testNode.cloneNode(true); + newParent.appendChild(node); + testNode.remove(); + + // Check what getElementById returns, no flushing + is(getCont(), node, "Should be getting clone pre-flush"); + + // Trigger a layout flush, just in case. + // eslint-disable-next-line no-unused-vars + itemHeight = newParent.offsetHeight/10; + + // Check what getElementById returns now. + is(getCont(), node, "Should be getting clone post-flush"); + + } + + function clear(node) { + while (node.hasChildNodes()) { + node.firstChild.remove(); + } + } + + addLoadEvent(testClone); + addLoadEvent(SimpleTest.finish); +]]> +</script> +<p id="display"></p> +<div id="content" style="display: none"> + <script class="testbody" type="text/javascript"> + <![CDATA[ + testNode = fun.call(document, "content"); + // Needs incremental XML parser + isnot(testNode, null, "Should have node here"); + ]]> + </script> +</div> +<pre id="test"> +</pre> +</body> + +</window> diff --git a/dom/xul/test/test_bug391002.xhtml b/dom/xul/test/test_bug391002.xhtml new file mode 100644 index 0000000000..da8c8b4d35 --- /dev/null +++ b/dom/xul/test/test_bug391002.xhtml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=391002 +--> +<window title="Mozilla Bug 391002" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=391002" + target="_blank">Mozilla Bug 391002</a> + </body> + + <button id="btn1" command="cmd1"/> + + <button id="btn2"> + <observes id="observes" element="cmd1" attribute="label"/> + </button> + + <commandset> + <command id="cmd1" label="cmd1"/> + <command id="cmd2" label="cmd2"/> + </commandset> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 391002 **/ + + $("btn1").setAttribute("command", "cmd2"); + is($("btn1").getAttribute("label"), $("cmd2").getAttribute("label")) + + $("observes").setAttribute("element", "cmd2"); + is($("btn2").getAttribute("label"), $("cmd2").getAttribute("label")) + + ]]></script> +</window> + diff --git a/dom/xul/test/test_bug398289.html b/dom/xul/test/test_bug398289.html new file mode 100644 index 0000000000..c4873fe2b2 --- /dev/null +++ b/dom/xul/test/test_bug398289.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html style="height: 100%"> +<head> + <title>Test for bug 398289</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +</head> +<body style="height: 100%; margin: 0; overflow: hidden;" onload="setTimeout(onBodyLoad, 0);"> + <iframe id="test" style="border: 0; width: 100%; height: 100%" scrolling="no" src="398289-resource.xhtml"></iframe> + + <script class="testbody"> + var snap1, snap2; + SimpleTest.waitForExplicitFinish(); + + async function onBodyLoad() { + window.frames[0].document.getElementById("test").selectedIndex = 0; + window.frames[0].document.getElementById("test").selectedIndex = 1; + + frames[0].scrollTo(0, 0); + scrollTo(0, 0); + snap1 = await snapshotWindow(window); + + document.getElementById("test").onload = onFrameLoad; + window.frames[0].location.reload(); + } + + async function onFrameLoad() { + frames[0].scrollTo(0, 0); + scrollTo(0, 0); + snap2 = await snapshotWindow(window); + + var equal, str1, str2; + [equal, str1, str2] = compareSnapshots(snap1, snap2, true); + + ok(equal, "persistent attribute in tab box broken, expected: "+str1+" got: "+str2); + SimpleTest.finish(); + } + </script> +</body> +</html> diff --git a/dom/xul/test/test_bug403868.xhtml b/dom/xul/test/test_bug403868.xhtml new file mode 100644 index 0000000000..c2427bb644 --- /dev/null +++ b/dom/xul/test/test_bug403868.xhtml @@ -0,0 +1,83 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=403868 +--> +<window title="Mozilla Bug 403868" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=403868" + target="_blank">Mozilla Bug 403868</a> + <div id="content" style="display: none"/> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 403868 **/ +function createSpan(id, insertionPoint) { + var s = document.createElementNS("http://www.w3.org/1999/xhtml", "span"); + s.id = id; + $("content").insertBefore(s, insertionPoint); + return s; +} + +var s1a = createSpan("test1", null); +is(document.getElementById("test1"), s1a, + "Only one span with id=test1 in the tree; should work!"); + +var s2a = createSpan("test1", null); +is(document.getElementById("test1"), s1a, + "Appending span with id=test1 doesn't change which one comes first"); + +var s3a = createSpan("test1", s2a); +is(document.getElementById("test1"), s1a, + "Inserting span with id=test1 not at the beginning; doesn't matter"); + +var s4a = createSpan("test1", s1a); +is(document.getElementById("test1"), s4a, + "Inserting span with id=test1 at the beginning changes which one is first"); + +s4a.remove(); +is(document.getElementById("test1"), s1a, + "First-created span with id=test1 is first again"); + +s1a.remove(); +is(document.getElementById("test1"), s3a, + "Third-created span with id=test1 is first now"); + +// Start the id hashtable +for (var i = 0; i < 256; ++i) { + document.getElementById("no-such-id-in-the-document" + i); +} + +var s1b = createSpan("test2", null); +is(document.getElementById("test2"), s1b, + "Only one span with id=test2 in the tree; should work!"); + +var s2b = createSpan("test2", null); +is(document.getElementById("test2"), s1b, + "Appending span with id=test2 doesn't change which one comes first"); + +var s3b = createSpan("test2", s2b); +is(document.getElementById("test2"), s1b, + "Inserting span with id=test2 not at the beginning; doesn't matter"); + +var s4b = createSpan("test2", s1b); +is(document.getElementById("test2"), s4b, + "Inserting span with id=test2 at the beginning changes which one is first"); + +s4b.remove(); +is(document.getElementById("test2"), s1b, + "First-created span with id=test2 is first again"); + +s1b.remove(); +is(document.getElementById("test2"), s3b, + "Third-created span with id=test2 is first now"); + + ]]></script> +</window> diff --git a/dom/xul/test/test_bug418216.xhtml b/dom/xul/test/test_bug418216.xhtml new file mode 100644 index 0000000000..56e487faf2 --- /dev/null +++ b/dom/xul/test/test_bug418216.xhtml @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=418216 +--> +<window title="Mozilla Bug 418216" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=418216" + target="_blank">Mozilla Bug 418216</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 418216 **/ + SimpleTest.waitForExplicitFinish(); + window.onload = function onload() { + var element = $("item"); + $("container").removeChild($("item")); + $("broadcaster").removeAttribute("disabled"); + $("container").appendChild(element); + is($("item").hasAttribute("disabled"), $("broadcaster").hasAttribute("disabled")); + SimpleTest.finish(); + } + + + + + ]]></script> + +<box id="container"> +<box id="item"> + <observes element="broadcaster" attribute="disabled"/> +</box> +</box> + +<broadcasterset> + <broadcaster id="broadcaster" disabled="true"/> +</broadcasterset> + +</window> diff --git a/dom/xul/test/test_bug445177.xhtml b/dom/xul/test/test_bug445177.xhtml new file mode 100644 index 0000000000..d188f19241 --- /dev/null +++ b/dom/xul/test/test_bug445177.xhtml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=445177 +--> +<window title="Test for Bug 445177" + id="test_bug445177.xhtml" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body id="body" xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=445177">Mozilla Bug 445177</a> + + +<xul:hbox id="b1" value="foo"/> +<xul:hbox id="o1" observes="b1"/> + +<pre id="test"> + <script class="testbody" type="text/javascript"> +<![CDATA[ + SimpleTest.waitForExplicitFinish(); + function do_test() { + var b1 = document.getElementById("b1"); + var o1 = document.getElementById("o1"); + + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (1)"); + + b1.setAttribute("value", "bar"); + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (2)"); + + b1.removeAttribute("value"); + is(o1.hasAttribute("value"), b1.hasAttribute("value"), "Wrong value (3)"); + + o1.setAttribute("value", "foo"); + isnot(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (4)"); + + b1.setAttribute("value", "foobar"); + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (5)"); + + //After removing listener, changes to broadcaster shouldn't have any effect. + o1.remove(); + b1.setAttribute("value", "foo"); + isnot(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (6)"); + + b1.parentNode.appendChild(o1); + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (7)"); + + o1.remove(); + o1.removeAttribute("observes"); + o1.removeAttribute("value"); + b1.parentNode.appendChild(o1); + isnot(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (8)"); + + SimpleTest.finish(); + } + + addLoadEvent(do_test); +]]> + </script> +</pre> +</body> +</window> diff --git a/dom/xul/test/test_bug468176.xhtml b/dom/xul/test/test_bug468176.xhtml new file mode 100644 index 0000000000..f21c1bcde3 --- /dev/null +++ b/dom/xul/test/test_bug468176.xhtml @@ -0,0 +1,84 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=468176 +--> +<window title="Test for Bug 468176" + id="test_bug468176.xhtml" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body id="body" xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=468176">Mozilla Bug 468176</a> + +<xul:hbox id="b1" value="foo"/> + +<xul:hbox id="o1"> + <xul:observes id="inner" element="b1" attribute="*"/> +</xul:hbox> + +<pre id="test"> + <script class="testbody" type="text/javascript"> +<![CDATA[ + SimpleTest.waitForExplicitFinish(); + + var broadcastCount = 0; + function b_listener(evt) { + ++broadcastCount; + } + + function do_test() { + var b1 = document.getElementById("b1"); + var o1 = document.getElementById("o1"); + var inner = document.getElementById("inner"); + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (1)"); + + inner.addEventListener("broadcast", b_listener, true); + b1.setAttribute("value", "bar"); + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (2)"); + is(broadcastCount, 1, "Wrong value (3)"); + + b1.removeAttribute("value"); + is(o1.hasAttribute("value"), b1.hasAttribute("value"), "Wrong value (4)"); + is(broadcastCount, 2, "Wrong value (5)"); + + o1.setAttribute("value", "foo"); + isnot(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (6)"); + is(broadcastCount, 2, "Wrong value (7)"); + + b1.setAttribute("value", "foobar"); + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (8)"); + is(broadcastCount, 3, "Wrong value (9)"); + + b1.removeAttribute("value"); + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (10)"); + is(broadcastCount, 4, "Wrong value (11)"); + + b1.removeAttribute("value"); + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (12)"); + is(broadcastCount, 4, "Wrong value (13)"); + + o1.setAttribute("value", "bar"); + b1.setAttribute("value", "bar"); // This should still dispatch 'broadcast' + is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (14)"); + is(broadcastCount, 5, "Wrong value (15)"); + + //After removing listener, changes to broadcaster shouldn't have any effect. + o1.remove(); + b1.setAttribute("value", "foo"); + isnot(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (16)"); + is(broadcastCount, 5, "Wrong value (17)"); + + SimpleTest.finish(); + } + + addLoadEvent(do_test); +]]> + </script> +</pre> +</body> +</window> diff --git a/dom/xul/test/test_bug583948.xhtml b/dom/xul/test/test_bug583948.xhtml new file mode 100644 index 0000000000..2cab13a4ac --- /dev/null +++ b/dom/xul/test/test_bug583948.xhtml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + +<body xmlns="http://www.w3.org/1999/xhtml"> + <div id="content" style="display: none"/> +</body> + +<script> +SimpleTest.waitForExplicitFinish(); + +let chromeWindow = window.browsingContext.topChromeWindow; + +var attempts = 0; + +chromeWindow.update = function () { + // without the crash fix, this usually crashes after 2 to 4 reloads + if (++attempts == 6) { + ok(true, "didn't crash after 6 attempts"); + otherWindow.close(); + SimpleTest.waitForFocus(function() { + chromeWindow.update = null; + SimpleTest.finish(); + }); + } else { + otherWindow.document.commandDispatcher.updateCommands(''); + setTimeout(function() { + otherWindow.location.reload() + }, 0); + } +} + +var otherWindow = chromeWindow.open("window_bug583948.xhtml", "_blank", "chrome"); +</script> + +</window> diff --git a/dom/xul/test/test_bug749367.xhtml b/dom/xul/test/test_bug749367.xhtml new file mode 100644 index 0000000000..3dcea24f1c --- /dev/null +++ b/dom/xul/test/test_bug749367.xhtml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=749367 +--> +<window title="Mozilla Bug 749367" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="setTimeout(runTests, 0);"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=486990" + target="_blank">Mozilla Bug 486990</a> + </body> + + <!-- test code goes here --> + <script type="text/template"> + <![CDATA[ + SimpleTest.waitForExplicitFinish(); + function runTests() { + ok(false, "Shouldn't execute"); + SimpleTest.finish(); + } + ]]> + </script> + + <script type="text/javascript"> + <![CDATA[ + SimpleTest.waitForExplicitFinish(); + function runTests() { + ok(true, "Should execute"); + SimpleTest.finish(); + } + ]]> + </script> + +</window> diff --git a/dom/xul/test/test_bug757137.xhtml b/dom/xul/test/test_bug757137.xhtml new file mode 100644 index 0000000000..a08309bd49 --- /dev/null +++ b/dom/xul/test/test_bug757137.xhtml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + +<body xmlns="http://www.w3.org/1999/xhtml"> + <div id="content" style="display: none"/> +</body> + +<script> +SimpleTest.waitForExplicitFinish(); + +// Force off out-of-process mozbrowser because we need to grab its +// |window| synchronously from here. Out-of-process docshell creation +// for mozbrowser haves entirely differently. +SpecialPowers.pushPrefEnv({"set":[["dom.ipc.tabs.disabled", true]]}).then(startTest); + +function startTest() { + var otherWindow = window.browsingContext.topChromeWindow.open("window_bug757137.xhtml", "", "chrome"); + ok(otherWindow.isChromeWindow, 'XUL window should be a ChromeWindow'); + + otherWindow.onload = function () { + var w = otherWindow.document.getElementById('f').contentWindow; + ok(w !== null, 'got the |window| for a mozbrowser iframe'); + ok(!w.isChromeWindow, 'mozbrowser iframe should not be a ChromeWindow'); + + otherWindow.close(); + SimpleTest.waitForFocus(SimpleTest.finish); + }; +} +</script> + +</window> diff --git a/dom/xul/test/test_bug775972.xhtml b/dom/xul/test/test_bug775972.xhtml new file mode 100644 index 0000000000..571bf6a6c3 --- /dev/null +++ b/dom/xul/test/test_bug775972.xhtml @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=775972 +--> +<window title="Mozilla Bug 775972" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="test()"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=775972" + target="_blank">Mozilla Bug 775972</a> + </body> + + <hbox id="container"><label value="test" id=""/></hbox> + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 775972 **/ + + function test() { + var c = document.getElementById("container"); + var clone = c.cloneNode(true); + document.documentElement.appendChild(clone); + ok(true, "This shouldn't crash!"); + } + + + ]]> + </script> +</window> diff --git a/dom/xul/test/test_disable_scroll_frame_plain.html b/dom/xul/test/test_disable_scroll_frame_plain.html new file mode 100644 index 0000000000..8104f55721 --- /dev/null +++ b/dom/xul/test/test_disable_scroll_frame_plain.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html scrolling="false"> +<head> + <meta charset="utf-8"> + <title>disable scroll frame exposed</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +<div style="height: 300vh"></div> +<script> + // Ensure that disabling the scroll frame isn't exposed to content. + ok(document.scrollingElement.scrollTopMax > 0, "Scrolling should still work."); +</script> +</body> +</html> diff --git a/dom/xul/test/test_html_template.xhtml b/dom/xul/test/test_html_template.xhtml new file mode 100644 index 0000000000..7e6029486e --- /dev/null +++ b/dom/xul/test/test_html_template.xhtml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<window title="HTML template in XUL" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <body xmlns="http://www.w3.org/1999/xhtml"> + <template id="template">Content<span>Content</span></template> +<script type="application/javascript"><![CDATA[ + add_task(async function test_template() { + let template = document.getElementById("template"); + ok("content" in template, "Template has shadow root."); + is(template.childNodes.length, 0, "Template should have no children."); + is(template.content.childNodes.length, 2, "Template content should have two children."); + }); +]]></script> + </body> +</window> diff --git a/dom/xul/test/test_import_xul_to_content.xhtml b/dom/xul/test/test_import_xul_to_content.xhtml new file mode 100644 index 0000000000..32db06e564 --- /dev/null +++ b/dom/xul/test/test_import_xul_to_content.xhtml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<window title="Mozilla Importing XUL into Content" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1027299" + target="_blank">Mozilla Bug 1027299</a> + </body> + + <browser id="browserelt" src="about:blank" type="content"/> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + SimpleTest.waitForExplicitFinish(); + + function expectWarning(expected, when, f) { + Services.console.reset(); + + f(); + + var sawWarning = false; + var msgs = Services.console.getMessageArray(); + for (var i = 0; i < msgs.length; i++) { + var msg = msgs[i]; + if (!msg || !(msg instanceof Ci.nsIScriptError)) { + continue; + } + + if (msg.category.includes("DOM") && msg.errorMessage.includes("Importing XUL")) { + sawWarning = true; + } + } + + ok(sawWarning == expected, "correct warning condition when " + when); + } + + var browser = document.getElementById("browserelt"); + browser.addEventListener("load", function() { + var doc = browser.contentDocument; + + // We add a <video> element, which contains anonymous XUL content. This should not warn. + var video = doc.createElement("video"); + expectWarning(false, "appending video", function() { + doc.documentElement.appendChild(video); + // Force a layout flush to make sure the anonymous content is added. + // eslint-disable-next-line no-unused-vars + let dummy = doc.documentElement.offsetLeft; + }); + + // We add some XUL to a content document. This should generate a warning. + var elt = document.createXULElement("scrollbar"); + var newElt = doc.importNode(elt, false); + expectWarning(true, "appending XUL", function() { + doc.documentElement.appendChild(newElt); + }); + + SimpleTest.finish(); + }); + + ]]> + </script> +</window> diff --git a/dom/xul/test/test_xul_tabindex_focus.xhtml b/dom/xul/test/test_xul_tabindex_focus.xhtml new file mode 100644 index 0000000000..1363d9b1e1 --- /dev/null +++ b/dom/xul/test/test_xul_tabindex_focus.xhtml @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1128054 +--> +<window title="Mozilla Bug 1128054" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<body> +<!-- Test default focusability --> +<label></label> +<!-- Test tabindex=0 focusability --> +<label tabindex="0"></label> +<!-- Test tabindex=-1 focusability --> +<label tabindex="-1"></label> +<!-- Test tabindex=invalid focusability --> +<label tabindex="invalid"></label> +<!-- Tests code --> +<script type="application/javascript"> +<![CDATA[ + +/** Test for Bug 1128054 **/ + +add_task(function test_xul_tabindex_focus() { + for (let element of document.querySelectorAll("label")) { + let desc = "xul element"; + let focusable = false; + if (element.hasAttribute("tabindex")) { + let attr = element.getAttribute("tabindex"); + focusable = Number.isInteger(Number.parseInt(attr)); + desc += ` with tabindex=${attr}`; + } + + element.focus(); + focusable ? is(document.activeElement, element, desc + " should focusable") + : isnot(document.activeElement, element, desc + " should not focusable"); + } +}); + +]]> +</script> +</body> +</window> diff --git a/dom/xul/test/window_bug1686822.xhtml b/dom/xul/test/window_bug1686822.xhtml new file mode 100644 index 0000000000..1a2cf25636 --- /dev/null +++ b/dom/xul/test/window_bug1686822.xhtml @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml"> + <html:script type="module"><![CDATA[ + window.opener.moduleScriptRan(); + ]]></html:script> +</window> diff --git a/dom/xul/test/window_bug583948.xhtml b/dom/xul/test/window_bug583948.xhtml new file mode 100644 index 0000000000..d0f6a26926 --- /dev/null +++ b/dom/xul/test/window_bug583948.xhtml @@ -0,0 +1,8 @@ +<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="opener.update()"> + +<command oncommandupdate="document.removeChild(document.documentElement)" commandupdater="true"/> +<box command="c"/> +<iframe/> + +</window> diff --git a/dom/xul/test/window_bug757137.xhtml b/dom/xul/test/window_bug757137.xhtml new file mode 100644 index 0000000000..16f38ef20f --- /dev/null +++ b/dom/xul/test/window_bug757137.xhtml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml"> + <html:iframe id="f" mozbrowser="true" + src="data:text/html;charset=utf-8,%3C!DOCTYPE html>Hi" /> +</window> |