tor-browser

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

cross-origin-tall-subframe.sub.html (1979B)


      1 <!doctype html>
      2 <style>
      3  body { margin: 0 }
      4  .spacer {
      5    height: 5000px;
      6  }
      7  #target {
      8    height: 100px;
      9    background-color: green;
     10  }
     11  #next {
     12    position: absolute;
     13    inset: 0;
     14    width: 100%;
     15    height: 100%;
     16    border: 0;
     17  }
     18  #leaf {
     19    display: none;
     20  }
     21  .leaf #next {
     22    display: none;
     23  }
     24  .leaf #leaf {
     25    display: block;
     26  }
     27 </style>
     28 <iframe id="next" sandbox="allow-scripts"></iframe>
     29 <div id="leaf">
     30  <div class=spacer></div>
     31  <div id="target"></div>
     32 </div>
     33 <script>
     34  const A = "http://{{hosts[alt][]}}:{{ports[http][0]}}";
     35  const B = "http://{{hosts[][]}}:{{ports[http][0]}}";
     36 
     37  const nestingLevel = parseInt(new URL(document.URL).searchParams.get("nest"), 10);
     38 
     39  const isLeaf = nestingLevel == 0;
     40  document.documentElement.classList.toggle("leaf", isLeaf);
     41  if (!isLeaf) {
     42    next.src = `${location.origin == A ? B : A}${location.pathname}?nest=${nestingLevel - 1}`;
     43  }
     44 
     45  window.addEventListener("message", function(e) {
     46    if (e.data.entries) {
     47      // This is a response from another frame, there's another listener that
     48      // will forward it.
     49      return;
     50    }
     51    let port = e.source;
     52    if (!isLeaf) {
     53      function respond(e) {
     54        if (!e.data.entries) {
     55          return;
     56        }
     57        port.postMessage(e.data, "*");
     58        window.removeEventListener("message", respond);
     59      }
     60      window.addEventListener("message", respond);
     61      next.contentWindow.postMessage(e.data, "*");
     62      return;
     63    }
     64    let observer = new IntersectionObserver(function(entries) {
     65      port.postMessage({
     66        entries: entries.map(e => {
     67          return {
     68            isIntersecting: e.isIntersecting,
     69            intersectionRatio: e.intersectionRatio,
     70            intersectionRect: e.intersectionRect,
     71            boundingClientRect: e.boundingClientRect.toJSON(),
     72          }
     73        }),
     74      }, "*")
     75      observer.disconnect();
     76    });
     77    observer.observe(document.getElementById("target"));
     78  });
     79 </script>