diff --git a/index.js b/index.js index e1cd577..be2bb05 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,12 @@ /* global require */ const {ContextualIdentityService} = require('resource://gre/modules/ContextualIdentityService.jsm'); +const { Cc, Ci, Cu, Cr } = require('chrome'); + +Cu.import("resource://gre/modules/Services.jsm"); const tabs = require('sdk/tabs'); const webExtension = require('sdk/webextension'); +const { viewFor } = require("sdk/view/core"); /* Let's start enabling Containers */ var prefs = [ @@ -17,63 +21,26 @@ prefs.forEach((pref) => { prefService.set(pref[0], pref[1]); }); -const CONTAINER_STORE = 'firefox-container-'; - const identitiesState = { }; -function getCookieStoreIdForContainer(containerId) { - return CONTAINER_STORE + containerId; -} - function convert(identity) { - const cookieStoreId = getCookieStoreIdForContainer(identity.userContextId); let hiddenTabUrls = []; - if (cookieStoreId in identitiesState) { - hiddenTabUrls = identitiesState[cookieStoreId].hiddenTabUrls; + if (identity.userContextId in identitiesState) { + hiddenTabUrls = identitiesState[identity.userContextId].hiddenTabUrls; } const result = { name: ContextualIdentityService.getUserContextLabel(identity.userContextId), icon: identity.icon, color: identity.color, - cookieStoreId: cookieStoreId, + userContextId: identity.userContextId, hiddenTabUrls: hiddenTabUrls }; return result; } -function isContainerCookieStoreId(storeId) { - return storeId !== null && storeId.startsWith(CONTAINER_STORE); -} - -function getContainerForCookieStoreId(storeId) { - if (!isContainerCookieStoreId(storeId)) { - return null; - } - - const containerId = storeId.substring(CONTAINER_STORE.length); - - if (ContextualIdentityService.getIdentityFromId(containerId)) { - return parseInt(containerId, 10); - } - - return null; -} - -function getContainer(cookieStoreId) { - const containerId = getContainerForCookieStoreId(cookieStoreId); - - if (!containerId) { - return Promise.resolve(null); - } - - const identity = ContextualIdentityService.getIdentityFromId(containerId); - - return Promise.resolve(convert(identity)); -} - function queryContainers(details) { const identities = []; @@ -86,64 +53,20 @@ function queryContainers(details) { const convertedIdentity = convert(identity); identities.push(convertedIdentity); - if (!(convertedIdentity.cookieStoreId in identitiesState)) { - identitiesState[convertedIdentity.cookieStoreId] = {hiddenTabUrls: []}; + if (!(convertedIdentity.userContextId in identitiesState)) { + identitiesState[convertedIdentity.userContextId] = {hiddenTabUrls: []}; } }); return Promise.resolve(identities); } -function createContainer(details) { - const identity = ContextualIdentityService.create(details.name, - details.icon, - details.color); - - return Promise.resolve(convert(identity)); -} - -function updateContainer(cookieStoreId, details) { - const containerId = getContainerForCookieStoreId(cookieStoreId); - - if (!containerId) { +function removeContainer(userContextId) { + if (!userContextId) { return Promise.resolve(null); } - const identity = ContextualIdentityService.getIdentityFromId(containerId); - - if (!identity) { - return Promise.resolve(null); - } - - if (details.name !== null) { - identity.name = details.name; - } - - if (details.color !== null) { - identity.color = details.color; - } - - if (details.icon !== null) { - identity.icon = details.icon; - } - - if (!ContextualIdentityService.update(identity.userContextId, - identity.name, identity.icon, - identity.color)) { - return Promise.resolve(null); - } - - return Promise.resolve(convert(identity)); -} - -function removeContainer(cookieStoreId) { - const containerId = getContainerForCookieStoreId(cookieStoreId); - - if (!containerId) { - return Promise.resolve(null); - } - - const identity = ContextualIdentityService.getIdentityFromId(containerId); + const identity = ContextualIdentityService.getIdentityFromId(userContextId); if (!identity) { return Promise.resolve(null); @@ -159,44 +82,82 @@ function removeContainer(cookieStoreId) { return Promise.resolve(convertedIdentity); } -const contextualIdentities = { - get: getContainer, - query: queryContainers, - create: createContainer, - update: updateContainer, - remove: removeContainer -}; +function openTab(args) { + let browserWin = Services.wm.getMostRecentWindow('navigator:browser'); + + // This should not really happen. + if (!browserWin || !browserWin.gBrowser) { + return Promise.resolve(false); + } + + let userContextId = 0; + if ('userContextId' in args) { + userContextId = args.userContextId; + } + + let tab = browserWin.gBrowser.addTab(args.url || null, + { userContextId: userContextId }) + browserWin.gBrowser.selectedTab = tab; + return Promise.resolve(true); +} + +function queryTabs(args) { + return new Promise((resolve, reject) => { + let tabList = []; + + for (let tab of tabs) { + let xulTab = viewFor(tab); + let userContextId = parseInt(xulTab.getAttribute('usercontextid') || 0, 10); + + if ("userContextId" in args && args.userContextId != userContextId) { + continue; + } + + tabList.push({ + id: tab.id, + url: tab.url, + userContextId: userContextId, + }); + } + + resolve(tabList); + }); +} + +function removeTabs(ids) { + for (let tab of tabs) { + if (ids.indexOf(tab.id) != -1) { + tab.close(); + } + } + + return Promise.resolve(null); +} function handleWebExtensionMessage(message, sender, sendReply) { switch (message.method) { - case 'query': - sendReply(contextualIdentities.query(message.arguments)); + case 'queryIdentities': + sendReply(queryContainers(message.arguments)); break; - case 'hide': - identitiesState[message.cookieStoreId].hiddenTabUrls = message.tabUrlsToSave; + case 'queryTabs': + sendReply(queryTabs(message)); break; - case 'show': - sendReply(identitiesState[message.cookieStoreId].hiddenTabUrls); - identitiesState[message.cookieStoreId].hiddenTabUrls = []; + case 'hideTabs': + identitiesState[message.userContextId].hiddenTabUrls = message.tabUrlsToSave; break; - case 'get': - sendReply(contextualIdentities.get(message.arguments)); + case 'showTabs': + sendReply(identitiesState[message.userContextId].hiddenTabUrls); + identitiesState[message.userContextId].hiddenTabUrls = []; break; - case 'create': - sendReply(contextualIdentities.create(message.arguments)); - break; - case 'update': - sendReply(contextualIdentities.update(message.arguments)); - break; - case 'remove': - sendReply(contextualIdentities.remove(message.arguments)); + case 'removeTabs': + sendReply(removeTabs(message.tabIds)); + identitiesState[message.userContextId].hiddenTabUrls = []; break; case 'getIdentitiesState': sendReply(identitiesState); break; - case 'open-containers-preferences': - tabs.open('about:preferences#containers'); - sendReply({content: 'opened'}); + case 'openTab': + sendReply(openTab(message)); break; } } diff --git a/webextension/js/popup.js b/webextension/js/popup.js index fb3fbd2..b987c53 100644 --- a/webextension/js/popup.js +++ b/webextension/js/popup.js @@ -2,38 +2,45 @@ const CONTAINER_HIDE_SRC = '/img/container-hide.svg'; const CONTAINER_UNHIDE_SRC = '/img/container-unhide.svg'; -function hideContainerTabs(containerId) { +function hideContainerTabs(userContextId) { const tabIdsToRemove = []; const tabUrlsToSave = []; - const hideorshowIcon = document.querySelector(`#${containerId}-hideorshow-icon`); + const hideorshowIcon = document.querySelector(`#uci-${userContextId}-hideorshow-icon`); - browser.tabs.query({cookieStoreId: containerId}).then(tabs=> { + browser.runtime.sendMessage({ + method: 'queryTabs', + userContextId: userContextId + }).then(tabs=> { tabs.forEach(tab=> { tabIdsToRemove.push(tab.id); tabUrlsToSave.push(tab.url); }); browser.runtime.sendMessage({ - method: 'hide', - cookieStoreId: containerId, + method: 'hideTabs', + userContextId: userContextId, tabUrlsToSave: tabUrlsToSave }).then(()=> { - browser.tabs.remove(tabIdsToRemove); + browser.runtime.sendMessage({ + method: 'removeTabs', + tabIds: tabIdsToRemove + }); hideorshowIcon.src = CONTAINER_UNHIDE_SRC; }); }); } -function showContainerTabs(containerId) { - const hideorshowIcon = document.querySelector(`#${containerId}-hideorshow-icon`); +function showContainerTabs(userContextId) { + const hideorshowIcon = document.querySelector(`#uci-${userContextId}-hideorshow-icon`); browser.runtime.sendMessage({ - method: 'show', - cookieStoreId: containerId + method: 'showTabs', + userContextId: userContextId }).then(hiddenTabUrls=> { hiddenTabUrls.forEach(url=> { - browser.tabs.create({ - url: url, - cookieStoreId: containerId + browser.runtime.sendMessage({ + method: 'openTab', + userContextId: userContextId, + url: url }); }); }); @@ -67,7 +74,7 @@ document.querySelector('#onboarding-done-button').addEventListener('click', ()=> document.querySelector('#container-panel').classList.remove('hide'); }); -browser.runtime.sendMessage({method: 'query'}).then(identities=> { +browser.runtime.sendMessage({method: 'queryIdentities'}).then(identities=> { const identitiesListElement = document.querySelector('.identities-list'); identities.forEach(identity=> { @@ -77,7 +84,7 @@ browser.runtime.sendMessage({method: 'query'}).then(identities=> { hideOrShowIconSrc = CONTAINER_UNHIDE_SRC; } const identityRow = ` -