tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

file_bug1326251.html (10618B)


      1 <!DOCTYPE html>
      2 <html lang="en">
      3  <head>
      4    <meta charset="utf-8">
      5    <title>Bug 1326251</title>
      6    <script>
      7    var bc = new BroadcastChannel("file_bug1326251");
      8    bc.onmessage = function(event) {
      9      if ("nextTest" in event.data) {
     10        testSteps[event.data.nextTest]();
     11      }
     12    }
     13 
     14    function is(val1, val2, msg) {
     15      bc.postMessage({type: "is", value1: val1, value2: val2, message: msg});
     16    }
     17 
     18    function ok(val, msg) {
     19      bc.postMessage({type: "ok", value: val, message: msg});
     20    }
     21 
     22    const BASE_URL = "http://mochi.test:8888/tests/docshell/test/navigation/";
     23    let testSteps = [
     24      async function() {
     25        // Test 1: Create dynamic iframe with bfcache enabled.
     26        // Navigate static / dynamic iframes, then navigate top level window
     27        // and navigate back. Both iframes should still exist with history
     28        // entries preserved.
     29        window.onunload = null; // enable bfcache
     30        await createDynamicFrame(document);
     31        await loadUriInFrame(document.getElementById("staticFrame"), "frame1.html");
     32        await loadUriInFrame(document.getElementById("dynamicFrame"), "frame1.html");
     33        await loadUriInFrame(document.getElementById("staticFrame"), "frame2.html");
     34        await loadUriInFrame(document.getElementById("dynamicFrame"), "frame2.html");
     35        is(history.length, 5, "history.length");
     36        window.location = "goback.html";
     37      },
     38      async function() {
     39        let webNav = SpecialPowers.wrap(window)
     40                       .docShell
     41                       .QueryInterface(SpecialPowers.Ci.nsIWebNavigation);
     42        let shistory = webNav.sessionHistory;
     43        is(webNav.canGoForward, true, "canGoForward");
     44        is(shistory.index, 4, "shistory.index");
     45        is(history.length, 6, "history.length");
     46        is(document.getElementById("staticFrame").contentWindow.location.href, BASE_URL + "frame2.html", "staticFrame location");
     47        is(document.getElementById("dynamicFrame").contentWindow.location.href, BASE_URL + "frame2.html", "dynamicFrame location");
     48 
     49        // Test 2: Load another page in dynamic iframe, canGoForward should be
     50        // false.
     51        await loadUriInFrame(document.getElementById("dynamicFrame"), "frame3.html");
     52        is(webNav.canGoForward, false, "canGoForward");
     53        is(shistory.index, 5, "shistory.index");
     54        is(history.length, 6, "history.length");
     55 
     56        // Test 3: Navigate to antoher page with bfcache disabled, all dynamic
     57        // iframe entries should be removed.
     58        window.onunload = function() {}; // disable bfcache
     59        window.location = "goback.html";
     60      },
     61      async function() {
     62        let windowWrap = SpecialPowers.wrap(window);
     63        let docShell = windowWrap.docShell;
     64        let shistory = docShell.QueryInterface(SpecialPowers.Ci.nsIWebNavigation)
     65                               .sessionHistory;
     66        // Now staticFrame has frame0 -> frame1 -> frame2.
     67        if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) {
     68          // *EntryIndex attributes aren't meaningful when the session history
     69          // lives in the parent process.
     70          is(docShell.previousEntryIndex, 3, "docShell.previousEntryIndex");
     71          is(docShell.loadedEntryIndex, 2, "docShell.loadedEntryIndex");
     72        }
     73        is(shistory.index, 2, "shistory.index");
     74        is(history.length, 4, "history.length");
     75        is(document.getElementById("staticFrame").contentWindow.location.href, BASE_URL + "frame2.html", "staticFrame location");
     76        ok(!document.getElementById("dynamicFrame"), "dynamicFrame should not exist");
     77 
     78        // Test 4: Load a nested frame in the static frame, navigate the inner
     79        // static frame, add a inner dynamic frame and navigate the dynamic
     80        // frame. Then navigate the outer static frame and go back. The inner
     81        // iframe should show the last entry of inner static frame.
     82        let staticFrame = document.getElementById("staticFrame");
     83        staticFrame.width = "320px";
     84        staticFrame.height = "360px";
     85        await loadUriInFrame(staticFrame, "iframe_static.html");
     86        let innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame");
     87        await loadUriInFrame(innerStaticFrame, "frame1.html");
     88        let innerDynamicFrame = await createDynamicFrame(staticFrame.contentDocument, "frame2.html");
     89        await loadUriInFrame(innerDynamicFrame, "frame3.html");
     90        // staticFrame:       frame0 -> frame1 -> frame2 -> iframe_static
     91        // innerStaticFrame:                                frame0        -> frame1
     92        // innerDynamicFrame:                                                frame2 -> frame3
     93        is(shistory.index, 5, "shistory.index");
     94        is(history.length, 6, "history.length");
     95 
     96        // Wait for 2 load events - navigation and goback.
     97        let onloadPromise = awaitOnload(staticFrame, 2);
     98        await loadUriInFrame(staticFrame, "goback.html");
     99        await onloadPromise;
    100        // staticFrame:       frame0 -> frame1 -> frame2 -> iframe_static           -> goback
    101        // innerStaticFrame:                                frame0        -> frame1
    102        is(shistory.index, 4, "shistory.index");
    103        is(history.length, 6, "history.length");
    104        innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame");
    105        is(innerStaticFrame.contentDocument.location.href, BASE_URL + "frame1.html", "innerStaticFrame location");
    106        ok(!staticFrame.contentDocument.getElementById("dynamicFrame"), "innerDynamicFrame should not exist");
    107 
    108        // Test 5: Insert and navigate inner dynamic frame again with bfcache
    109        // enabled, and navigate top level window to a special page which will
    110        // evict bfcache then goback. Verify that dynamic entries are correctly
    111        // removed in this case.
    112        window.onunload = null; // enable bfcache
    113        staticFrame.width = "320px";
    114        staticFrame.height = "360px";
    115        innerDynamicFrame = await createDynamicFrame(staticFrame.contentDocument, "frame2.html");
    116        await loadUriInFrame(innerDynamicFrame, "frame3.html");
    117        // staticFrame:       frame0 -> frame1 -> frame2 -> iframe_static
    118        // innerStaticFrame:                                frame0        -> frame1
    119        // innerDynamicFrame:                                                frame2 -> frame3
    120        is(shistory.index, 5, "shistory.index");
    121        is(history.length, 6, "history.length");
    122        window.location = "file_bug1326251_evict_cache.html";
    123      },
    124      async function() {
    125        let windowWrap = SpecialPowers.wrap(window);
    126        let docShell = windowWrap.docShell;
    127        let shistory = docShell.QueryInterface(SpecialPowers.Ci.nsIWebNavigation)
    128                               .sessionHistory;
    129        // staticFrame:       frame0 -> frame1 -> frame2 -> iframe_static
    130        // innerStaticFrame:                                frame0        -> frame1
    131        if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) {
    132          // *EntryIndex attributes aren't meaningful when the session history
    133          // lives in the parent process.
    134          is(docShell.previousEntryIndex, 5, "docShell.previousEntryIndex");
    135          is(docShell.loadedEntryIndex, 4, "docShell.loadedEntryIndex");
    136        }
    137        is(shistory.index, 4, "shistory.index");
    138        is(history.length, 6, "history.length");
    139        let staticFrame = document.getElementById("staticFrame");
    140        let innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame");
    141        is(innerStaticFrame.contentDocument.location.href, BASE_URL + "frame1.html", "innerStaticFrame location");
    142        ok(!staticFrame.contentDocument.getElementById("dynamicFrame"), "innerDynamicFrame should not exist");
    143 
    144        // Test 6: Insert and navigate inner dynamic frame and then reload outer
    145        // frame. Verify that inner dynamic frame entries are all removed.
    146        staticFrame.width = "320px";
    147        staticFrame.height = "360px";
    148        let innerDynamicFrame = await createDynamicFrame(staticFrame.contentDocument, "frame2.html");
    149        await loadUriInFrame(innerDynamicFrame, "frame3.html");
    150        // staticFrame:       frame0 -> frame1 -> frame2 -> iframe_static
    151        // innerStaticFrame:                                frame0        -> frame1
    152        // innerDynamicFrame:                                                frame2 -> frame3
    153        is(shistory.index, 5, "shistory.index");
    154        is(history.length, 6, "history.length");
    155        let staticFrameLoadPromise = new Promise(resolve => {
    156          staticFrame.onload = resolve;
    157        });
    158        staticFrame.contentWindow.location.reload();
    159        await staticFrameLoadPromise;
    160        // staticFrame:       frame0 -> frame1 -> frame2 -> iframe_static
    161        // innerStaticFrame:                                frame0        -> frame1
    162        is(shistory.index, 4, "shistory.index");
    163        is(history.length, 5, "history.length");
    164        innerStaticFrame = staticFrame.contentDocument.getElementById("staticFrame");
    165        is(innerStaticFrame.contentDocument.location.href, BASE_URL + "frame1.html", "innerStaticFrame location");
    166        ok(!staticFrame.contentDocument.getElementById("dynamicFrame"), "innerDynamicFrame should not exist");
    167        bc.postMessage("finishTest");
    168        bc.close();
    169        window.close();
    170      },
    171    ];
    172 
    173    function awaitOnload(frame, occurances = 1) {
    174      return new Promise(function(resolve) {
    175        let count = 0;
    176        frame.addEventListener("load", function listener() {
    177          if (++count == occurances) {
    178            frame.removeEventListener("load", listener);
    179            setTimeout(resolve, 0);
    180          }
    181        });
    182      });
    183    }
    184 
    185    async function createDynamicFrame(targetDocument, frameSrc = "frame0.html") {
    186      let dynamicFrame = targetDocument.createElement("iframe");
    187      let onloadPromise = awaitOnload(dynamicFrame);
    188      dynamicFrame.id = "dynamicFrame";
    189      dynamicFrame.src = frameSrc;
    190      let container = targetDocument.getElementById("frameContainer");
    191      container.appendChild(dynamicFrame);
    192      await onloadPromise;
    193      return dynamicFrame;
    194    }
    195 
    196    async function loadUriInFrame(frame, uri) {
    197      let onloadPromise = awaitOnload(frame);
    198      frame.src = uri;
    199      return onloadPromise;
    200    }
    201 
    202    function test() {
    203      bc.postMessage("requestNextTest");
    204    }
    205    </script>
    206  </head>
    207  <body onpageshow="test();">
    208    <div id="frameContainer">
    209      <iframe id="staticFrame" src="frame0.html"></iframe>
    210    </div>
    211  </body>
    212 </html>