<commit_before>// Copyright (c) 2009-2011 by <NAME> <<EMAIL>>
// Copyright (c) 2009-2010 by <NAME> <<EMAIL>>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
/* use strict */

try {

Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("addons", {
    exports: ["AddonManager", "Addons", "Addon", "addons"],
    require: ["services"]
}, this);

var callResult = function callResult(method) {
    let args = Array.slice(arguments, 1);
    return function (result) { result[method].apply(result, args); };
}

var listener = function listener(action, event)
    function addonListener(install) {
        this.dactyl[install.error ? "echoerr" : "echomsg"](
            _("addon.error", action, event, (install.name || install.sourceURI.spec) +
                (install.error ? ": " + addons.errors[install.error] : "")));
    }

var AddonListener = Class("AddonListener", {
    init: function init(modules) {
        this.dactyl = modules.dactyl;
    },

    onNewInstall:        function (install) {},
    onExternalInstall:   function (addon, existingAddon, needsRestart) {},
    onDownloadStarted:   listener("download", "started"),
    onDownloadEnded:     listener("download", "complete"),
    onDownloadCancelled: listener("download", "canceled"),
    onDownloadFailed:    listener("download", "failed"),
    onDownloadProgress:  function (install) {},
    onInstallStarted:    function (install) {},
    onInstallEnded:      listener("installation", "complete"),
    onInstallCancelled:  listener("installation", "canceled"),
    onInstallFailed:     listener("installation", "failed")
});

var updateAddons = Class("UpgradeListener", AddonListener, {
    init: function init(addons, modules) {
        init.supercall(this, modules);

        util.assert(!addons.length || addons[0].findUpdates,
                    _("error.unavailable", config.host, services.runtime.version));

        this.remaining = addons;
        this.upgrade = [];
        this.dactyl.echomsg(_("addon.check", addons.map(function (a) a.name).join(", ")));
        for (let addon in values(addons))
            addon.findUpdates(this, AddonManager.UPDATE_WHEN_USER_REQUESTED, null, null);

    },
    onUpdateAvailable: function (addon, install) {
        this.upgrade.push(addon);
        install.addListener(this);
        install.install();
    },
    onUpdateFinished: function (addon, error) {
        this.remaining = this.remaining.filter(function (a) a.type != addon.type || a.id != addon.id);
        if (!this.remaining.length)
            this.dactyl.echomsg(
                this.upgrade.length
                    ? _("addon.installingUpdates", this.upgrade.map(function (i) i.name).join(", "))
                    : _("addon.noUpdates"));
    }
});

var actions = {
    delete: {
        name: ["extde[lete]", "extrm"],
        description: "Uninstall an extension",
        action: callResult("uninstall"),
        perm: "uninstall"
    },
    enable: {
        name: "exte[nable]",
        description: "Enable an extension",
        action: function (addon) { addon.userDisabled = false; },
        filter: function (addon) addon.userDisabled,
        perm: "enable"
    },
    disable: {
        name: "extd[isable]",
        description: "Disable an extension",
        action: function (addon) { addon.userDisabled = true; },
        filter: function (addon) !addon.userDisabled,
        perm: "disable"
    },
    options: {
        name: ["exto[ptions]", "extp[references]"],
        description: "Open an extension's preference dialog",
        bang: true,
        action: function (addon, bang) {
            if (bang)
                this.window.openDialog(addon.optionsURL, "_blank", "chrome");
            else
                this.dactyl.open(addon.optionsURL, { from: "extoptions" });
        },
        filter: function (addon) addon.isActive && addon.optionsURL
    },
    rehash: {
        name: "extr[ehash]",
        description: "Reload an extension",
        action: function (addon) {
            util.assert(config.haveGecko("2b"), _("command.notUseful", config.host));
            util.flushCache();
            util.timeout(function () {
                addon.userDisabled = true;
                addon.userDisabled = false;
            });
        },
        get filter() {
            return function (addon) !addon.userDisabled &&
                !(addon.operationsRequiringRestart & (AddonManager.OP_NEEDS_RESTART_ENABLE | AddonManager.OP_NEEDS_RESTART_DISABLE))
        },
        perm: "disable"
    },
    toggle: {
        name: "extt[oggle]",
        description: "Toggle an extension's enabled status",
        action: function (addon) { addon.userDisabled = !addon.userDisabled; }
    },
    update: {
        name: "extu[pdate]",
        description: "Update an extension",
        actions: updateAddons,
        perm: "upgrade"
    }
};

var Addon = Class("Addon", {
    init: function init(addon, list) {
        this.addon = addon;
        this.instance = this;
        this.list = list;

        this.nodes = {
            commandTarget: this
        };
        XML.ignoreWhitespace = true;
        util.xmlToDom(
            <tr highlight="Addon" key="row" xmlns:dactyl={NS} xmlns={XHTML}>
                <td highlight="AddonName" key="name"/>
                <td highlight="AddonVersion" key="version"/>
                <td highlight="AddonButtons Buttons">
                    <a highlight="Button" href="javascript:0" key="enable">{_("addon.action.On")}</a>
                    <a highlight="Button" href="javascript:0" key="disable">{_("addon.action.Off")}</a>
                    <a highlight="Button" href="javascript:0" key="delete">{_("addon.action.Delete")}</a>
                    <a highlight="Button" href="javascript:0" key="update">{_("addon.action.Update")}</a>
                    <a highlight="Button" href="javascript:0" key="options">{_("addon.action.Options")}</a>
                </td>
                <td highlight="AddonStatus" key="status"/>
                <td highlight="AddonDescription" key="description"/>
            </tr>,
            this.list.document, this.nodes);

        this.update();
    },

    commandAllowed: function commandAllowed(cmd) {
        util.assert(Set.has(actions, cmd), _("addon.unknownCommand"));

        let action = actions[cmd];
        if ("perm" in action && !(this.permissions & AddonManager["PERM_CAN_" + action.perm.toUpperCase()]))
            return false;
        if ("filter" in action && !action.filter({ item: this }))
            return false;
        return true;
    },

    command: function command(cmd) {
        util.assert(this.commandAllowed(cmd), _("addon.commandNotAllowed"));

        let action = actions[cmd];
        if (action.action)
            action.action.call(this.list.modules, this, true);
        else
            action.actions([this], this.list.modules);
    },

    compare: function compare(other) String.localeCompare(this.name, other.name),

    get statusInfo() {
        XML.ignoreWhitespace = XML.prettyPrinting = false;
        default xml namespace = XHTML;

        let info = this.isActive ? <span highlight="Enabled">enabled</span>
                                 : <span highlight="Disabled">disabled</span>;

        let pending;
        if (this.pendingOperations & AddonManager.PENDING_UNINSTALL)
            pending = ["Disabled", "uninstalled"];
        else if (this.pendingOperations & AddonManager.PENDING_DISABLE)
            pending = ["Disabled", "disabled"];<commit_msg>Fix revision 8844fd390b8c.<commit_after>// Copyright (c) 2009-2011 by <NAME> <<EMAIL>>
// Copyright (c) 2009-2010 by <NAME> <<EMAIL>>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
/* use strict */

try {

Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("addons", {
    exports: ["AddonManager", "Addons", "Addon", "addons"],
    require: ["services"]
}, this);

var callResult = function callResult(method) {
    let args = Array.slice(arguments, 1);
    return function (result) { result[method].apply(result, args); };
}

var listener = function listener(action, event)
    function addonListener(install) {
        this.dactyl[install.error ? "echoerr" : "echomsg"](
            _("addon.error", action, event, (install.name || install.sourceURI.spec) +
                (install.error ? ": " + addons.errors[install.error] : "")));
    }

var AddonListener = Class("AddonListener", {
    init: function init(modules) {
        this.dactyl = modules.dactyl;
    },

    onNewInstall:        function (install) {},
    onExternalInstall:   function (addon, existingAddon, needsRestart) {},
    onDownloadStarted:   listener("download", "started"),
    onDownloadEnded:     listener("download", "complete"),
    onDownloadCancelled: listener("download", "canceled"),
    onDownloadFailed:    listener("download", "failed"),
    onDownloadProgress:  function (install) {},
    onInstallStarted:    function (install) {},
    onInstallEnded:      listener("installation", "complete"),
    onInstallCancelled:  listener("installation", "canceled"),
    onInstallFailed:     listener("installation", "failed")
});

var updateAddons = Class("UpgradeListener", AddonListener, {
    init: function init(addons, modules) {
        init.supercall(this, modules);

        util.assert(!addons.length || addons[0].findUpdates,
                    _("error.unavailable", config.host, services.runtime.version));

        this.remaining = addons;
        this.upgrade = [];
        this.dactyl.echomsg(_("addon.check", addons.map(function (a) a.name).join(", ")));
        for (let addon in values(addons))
            addon.findUpdates(this, AddonManager.UPDATE_WHEN_USER_REQUESTED, null, null);

    },
    onUpdateAvailable: function (addon, install) {
        this.upgrade.push(addon);
        install.addListener(this);
        install.install();
    },
    onUpdateFinished: function (addon, error) {
        this.remaining = this.remaining.filter(function (a) a.type != addon.type || a.id != addon.id);
        if (!this.remaining.length)
            this.dactyl.echomsg(
                this.upgrade.length
                    ? _("addon.installingUpdates", this.upgrade.map(function (i) i.name).join(", "))
                    : _("addon.noUpdates"));
    }
});

var actions = {
    delete: {
        name: ["extde[lete]", "extrm"],
        description: "Uninstall an extension",
        action: callResult("uninstall"),
        perm: "uninstall"
    },
    enable: {
        name: "exte[nable]",
        description: "Enable an extension",
        action: function (addon) { addon.userDisabled = false; },
        filter: function (addon) addon.userDisabled,
        perm: "enable"
    },
    disable: {
        name: "extd[isable]",
        description: "Disable an extension",
        action: function (addon) { addon.userDisabled = true; },
        filter: function (addon) !addon.userDisabled,
        perm: "disable"
    },
    options: {
        name: ["exto[ptions]", "extp[references]"],
        description: "Open an extension's preference dialog",
        bang: true,
        action: function (addon, bang) {
            if (bang)
                this.window.openDialog(addon.optionsURL, "_blank", "chrome");
            else
                this.dactyl.open(addon.optionsURL, { from: "extoptions" });
        },
        filter: function (addon) addon.isActive && addon.optionsURL
    },
    rehash: {
        name: "extr[ehash]",
        description: "Reload an extension",
        action: function (addon) {
            util.assert(config.haveGecko("2b"), _("command.notUseful", config.host));
            util.flushCache();
            util.timeout(function () {
                addon.userDisabled = true;
                addon.userDisabled = false;
            });
        },
        get filter() {
            return function (addon) !addon.userDisabled &&
                !(addon.operationsRequiringRestart & (AddonManager.OP_NEEDS_RESTART_ENABLE | AddonManager.OP_NEEDS_RESTART_DISABLE))
        },
        perm: "disable"
    },
    toggle: {
        name: "extt[oggle]",
        description: "Toggle an extension's enabled status",
        action: function (addon) { addon.userDisabled = !addon.userDisabled; }
    },
    update: {
        name: "extu[pdate]",
        description: "Update an extension",
        actions: updateAddons,
        perm: "upgrade"
    }
};

var Addon = Class("Addon", {
    init: function init(addon, list) {
        this.addon = addon;
        this.instance = this;
        this.list = list;

        this.nodes = {
            commandTarget: this
        };
        XML.ignoreWhitespace = true;
        util.xmlToDom(
            <tr highlight="Addon" key="row" xmlns:dactyl={NS} xmlns={XHTML}>
                <td highlight="AddonName" key="name"/>
                <td highlight="AddonVersion" key="version"/>
                <td highlight="AddonButtons Buttons">
                    <a highlight="Button" href="javascript:0" key="enable">{_("addon.action.On")}</a>
                    <a highlight="Button" href="javascript:0" key="disable">{_("addon.action.Off")}</a>
                    <a highlight="Button" href="javascript:0" key="delete">{_("addon.action.Delete")}</a>
                    <a highlight="Button" href="javascript:0" key="update">{_("addon.action.Update")}</a>
                    <a highlight="Button" href="javascript:0" key="options">{_("addon.action.Options")}</a>
                </td>
                <td highlight="AddonStatus" key="status"/>
                <td highlight="AddonDescription" key="description"/>
            </tr>,
            this.list.document, this.nodes);

        this.update();
    },

    commandAllowed: function commandAllowed(cmd) {
        util.assert(Set.has(actions, cmd), _("addon.unknownCommand"));

        let action = actions[cmd];
        if ("perm" in action && !(this.permissions & AddonManager["PERM_CAN_" + action.perm.toUpperCase()]))
            return false;
        if ("filter" in action && !action.filter(this))
            return false;
        return true;
    },

    command: function command(cmd) {
        util.assert(this.commandAllowed(cmd), _("addon.commandNotAllowed"));

        let action = actions[cmd];
        if (action.action)
            action.action.call(this.list.modules, this, true);
        else
            action.actions([this], this.list.modules);
    },

    compare: function compare(other) String.localeCompare(this.name, other.name),

    get statusInfo() {
        XML.ignoreWhitespace = XML.prettyPrinting = false;
        default xml namespace = XHTML;

        let info = this.isActive ? <span highlight="Enabled">enabled</span>
                                 : <span highlight="Disabled">disabled</span>;

        let pending;
        if (this.pendingOperations & AddonManager.PENDING_UNINSTALL)
            pending = ["Disabled", "uninstalled"];
        else if (this.pendingOperations & AddonManager.PENDING_DISABLE)
            pending = ["Disabled", "disabled"];
{'fraction_non_alphanumeric': 0.14503766786767114, 'fraction_numerical': 0.0036685227644939404, 'mean_word_length': 2.470334166856104, 'pattern_counts': {'":': 2, '<': 59, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1649526', 'n_tokens_mistral': 4493, 'n_tokens_neox': 4389, 'n_words': 915}