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

Quelle  ext-userScripts.js   Sprache: JAVA

 
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/* 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/. */


"use strict";

ChromeUtils.defineESModuleGetters(this, {
  ExtensionUserScripts: "resource://gre/modules/ExtensionUserScripts.sys.mjs",
});

var { ExtensionUtils } = ChromeUtils.importESModule(
  "resource://gre/modules/ExtensionUtils.sys.mjs"
);

var { ExtensionError } = ExtensionUtils;

/**
 * Represents (in the main browser process) a user script.
 * (legacy MV2-only userScripts API)
 *
 * @param {UserScriptOptions} details
 *        The options object related to the user script
 *        (which has the properties described in the user_scripts.json
 *        JSON API schema file).
 */

class UserScriptParent {
  constructor(details) {
    this.scriptId = details.scriptId;
    this.options = this._convertOptions(details);
  }

  destroy() {
    if (this.destroyed) {
      throw new Error("Unable to destroy UserScriptParent twice");
    }

    this.destroyed = true;
    this.options = null;
  }

  _convertOptions(details) {
    const options = {
      matches: details.matches,
      excludeMatches: details.excludeMatches,
      includeGlobs: details.includeGlobs,
      excludeGlobs: details.excludeGlobs,
      allFrames: details.allFrames,
      matchAboutBlank: details.matchAboutBlank,
      // New matchOriginAsFallback option not supported in userScripts API
      // because the current MV2-only userScripts API is deprecated and will be
      // superseded by the new one in bug 1875475.
      matchOriginAsFallback: false,
      runAt: details.runAt || "document_idle",
      // "world" option is unsupported in the old userScripts API. The new one
      // (bug 1875475) will support "USER_SCRIPT" (default) and "MAIN".
      jsPaths: details.js,
      userScriptOptions: {
        scriptMetadata: details.scriptMetadata,
      },
      originAttributesPatterns: null,
    };

    if (details.cookieStoreId != null) {
      const cookieStoreIds = Array.isArray(details.cookieStoreId)
        ? details.cookieStoreId
        : [details.cookieStoreId];
      options.originAttributesPatterns = cookieStoreIds.map(cookieStoreId =>
        getOriginAttributesPatternForCookieStoreId(cookieStoreId)
      );
    }

    return options;
  }

  serialize() {
    return this.options;
  }
}

this.userScripts = class extends ExtensionAPI {
  constructor(...args) {
    super(...args);

    // Map<scriptId -> UserScriptParent>
    this.userScriptsMap = new Map();
  }

  getAPI(context) {
    const { extension } = context;
    if (extension.manifestVersion == 2) {
      return this.getLegacyMV2API(context);
    }

    function ensureIdsValidAndUnique(publicScriptIds) {
      let seen = new Set();
      for (let id of publicScriptIds) {
        if (!id.length || id.startsWith("_")) {
          throw new ExtensionError("Invalid id for RegisteredUserScript.");
        }
        if (seen.has(id)) {
          throw new ExtensionError(`Duplicate script id: ${id}`);
        }
        seen.add(id);
      }
    }

    function ensureValidWorldId(worldId) {
      if (worldId && (worldId.startsWith("_") || worldId.length > 256)) {
        // worldId "" is the default world.
        // worldId starting with "_" are reserved.
        // worldId length is capped. Limit is consistent with Chrome.
        throw new ExtensionError(`Invalid worldId: ${worldId}`);
      }
    }

    if (!extension.userScriptsManager) {
      // extension.userScriptsManager is initialized by initExtension() at
      // extension startup when the extension has the "userScripts" permission.
      // When we get here, it means that "userScripts" was requested after
      // startup, and we need to initialize it here.
      ExtensionUserScripts.initExtension(extension);
    }

    const usm = extension.userScriptsManager;

    return {
      userScripts: {
        register: async scripts => {
          ensureIdsValidAndUnique(scripts.map(s => s.id));
          scripts.forEach(s => ensureValidWorldId(s.worldId));

          return usm.runWriteTask(async () => {
            await usm.registerNewScripts(scripts);
          });
        },

        update: async scripts => {
          ensureIdsValidAndUnique(scripts.map(s => s.id));
          scripts.forEach(s => ensureValidWorldId(s.worldId));

          return usm.runWriteTask(async () => {
            await usm.updateScripts(scripts);
          });
        },

        unregister: async filter => {
          let ids = filter?.ids;
          if (ids) {
            ensureIdsValidAndUnique(ids);
          }
          return usm.runWriteTask(async () => {
            await usm.unregisterScripts(ids);
          });
        },

        getScripts: async filter => {
          let ids = filter?.ids;
          if (ids) {
            ensureIdsValidAndUnique(ids);
          }
          return usm.runReadTask(async () => {
            return usm.getScripts(ids);
          });
        },

        configureWorld: async properties => {
          ensureValidWorldId(properties.worldId);
          return usm.runWriteTask(async () => {
            await usm.configureWorld(properties);
          });
        },

        resetWorldConfiguration: async worldId => {
          ensureValidWorldId(worldId);
          return usm.runWriteTask(async () => {
            await usm.resetWorldConfiguration(worldId);
          });
        },

        getWorldConfigurations: async () => {
          return usm.runReadTask(async () => {
            return usm.getWorldConfigurations();
          });
        },
      },
    };
  }

  getLegacyMV2API(context) {
    const { extension } = context;

    // Set of the scriptIds registered from this context.
    const registeredScriptIds = new Set();

    const unregisterContentScripts = scriptIds => {
      if (scriptIds.length === 0) {
        return Promise.resolve();
      }

      for (let scriptId of scriptIds) {
        registeredScriptIds.delete(scriptId);
        extension.registeredContentScripts.delete(scriptId);
        this.userScriptsMap.delete(scriptId);
      }
      extension.updateContentScripts();

      return context.extension.broadcast("Extension:UnregisterContentScripts", {
        id: context.extension.id,
        scriptIds,
      });
    };

    // Unregister all the scriptId related to a context when it is closed,
    // and revoke all the created blob urls once the context is destroyed.
    context.callOnClose({
      close() {
        unregisterContentScripts(Array.from(registeredScriptIds));
      },
    });

    return {
      userScripts: {
        register: async details => {
          for (let origin of details.matches) {
            if (!extension.allowedOrigins.subsumes(new MatchPattern(origin))) {
              throw new ExtensionError(
                `Permission denied to register a user script for ${origin}`
              );
            }
          }

          const userScript = new UserScriptParent(details);
          const { scriptId } = userScript;

          this.userScriptsMap.set(scriptId, userScript);
          registeredScriptIds.add(scriptId);

          const scriptOptions = userScript.serialize();

          extension.registeredContentScripts.set(scriptId, scriptOptions);
          extension.updateContentScripts();

          await extension.broadcast("Extension:RegisterContentScripts", {
            id: extension.id,
            scripts: [{ scriptId, options: scriptOptions }],
          });

          return scriptId;
        },

        // This method is not available to the extension code, the extension code
        // doesn't have access to the internally used scriptId, on the contrary
        // the extension code will call script.unregister on the script API object
        // that is resolved from the register API method returned promise.
        unregister: async scriptId => {
          const userScript = this.userScriptsMap.get(scriptId);
          if (!userScript) {
            throw new Error(`No such user script ID: ${scriptId}`);
          }

          userScript.destroy();

          await unregisterContentScripts([scriptId]);
        },
      },
    };
  }
};

Messung V0.5
C=96 H=96 G=95

¤ Dauer der Verarbeitung: 0.37 Sekunden  (vorverarbeitet)  ¤

*© 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.