toolkit/devtools/gcli/commands/addon.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 const { Cc, Ci, Cu } = require("chrome");
     8 const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
     9 const gcli = require("gcli/index");
    10 const { Promise: promise } = require("resource://gre/modules/Promise.jsm");
    12 const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"]
    13                            .getService(Ci.nsIStringBundleService)
    14                            .createBundle("chrome://branding/locale/brand.properties")
    15                            .GetStringFromName("brandShortName");
    17 /**
    18  * Takes a function that uses a callback as its last parameter, and returns a
    19  * new function that returns a promise instead.
    20  * This should probably live in async-util
    21  */
    22 const promiseify = function(scope, functionWithLastParamCallback) {
    23   return (...args) => {
    24     return new Promise(resolve => {
    25       args.push((...results) => {
    26         resolve(results.length > 1 ? results : results[0]);
    27       });
    28       functionWithLastParamCallback.apply(scope, args);
    29     });
    30   }
    31 };
    33 // Convert callback based functions to promise based ones
    34 const getAllAddons = promiseify(AddonManager, AddonManager.getAllAddons);
    35 const getAddonsByTypes = promiseify(AddonManager, AddonManager.getAddonsByTypes);
    37 /**
    38  * Return a string array containing the pending operations on an addon
    39  */
    40 function pendingOperations(addon) {
    41   let allOperations = [
    42     "PENDING_ENABLE", "PENDING_DISABLE", "PENDING_UNINSTALL",
    43     "PENDING_INSTALL", "PENDING_UPGRADE"
    44   ];
    45   return allOperations.reduce(function(operations, opName) {
    46     return addon.pendingOperations & AddonManager[opName] ?
    47       operations.concat(opName) :
    48       operations;
    49   }, []);
    50 }
    52 exports.items = [
    53   {
    54     item: "type",
    55     name: "addon",
    56     parent: "selection",
    57     stringifyProperty: "name",
    58     cacheable: true,
    59     constructor: function() {
    60       // Tell GCLI to clear the cache of addons when one is added or removed
    61       let listener = {
    62         onInstalled: addon => { this.clearCache(); },
    63         onUninstalled: addon => { this.clearCache(); },
    64       };
    65       AddonManager.addAddonListener(listener);
    66     },
    67     lookup: function() {
    68       return getAllAddons().then(addons => {
    69         return addons.map(addon => {
    70           let name = addon.name + " " + addon.version;
    71           name = name.trim().replace(/\s/g, "_");
    72           return { name: name, value: addon };
    73         });
    74       });
    75     }
    76   },
    77   {
    78     name: "addon",
    79     description: gcli.lookup("addonDesc")
    80   },
    81   {
    82     name: "addon list",
    83     description: gcli.lookup("addonListDesc"),
    84     returnType: "addonsInfo",
    85     params: [{
    86       name: "type",
    87       type: {
    88         name: "selection",
    89         data: [ "dictionary", "extension", "locale", "plugin", "theme", "all" ]
    90       },
    91       defaultValue: "all",
    92       description: gcli.lookup("addonListTypeDesc")
    93     }],
    94     exec: function(args, context) {
    95       let types = (args.type === "all") ? null : [ args.type ];
    96       return getAddonsByTypes(types).then(addons => {
    97         addons = addons.map(function(addon) {
    98           return {
    99             name: addon.name,
   100             version: addon.version,
   101             isActive: addon.isActive,
   102             pendingOperations: pendingOperations(addon)
   103           };
   104         });
   105         return { addons: addons, type: args.type };
   106       });
   107     }
   108   },
   109   {
   110     item: "converter",
   111     from: "addonsInfo",
   112     to: "view",
   113     exec: function(addonsInfo, context) {
   114       if (!addonsInfo.addons.length) {
   115         return context.createView({
   116           html: "<p>${message}</p>",
   117           data: { message: gcli.lookup("addonNoneOfType") }
   118         });
   119       }
   121       let headerLookups = {
   122         "dictionary": "addonListDictionaryHeading",
   123         "extension": "addonListExtensionHeading",
   124         "locale": "addonListLocaleHeading",
   125         "plugin": "addonListPluginHeading",
   126         "theme": "addonListThemeHeading",
   127         "all": "addonListAllHeading"
   128       };
   129       let header = gcli.lookup(headerLookups[addonsInfo.type] ||
   130                                "addonListUnknownHeading");
   132       let operationLookups = {
   133         "PENDING_ENABLE": "addonPendingEnable",
   134         "PENDING_DISABLE": "addonPendingDisable",
   135         "PENDING_UNINSTALL": "addonPendingUninstall",
   136         "PENDING_INSTALL": "addonPendingInstall",
   137         "PENDING_UPGRADE": "addonPendingUpgrade"
   138       };
   139       function lookupOperation(opName) {
   140         let lookupName = operationLookups[opName];
   141         return lookupName ? gcli.lookup(lookupName) : opName;
   142       }
   144       function arrangeAddons(addons) {
   145         let enabledAddons = [];
   146         let disabledAddons = [];
   147         addons.forEach(function(addon) {
   148           if (addon.isActive) {
   149             enabledAddons.push(addon);
   150           } else {
   151             disabledAddons.push(addon);
   152           }
   153         });
   155         function compareAddonNames(nameA, nameB) {
   156           return String.localeCompare(nameA.name, nameB.name);
   157         }
   158         enabledAddons.sort(compareAddonNames);
   159         disabledAddons.sort(compareAddonNames);
   161         return enabledAddons.concat(disabledAddons);
   162       }
   164       function isActiveForToggle(addon) {
   165         return (addon.isActive && ~~addon.pendingOperations.indexOf("PENDING_DISABLE"));
   166       }
   168       return context.createView({
   169         html:
   170           "<table>" +
   171           " <caption>${header}</caption>" +
   172           " <tbody>" +
   173           "  <tr foreach='addon in ${addons}'" +
   174           "      class=\"gcli-addon-${addon.status}\">" +
   175           "    <td>${addon.name} ${addon.version}</td>" +
   176           "    <td>${addon.pendingOperations}</td>" +
   177           "    <td>" +
   178           "      <span class='gcli-out-shortcut'" +
   179           "          data-command='addon ${addon.toggleActionName} ${addon.label}'" +
   180           "          onclick='${onclick}' ondblclick='${ondblclick}'" +
   181           "      >${addon.toggleActionMessage}</span>" +
   182           "    </td>" +
   183           "  </tr>" +
   184           " </tbody>" +
   185           "</table>",
   186         data: {
   187           header: header,
   188           addons: arrangeAddons(addonsInfo.addons).map(function(addon) {
   189             return {
   190               name: addon.name,
   191               label: addon.name.replace(/\s/g, "_") +
   192                     (addon.version ? "_" + addon.version : ""),
   193               status: addon.isActive ? "enabled" : "disabled",
   194               version: addon.version,
   195               pendingOperations: addon.pendingOperations.length ?
   196                 (" (" + gcli.lookup("addonPending") + ": "
   197                  + addon.pendingOperations.map(lookupOperation).join(", ")
   198                  + ")") :
   199                 "",
   200               toggleActionName: isActiveForToggle(addon) ? "disable": "enable",
   201               toggleActionMessage: isActiveForToggle(addon) ?
   202                 gcli.lookup("addonListOutDisable") :
   203                 gcli.lookup("addonListOutEnable")
   204             };
   205           }),
   206           onclick: context.update,
   207           ondblclick: context.updateExec
   208         }
   209       });
   210     }
   211   },
   212   {
   213     name: "addon enable",
   214     description: gcli.lookup("addonEnableDesc"),
   215     params: [
   216       {
   217         name: "addon",
   218         type: "addon",
   219         description: gcli.lookup("addonNameDesc")
   220       }
   221     ],
   222     exec: function(args, context) {
   223       let name = (args.addon.name + " " + args.addon.version).trim();
   224       if (args.addon.userDisabled) {
   225         args.addon.userDisabled = false;
   226         return gcli.lookupFormat("addonEnabled", [ name ]);
   227       }
   229       return gcli.lookupFormat("addonAlreadyEnabled", [ name ]);
   230     }
   231   },
   232   {
   233     name: "addon disable",
   234     description: gcli.lookup("addonDisableDesc"),
   235     params: [
   236       {
   237         name: "addon",
   238         type: "addon",
   239         description: gcli.lookup("addonNameDesc")
   240       }
   241     ],
   242     exec: function(args, context) {
   243       // If the addon is not disabled or is set to "click to play" then
   244       // disable it. Otherwise display the message "Add-on is already
   245       // disabled."
   246       let name = (args.addon.name + " " + args.addon.version).trim();
   247       if (!args.addon.userDisabled ||
   248           args.addon.userDisabled === AddonManager.STATE_ASK_TO_ACTIVATE) {
   249         args.addon.userDisabled = true;
   250         return gcli.lookupFormat("addonDisabled", [ name ]);
   251       }
   253       return gcli.lookupFormat("addonAlreadyDisabled", [ name ]);
   254     }
   255   }
   256 ];

mercurial