tor-browser

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

browser_fullscreen_exit_on_external_protocol.js (6800B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 "use strict";
      4 
      5 SimpleTest.requestCompleteLog();
      6 
      7 requestLongerTimeout(2);
      8 
      9 // Import helpers
     10 Services.scriptloader.loadSubScript(
     11  "chrome://mochitests/content/browser/dom/base/test/fullscreen/fullscreen_helpers.js",
     12  this
     13 );
     14 
     15 add_setup(async function () {
     16  await pushPrefs(
     17    ["test.wait300msAfterTabSwitch", true],
     18    ["full-screen-api.transition-duration.enter", "0 0"],
     19    ["full-screen-api.transition-duration.leave", "0 0"],
     20    ["full-screen-api.allow-trusted-requests-only", false]
     21  );
     22 });
     23 
     24 const { HandlerServiceTestUtils } = ChromeUtils.importESModule(
     25  "resource://testing-common/HandlerServiceTestUtils.sys.mjs"
     26 );
     27 
     28 const gHandlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"].getService(
     29  Ci.nsIHandlerService
     30 );
     31 
     32 const CONTENT = `data:text/html,
     33    <!DOCTYPE html>
     34    <html>
     35        <body>
     36            <button>
     37                <a href="mailto:test@example.com"></a>
     38            </button>
     39        </body>
     40    </html>
     41 `;
     42 
     43 function setupMailHandler() {
     44  let mailHandlerInfo = HandlerServiceTestUtils.getHandlerInfo("mailto");
     45  let gOldMailHandlers = [];
     46 
     47  // Remove extant web handlers because they have icons that
     48  // we fetch from the web, which isn't allowed in tests.
     49  let handlers = mailHandlerInfo.possibleApplicationHandlers;
     50  for (let i = handlers.Count() - 1; i >= 0; i--) {
     51    try {
     52      let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
     53      gOldMailHandlers.push(handler);
     54      // If we get here, this is a web handler app. Remove it:
     55      handlers.removeElementAt(i);
     56    } catch (ex) {}
     57  }
     58 
     59  let previousHandling = mailHandlerInfo.alwaysAskBeforeHandling;
     60  mailHandlerInfo.alwaysAskBeforeHandling = true;
     61 
     62  // Create a dummy web mail handler so we always know the mailto: protocol.
     63  // Without this, the test fails on VMs without a default mailto: handler,
     64  // because no dialog is ever shown, as we ignore subframe navigations to
     65  // protocols that cannot be handled.
     66  let dummy = Cc["@mozilla.org/uriloader/web-handler-app;1"].createInstance(
     67    Ci.nsIWebHandlerApp
     68  );
     69  dummy.name = "Handler 1";
     70  dummy.uriTemplate = "https://example.com/first/%s";
     71  mailHandlerInfo.possibleApplicationHandlers.appendElement(dummy);
     72 
     73  gHandlerSvc.store(mailHandlerInfo);
     74  registerCleanupFunction(() => {
     75    // Re-add the original protocol handlers:
     76    let mailHandlers = mailHandlerInfo.possibleApplicationHandlers;
     77    for (let i = handlers.Count() - 1; i >= 0; i--) {
     78      try {
     79        // See if this is a web handler. If it is, it'll throw, otherwise,
     80        // we will remove it.
     81        mailHandlers.queryElementAt(i, Ci.nsIWebHandlerApp);
     82        mailHandlers.removeElementAt(i);
     83      } catch (ex) {}
     84    }
     85    for (let h of gOldMailHandlers) {
     86      mailHandlers.appendElement(h);
     87    }
     88    mailHandlerInfo.alwaysAskBeforeHandling = previousHandling;
     89    gHandlerSvc.store(mailHandlerInfo);
     90  });
     91 }
     92 
     93 add_task(setupMailHandler);
     94 
     95 // Fullscreen is canceled during fullscreen transition
     96 add_task(async function OpenExternalProtocolOnPendingLaterFullscreen() {
     97  for (const useClick of [true, false]) {
     98    await BrowserTestUtils.withNewTab(CONTENT, async browser => {
     99      const leavelFullscreen = waitForFullscreenState(document, false, true);
    100      await SpecialPowers.spawn(
    101        browser,
    102        [useClick],
    103        async function (shouldClick) {
    104          const button = content.document.querySelector("button");
    105 
    106          const clickDone = new Promise(r => {
    107            button.addEventListener(
    108              "click",
    109              function () {
    110                content.document.documentElement.requestFullscreen();
    111                // When anchor.click() is called, the fullscreen request
    112                // is probably still pending.
    113                content.setTimeout(() => {
    114                  if (shouldClick) {
    115                    content.document.querySelector("a").click();
    116                  } else {
    117                    content.document.location = "mailto:test@example.com";
    118                  }
    119                  r();
    120                }, 0);
    121              },
    122              { once: true }
    123            );
    124          });
    125          button.click();
    126          await clickDone;
    127        }
    128      );
    129 
    130      await leavelFullscreen;
    131      ok(true, "Fullscreen should be exited");
    132    });
    133  }
    134 });
    135 
    136 // Fullscreen is canceled immediately.
    137 add_task(async function OpenExternalProtocolOnPendingFullscreen() {
    138  for (const useClick of [true, false]) {
    139    await BrowserTestUtils.withNewTab(CONTENT, async browser => {
    140      await SpecialPowers.spawn(
    141        browser,
    142        [useClick],
    143        async function (shouldClick) {
    144          const button = content.document.querySelector("button");
    145 
    146          const clickDone = new Promise(r => {
    147            button.addEventListener(
    148              "click",
    149              function () {
    150                content.document.documentElement
    151                  .requestFullscreen()
    152                  .then(() => {
    153                    ok(false, "Don't enter fullscreen");
    154                  })
    155                  .catch(() => {
    156                    ok(true, "Cancel entering fullscreen");
    157                    r();
    158                  });
    159                // When anchor.click() is called, the fullscreen request
    160                // is probably still pending.
    161                if (shouldClick) {
    162                  content.document.querySelector("a").click();
    163                } else {
    164                  content.document.location = "mailto:test@example.com";
    165                }
    166              },
    167              { once: true }
    168            );
    169          });
    170          button.click();
    171          await clickDone;
    172        }
    173      );
    174 
    175      ok(true, "Fullscreen should be exited");
    176    });
    177  }
    178 });
    179 
    180 add_task(async function OpenExternalProtocolOnFullscreen() {
    181  for (const useClick of [true, false]) {
    182    await BrowserTestUtils.withNewTab(CONTENT, async browser => {
    183      const leavelFullscreen = waitForFullscreenState(document, false, true);
    184      await SpecialPowers.spawn(
    185        browser,
    186        [useClick],
    187        async function (shouldClick) {
    188          let button = content.document.querySelector("button");
    189          button.addEventListener("click", function () {
    190            content.document.documentElement.requestFullscreen();
    191          });
    192          button.click();
    193 
    194          await new Promise(r => {
    195            content.document.addEventListener("fullscreenchange", r);
    196          });
    197 
    198          if (shouldClick) {
    199            content.document.querySelector("a").click();
    200          } else {
    201            content.document.location = "mailto:test@example.com";
    202          }
    203        }
    204      );
    205 
    206      await leavelFullscreen;
    207      ok(true, "Fullscreen should be exited");
    208    });
    209  }
    210 });