commit
ac02c45e81
5 changed files with 157 additions and 127 deletions
94
index.js
94
index.js
|
@ -196,12 +196,11 @@ const ContainerService = {
|
|||
"moveTabsToWindow",
|
||||
"queryIdentities",
|
||||
"getIdentity",
|
||||
"createIdentity",
|
||||
"removeIdentity",
|
||||
"updateIdentity",
|
||||
"getPreference",
|
||||
"sendTelemetryPayload",
|
||||
"getTheme",
|
||||
"refreshNeeded",
|
||||
"forgetIdentityAndRefresh",
|
||||
"checkIncompatibleAddons"
|
||||
];
|
||||
|
||||
|
@ -309,7 +308,7 @@ const ContainerService = {
|
|||
},
|
||||
|
||||
registerBackgroundConnection(api) {
|
||||
// This is only used for theme and container deletion notifications
|
||||
// This is only used for theme notifications
|
||||
api.browser.runtime.onConnect.addListener((port) => {
|
||||
this._onBackgroundConnectCallback = (message, topic) => {
|
||||
port.postMessage({
|
||||
|
@ -911,86 +910,6 @@ const ContainerService = {
|
|||
return Promise.resolve(identity ? this._convert(identity) : null);
|
||||
},
|
||||
|
||||
createIdentity(args) {
|
||||
this.sendTelemetryPayload({
|
||||
"event": "add-container",
|
||||
});
|
||||
|
||||
for (let arg of [ "name", "color", "icon"]) { // eslint-disable-line prefer-const
|
||||
if (!(arg in args)) {
|
||||
return Promise.reject("createIdentity must be called with " + arg + " argument.");
|
||||
}
|
||||
}
|
||||
|
||||
const color = this._fromNameToColor(args.color);
|
||||
const icon = this._fromNameToIcon(args.icon);
|
||||
|
||||
const identity = ContextualIdentityProxy.create(args.name, icon, color);
|
||||
|
||||
this._identitiesState[identity.userContextId] = this._createIdentityState();
|
||||
|
||||
this._refreshNeeded().then(() => {
|
||||
return this._convert(identity);
|
||||
}).catch(() => {
|
||||
return this._convert(identity);
|
||||
});
|
||||
},
|
||||
|
||||
updateIdentity(args) {
|
||||
if (!("userContextId" in args)) {
|
||||
return Promise.reject("updateIdentity must be called with userContextId argument.");
|
||||
}
|
||||
|
||||
this.sendTelemetryPayload({
|
||||
"event": "edit-container",
|
||||
"userContextId": args.userContextId
|
||||
});
|
||||
|
||||
const identity = ContextualIdentityProxy.getIdentityFromId(args.userContextId);
|
||||
for (let arg of [ "name", "color", "icon"]) { // eslint-disable-line prefer-const
|
||||
if ((arg in args)) {
|
||||
identity[arg] = args[arg];
|
||||
}
|
||||
}
|
||||
|
||||
const color = this._fromNameToColor(identity.color);
|
||||
const icon = this._fromNameToIcon(identity.icon);
|
||||
|
||||
const updated = ContextualIdentityProxy.update(args.userContextId,
|
||||
identity.name,
|
||||
icon, color);
|
||||
|
||||
this._refreshNeeded().then(() => {
|
||||
return updated;
|
||||
}).catch(() => {
|
||||
return updated;
|
||||
});
|
||||
},
|
||||
|
||||
removeIdentity(args) {
|
||||
const eventName = "delete-container";
|
||||
if (!("userContextId" in args)) {
|
||||
return Promise.reject("removeIdentity must be called with userContextId argument.");
|
||||
}
|
||||
|
||||
this.sendTelemetryPayload({
|
||||
"event": eventName,
|
||||
"userContextId": args.userContextId
|
||||
});
|
||||
|
||||
const tabsToClose = [];
|
||||
this._containerTabIterator(args.userContextId, tab => {
|
||||
tabsToClose.push(tab);
|
||||
});
|
||||
|
||||
return this._closeTabs(tabsToClose).then(() => {
|
||||
const removed = ContextualIdentityProxy.remove(args.userContextId);
|
||||
this.triggerBackgroundCallback({userContextId: args.userContextId}, eventName);
|
||||
this._forgetIdentity(args.userContextId);
|
||||
return this._refreshNeeded().then(() => removed );
|
||||
});
|
||||
},
|
||||
|
||||
// Preferences
|
||||
|
||||
getPreference(args) {
|
||||
|
@ -1039,7 +958,7 @@ const ContainerService = {
|
|||
return this._windowMap.get(window);
|
||||
},
|
||||
|
||||
_refreshNeeded() {
|
||||
refreshNeeded() {
|
||||
return this._configureWindows();
|
||||
},
|
||||
|
||||
|
@ -1169,6 +1088,11 @@ const ContainerService = {
|
|||
// End-Of-Hack
|
||||
},
|
||||
|
||||
forgetIdentityAndRefresh(args) {
|
||||
this._forgetIdentity(args.userContextId);
|
||||
return this.refreshNeeded();
|
||||
},
|
||||
|
||||
_forgetIdentity(userContextId = 0) {
|
||||
for (let window of windows.browserWindows) { // eslint-disable-line prefer-const
|
||||
window = viewFor(window);
|
||||
|
|
|
@ -58,22 +58,22 @@ const assignManager = {
|
|||
}
|
||||
},
|
||||
|
||||
init() {
|
||||
browser.runtime.onMessage.addListener((neverAskMessage) => {
|
||||
const pageUrl = neverAskMessage.pageUrl;
|
||||
if (neverAskMessage.neverAsk === true) {
|
||||
// If we have existing data and for some reason it hasn't been deleted etc lets update it
|
||||
this.storageArea.get(pageUrl).then((siteSettings) => {
|
||||
if (siteSettings) {
|
||||
siteSettings.neverAsk = true;
|
||||
this.storageArea.set(pageUrl, siteSettings);
|
||||
}
|
||||
}).catch((e) => {
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
});
|
||||
_neverAsk(m) {
|
||||
const pageUrl = m.pageUrl;
|
||||
if (m.neverAsk === true) {
|
||||
// If we have existing data and for some reason it hasn't been deleted etc lets update it
|
||||
this.storageArea.get(pageUrl).then((siteSettings) => {
|
||||
if (siteSettings) {
|
||||
siteSettings.neverAsk = true;
|
||||
this.storageArea.set(pageUrl, siteSettings);
|
||||
}
|
||||
}).catch((e) => {
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
init() {
|
||||
browser.contextMenus.onClicked.addListener((info, tab) => {
|
||||
const userContextId = this.getUserContextIdFromCookieStore(tab);
|
||||
// Mapping ${URL(info.pageUrl).hostname} to ${userContextId}
|
||||
|
@ -97,8 +97,7 @@ const assignManager = {
|
|||
message: `Successfully ${actionName} site to always open in this container`,
|
||||
iconUrl: browser.extension.getURL("/img/onboarding-1.png")
|
||||
});
|
||||
browser.runtime.sendMessage({
|
||||
method: "sendTelemetryPayload",
|
||||
backgroundLogic.sendTelemetryPayload({
|
||||
event: `${actionName}-container-assignment`,
|
||||
userContextId: userContextId,
|
||||
});
|
||||
|
@ -218,14 +217,12 @@ const assignManager = {
|
|||
// If the user has explicitly checked "Never Ask Again" on the warning page we will send them straight there
|
||||
if (neverAsk) {
|
||||
browser.tabs.create({url, cookieStoreId: `firefox-container-${userContextId}`, index});
|
||||
browser.runtime.sendMessage({
|
||||
method: "sendTelemetryPayload",
|
||||
backgroundLogic.sendTelemetryPayload({
|
||||
event: "auto-reload-page-in-container",
|
||||
userContextId: userContextId,
|
||||
});
|
||||
} else {
|
||||
browser.runtime.sendMessage({
|
||||
method: "sendTelemetryPayload",
|
||||
backgroundLogic.sendTelemetryPayload({
|
||||
event: "prompt-to-reload-page-in-container",
|
||||
userContextId: userContextId,
|
||||
});
|
||||
|
@ -240,6 +237,77 @@ const assignManager = {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
const backgroundLogic = {
|
||||
deleteContainer(userContextId) {
|
||||
this.sendTelemetryPayload({
|
||||
event: "delete-container",
|
||||
userContextId
|
||||
});
|
||||
|
||||
const removeTabsPromise = this._containerTabs(userContextId).then((tabs) => {
|
||||
const tabIds = tabs.map((tab) => tab.id);
|
||||
return browser.tabs.remove(tabIds);
|
||||
});
|
||||
|
||||
return new Promise((resolve) => {
|
||||
removeTabsPromise.then(() => {
|
||||
const removed = browser.contextualIdentities.remove(this.cookieStoreId(userContextId));
|
||||
removed.then(() => {
|
||||
assignManager.deleteContainer(userContextId);
|
||||
browser.runtime.sendMessage({
|
||||
method: "forgetIdentityAndRefresh"
|
||||
}).then(() => {
|
||||
resolve({done: true, userContextId});
|
||||
}).catch((e) => {throw e;});
|
||||
}).catch((e) => {throw e;});
|
||||
}).catch((e) => {throw e;});
|
||||
});
|
||||
},
|
||||
|
||||
createOrUpdateContainer(options) {
|
||||
let donePromise;
|
||||
if (options.userContextId) {
|
||||
donePromise = browser.contextualIdentities.update(
|
||||
this.cookieStoreId(options.userContextId),
|
||||
options.params
|
||||
);
|
||||
this.sendTelemetryPayload({
|
||||
event: "edit-container",
|
||||
userContextId: options.userContextId
|
||||
});
|
||||
} else {
|
||||
donePromise = browser.contextualIdentities.create(options.params);
|
||||
this.sendTelemetryPayload({
|
||||
event: "add-container"
|
||||
});
|
||||
}
|
||||
return donePromise.then(() => {
|
||||
browser.runtime.sendMessage({
|
||||
method: "refreshNeeded"
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
sendTelemetryPayload(message = {}) {
|
||||
if (!message.event) {
|
||||
throw new Error("Missing event name for telemetry");
|
||||
}
|
||||
message.method = "sendTelemetryPayload";
|
||||
browser.runtime.sendMessage(message);
|
||||
},
|
||||
|
||||
cookieStoreId(userContextId) {
|
||||
return `firefox-container-${userContextId}`;
|
||||
},
|
||||
|
||||
_containerTabs(userContextId) {
|
||||
return browser.tabs.query({
|
||||
cookieStoreId: this.cookieStoreId(userContextId)
|
||||
}).catch((e) => {throw e;});
|
||||
},
|
||||
};
|
||||
|
||||
const messageHandler = {
|
||||
// After the timer completes we assume it's a tab the user meant to keep open
|
||||
// We use this to catch redirected tabs that have just opened
|
||||
|
@ -247,6 +315,23 @@ const messageHandler = {
|
|||
LAST_CREATED_TAB_TIMER: 2000,
|
||||
|
||||
init() {
|
||||
browser.runtime.onMessage.addListener((m) => {
|
||||
let response;
|
||||
|
||||
switch (m.method) {
|
||||
case "deleteContainer":
|
||||
response = backgroundLogic.deleteContainer(m.message.userContextId);
|
||||
break;
|
||||
case "createOrUpdateContainer":
|
||||
response = backgroundLogic.createOrUpdateContainer(m.message);
|
||||
break;
|
||||
case "neverAsk":
|
||||
assignManager._neverAsk(m);
|
||||
break;
|
||||
}
|
||||
return response;
|
||||
});
|
||||
|
||||
// Handles messages from index.js
|
||||
const port = browser.runtime.connect();
|
||||
port.onMessage.addListener(m => {
|
||||
|
@ -254,9 +339,6 @@ const messageHandler = {
|
|||
case "lightweight-theme-changed":
|
||||
themeManager.update(m.message);
|
||||
break;
|
||||
case "delete-container":
|
||||
assignManager.deleteContainer(m.message.userContextId);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unhandled message type: ${m.message}`);
|
||||
}
|
||||
|
@ -408,8 +490,7 @@ const tabPageCounter = {
|
|||
return;
|
||||
}
|
||||
if (why === "user-closed-tab" && this.counters[tabId].tab) {
|
||||
browser.runtime.sendMessage({
|
||||
method: "sendTelemetryPayload",
|
||||
backgroundLogic.sendTelemetryPayload({
|
||||
event: "page-requests-completed-per-tab",
|
||||
userContextId: this.counters[tabId].tab.cookieStoreId,
|
||||
pageRequestCount: this.counters[tabId].tab.pageRequests
|
||||
|
@ -418,8 +499,7 @@ const tabPageCounter = {
|
|||
// delete both the 'tab' and 'activity' counters
|
||||
delete this.counters[tabId];
|
||||
} else if (why === "user-went-idle" && this.counters[tabId].activity) {
|
||||
browser.runtime.sendMessage({
|
||||
method: "sendTelemetryPayload",
|
||||
backgroundLogic.sendTelemetryPayload({
|
||||
event: "page-requests-completed-per-activity",
|
||||
userContextId: this.counters[tabId].activity.cookieStoreId,
|
||||
pageRequestCount: this.counters[tabId].activity.pageRequests
|
||||
|
|
|
@ -9,6 +9,7 @@ document.getElementById("redirect-form").addEventListener("submit", (e) => {
|
|||
// Sending neverAsk message to background to store for next time we see this process
|
||||
if (neverAsk) {
|
||||
browser.runtime.sendMessage({
|
||||
method: "neverAsk",
|
||||
neverAsk: true,
|
||||
pageUrl: redirectUrl
|
||||
}).then(() => {
|
||||
|
|
|
@ -141,6 +141,25 @@ const Logic = {
|
|||
return this._currentIdentity;
|
||||
},
|
||||
|
||||
sendTelemetryPayload(message = {}) {
|
||||
if (!message.event) {
|
||||
throw new Error("Missing event name for telemetry");
|
||||
}
|
||||
message.method = "sendTelemetryPayload";
|
||||
browser.runtime.sendMessage(message);
|
||||
},
|
||||
|
||||
removeIdentity(userContextId) {
|
||||
if (!userContextId) {
|
||||
return Promise.reject("removeIdentity must be called with userContextId argument.");
|
||||
}
|
||||
|
||||
return browser.runtime.sendMessage({
|
||||
method: "deleteContainer",
|
||||
message: {userContextId}
|
||||
});
|
||||
},
|
||||
|
||||
generateIdentityName() {
|
||||
const defaultName = "Container #";
|
||||
const ids = [];
|
||||
|
@ -240,8 +259,7 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
|||
});
|
||||
|
||||
document.querySelector("#edit-containers-link").addEventListener("click", () => {
|
||||
browser.runtime.sendMessage({
|
||||
method: "sendTelemetryPayload",
|
||||
Logic.sendTelemetryPayload({
|
||||
event: "edit-containers"
|
||||
});
|
||||
Logic.showPanel(P_CONTAINERS_EDIT);
|
||||
|
@ -360,12 +378,12 @@ Logic.registerPanel(P_CONTAINER_INFO, {
|
|||
moveTabsEl.parentNode.insertBefore(fragment, moveTabsEl.nextSibling);
|
||||
} else {
|
||||
moveTabsEl.addEventListener("click", () => {
|
||||
return browser.runtime.sendMessage({
|
||||
browser.runtime.sendMessage({
|
||||
method: "moveTabsToWindow",
|
||||
userContextId: Logic.currentIdentity().userContextId,
|
||||
}).then(() => {
|
||||
window.close();
|
||||
});
|
||||
}).catch((e) => { throw e; });
|
||||
});
|
||||
}
|
||||
}).catch(() => {
|
||||
|
@ -531,12 +549,16 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
_submitForm() {
|
||||
const identity = Logic.currentIdentity();
|
||||
const formValues = new FormData(this._editForm);
|
||||
browser.runtime.sendMessage({
|
||||
method: identity.userContextId ? "updateIdentity" : "createIdentity",
|
||||
userContextId: identity.userContextId || 0,
|
||||
name: document.getElementById("edit-container-panel-name-input").value || Logic.generateIdentityName(),
|
||||
icon: formValues.get("container-icon") || DEFAULT_ICON,
|
||||
color: formValues.get("container-color") || DEFAULT_COLOR,
|
||||
return browser.runtime.sendMessage({
|
||||
method: "createOrUpdateContainer",
|
||||
message: {
|
||||
userContextId: identity.userContextId || false,
|
||||
params: {
|
||||
name: document.getElementById("edit-container-panel-name-input").value || Logic.generateIdentityName(),
|
||||
icon: formValues.get("container-icon") || DEFAULT_ICON,
|
||||
color: formValues.get("container-color") || DEFAULT_COLOR,
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
return Logic.refreshIdentities();
|
||||
}).then(() => {
|
||||
|
@ -603,10 +625,12 @@ Logic.registerPanel(P_CONTAINER_DELETE, {
|
|||
});
|
||||
|
||||
document.querySelector("#delete-container-ok-link").addEventListener("click", () => {
|
||||
browser.runtime.sendMessage({
|
||||
method: "removeIdentity",
|
||||
userContextId: Logic.currentIdentity().userContextId,
|
||||
}).then(() => {
|
||||
/* This promise wont resolve if the last tab was removed from the window.
|
||||
as the message async callback stops listening, this isn't an issue for us however it might be in future
|
||||
if you want to do anything post delete do it in the background script.
|
||||
Browser console currently warns about not listening also.
|
||||
*/
|
||||
Logic.removeIdentity(Logic.currentIdentity().userContextId).then(() => {
|
||||
return Logic.refreshIdentities();
|
||||
}).then(() => {
|
||||
Logic.showPreviousPanel();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"activeTab",
|
||||
"cookies",
|
||||
"contextMenus",
|
||||
"contextualIdentities",
|
||||
"history",
|
||||
"idle",
|
||||
"notifications",
|
||||
|
|
Loading…
Add table
Reference in a new issue