Merge branch 'asyncify' into remove-sdk-further

This commit is contained in:
Jonathan Kingston 2017-05-17 16:09:33 +01:00
commit 31f3a76a1c

183
index.js
View file

@ -122,7 +122,7 @@ const ContainerService = {
_containerWasEnabled: false, _containerWasEnabled: false,
_onBackgroundConnectCallback: null, _onBackgroundConnectCallback: null,
init(installation, reason) { async init(installation, reason) {
// If we are just been installed, we must store some information for the // If we are just been installed, we must store some information for the
// uninstallation. This object contains also a version number, in case we // uninstallation. This object contains also a version number, in case we
// need to implement a migration in the future. // need to implement a migration in the future.
@ -267,7 +267,8 @@ const ContainerService = {
// WebExtension startup // WebExtension startup
webExtension.startup().then(api => { try {
const api = await webExtension.startup();
api.browser.runtime.onMessage.addListener((message, sender, sendReply) => { api.browser.runtime.onMessage.addListener((message, sender, sendReply) => {
if ("method" in message && methods.indexOf(message.method) !== -1) { if ("method" in message && methods.indexOf(message.method) !== -1) {
sendReply(this[message.method](message)); sendReply(this[message.method](message));
@ -275,9 +276,9 @@ const ContainerService = {
}); });
this.registerBackgroundConnection(api); this.registerBackgroundConnection(api);
}).catch(() => { } catch (e) {
throw new Error("WebExtension startup failed. Unable to continue."); throw new Error("WebExtension startup failed. Unable to continue.");
}); }
this._sendEvent = new Metrics({ this._sendEvent = new Metrics({
type: "sdk", type: "sdk",
@ -339,13 +340,14 @@ const ContainerService = {
} }
}, },
observe(subject, topic) { async observe(subject, topic) {
if (topic === "lightweight-theme-changed") { if (topic === "lightweight-theme-changed") {
this.getTheme().then((theme) => { try {
const theme = await this.getTheme();
this.triggerBackgroundCallback(theme, topic); this.triggerBackgroundCallback(theme, topic);
}).catch(() => { } catch (e) {
throw new Error("Unable to get theme"); throw new Error("Unable to get theme");
}); }
} }
}, },
@ -454,22 +456,31 @@ const ContainerService = {
return parseInt(viewFor(tab).getAttribute("usercontextid") || 0, 10); return parseInt(viewFor(tab).getAttribute("usercontextid") || 0, 10);
}, },
_createTabObject(tab) { async _createTabObject(tab) {
let url;
try {
url = await getFavicon(tab.url);
} catch (e) {
url = "";
}
return { return {
title: tab.title, title: tab.title,
url: tab.url, url: tab.url,
favicon: url,
id: tab.id, id: tab.id,
active: true, active: true,
pinned: tabsUtils.isPinned(viewFor(tab)) pinned: tabsUtils.isPinned(viewFor(tab))
}; };
}, },
_containerTabIterator(userContextId, cb) { _matchTabsByContainer(userContextId) {
for (let tab of tabs) { // eslint-disable-line prefer-const const matchedTabs = [];
for (const tab of tabs) {
if (userContextId === this._getUserContextIdFromTab(tab)) { if (userContextId === this._getUserContextIdFromTab(tab)) {
cb(tab); matchedTabs.push(tab);
} }
} }
return matchedTabs;
}, },
_createIdentityState() { _createIdentityState() {
@ -490,10 +501,7 @@ const ContainerService = {
}, },
_remapTabsFromUserContextId(userContextId) { _remapTabsFromUserContextId(userContextId) {
this._identitiesState[userContextId].openTabs = 0; this._identitiesState[userContextId].openTabs = this._matchTabsByContainer(userContextId).length;
this._containerTabIterator(userContextId, () => {
++this._identitiesState[userContextId].openTabs;
});
}, },
_remapTab(tab) { _remapTab(tab) {
@ -507,30 +515,25 @@ const ContainerService = {
return userContextId in this._identitiesState; return userContextId in this._identitiesState;
}, },
_closeTabs(tabsToClose) { async _closeTabs(tabsToClose) {
// We create a new tab only if the current operation closes all the // We create a new tab only if the current operation closes all the
// existing ones. // existing ones.
let promise; if (tabs.length === tabsToClose.length) {
if (tabs.length !== tabsToClose.length) { await this.openTab({});
promise = Promise.resolve(null);
} else {
promise = this.openTab({});
} }
return promise.then(() => { for (const tab of tabsToClose) {
for (let tab of tabsToClose) { // eslint-disable-line prefer-const // after .close() window is null. Let's take it now.
// after .close() window is null. Let's take it now. const window = viewFor(tab.window);
const window = viewFor(tab.window);
tab.close(); tab.close();
// forget about this tab. 0 is the index of the forgotten tab and 0 // forget about this tab. 0 is the index of the forgotten tab and 0
// means the last one. // means the last one.
try { try {
SessionStore.forgetClosedTab(window, 0); SessionStore.forgetClosedTab(window, 0);
} catch(e) {} // eslint-disable-line no-empty } catch (e) {} // eslint-disable-line no-empty
} }
}).catch(() => null);
}, },
_recentBrowserWindow() { _recentBrowserWindow() {
@ -563,18 +566,18 @@ const ContainerService = {
let value = payload[keyName]; let value = payload[keyName];
if (value === LOOKUP_KEY) { if (value === LOOKUP_KEY) {
switch (keyName) { switch (keyName) {
case "clickedContainerTabCount": case "clickedContainerTabCount":
value = this._containerTabCount(payload.userContextId); value = this._containerTabCount(payload.userContextId);
break; break;
case "shownContainersCount": case "shownContainersCount":
value = containersCounts.shown; value = containersCounts.shown;
break; break;
case "hiddenContainersCount": case "hiddenContainersCount":
value = containersCounts.hidden; value = containersCounts.hidden;
break; break;
case "totalContainersCount": case "totalContainersCount":
value = containersCounts.total; value = containersCounts.total;
break; break;
} }
} }
payload[keyName] = value; payload[keyName] = value;
@ -600,17 +603,16 @@ const ContainerService = {
// Tabs management // Tabs management
hideTabs(args) { async hideTabs(args) {
if (!("userContextId" in args)) { if (!("userContextId" in args)) {
return Promise.reject("hideTabs must be called with userContextId argument."); return new Error("hideTabs must be called with userContextId argument.");
} }
this._remapTabsIfMissing(args.userContextId); this._remapTabsIfMissing(args.userContextId);
if (!this._isKnownContainer(args.userContextId)) { if (!this._isKnownContainer(args.userContextId)) {
return Promise.resolve(null); return null;
} }
const containersCounts = this._containersCounts();
this.sendTelemetryPayload({ this.sendTelemetryPayload({
"event": "hide-tabs", "event": "hide-tabs",
"userContextId": args.userContextId, "userContextId": args.userContextId,
@ -622,29 +624,25 @@ const ContainerService = {
const tabsToClose = []; const tabsToClose = [];
this._containerTabIterator(args.userContextId, tab => { const tabObjects = await Promise.all(this._matchTabsByContainer(args.userContextId).map((tab) => {
const object = this._createTabObject(tab); tabsToClose.push(tab);
return this._createTabObject(tab);
}));
tabObjects.forEach((object) => {
// This tab is going to be closed. Let's mark this tabObject as // This tab is going to be closed. Let's mark this tabObject as
// non-active. // non-active.
object.active = false; object.active = false;
getFavicon(object.url).then(url => {
object.favicon = url;
}).catch(() => {
object.favicon = "";
});
this._identitiesState[args.userContextId].hiddenTabs.push(object); this._identitiesState[args.userContextId].hiddenTabs.push(object);
tabsToClose.push(tab);
}); });
return this._closeTabs(tabsToClose).then(() => { await this._closeTabs(tabsToClose);
return this._syncTabs();
}); return this._syncTabs();
}, },
showTabs(args) { async showTabs(args) {
if (!("userContextId" in args)) { if (!("userContextId" in args)) {
return Promise.reject("showTabs must be called with userContextId argument."); return Promise.reject("showTabs must be called with userContextId argument.");
} }
@ -679,9 +677,8 @@ const ContainerService = {
this._identitiesState[args.userContextId].hiddenTabs = []; this._identitiesState[args.userContextId].hiddenTabs = [];
return Promise.all(promises).then(() => { await Promise.all(promises);
return this._syncTabs(); return this._syncTabs();
});
}, },
sortTabs() { sortTabs() {
@ -711,7 +708,7 @@ const ContainerService = {
// Let's collect UCIs/tabs for this window. // Let's collect UCIs/tabs for this window.
const map = new Map; const map = new Map;
for (let tab of tabs) { // eslint-disable-line prefer-const for (const tab of tabs) {
if (pinnedTabs && !tabsUtils.isPinned(tab)) { if (pinnedTabs && !tabsUtils.isPinned(tab)) {
// We don't have, or we already handled all the pinned tabs. // We don't have, or we already handled all the pinned tabs.
break; break;
@ -735,44 +732,29 @@ const ContainerService = {
// Let's move tabs. // Let's move tabs.
sortMap.forEach(tabs => { sortMap.forEach(tabs => {
for (let tab of tabs) { // eslint-disable-line prefer-const for (const tab of tabs) {
xulWindow.gBrowser.moveTabTo(tab, pos++); xulWindow.gBrowser.moveTabTo(tab, pos++);
} }
}); });
}, },
getTabs(args) { async getTabs(args) {
if (!("userContextId" in args)) { if (!("userContextId" in args)) {
return Promise.reject("getTabs must be called with userContextId argument."); return new Error("getTabs must be called with userContextId argument.");
} }
this._remapTabsIfMissing(args.userContextId); this._remapTabsIfMissing(args.userContextId);
if (!this._isKnownContainer(args.userContextId)) { if (!this._isKnownContainer(args.userContextId)) {
return Promise.resolve([]); return [];
} }
return new Promise((resolve, reject) => { const promises = [];
const list = []; this._matchTabsByContainer(args.userContextId).forEach((tab) => {
this._containerTabIterator(args.userContextId, tab => { promises.push(this._createTabObject(tab));
list.push(this._createTabObject(tab));
});
const promises = [];
for (let object of list) { // eslint-disable-line prefer-const
promises.push(getFavicon(object.url).then(url => {
object.favicon = url;
}).catch(() => {
object.favicon = "";
}));
}
Promise.all(promises).then(() => {
resolve(list.concat(this._identitiesState[args.userContextId].hiddenTabs));
}).catch((e) => {
reject(e);
});
}); });
const list = await Promise.all(promises);
return list.concat(this._identitiesState[args.userContextId].hiddenTabs);
}, },
showTab(args) { showTab(args) {
@ -782,7 +764,7 @@ const ContainerService = {
return; return;
} }
for (let tab of tabs) { // eslint-disable-line prefer-const for (const tab of tabs) {
if (tab.id === args.tabId) { if (tab.id === args.tabId) {
tab.window.activate(); tab.window.activate();
tab.activate(); tab.activate();
@ -812,11 +794,7 @@ const ContainerService = {
"clickedContainerTabCount": this._containerTabCount(args.userContextId), "clickedContainerTabCount": this._containerTabCount(args.userContextId),
}); });
// Let's create a list of the tabs. const list = this._matchTabsByContainer(args.userContextId);
const list = [];
this._containerTabIterator(args.userContextId, tab => {
list.push(tab);
});
// Nothing to do // Nothing to do
if (list.length === 0 && if (list.length === 0 &&
@ -1183,7 +1161,7 @@ ContainerWindow.prototype = {
} }
}, },
_configurePlusButtonMenu() { async _configurePlusButtonMenu() {
const mainPopupSetElement = this._window.document.getElementById("mainPopupSet"); const mainPopupSetElement = this._window.document.getElementById("mainPopupSet");
// Let's remove all the previous panels. // Let's remove all the previous panels.
@ -1210,7 +1188,8 @@ ContainerWindow.prototype = {
this._cleanAllTimeouts(); this._cleanAllTimeouts();
}); });
return ContainerService.queryIdentities().then(identities => { try {
const identities = await ContainerService.queryIdentities();
identities.forEach(identity => { identities.forEach(identity => {
const menuItemElement = this._window.document.createElementNS(XUL_NS, "menuitem"); const menuItemElement = this._window.document.createElementNS(XUL_NS, "menuitem");
this._panelElement.appendChild(menuItemElement); this._panelElement.appendChild(menuItemElement);
@ -1236,9 +1215,9 @@ ContainerWindow.prototype = {
this._panelElement.appendChild(menuItemElement); this._panelElement.appendChild(menuItemElement);
}); });
}).catch(() => { } catch (e) {
this.hidePanel(); this.hidePanel();
}); }
}, },
_configureTabStyle() { _configureTabStyle() {