diff options
Diffstat (limited to 'dom/tests/mochitest/whatwg/test_postMessage_special.xhtml')
-rw-r--r-- | dom/tests/mochitest/whatwg/test_postMessage_special.xhtml | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml b/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml new file mode 100644 index 0000000000..deb3930550 --- /dev/null +++ b/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml @@ -0,0 +1,304 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage +--> +<head> + <title>postMessage from about:blank, data URLs</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a> +<p id="display"></p> +<div id="content" style="display: none"></div> + +<pre id="test"> +<script class="testbody" type="application/javascript"><![CDATA[ +/** Test for Bug 387706 **/ + +SimpleTest.waitForExplicitFinish(); + +var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * Encodes an array of bytes into a string using the base 64 encoding scheme. + * + * @param bytes + * An array of bytes to encode. + */ +function b64(str) +{ + var byteArray = new Array(str.length); + for (var i = 0, sz = str.length; i < sz; i++) + byteArray[i] = str.charCodeAt(i); + + var index = 0; + function get3Bytes() + { + if (byteArray.length - index < 3) + return null; // Less than three bytes remaining + + // Return the next three bytes in the array, and increment index for our + // next invocation + return byteArray.slice(index, index += 3); + } + + var out = ""; + var bytes = null; + while ((bytes = get3Bytes())) + { + var bits = 0; + for (var i = 0; i < 3; i++) + bits = (bits << 8) | bytes[i]; + for (var j = 18; j >= 0; j -= 6) + out += B64_CHARS[(bits>>j) & 0x3F]; + } + + // Get the remaining bytes + bytes = byteArray.slice(index); + + switch (bytes.length) + { + case 2: + out += B64_CHARS[(bytes[0]>>2) & 0x3F] + + B64_CHARS[((bytes[0] & 0x03) << 4) | ((bytes[1] >> 4) & 0x0F)] + + B64_CHARS[((bytes[1] & 0x0F) << 2)] + + "="; + break; + case 1: + out += B64_CHARS[(bytes[0]>>2) & 0x3F] + + B64_CHARS[(bytes[0] & 0x03) << 4] + + "=="; + break; + } + + return out; +} + + +var aboutBlankWindow = null; +var aboutBlank2Window = null; +var dataWindow = null; + +/** Convert a nullable string to a pretty representation */ +function sourceify(v) +{ + if (typeof v == "string") + return "'" + v + "'"; + return String(v); +} + +/** Receives MessageEvents to this window. */ +function messageReceiver(evt) +{ + // It's not clear what the security model is for data: URLs and whether they + // can access their parents; WebKit denies access, while Gecko currently + // allows it. We work around this problem by using postMessage (surprise!) + // to start the round of tests when each iframe loads. + if (evt.data === "next-test") + { + setTimeout(nextTest, 0); + return; + } + + + try + { + ok(evt instanceof MessageEvent, "umm, how did we get this?"); + is(evt.type, "message", "expected events of type 'message'"); + ok(evt.isTrusted === true, "should have been a trusted event"); + + if (evt.data === "about:blank-response") + { + // This isn't clarified in HTML5 yet, but the origin for a document which + // has been open()ed is the origin of the calling code, somewhat loosely + // speaking. For the specific case of about:blank it's also possible + // that the origin is determined by the code that opens the window. It's + // not codified yet which of these two causes the identifier tokens on + // the event generated by the new window to be those of this window, but + // in either case this is what they should be. + is(evt.origin, "http://mochi.test:8888", + "wrong origin for event from about:blank"); + is(evt.source, aboutBlankWindow, "wrong source"); + + // ...and onto the next test + setupBlank2(); + } + else if (evt.data === "about:blank2-response") + { + is(evt.origin, "http://mochi.test:8888", + "wrong origin for event from about:blank #2"); + is(evt.source, aboutBlank2Window, "wrong source"); + + setupData(); + } + else if (evt.data === "data-response") + { + is(evt.origin, "null", + "wrong origin for event from data URL (should be the origin of the " + + "window/script that opened the URL, in this case the origin of this " + + "file)"); + is(evt.source, dataWindow, "wrong source"); + + finish(); + } + else + { + ok(false, "unexpected message: " + evt.data); + } + } + catch (e) + { + ok(false, "error processing event with data '" + evt.data + "': " + e); + } +} + +function getContents(description, responseText) +{ + var contents = + "<!DOCTYPE html>\n" + + "<html>\n" + + "<head>\n" + + " <title>about:blank</title>\n" + + " <script type='application/javascript'>\n" + + "function receive(evt)\n" + + "{\n" + + " var response = '" + responseText + "';\n" + + "\n" + + " if (evt.source !== window.parent)\n" + + " response += ' wrong-source';\n" + + " if (evt.origin !== 'http://mochi.test:8888')\n" + + " response += ' wrong-origin(' + evt.origin + ')';\n" + + " if (evt.data !== 'from-opener')\n" + + " response += ' wrong-data(' + evt.data + ')';\n" + + "\n" + + " window.parent.postMessage(response, 'http://mochi.test:8888');\n" + + "}\n" + + "\n" + + "function ready()\n" + + "{\n" + + " window.parent.postMessage('next-test', 'http://mochi.test:8888');\n" + + "}\n" + + "\n" + + "window.addEventListener('load', ready, false);\n" + + "window.addEventListener('message', receive, false);\n" + + " </script>\n" + + "</head>\n" + + "<body><p>" + description + "</p></body>\n" + + "</html>"; + + return contents; +} + +function finish() +{ + SimpleTest.finish(); +} + +var xhtmlns = "http://www.w3.org/1999/xhtml"; + +function insert(el) +{ + var content = $("content"); + content.parentNode.insertBefore(el, content); +} + +function setupBlank() +{ + var aboutBlankFrame = document.createElementNS(xhtmlns, "iframe"); + aboutBlankFrame.setAttribute("src", "about:blank"); + insert(aboutBlankFrame); + + aboutBlankWindow = aboutBlankFrame.contentWindow; + var doc = aboutBlankWindow.document; + doc.open(); + doc.write(getContents("This was about:blank #1", "about:blank-response")); + doc.close(); + + // I don't believe anything guarantees sync parsing, so we have to wait for + // the new window to poke us to actually do the test. :-\ +} + +function setupBlank2() +{ + var aboutBlank2Frame = document.createElementNS(xhtmlns, "iframe"); + aboutBlank2Frame.addEventListener("load", nextTest); + aboutBlank2Frame.setAttribute("src", "about:blank"); + + insert(aboutBlank2Frame); +} + +// Could use window.btoa here, but that's not standardized, and we want to be +// able to run these tests against browsers that don't support it. +var dataURI = "data:text/html;base64," + + b64(getContents("A data: URL", "data-response")); + +function setupData() +{ + var dataFrame = document.createElementNS(xhtmlns, "iframe"); + dataFrame.setAttribute("src", dataURI); + insert(dataFrame); + + dataWindow = dataFrame.contentWindow; + + // ...and wait again for the window to load... +} + +var count = 0; +function nextTest() +{ + switch (count++) + { + case 0: + testBlank(); + break; + + case 1: + testBlank2(); + break; + + case 2: + testData(); + break; + + default: + ok(false, "unreached"); + break; + } +} + +function testBlank() +{ + aboutBlankWindow.postMessage("from-opener", "http://mochi.test:8888"); +} + +function testBlank2() +{ + // For some reason we can't access this across browsers prior to the iframe + // loading, so set its value here. + aboutBlank2Window = window.frames[1]; + + var doc = aboutBlank2Window.document; + + doc.body.textContent = "This was about:blank #2"; + + var script = doc.createElement("script"); + script.textContent = + "window.parent.postMessage('about:blank2-response', " + + " 'http://mochi.test:8888');"; + doc.body.appendChild(script); +} + +function testData() +{ + dataWindow.postMessage("from-opener", "*"); +} + +window.addEventListener("message", messageReceiver); + +addLoadEvent(setupBlank); +]]></script> +</pre> +</body> +</html> |