Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/browser/extensions/screenshots/background/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 6 kB image not shown  

Quelle  main.js   Sprache: JAVA

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


/* globals browser, getStrings, selectorLoader, communication, catcher, log, senderror, startBackground, blobConverters, startSelectionWithOnboarding */

"use strict";

this.main = (function () {
  const exports = {};

  const manifest = browser.runtime.getManifest();
  let backend;

  exports.setBackend = function (newBackend) {
    backend = newBackend;
    backend = backend.replace(/\/*$/, "");
  };

  exports.getBackend = function () {
    return backend;
  };

  communication.register("getBackend", () => {
    return backend;
  });

  for (const permission of manifest.permissions) {
    if (/^https?:\/\//.test(permission)) {
      exports.setBackend(permission);
      break;
    }
  }

  function toggleSelector(tab) {
    return selectorLoader.toggle(tab.id).catch(error => {
      if (
        error.message &&
        /Missing host permission for the tab/.test(error.message)
      ) {
        error.noReport = true;
      }
      error.popupMessage = "UNSHOOTABLE_PAGE";
      throw error;
    });
  }

  // This is called by startBackground.js, where is registered as a click
  // handler for the webextension page action.
  exports.onClicked = catcher.watchFunction(tab => {
    _startShotFlow(tab, "toolbar-button");
  });

  exports.onClickedContextMenu = catcher.watchFunction(tab => {
    _startShotFlow(tab, "context-menu");
  });

  exports.onShortcut = catcher.watchFunction(tab => {
    _startShotFlow(tab, "keyboard-shortcut");
  });

  const _startShotFlow = tab => {
    if (!tab) {
      // Not in a page/tab context, ignore
      return;
    }
    if (!urlEnabled(tab.url)) {
      senderror.showError({
        popupMessage: "UNSHOOTABLE_PAGE",
      });
      return;
    }

    catcher.watchPromise(
      toggleSelector(tab).catch(error => {
        throw error;
      })
    );
  };

  function urlEnabled(url) {
    // Allow screenshots on urls related to web pages in reader mode.
    if (url && url.startsWith("about:reader?url=")) {
      return true;
    }
    if (
      isShotOrMyShotPage(url) ||
      /^(?:about|data|moz-extension):/i.test(url) ||
      isBlacklistedUrl(url)
    ) {
      return false;
    }
    return true;
  }

  function isShotOrMyShotPage(url) {
    // It's okay to take a shot of any pages except shot pages and My Shots
    if (!url.startsWith(backend)) {
      return false;
    }
    const path = url
      .substr(backend.length)
      .replace(/^\/*/

      .replace(/[?#].*/, "");
    if (path === "shots") {
      return true;
    }
    if (/^[^/]{1,4000}\/[^/]{1,4000}$/.test(path)) {
      // Blocks {:id}/{:domain}, but not /, /privacy, etc
      return true;
    }
    return false;
  }

  function isBlacklistedUrl(url) {
    // These specific domains are not allowed for general WebExtension permission reasons
    // Discussion: https://bugzilla.mozilla.org/show_bug.cgi?id=1310082
    // List of domains copied from: https://searchfox.org/mozilla-central/source/browser/app/permissions#18-19
    // Note we disable it here to be informative, the security check is done in WebExtension code
    const badDomains = ["testpilot.firefox.com"];
    let domain = url.replace(/^https?:\/\//i, "");
    domain = domain.replace(/\/.*/, "").replace(/:.*/, "");
    domain = domain.toLowerCase();
    return badDomains.includes(domain);
  }

  communication.register("getStrings", (sender, ids) => {
    return getStrings(ids.map(id => ({ id })));
  });

  communication.register("openShot", async (sender, { copied }) => {
    if (copied) {
      const id = crypto.randomUUID();
      const [title, message] = await getStrings([
        { id: "screenshots-notification-link-copied-title" },
        { id: "screenshots-notification-link-copied-details" },
      ]);
      return browser.notifications.create(id, {
        type: "basic",
        iconUrl: "chrome://browser/content/screenshots/copied-notification.svg",
        title,
        message,
      });
    }
    return null;
  });

  communication.register("copyShotToClipboard", async (sender, blob) => {
    let buffer = await blobConverters.blobToArray(blob);
    await browser.clipboard.setImageData(buffer, blob.type.split("/", 2)[1]);

    const [title, message] = await getStrings([
      { id: "screenshots-notification-image-copied-title" },
      { id: "screenshots-notification-image-copied-details" },
    ]);

    return browser.notifications.create({
      type: "basic",
      iconUrl: "chrome://browser/content/screenshots/copied-notification.svg",
      title,
      message,
    });
  });

  communication.register("downloadShot", (sender, info) => {
    // 'data:' urls don't work directly, let's use a Blob
    // see http://stackoverflow.com/questions/40269862/save-data-uri-as-file-using-downloads-download-api
    const blob = blobConverters.dataUrlToBlob(info.url);
    const url = URL.createObjectURL(blob);
    let downloadId;
    const onChangedCallback = catcher.watchFunction(function (change) {
      if (!downloadId || downloadId !== change.id) {
        return;
      }
      if (change.state && change.state.current !== "in_progress") {
        URL.revokeObjectURL(url);
        browser.downloads.onChanged.removeListener(onChangedCallback);
      }
    });
    browser.downloads.onChanged.addListener(onChangedCallback);
    return browser.windows.getLastFocused().then(windowInfo => {
      return browser.downloads
        .download({
          url,
          incognito: windowInfo.incognito,
          filename: info.filename,
        })
        .catch(error => {
          // We are not logging error message when user cancels download
          if (error && error.message && !error.message.includes("canceled")) {
            log.error(error.message);
          }
        })
        .then(id => {
          downloadId = id;
        });
    });
  });

  communication.register("abortStartShot", () => {
    // Note, we only show the error but don't report it, as we know that we can't
    // take shots of these pages:
    senderror.showError({
      popupMessage: "UNSHOOTABLE_PAGE",
    });
  });

  // A Screenshots page wants us to start/force onboarding
  communication.register("requestOnboarding", sender => {
    return startSelectionWithOnboarding(sender.tab);
  });

  communication.register("getPlatformOs", () => {
    return catcher.watchPromise(
      browser.runtime.getPlatformInfo().then(platformInfo => {
        return platformInfo.os;
      })
    );
  });

  // This allows the web site show notifications through sitehelper.js
  communication.register("showNotification", (sender, notification) => {
    return browser.notifications.create(notification);
  });

  return exports;
})();

Messung V0.5
C=84 H=96 G=90

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.