dom/tests/mochitest/whatwg/test_postMessage_special.xhtml

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,311 @@
     1.4 +<!DOCTYPE html>
     1.5 +<html xmlns="http://www.w3.org/1999/xhtml">
     1.6 +<!--
     1.7 +https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
     1.8 +-->
     1.9 +<head>
    1.10 +  <title>postMessage from about:blank, data URLs</title>
    1.11 +  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
    1.12 +  <script type="text/javascript" src="browserFu.js"></script>
    1.13 +  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
    1.14 +</head>
    1.15 +<body>
    1.16 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
    1.17 +<p id="display"></p>
    1.18 +<div id="content" style="display: none"></div>
    1.19 +
    1.20 +<pre id="test">
    1.21 +<script class="testbody" type="application/javascript"><![CDATA[
    1.22 +/** Test for Bug 387706 **/
    1.23 +
    1.24 +SimpleTest.waitForExplicitFinish();
    1.25 +
    1.26 +var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    1.27 +
    1.28 +/**
    1.29 + * Encodes an array of bytes into a string using the base 64 encoding scheme.
    1.30 + *
    1.31 + * @param bytes
    1.32 + *   An array of bytes to encode.
    1.33 + */
    1.34 +function b64(str)
    1.35 +{
    1.36 +  var byteArray = new Array(str.length);
    1.37 +  for (var i = 0, sz = str.length; i < sz; i++)
    1.38 +    byteArray[i] = str.charCodeAt(i);
    1.39 +
    1.40 +  var index = 0;
    1.41 +  function get3Bytes()
    1.42 +  {
    1.43 +    if (byteArray.length - index < 3)
    1.44 +      return null; // Less than three bytes remaining
    1.45 +
    1.46 +    // Return the next three bytes in the array, and increment index for our
    1.47 +    // next invocation
    1.48 +    return byteArray.slice(index, index += 3);
    1.49 +  }
    1.50 +
    1.51 +  var out = "";
    1.52 +  var bytes = null;
    1.53 +  while ((bytes = get3Bytes()))
    1.54 +  {
    1.55 +    var bits = 0;
    1.56 +    for (var i = 0; i < 3; i++)
    1.57 +      bits = (bits << 8) | bytes[i];
    1.58 +    for (var j = 18; j >= 0; j -= 6)
    1.59 +      out += B64_CHARS[(bits>>j) & 0x3F];
    1.60 +  }
    1.61 +
    1.62 +  // Get the remaining bytes
    1.63 +  bytes = byteArray.slice(index);
    1.64 +
    1.65 +  switch (bytes.length)
    1.66 +  {
    1.67 +    case 2:
    1.68 +      out += B64_CHARS[(bytes[0]>>2) & 0x3F] +
    1.69 +             B64_CHARS[((bytes[0] & 0x03) << 4) | ((bytes[1] >> 4) & 0x0F)] +
    1.70 +             B64_CHARS[((bytes[1] & 0x0F) << 2)] +
    1.71 +             "=";
    1.72 +      break;
    1.73 +    case 1:
    1.74 +      out += B64_CHARS[(bytes[0]>>2) & 0x3F] +
    1.75 +             B64_CHARS[(bytes[0] & 0x03) << 4] +
    1.76 +             "==";
    1.77 +      break;
    1.78 +  }
    1.79 +
    1.80 +  return out;
    1.81 +}
    1.82 +
    1.83 +
    1.84 +var aboutBlankWindow = null;
    1.85 +var aboutBlank2Window = null;
    1.86 +var dataWindow = null;
    1.87 +
    1.88 +/** Convert a nullable string to a pretty representation */
    1.89 +function sourceify(v)
    1.90 +{
    1.91 +  if (typeof v == "string")
    1.92 +    return "'" + v + "'";
    1.93 +  return String(v);
    1.94 +}
    1.95 +
    1.96 +/** Receives MessageEvents to this window. */
    1.97 +function messageReceiver(evt)
    1.98 +{
    1.99 +  // It's not clear what the security model is for data: URLs and whether they
   1.100 +  // can access their parents; WebKit denies access, while Gecko currently
   1.101 +  // allows it.  We work around this problem by using postMessage (surprise!)
   1.102 +  // to start the round of tests when each iframe loads.
   1.103 +  if (evt.data === "next-test")
   1.104 +  {
   1.105 +    setTimeout(nextTest, 0);
   1.106 +    return;
   1.107 +  }
   1.108 +
   1.109 +
   1.110 +  try
   1.111 +  {
   1.112 +    ok(evt instanceof MessageEvent, "umm, how did we get this?");
   1.113 +    is(evt.type, "message", "expected events of type 'message'");
   1.114 +  
   1.115 +    if (isMozilla)
   1.116 +    {
   1.117 +      ok(evt.isTrusted === false, "shouldn't have been a trusted event");
   1.118 +    }
   1.119 +  
   1.120 +    if (evt.data === "about:blank-response")
   1.121 +    {
   1.122 +      // This isn't clarified in HTML5 yet, but the origin for a document which
   1.123 +      // has been open()ed is the origin of the calling code, somewhat loosely
   1.124 +      // speaking.  For the specific case of about:blank it's also possible
   1.125 +      // that the origin is determined by the code that opens the window.  It's
   1.126 +      // not codified yet which of these two causes the identifier tokens on
   1.127 +      // the event generated by the new window to be those of this window, but
   1.128 +      // in either case this is what they should be.
   1.129 +      is(evt.origin, "http://mochi.test:8888",
   1.130 +         "wrong origin for event from about:blank");
   1.131 +      is(evt.source, aboutBlankWindow, "wrong source");
   1.132 +
   1.133 +      // ...and onto the next test
   1.134 +      setupBlank2();
   1.135 +    }
   1.136 +    else if (evt.data === "about:blank2-response")
   1.137 +    {
   1.138 +      is(evt.origin, "http://mochi.test:8888",
   1.139 +         "wrong origin for event from about:blank #2");
   1.140 +      is(evt.source, aboutBlank2Window, "wrong source");
   1.141 +
   1.142 +      setupData();
   1.143 +    }
   1.144 +    else if (evt.data === "data-response")
   1.145 +    {
   1.146 +      // HTML5 defines the origin of a data: URI as the origin of the window or
   1.147 +      // script that opened the data: URI.
   1.148 +      is(evt.origin, "http://mochi.test:8888",
   1.149 +         "wrong origin for event from data URL (should be the origin of the " +
   1.150 +         "window/script that opened the URL, in this case the origin of this " +
   1.151 +         "file)");
   1.152 +      is(evt.source, dataWindow, "wrong source");
   1.153 +
   1.154 +      finish();
   1.155 +    }
   1.156 +    else
   1.157 +    {
   1.158 +      ok(false, "unexpected message: " + evt.data);
   1.159 +    }
   1.160 +  }
   1.161 +  catch (e)
   1.162 +  {
   1.163 +    ok(false, "error processing event with data '" + evt.data + "': " + e);
   1.164 +  }
   1.165 +}
   1.166 +
   1.167 +function getContents(description, responseText)
   1.168 +{
   1.169 +  var contents =
   1.170 +    "<!DOCTYPE html>\n" +
   1.171 +    "<html>\n" +
   1.172 +    "<head>\n" + 
   1.173 +    "  <title>about:blank</title>\n" +
   1.174 +    "  <script type='application/javascript'>\n" +
   1.175 +    "function receive(evt)\n" +
   1.176 +    "{\n" +
   1.177 +    "  var response = '" + responseText + "';\n" +
   1.178 +    "\n" +
   1.179 +    "  if (evt.source !== window.parent)\n" +
   1.180 +    "    response += ' wrong-source';\n" +
   1.181 +    "  if (evt.origin !== 'http://mochi.test:8888')\n" +
   1.182 +    "    response += ' wrong-origin(' + evt.origin + ')';\n" +
   1.183 +    "  if (evt.data !== 'from-opener')\n" +
   1.184 +    "    response += ' wrong-data(' + evt.data + ')';\n" +
   1.185 +    "\n" +
   1.186 +    "  window.parent.postMessage(response, 'http://mochi.test:8888');\n" +
   1.187 +    "}\n" +
   1.188 +    "\n" +
   1.189 +    "function ready()\n" +
   1.190 +    "{\n" +
   1.191 +    "  window.parent.postMessage('next-test', 'http://mochi.test:8888');\n" +
   1.192 +    "}\n" +
   1.193 +    "\n" +
   1.194 +    "window.addEventListener('load', ready, false);\n" +
   1.195 +    "window.addEventListener('message', receive, false);\n" +
   1.196 +    "  </script>\n" +
   1.197 +    "</head>\n" +
   1.198 +    "<body><p>" + description + "</p></body>\n" +
   1.199 +    "</html>";
   1.200 +
   1.201 +  return contents;
   1.202 +}
   1.203 +
   1.204 +function finish()
   1.205 +{
   1.206 +  SimpleTest.finish();
   1.207 +}
   1.208 +
   1.209 +var xhtmlns = "http://www.w3.org/1999/xhtml";
   1.210 +
   1.211 +function insert(el)
   1.212 +{
   1.213 +  var content = $("content");
   1.214 +  content.parentNode.insertBefore(el, content);
   1.215 +}
   1.216 +
   1.217 +function setupBlank()
   1.218 +{
   1.219 +  var aboutBlankFrame = document.createElementNS(xhtmlns, "iframe");
   1.220 +  aboutBlankFrame.setAttribute("src", "about:blank");
   1.221 +  insert(aboutBlankFrame);
   1.222 +
   1.223 +  aboutBlankWindow = aboutBlankFrame.contentWindow;
   1.224 +  var doc = aboutBlankWindow.document;
   1.225 +  doc.open();
   1.226 +  doc.write(getContents("This was about:blank #1", "about:blank-response"));
   1.227 +  doc.close();
   1.228 +
   1.229 +  // I don't believe anything guarantees sync parsing, so we have to wait for
   1.230 +  // the new window to poke us to actually do the test.  :-\
   1.231 +}
   1.232 +
   1.233 +function setupBlank2()
   1.234 +{
   1.235 +  var aboutBlank2Frame = document.createElementNS(xhtmlns, "iframe");
   1.236 +  aboutBlank2Frame.addEventListener("load", nextTest, false);
   1.237 +  aboutBlank2Frame.setAttribute("src", "about:blank");
   1.238 +
   1.239 +  insert(aboutBlank2Frame);
   1.240 +}
   1.241 +
   1.242 +// Could use window.btoa here, but that's not standardized, and we want to be
   1.243 +// able to run these tests against browsers that don't support it.
   1.244 +var dataURI = "data:text/html;base64," +
   1.245 +              b64(getContents("A data: URL", "data-response"));
   1.246 +
   1.247 +function setupData()
   1.248 +{
   1.249 +  var dataFrame = document.createElementNS(xhtmlns, "iframe");
   1.250 +  dataFrame.setAttribute("src", dataURI);
   1.251 +  insert(dataFrame);
   1.252 +
   1.253 +  dataWindow = dataFrame.contentWindow;
   1.254 +
   1.255 +  // ...and wait again for the window to load...
   1.256 +}
   1.257 +
   1.258 +var count = 0;
   1.259 +function nextTest()
   1.260 +{
   1.261 +  switch (count++)
   1.262 +  {
   1.263 +    case 0:
   1.264 +      testBlank();
   1.265 +      break;
   1.266 +
   1.267 +    case 1:
   1.268 +      testBlank2();
   1.269 +      break;
   1.270 +
   1.271 +    case 2:
   1.272 +      testData();
   1.273 +      break;
   1.274 +
   1.275 +    default:
   1.276 +      ok(false, "unreached");
   1.277 +      break;
   1.278 +  }
   1.279 +}
   1.280 +
   1.281 +function testBlank()
   1.282 +{
   1.283 +  aboutBlankWindow.postMessage("from-opener", "http://mochi.test:8888");
   1.284 +}
   1.285 +
   1.286 +function testBlank2()
   1.287 +{
   1.288 +  // For some reason we can't access this across browsers prior to the iframe
   1.289 +  // loading, so set its value here.
   1.290 +  aboutBlank2Window = window.frames[1];
   1.291 +
   1.292 +  var doc = aboutBlank2Window.document;
   1.293 +
   1.294 +  doc.body.textContent = "This was about:blank #2";
   1.295 +
   1.296 +  var script = doc.createElement("script");
   1.297 +  script.textContent =
   1.298 +    "window.parent.postMessage('about:blank2-response', " +
   1.299 +    "                          'http://mochi.test:8888');";
   1.300 +  doc.body.appendChild(script);
   1.301 +}
   1.302 +
   1.303 +function testData()
   1.304 +{
   1.305 +  dataWindow.postMessage("from-opener", "http://mochi.test:8888");
   1.306 +}
   1.307 +
   1.308 +window.addEventListener("message", messageReceiver, false);
   1.309 +
   1.310 +addLoadEvent(setupBlank);
   1.311 +]]></script>
   1.312 +</pre>
   1.313 +</body>
   1.314 +</html>

mercurial