dom/tests/mochitest/whatwg/test_postMessage_special.xhtml

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 <!DOCTYPE html>
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <!--
     4 https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage
     5 -->
     6 <head>
     7   <title>postMessage from about:blank, data URLs</title>
     8   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
     9   <script type="text/javascript" src="browserFu.js"></script>
    10   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
    11 </head>
    12 <body>
    13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=postMessage">Mozilla Bug 387706</a>
    14 <p id="display"></p>
    15 <div id="content" style="display: none"></div>
    17 <pre id="test">
    18 <script class="testbody" type="application/javascript"><![CDATA[
    19 /** Test for Bug 387706 **/
    21 SimpleTest.waitForExplicitFinish();
    23 var B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    25 /**
    26  * Encodes an array of bytes into a string using the base 64 encoding scheme.
    27  *
    28  * @param bytes
    29  *   An array of bytes to encode.
    30  */
    31 function b64(str)
    32 {
    33   var byteArray = new Array(str.length);
    34   for (var i = 0, sz = str.length; i < sz; i++)
    35     byteArray[i] = str.charCodeAt(i);
    37   var index = 0;
    38   function get3Bytes()
    39   {
    40     if (byteArray.length - index < 3)
    41       return null; // Less than three bytes remaining
    43     // Return the next three bytes in the array, and increment index for our
    44     // next invocation
    45     return byteArray.slice(index, index += 3);
    46   }
    48   var out = "";
    49   var bytes = null;
    50   while ((bytes = get3Bytes()))
    51   {
    52     var bits = 0;
    53     for (var i = 0; i < 3; i++)
    54       bits = (bits << 8) | bytes[i];
    55     for (var j = 18; j >= 0; j -= 6)
    56       out += B64_CHARS[(bits>>j) & 0x3F];
    57   }
    59   // Get the remaining bytes
    60   bytes = byteArray.slice(index);
    62   switch (bytes.length)
    63   {
    64     case 2:
    65       out += B64_CHARS[(bytes[0]>>2) & 0x3F] +
    66              B64_CHARS[((bytes[0] & 0x03) << 4) | ((bytes[1] >> 4) & 0x0F)] +
    67              B64_CHARS[((bytes[1] & 0x0F) << 2)] +
    68              "=";
    69       break;
    70     case 1:
    71       out += B64_CHARS[(bytes[0]>>2) & 0x3F] +
    72              B64_CHARS[(bytes[0] & 0x03) << 4] +
    73              "==";
    74       break;
    75   }
    77   return out;
    78 }
    81 var aboutBlankWindow = null;
    82 var aboutBlank2Window = null;
    83 var dataWindow = null;
    85 /** Convert a nullable string to a pretty representation */
    86 function sourceify(v)
    87 {
    88   if (typeof v == "string")
    89     return "'" + v + "'";
    90   return String(v);
    91 }
    93 /** Receives MessageEvents to this window. */
    94 function messageReceiver(evt)
    95 {
    96   // It's not clear what the security model is for data: URLs and whether they
    97   // can access their parents; WebKit denies access, while Gecko currently
    98   // allows it.  We work around this problem by using postMessage (surprise!)
    99   // to start the round of tests when each iframe loads.
   100   if (evt.data === "next-test")
   101   {
   102     setTimeout(nextTest, 0);
   103     return;
   104   }
   107   try
   108   {
   109     ok(evt instanceof MessageEvent, "umm, how did we get this?");
   110     is(evt.type, "message", "expected events of type 'message'");
   112     if (isMozilla)
   113     {
   114       ok(evt.isTrusted === false, "shouldn't have been a trusted event");
   115     }
   117     if (evt.data === "about:blank-response")
   118     {
   119       // This isn't clarified in HTML5 yet, but the origin for a document which
   120       // has been open()ed is the origin of the calling code, somewhat loosely
   121       // speaking.  For the specific case of about:blank it's also possible
   122       // that the origin is determined by the code that opens the window.  It's
   123       // not codified yet which of these two causes the identifier tokens on
   124       // the event generated by the new window to be those of this window, but
   125       // in either case this is what they should be.
   126       is(evt.origin, "http://mochi.test:8888",
   127          "wrong origin for event from about:blank");
   128       is(evt.source, aboutBlankWindow, "wrong source");
   130       // ...and onto the next test
   131       setupBlank2();
   132     }
   133     else if (evt.data === "about:blank2-response")
   134     {
   135       is(evt.origin, "http://mochi.test:8888",
   136          "wrong origin for event from about:blank #2");
   137       is(evt.source, aboutBlank2Window, "wrong source");
   139       setupData();
   140     }
   141     else if (evt.data === "data-response")
   142     {
   143       // HTML5 defines the origin of a data: URI as the origin of the window or
   144       // script that opened the data: URI.
   145       is(evt.origin, "http://mochi.test:8888",
   146          "wrong origin for event from data URL (should be the origin of the " +
   147          "window/script that opened the URL, in this case the origin of this " +
   148          "file)");
   149       is(evt.source, dataWindow, "wrong source");
   151       finish();
   152     }
   153     else
   154     {
   155       ok(false, "unexpected message: " + evt.data);
   156     }
   157   }
   158   catch (e)
   159   {
   160     ok(false, "error processing event with data '" + evt.data + "': " + e);
   161   }
   162 }
   164 function getContents(description, responseText)
   165 {
   166   var contents =
   167     "<!DOCTYPE html>\n" +
   168     "<html>\n" +
   169     "<head>\n" + 
   170     "  <title>about:blank</title>\n" +
   171     "  <script type='application/javascript'>\n" +
   172     "function receive(evt)\n" +
   173     "{\n" +
   174     "  var response = '" + responseText + "';\n" +
   175     "\n" +
   176     "  if (evt.source !== window.parent)\n" +
   177     "    response += ' wrong-source';\n" +
   178     "  if (evt.origin !== 'http://mochi.test:8888')\n" +
   179     "    response += ' wrong-origin(' + evt.origin + ')';\n" +
   180     "  if (evt.data !== 'from-opener')\n" +
   181     "    response += ' wrong-data(' + evt.data + ')';\n" +
   182     "\n" +
   183     "  window.parent.postMessage(response, 'http://mochi.test:8888');\n" +
   184     "}\n" +
   185     "\n" +
   186     "function ready()\n" +
   187     "{\n" +
   188     "  window.parent.postMessage('next-test', 'http://mochi.test:8888');\n" +
   189     "}\n" +
   190     "\n" +
   191     "window.addEventListener('load', ready, false);\n" +
   192     "window.addEventListener('message', receive, false);\n" +
   193     "  </script>\n" +
   194     "</head>\n" +
   195     "<body><p>" + description + "</p></body>\n" +
   196     "</html>";
   198   return contents;
   199 }
   201 function finish()
   202 {
   203   SimpleTest.finish();
   204 }
   206 var xhtmlns = "http://www.w3.org/1999/xhtml";
   208 function insert(el)
   209 {
   210   var content = $("content");
   211   content.parentNode.insertBefore(el, content);
   212 }
   214 function setupBlank()
   215 {
   216   var aboutBlankFrame = document.createElementNS(xhtmlns, "iframe");
   217   aboutBlankFrame.setAttribute("src", "about:blank");
   218   insert(aboutBlankFrame);
   220   aboutBlankWindow = aboutBlankFrame.contentWindow;
   221   var doc = aboutBlankWindow.document;
   222   doc.open();
   223   doc.write(getContents("This was about:blank #1", "about:blank-response"));
   224   doc.close();
   226   // I don't believe anything guarantees sync parsing, so we have to wait for
   227   // the new window to poke us to actually do the test.  :-\
   228 }
   230 function setupBlank2()
   231 {
   232   var aboutBlank2Frame = document.createElementNS(xhtmlns, "iframe");
   233   aboutBlank2Frame.addEventListener("load", nextTest, false);
   234   aboutBlank2Frame.setAttribute("src", "about:blank");
   236   insert(aboutBlank2Frame);
   237 }
   239 // Could use window.btoa here, but that's not standardized, and we want to be
   240 // able to run these tests against browsers that don't support it.
   241 var dataURI = "data:text/html;base64," +
   242               b64(getContents("A data: URL", "data-response"));
   244 function setupData()
   245 {
   246   var dataFrame = document.createElementNS(xhtmlns, "iframe");
   247   dataFrame.setAttribute("src", dataURI);
   248   insert(dataFrame);
   250   dataWindow = dataFrame.contentWindow;
   252   // ...and wait again for the window to load...
   253 }
   255 var count = 0;
   256 function nextTest()
   257 {
   258   switch (count++)
   259   {
   260     case 0:
   261       testBlank();
   262       break;
   264     case 1:
   265       testBlank2();
   266       break;
   268     case 2:
   269       testData();
   270       break;
   272     default:
   273       ok(false, "unreached");
   274       break;
   275   }
   276 }
   278 function testBlank()
   279 {
   280   aboutBlankWindow.postMessage("from-opener", "http://mochi.test:8888");
   281 }
   283 function testBlank2()
   284 {
   285   // For some reason we can't access this across browsers prior to the iframe
   286   // loading, so set its value here.
   287   aboutBlank2Window = window.frames[1];
   289   var doc = aboutBlank2Window.document;
   291   doc.body.textContent = "This was about:blank #2";
   293   var script = doc.createElement("script");
   294   script.textContent =
   295     "window.parent.postMessage('about:blank2-response', " +
   296     "                          'http://mochi.test:8888');";
   297   doc.body.appendChild(script);
   298 }
   300 function testData()
   301 {
   302   dataWindow.postMessage("from-opener", "http://mochi.test:8888");
   303 }
   305 window.addEventListener("message", messageReceiver, false);
   307 addLoadEvent(setupBlank);
   308 ]]></script>
   309 </pre>
   310 </body>
   311 </html>

mercurial