gecko-dev/toolkit/components/extensions/parent/ext-contextualIdentities.js
Kendall Werts 7f966c7fbf Bug 1606265 - Work on new tab containers menu popup. r=fluent-reviewers,Gijs,flod
Added right click on new tab button to open containers menu.
Removed long press and added option to enable left click in preferences menu.
Renamed privacy.userContext.longPressBehavior to privacy.userContext.newTabContainer.enabled

Differential Revision: https://phabricator.services.mozilla.com/D58410

--HG--
extra : moz-landing-system : lando
2020-01-23 22:28:30 +00:00

338 lines
9.1 KiB
JavaScript

/* 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.defineModuleGetter(
this,
"ContextualIdentityService",
"resource://gre/modules/ContextualIdentityService.jsm"
);
XPCOMUtils.defineLazyPreferenceGetter(
this,
"containersEnabled",
"privacy.userContext.enabled"
);
var { ExtensionPreferencesManager } = ChromeUtils.import(
"resource://gre/modules/ExtensionPreferencesManager.jsm"
);
var { ExtensionError } = ExtensionUtils;
const CONTAINER_PREF_INSTALL_DEFAULTS = {
"privacy.userContext.enabled": true,
"privacy.userContext.ui.enabled": true,
"privacy.usercontext.about_newtab_segregation.enabled": true,
"privacy.userContext.extension": undefined,
};
const CONTAINERS_ENABLED_SETTING_NAME = "privacy.containers";
const CONTAINER_COLORS = new Map([
["blue", "#37adff"],
["turquoise", "#00c79a"],
["green", "#51cd00"],
["yellow", "#ffcb00"],
["orange", "#ff9f00"],
["red", "#ff613d"],
["pink", "#ff4bda"],
["purple", "#af51f5"],
["toolbar", "#7c7c7d"],
]);
const CONTAINER_ICONS = new Set([
"briefcase",
"cart",
"circle",
"dollar",
"fence",
"fingerprint",
"gift",
"vacation",
"food",
"fruit",
"pet",
"tree",
"chill",
]);
function getContainerIcon(iconName) {
if (!CONTAINER_ICONS.has(iconName)) {
throw new ExtensionError(`Invalid icon ${iconName} for container`);
}
return `resource://usercontext-content/${iconName}.svg`;
}
function getContainerColor(colorName) {
if (!CONTAINER_COLORS.has(colorName)) {
throw new ExtensionError(`Invalid color name ${colorName} for container`);
}
return CONTAINER_COLORS.get(colorName);
}
const convertIdentity = identity => {
let result = {
name: ContextualIdentityService.getUserContextLabel(identity.userContextId),
icon: identity.icon,
iconUrl: getContainerIcon(identity.icon),
color: identity.color,
colorCode: getContainerColor(identity.color),
cookieStoreId: getCookieStoreIdForContainer(identity.userContextId),
};
return result;
};
const checkAPIEnabled = () => {
if (!containersEnabled) {
throw new ExtensionError("Contextual identities are currently disabled");
}
};
const convertIdentityFromObserver = wrappedIdentity => {
let identity = wrappedIdentity.wrappedJSObject;
let iconUrl, colorCode;
try {
iconUrl = getContainerIcon(identity.icon);
colorCode = getContainerColor(identity.color);
} catch (e) {
return null;
}
let result = {
name: identity.name,
icon: identity.icon,
iconUrl,
color: identity.color,
colorCode,
cookieStoreId: getCookieStoreIdForContainer(identity.userContextId),
};
return result;
};
ExtensionPreferencesManager.addSetting(CONTAINERS_ENABLED_SETTING_NAME, {
prefNames: Object.keys(CONTAINER_PREF_INSTALL_DEFAULTS),
setCallback(value) {
if (value !== true) {
return {
...CONTAINER_PREF_INSTALL_DEFAULTS,
"privacy.userContext.extension": value,
};
}
return {};
},
});
this.contextualIdentities = class extends ExtensionAPI {
onStartup() {
let { extension } = this;
if (extension.hasPermission("contextualIdentities")) {
ExtensionPreferencesManager.setSetting(
extension.id,
CONTAINERS_ENABLED_SETTING_NAME,
extension.id
);
}
}
getAPI(context) {
let self = {
contextualIdentities: {
async get(cookieStoreId) {
checkAPIEnabled();
let containerId = getContainerForCookieStoreId(cookieStoreId);
if (!containerId) {
throw new ExtensionError(
`Invalid contextual identity: ${cookieStoreId}`
);
}
let identity = ContextualIdentityService.getPublicIdentityFromId(
containerId
);
return convertIdentity(identity);
},
async query(details) {
checkAPIEnabled();
let identities = [];
ContextualIdentityService.getPublicIdentities().forEach(identity => {
if (
details.name &&
ContextualIdentityService.getUserContextLabel(
identity.userContextId
) != details.name
) {
return;
}
identities.push(convertIdentity(identity));
});
return identities;
},
async create(details) {
// Lets prevent making containers that are not valid
getContainerIcon(details.icon);
getContainerColor(details.color);
let identity = ContextualIdentityService.create(
details.name,
details.icon,
details.color
);
return convertIdentity(identity);
},
async update(cookieStoreId, details) {
checkAPIEnabled();
let containerId = getContainerForCookieStoreId(cookieStoreId);
if (!containerId) {
throw new ExtensionError(
`Invalid contextual identity: ${cookieStoreId}`
);
}
let identity = ContextualIdentityService.getPublicIdentityFromId(
containerId
);
if (!identity) {
throw new ExtensionError(
`Invalid contextual identity: ${cookieStoreId}`
);
}
if (details.name !== null) {
identity.name = details.name;
}
if (details.color !== null) {
getContainerColor(details.color);
identity.color = details.color;
}
if (details.icon !== null) {
getContainerIcon(details.icon);
identity.icon = details.icon;
}
if (
!ContextualIdentityService.update(
identity.userContextId,
identity.name,
identity.icon,
identity.color
)
) {
throw new ExtensionError(
`Contextual identity failed to update: ${cookieStoreId}`
);
}
return convertIdentity(identity);
},
async remove(cookieStoreId) {
checkAPIEnabled();
let containerId = getContainerForCookieStoreId(cookieStoreId);
if (!containerId) {
throw new ExtensionError(
`Invalid contextual identity: ${cookieStoreId}`
);
}
let identity = ContextualIdentityService.getPublicIdentityFromId(
containerId
);
if (!identity) {
throw new ExtensionError(
`Invalid contextual identity: ${cookieStoreId}`
);
}
// We have to create the identity object before removing it.
let convertedIdentity = convertIdentity(identity);
if (!ContextualIdentityService.remove(identity.userContextId)) {
throw new ExtensionError(
`Contextual identity failed to remove: ${cookieStoreId}`
);
}
return convertedIdentity;
},
onCreated: new EventManager({
context,
name: "contextualIdentities.onCreated",
register: fire => {
let observer = (subject, topic) => {
let convertedIdentity = convertIdentityFromObserver(subject);
if (convertedIdentity) {
fire.async({ contextualIdentity: convertedIdentity });
}
};
Services.obs.addObserver(observer, "contextual-identity-created");
return () => {
Services.obs.removeObserver(
observer,
"contextual-identity-created"
);
};
},
}).api(),
onUpdated: new EventManager({
context,
name: "contextualIdentities.onUpdated",
register: fire => {
let observer = (subject, topic) => {
let convertedIdentity = convertIdentityFromObserver(subject);
if (convertedIdentity) {
fire.async({ contextualIdentity: convertedIdentity });
}
};
Services.obs.addObserver(observer, "contextual-identity-updated");
return () => {
Services.obs.removeObserver(
observer,
"contextual-identity-updated"
);
};
},
}).api(),
onRemoved: new EventManager({
context,
name: "contextualIdentities.onRemoved",
register: fire => {
let observer = (subject, topic) => {
let convertedIdentity = convertIdentityFromObserver(subject);
if (convertedIdentity) {
fire.async({ contextualIdentity: convertedIdentity });
}
};
Services.obs.addObserver(observer, "contextual-identity-deleted");
return () => {
Services.obs.removeObserver(
observer,
"contextual-identity-deleted"
);
};
},
}).api(),
},
};
return self;
}
};