tor-browser

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

browser_document_command_paste.js (12587B)


      1 /* -*- Mode: JavaScript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 "use strict";
      8 
      9 const kContentFileUrl = kBaseUrlForContent + "simple_page_ext.html";
     10 
     11 add_setup(async function init() {
     12  await SpecialPowers.pushPrefEnv({
     13    // This to turn off the paste contextmenu for testing.
     14    set: [["dom.events.testing.asyncClipboard", true]],
     15  });
     16 });
     17 
     18 [true, false].forEach(aPrefValue => {
     19  describe(`dom.execCommand.paste.enabled=${aPrefValue}`, () => {
     20    it("set preference", async () => {
     21      await SpecialPowers.pushPrefEnv({
     22        set: [["dom.execCommand.paste.enabled", aPrefValue]],
     23      });
     24    });
     25 
     26    describe("test paste comment", () => {
     27      beforeEach(async () => {
     28        info("Write random text to clipboard");
     29        await promiseWritingRandomTextToClipboard();
     30      });
     31 
     32      it(`called from system principal`, async () => {
     33        document.clearUserGestureActivation();
     34        ok(
     35          document.queryCommandSupported("paste"),
     36          "Check if the 'paste' command is supported"
     37        );
     38 
     39        // Test without editing.
     40        ok(
     41          !document.queryCommandEnabled("paste"),
     42          "Check if the 'paste' command is enabled without editing"
     43        );
     44        ok(
     45          !document.execCommand("paste"),
     46          "Check if the 'paste' command is succeed without editing"
     47        );
     48 
     49        // Test with editing.
     50        const textArea = document.createElement("textarea");
     51        document.body.appendChild(textArea);
     52        textArea.textContent = "textarea text";
     53        textArea.setSelectionRange(0, textArea.value.length);
     54        textArea.focus();
     55        ok(
     56          document.queryCommandEnabled("paste"),
     57          "Check if the 'paste' command is enabled when editing"
     58        );
     59        ok(
     60          document.execCommand("paste"),
     61          "Check if the 'paste' command is succeed when editing"
     62        );
     63        textArea.remove();
     64      });
     65 
     66      it(`called from web content`, async () => {
     67        await BrowserTestUtils.withNewTab(kContentFileUrl, async browser => {
     68          await SpecialPowers.spawn(browser, [aPrefValue], async aPrefValue => {
     69            const doc = Cu.waiveXrays(content.document);
     70            is(
     71              doc.queryCommandSupported("paste"),
     72              aPrefValue,
     73              `Check if the 'paste' command is supported`
     74            );
     75 
     76            // Test no user activation.
     77            content.document.clearUserGestureActivation();
     78            ok(
     79              !doc.queryCommandEnabled("paste"),
     80              "Check if the 'paste' command is enabled without user activation"
     81            );
     82            ok(
     83              !doc.execCommand("paste"),
     84              "Check if the 'paste' command is succeed without user activation"
     85            );
     86 
     87            // Test with user activation.
     88            content.document.notifyUserGestureActivation();
     89            is(
     90              doc.queryCommandEnabled("paste"),
     91              aPrefValue,
     92              "Check if the 'paste' command is enabled with user activation"
     93            );
     94            is(
     95              doc.execCommand("paste"),
     96              aPrefValue,
     97              "Check if the 'paste' command is succeed with user activation"
     98            );
     99 
    100            // Test with editing.
    101            const textArea = content.document.createElement("textarea");
    102            content.document.body.appendChild(textArea);
    103            textArea.textContent = "textarea text";
    104            textArea.setSelectionRange(0, textArea.value.length);
    105            textArea.focus();
    106 
    107            // Test no user activation.
    108            content.document.clearUserGestureActivation();
    109            ok(
    110              !doc.queryCommandEnabled("paste"),
    111              "Check if the 'paste' command is enabled without user activation when editing"
    112            );
    113            ok(
    114              !doc.execCommand("paste"),
    115              "Check if the 'paste' command is succeed without user activation when editing"
    116            );
    117 
    118            // Test with user activation.
    119            textArea.textContent = "textarea text";
    120            textArea.setSelectionRange(0, textArea.value.length);
    121            textArea.focus();
    122            content.document.notifyUserGestureActivation();
    123            is(
    124              doc.queryCommandEnabled("paste"),
    125              aPrefValue,
    126              "Check if the 'paste' command is enabled with user activation when editing"
    127            );
    128            is(
    129              doc.execCommand("paste"),
    130              aPrefValue,
    131              "Check if the 'paste' command is succeed with user activation when editing"
    132            );
    133          });
    134        });
    135      });
    136 
    137      [true, false].forEach(aPermission => {
    138        describe(`extension ${aPermission ? "with" : "without"} clipboardRead permission`, () => {
    139          const sharedScript = function () {
    140            this.testPasteCommand = function () {
    141              return [
    142                document.queryCommandSupported("paste"),
    143                document.queryCommandEnabled("paste"),
    144                document.execCommand("paste"),
    145              ];
    146            };
    147          };
    148 
    149          it("called from content script", async () => {
    150            const contentScript = function () {
    151              document
    152                .querySelector("button")
    153                .addEventListener("click", function (e) {
    154                  browser.test.sendMessage("result", testPasteCommand());
    155                });
    156              browser.test.sendMessage("ready", testPasteCommand());
    157            };
    158            const extensionData = {
    159              manifest: {
    160                content_scripts: [
    161                  {
    162                    js: ["sharedScript.js", "contentscript.js"],
    163                    matches: ["https://example.com/*"],
    164                  },
    165                ],
    166              },
    167              files: {
    168                "sharedScript.js": sharedScript,
    169                "contentscript.js": contentScript,
    170              },
    171            };
    172            if (aPermission) {
    173              extensionData.manifest.permissions = ["clipboardRead"];
    174            }
    175 
    176            // Load and start the extension.
    177            const extension = ExtensionTestUtils.loadExtension(extensionData);
    178            await extension.startup();
    179            await BrowserTestUtils.withNewTab(
    180              kContentFileUrl,
    181              async browser => {
    182                let [supported, enabled, succeed] =
    183                  await extension.awaitMessage("ready");
    184                is(
    185                  supported,
    186                  aPrefValue || aPermission,
    187                  "Check if the 'paste' command is supported"
    188                );
    189 
    190                // Test no user activation.
    191                is(
    192                  enabled,
    193                  aPermission,
    194                  "Check if the 'paste' command is enabled without user activation"
    195                );
    196                is(
    197                  succeed,
    198                  aPermission,
    199                  "Check if the 'paste' command is succeed without user activation"
    200                );
    201 
    202                // Click on the content to trigger user activation.
    203                promiseClickContentElement(browser, "btn");
    204                [supported, enabled, succeed] =
    205                  await extension.awaitMessage("result");
    206                is(
    207                  enabled,
    208                  aPrefValue || aPermission,
    209                  "Check if the 'paste' command is enabled with user activation"
    210                );
    211                is(
    212                  succeed,
    213                  aPrefValue || aPermission,
    214                  "Check if the 'paste' command is succeed with user activation"
    215                );
    216              }
    217            );
    218            await extension.unload();
    219          });
    220 
    221          it("called from content script when editing", async () => {
    222            const contentScript = function () {
    223              const textArea = document.createElement("textarea");
    224              document.body.appendChild(textArea);
    225              const testPasteCommandWhenEditing = function () {
    226                // Start editing.
    227                textArea.textContent = "textarea text";
    228                textArea.setSelectionRange(0, textArea.value.length);
    229                textArea.focus();
    230                return testPasteCommand();
    231              };
    232              document
    233                .querySelector("button")
    234                .addEventListener("click", function (e) {
    235                  browser.test.sendMessage(
    236                    "result",
    237                    testPasteCommandWhenEditing()
    238                  );
    239                });
    240              browser.test.sendMessage("ready", testPasteCommandWhenEditing());
    241            };
    242            const extensionData = {
    243              manifest: {
    244                content_scripts: [
    245                  {
    246                    js: ["sharedScript.js", "contentscript.js"],
    247                    matches: ["https://example.com/*"],
    248                  },
    249                ],
    250              },
    251              files: {
    252                "sharedScript.js": sharedScript,
    253                "contentscript.js": contentScript,
    254              },
    255            };
    256            if (aPermission) {
    257              extensionData.manifest.permissions = ["clipboardRead"];
    258            }
    259 
    260            // Load and start the extension.
    261            const extension = ExtensionTestUtils.loadExtension(extensionData);
    262            await extension.startup();
    263            await BrowserTestUtils.withNewTab(
    264              kContentFileUrl,
    265              async browser => {
    266                let [supported, enabled, succeed] =
    267                  await extension.awaitMessage("ready");
    268                is(
    269                  supported,
    270                  aPrefValue || aPermission,
    271                  "Check if the 'paste' command is supported"
    272                );
    273                is(
    274                  enabled,
    275                  aPermission,
    276                  "Check if the 'paste' command is enabled without user activation"
    277                );
    278                is(
    279                  succeed,
    280                  aPermission,
    281                  "Check if the 'paste' command is succeed without user activation"
    282                );
    283 
    284                // Click on the content to trigger user activation.
    285                promiseClickContentElement(browser, "btn");
    286                [supported, enabled, succeed] =
    287                  await extension.awaitMessage("result");
    288                is(
    289                  enabled,
    290                  aPrefValue || aPermission,
    291                  "Check if the 'paste' command is enabled with user activation"
    292                );
    293                is(
    294                  succeed,
    295                  aPrefValue || aPermission,
    296                  "Check if the 'paste' command is succeed with user activation"
    297                );
    298              }
    299            );
    300            await extension.unload();
    301          });
    302 
    303          it("called from background script", async () => {
    304            const backgroundScript = function () {
    305              browser.test.sendMessage("ready", testPasteCommand());
    306            };
    307            const extensionData = {
    308              background: [sharedScript, backgroundScript],
    309            };
    310            if (aPermission) {
    311              extensionData.manifest = {
    312                permissions: ["clipboardRead"],
    313              };
    314            }
    315 
    316            // Load and start the extension.
    317            const extension = ExtensionTestUtils.loadExtension(extensionData);
    318            await extension.startup();
    319            await BrowserTestUtils.withNewTab(
    320              kContentFileUrl,
    321              async browser => {
    322                let [supported, enabled, succeed] =
    323                  await extension.awaitMessage("ready");
    324                is(
    325                  supported,
    326                  aPrefValue || aPermission,
    327                  "Check if the 'paste' command is supported"
    328                );
    329                is(
    330                  enabled,
    331                  aPermission,
    332                  "Check if the 'paste' command is enabled"
    333                );
    334                is(
    335                  succeed,
    336                  aPermission,
    337                  "Check if the 'paste' command is succeed"
    338                );
    339              }
    340            );
    341            await extension.unload();
    342          });
    343        });
    344      });
    345    });
    346  });
    347 });