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.

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

mercurial