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 9 kB image not shown  

Quelle  ext-management.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.defineLazyGetter(this"strBundle"function () {
  return Services.strings.createBundle(
    "chrome://global/locale/extensions.properties"
  );
});
ChromeUtils.defineESModuleGetters(this, {
  AddonManager: "resource://gre/modules/AddonManager.sys.mjs",
});

// We can't use Services.prompt here at the moment, as tests need to mock
// the prompt service. We could use sinon, but that didn't seem to work
// with Android builds.
// eslint-disable-next-line mozilla/use-services
XPCOMUtils.defineLazyServiceGetter(
  this,
  "promptService",
  "@mozilla.org/prompter;1",
  "nsIPromptService"
);

var { ExtensionError } = ExtensionUtils;

const _ = (key, ...args) => {
  if (args.length) {
    return strBundle.formatStringFromName(key, args);
  }
  return strBundle.GetStringFromName(key);
};

const installType = addon => {
  if (addon.temporarilyInstalled) {
    return "development";
  } else if (addon.foreignInstall) {
    return "sideload";
  } else if (addon.isSystem) {
    return "other";
  } else if (addon.isInstalledByEnterprisePolicy) {
    return "admin";
  }
  return "normal";
};

const getExtensionInfoForAddon = (extension, addon) => {
  let extInfo = {
    id: addon.id,
    name: addon.name,
    description: addon.description || "",
    version: addon.version,
    mayDisable: !!(addon.permissions & AddonManager.PERM_CAN_DISABLE),
    enabled: addon.isActive,
    optionsUrl: addon.optionsURL || "",
    installType: installType(addon),
    type: addon.type,
  };

  if (extension) {
    let m = extension.manifest;

    let hostPerms = extension.allowedOrigins.patterns.map(
      matcher => matcher.pattern
    );

    extInfo.permissions = Array.from(extension.permissions).filter(perm => {
      return !hostPerms.includes(perm);
    });
    extInfo.hostPermissions = hostPerms;

    extInfo.shortName = m.short_name || "";
    if (m.icons) {
      extInfo.icons = Object.keys(m.icons).map(key => {
        return { size: Number(key), url: m.icons[key] };
      });
    }
  }

  if (!addon.isActive) {
    extInfo.disabledReason = "unknown";
  }
  if (addon.homepageURL) {
    extInfo.homepageUrl = addon.homepageURL;
  }
  if (addon.updateURL) {
    extInfo.updateUrl = addon.updateURL;
  }
  return extInfo;
};

// Some management APIs are intentionally limited.
const allowedTypes = ["theme""extension"];

function checkAllowedAddon(addon) {
  if (addon.isSystem || addon.isAPIExtension) {
    return false;
  }
  if (addon.type == "extension" && !addon.isWebExtension) {
    return false;
  }
  return allowedTypes.includes(addon.type);
}

class ManagementAddonListener extends ExtensionCommon.EventEmitter {
  eventNames = ["onEnabled""onDisabled""onInstalled""onUninstalled"];

  hasAnyListeners() {
    for (let event of this.eventNames) {
      if (this.has(event)) {
        return true;
      }
    }
    return false;
  }

  on(event, listener) {
    if (!this.eventNames.includes(event)) {
      throw new Error("unsupported event");
    }
    if (!this.hasAnyListeners()) {
      AddonManager.addAddonListener(this);
    }
    super.on(event, listener);
  }

  off(event, listener) {
    if (!this.eventNames.includes(event)) {
      throw new Error("unsupported event");
    }
    super.off(event, listener);
    if (!this.hasAnyListeners()) {
      AddonManager.removeAddonListener(this);
    }
  }

  getExtensionInfo(addon) {
    let ext = WebExtensionPolicy.getByID(addon.id)?.extension;
    return getExtensionInfoForAddon(ext, addon);
  }

  onEnabled(addon) {
    if (!checkAllowedAddon(addon)) {
      return;
    }
    this.emit("onEnabled"this.getExtensionInfo(addon));
  }

  onDisabled(addon) {
    if (!checkAllowedAddon(addon)) {
      return;
    }
    this.emit("onDisabled"this.getExtensionInfo(addon));
  }

  onInstalled(addon) {
    if (!checkAllowedAddon(addon)) {
      return;
    }
    this.emit("onInstalled"this.getExtensionInfo(addon));
  }

  onUninstalled(addon) {
    if (!checkAllowedAddon(addon)) {
      return;
    }
    this.emit("onUninstalled"this.getExtensionInfo(addon));
  }
}

