tor-browser

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

browser_dragdrop_impl.js (6963B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // Test that drag and drop events are sent at the right time.
      6 // Supports dragging between domains, windows and iframes.
      7 // To avoid symmetric tests, the drag source must be in the first window.
      8 // iframe domains must match outer frame domains.
      9 
     10 // This file should be included in DND tests that define its parameters.
     11 // That file needs to do the following:
     12 // 1. Call await setup(configParams), where configParams is an object that
     13 //    configures the specific test.  See `setup()` below.
     14 // 2. Use Services.scriptloader.loadSubScript to load this script.
     15 // 3. Define runTest(testName, srcBrowsingCxt, tgtBrowsingCxt, dndOptions),
     16 //    which defaults to `runDnd` below.  Other definitions will typically
     17 //    also need to delegate some functionality to runDnd.
     18 
     19 "use strict";
     20 
     21 const { MockRegistrar } = ChromeUtils.importESModule(
     22  "resource://testing-common/MockRegistrar.sys.mjs"
     23 );
     24 
     25 // The tabs, each in their own widget.
     26 let tab1Cxt;
     27 let tab2Cxt;
     28 
     29 let dragServiceCid;
     30 
     31 // JS controller for mock drag service
     32 let dragController;
     33 
     34 async function runDnd(
     35  testName,
     36  sourceBrowsingCxt,
     37  targetBrowsingCxt,
     38  dndOptions = {}
     39 ) {
     40  return EventUtils.synthesizeMockDragAndDrop({
     41    dragController,
     42    srcElement: "dropSource",
     43    targetElement: "dropTarget",
     44    sourceBrowsingCxt,
     45    targetBrowsingCxt,
     46    id: SpecialPowers.Ci.nsIDOMWindowUtils.DEFAULT_MOUSE_POINTER_ID,
     47    contextLabel: testName,
     48    info,
     49    record,
     50    dragAction: Ci.nsIDragService.DRAGDROP_ACTION_MOVE,
     51    ...dndOptions,
     52  });
     53 }
     54 
     55 async function openWindow(tabIdx, configParams) {
     56  let win =
     57    tabIdx == 0 ? window : await BrowserTestUtils.openNewBrowserWindow();
     58  const OUTER_URL_ARRAY = [configParams.outerURL1, configParams.outerURL2];
     59  let url = OUTER_URL_ARRAY[tabIdx];
     60  let tab = await BrowserTestUtils.openNewForegroundTab({
     61    gBrowser: win.gBrowser,
     62    url,
     63  });
     64  registerCleanupFunction(async function () {
     65    await BrowserTestUtils.removeTab(tab);
     66    if (tabIdx != 0) {
     67      await BrowserTestUtils.closeWindow(win);
     68    }
     69  });
     70 
     71  // Set the URL for the iframe.  Also set
     72  // neverAllowSessionIsSynthesizedForTests for both frames
     73  // (the second is redundant if they are in the same process).
     74  const INNER_URL_ARRAY = [configParams.innerURL1, configParams.innerURL2];
     75  await SpecialPowers.spawn(
     76    tab.linkedBrowser.browsingContext,
     77    [tabIdx, INNER_URL_ARRAY[tabIdx]],
     78    async (tabIdx, iframeUrl) => {
     79      let iframe = content.document.getElementById("iframe");
     80      if (!iframe && content.document.body.shadowRoot) {
     81        iframe = content.document.body.shadowRoot.getElementById("iframe");
     82      }
     83      ok(iframe, `Found iframe in window ${tabIdx}`);
     84      let loadedPromise = new Promise(res => {
     85        iframe.addEventListener("load", res, { once: true });
     86      });
     87      iframe.src = iframeUrl;
     88      await loadedPromise;
     89      const ds = SpecialPowers.Cc[
     90        "@mozilla.org/widget/dragservice;1"
     91      ].getService(SpecialPowers.Ci.nsIDragService);
     92      ds.neverAllowSessionIsSynthesizedForTests = true;
     93    }
     94  );
     95 
     96  await SpecialPowers.spawn(
     97    tab.linkedBrowser.browsingContext.children[0],
     98    [],
     99    () => {
    100      const ds = SpecialPowers.Cc[
    101        "@mozilla.org/widget/dragservice;1"
    102      ].getService(SpecialPowers.Ci.nsIDragService);
    103      ds.neverAllowSessionIsSynthesizedForTests = true;
    104    }
    105  );
    106 
    107  return tab.linkedBrowser.browsingContext;
    108 }
    109 
    110 /**
    111 * Configure the test.  All fields are required.
    112 *
    113 * @param {object} configParams
    114 * @param {string} configParams.outerURL1
    115 *                 URL of window #1's main frame's content (not iframes).
    116 *                 The document must contain an iframe with ID "iframe"
    117 *                 that will be used to load the iframe HTML.  It also
    118 *                 must contain an element with ID "dropSource" that will be
    119 *                 used as the source of a drag, as well as one with ID
    120 *                 "dropTarget" that will be used as the drop target.
    121 * @param {string} configParams.outerURL2
    122 *                 Like outerURL1 but for the second window.  outerURL1 and
    123 *                 outerURL2 may be identical.  Must include "dropSource" and
    124 *                 "dropTarget" elements.
    125 * @param {string} configParams.innerURL1
    126 *                 URL of the inner frame's content in window #1.  Must
    127 *                 include "dropSource" and "dropTarget" elements.
    128 * @param {string} configParams.innerURL1
    129 *                 URL of the inner frame's content in window #2.  Must
    130 *                 include "dropSource" and "dropTarget" elements.
    131 */
    132 async function setup(configParams) {
    133  const oldDragService = SpecialPowers.Cc[
    134    "@mozilla.org/widget/dragservice;1"
    135  ].getService(SpecialPowers.Ci.nsIDragService);
    136  dragController = oldDragService.getMockDragController();
    137  dragServiceCid = MockRegistrar.register(
    138    "@mozilla.org/widget/dragservice;1",
    139    dragController.mockDragService
    140  );
    141  ok(dragServiceCid, "MockDragService was registered");
    142  // If the mock failed then don't continue or else we could trigger native
    143  // DND behavior.
    144  if (!dragServiceCid) {
    145    SimpleTest.finish();
    146  }
    147  registerCleanupFunction(async function () {
    148    MockRegistrar.unregister(dragServiceCid);
    149  });
    150  dragController.mockDragService.neverAllowSessionIsSynthesizedForTests = true;
    151 
    152  tab1Cxt = await openWindow(0, configParams);
    153  tab2Cxt = await openWindow(1, configParams);
    154 }
    155 
    156 // ----------------------------------------------------------------------------
    157 // Test dragging between different frames and different domains
    158 // ----------------------------------------------------------------------------
    159 // Define runTest to establish a test between two (possibly identical) contexts.
    160 // runTest has the same signature as runDnd.
    161 var runTest = runDnd;
    162 
    163 add_task(async function test_dnd_tab1_to_tab1() {
    164  await runTest("tab1->tab1", tab1Cxt, tab1Cxt);
    165 });
    166 
    167 add_task(async function test_dnd_tab1_to_iframe1() {
    168  await runTest("tab1->iframe1", tab1Cxt, tab1Cxt.children[0]);
    169 });
    170 
    171 add_task(async function test_dnd_tab1_to_tab2() {
    172  await runTest("tab1->tab2", tab1Cxt, tab2Cxt);
    173 });
    174 
    175 add_task(async function test_dnd_tab1_to_iframe2() {
    176  await runTest("tab1->iframe2", tab1Cxt, tab2Cxt.children[0]);
    177 });
    178 
    179 add_task(async function test_dnd_iframe1_to_tab1() {
    180  await runTest("iframe1->tab1", tab1Cxt.children[0], tab1Cxt);
    181 });
    182 
    183 add_task(async function test_dnd_iframe1_to_iframe1() {
    184  await runTest("iframe1->iframe1", tab1Cxt.children[0], tab1Cxt.children[0]);
    185 });
    186 
    187 add_task(async function test_dnd_iframe1_to_tab2() {
    188  await runTest("iframe1->tab2", tab1Cxt.children[0], tab2Cxt);
    189 });
    190 
    191 add_task(async function test_dnd_iframe1_to_iframe2() {
    192  await runTest("iframe1->iframe2", tab1Cxt.children[0], tab2Cxt.children[0]);
    193 });