this.management = class extends ExtensionAPIPersistent {
  addonListener = new ManagementAddonListener();

  onShutdown() {
    AddonManager.removeAddonListener(this.addonListener);
  }

  eventRegistrar(eventName) {
    return ({ fire }) => {
      let listener = (event, data) => {
        fire.async(data);
      };

      this.addonListener.on(eventName, listener);
      return {
        unregister: () => {
          this.addonListener.off(eventName, listener);
        },
        convert(_fire) {
          fire = _fire;
        },
      };
    };
  }

  PERSISTENT_EVENTS = {
    onDisabled: this.eventRegistrar("onDisabled"),
    onEnabled: this.eventRegistrar("onEnabled"),
    onInstalled: this.eventRegistrar("onInstalled"),
    onUninstalled: this.eventRegistrar("onUninstalled"),
  };

  getAPI(context) {
    let { extension } = context;

    return {
      management: {
        async get(id) {
          let addon = await AddonManager.getAddonByID(id);
          if (!addon) {
            throw new ExtensionError(`No such addon ${id}`);
          }
          if (!checkAllowedAddon(addon)) {
            throw new ExtensionError("get not allowed for this addon");
          }
          // If the extension is enabled get it and use it for more data.
          let ext = WebExtensionPolicy.getByID(addon.id)?.extension;
          return getExtensionInfoForAddon(ext, addon);
        },

        async getAll() {
          let addons = await AddonManager.getAddonsByTypes(allowedTypes);
          return addons.filter(checkAllowedAddon).map(addon => {
            // If the extension is enabled get it and use it for more data.
            let ext = WebExtensionPolicy.getByID(addon.id)?.extension;
            return getExtensionInfoForAddon(ext, addon);
          });
        },

        async install({ url, hash }) {
          let listener = {
            onDownloadEnded(install) {
              if (install.addon.appDisabled || install.addon.type !== "theme") {
                install.cancel();
                return false;
              }
            },
          };

          let telemetryInfo = {
            source: "extension",
            method: "management-webext-api",
          };
          let install = await AddonManager.getInstallForURL(url, {
            hash,
            telemetryInfo,
            triggeringPrincipal: extension.principal,
          });
          install.addListener(listener);
          try {
            await install.install();
          } catch (e) {
            Cu.reportError(e);
            throw new ExtensionError("Incompatible addon");
          }
          await install.addon.enable();
          return { id: install.addon.id };
        },

        async getSelf() {
          let addon = await AddonManager.getAddonByID(extension.id);
          return getExtensionInfoForAddon(extension, addon);
        },

        async uninstallSelf(options) {
          if (options && options.showConfirmDialog) {
            let message = _("uninstall.confirmation.message", extension.name);
            if (options.dialogMessage) {
              message = `${options.dialogMessage}\n${message}`;
            }
            let title = _("uninstall.confirmation.title", extension.name);
            let buttonFlags =
              Ci.nsIPrompt.BUTTON_POS_0 * Ci.nsIPrompt.BUTTON_TITLE_IS_STRING +
              Ci.nsIPrompt.BUTTON_POS_1 * Ci.nsIPrompt.BUTTON_TITLE_IS_STRING;
            let button0Title = _("uninstall.confirmation.button-0.label");
            let button1Title = _("uninstall.confirmation.button-1.label");
            let response = promptService.confirmEx(
              null,
              title,
              message,
              buttonFlags,
              button0Title,
              button1Title,
              null,
              null,
              { value: 0 }
            );
            if (response == 1) {
              throw new ExtensionError("User cancelled uninstall of extension");
            }
          }
          let addon = await AddonManager.getAddonByID(extension.id);
          let canUninstall = Boolean(
            addon.permissions & AddonManager.PERM_CAN_UNINSTALL
          );
          if (!canUninstall) {
            throw new ExtensionError("The add-on cannot be uninstalled");
          }
          addon.uninstall();
        },

        async setEnabled(id, enabled) {
          let addon = await AddonManager.getAddonByID(id);
          if (!addon) {
            throw new ExtensionError(`No such addon ${id}`);
          }
          if (addon.type !== "theme") {
            throw new ExtensionError("setEnabled applies only to theme addons");
          }
          if (addon.isSystem) {
            throw new ExtensionError(
              "setEnabled cannot be used with a system addon"
            );
          }
          if (enabled) {
            await addon.enable();
          } else {
            await addon.disable();
          }
        },

        onDisabled: new EventManager({
          context,
          module: "management",
          event: "onDisabled",
          extensionApi: this,
        }).api(),

        onEnabled: new EventManager({
          context,
          module: "management",
          event: "onEnabled",
          extensionApi: this,
        }).api(),

        onInstalled: new EventManager({
          context,
          module: "management",
          event: "onInstalled",
          extensionApi: this,
        }).api(),

        onUninstalled: new EventManager({
          context,
          module: "management",
          event: "onUninstalled",
          extensionApi: this,
        }).api(),
      },
    };
  }
};

Messung V0.5
C=92 H=93 G=92

¤ Dauer der Verarbeitung: 0.10 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.