diff --git a/package.json b/package.json index 7b52d8b..b57cc35 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,14 @@ "name": "testpilot-containers", "title": "Multi-Account Containers", "description": "Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.", - "version": "6.0.0", + "version": "6.0.1", "author": "Andrea Marchesini, Luke Crouch and Jonathan Kingston", "bugs": { "url": "https://github.com/mozilla/multi-account-containers/issues" }, "dependencies": {}, "devDependencies": { + "ajv": "^6.6.2", "addons-linter": "^1.3.2", "chai": "^4.1.2", "eslint": "^3.17.1", diff --git a/src/css/popup.css b/src/css/popup.css index 6eb6496..f2423a3 100644 --- a/src/css/popup.css +++ b/src/css/popup.css @@ -45,6 +45,7 @@ body { --small-text-size: 0.833rem; /* 10px */ --small-radius: 3px; --icon-button-size: calc(calc(var(--block-line-separation-size) * 2) + 1.66rem); /* 20px */ + --column-panel-inline-size: 268px; --inactive-opacity: 0.3; } @@ -267,7 +268,7 @@ table { .column-panel-content { display: flex; flex-direction: column; - inline-size: 268px; + inline-size: var(--column-panel-inline-size); } .column-panel-content .panel-footer { @@ -538,7 +539,7 @@ span ~ .panel-header-text { } #current-tab > label > input:checked { - background-image: url("chrome://global/skin/in-content/check.svg#check-native"); + background-image: url("/img/check.svg"); background-position: -1px -1px; background-size: var(--icon-size); } @@ -659,7 +660,11 @@ span ~ .panel-header-text { /* Container info list */ .container-info-tab-title { - flex: 1; + display: flex; +} + +.container-info-tab-row:hover .container-info-tab-title .truncate-text { + inline-size: calc(var(--column-panel-inline-size) - 58px); } #container-info-hideorshow { @@ -676,6 +681,21 @@ span ~ .panel-header-text { opacity: 0.3; } +.container-close-tab { + transform: scale(0.7); + visibility: collapse; +} + +.container-info-tab-row:hover .container-close-tab { + opacity: 0.5; + visibility: visible; +} + +.container-info-tab-row .container-close-tab:hover { + opacity: 1; + visibility: visible; +} + .container-info-has-tabs, .container-info-tab-row { align-items: center; @@ -702,10 +722,6 @@ span ~ .panel-header-text { margin-inline-end: 0; } -.container-info-tab-row td { - max-inline-size: 200px; -} - .container-info-list { display: flex; flex-direction: column; diff --git a/src/img/blank-favicon.svg b/src/img/blank-favicon.svg new file mode 100644 index 0000000..c2393b6 --- /dev/null +++ b/src/img/blank-favicon.svg @@ -0,0 +1,8 @@ + + + diff --git a/src/img/check.svg b/src/img/check.svg new file mode 100644 index 0000000..bcbcfc0 --- /dev/null +++ b/src/img/check.svg @@ -0,0 +1,6 @@ + + diff --git a/src/img/container-close-tab.svg b/src/img/container-close-tab.svg new file mode 100644 index 0000000..a36fa01 --- /dev/null +++ b/src/img/container-close-tab.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/js/background/backgroundLogic.js b/src/js/background/backgroundLogic.js index 04906d8..89f9159 100644 --- a/src/js/background/backgroundLogic.js +++ b/src/js/background/backgroundLogic.js @@ -6,6 +6,7 @@ const backgroundLogic = { "about:home", "about:blank" ]), + unhideQueue: [], async getExtensionInfo() { const manifestPath = browser.extension.getURL("manifest.json"); @@ -112,6 +113,17 @@ const backgroundLogic = { return list.concat(containerState.hiddenTabs); }, + async unhideContainer(cookieStoreId) { + if (!this.unhideQueue.includes(cookieStoreId)) { + this.unhideQueue.push(cookieStoreId); + await this.showTabs({ + cookieStoreId + }); + this.unhideQueue.splice(this.unhideQueue.indexOf(cookieStoreId), 1); + } + }, + + async moveTabsToWindow(options) { const requiredArguments = ["cookieStoreId", "windowId"]; this.checkArgs(requiredArguments, options, "moveTabsToWindow"); @@ -123,6 +135,7 @@ const backgroundLogic = { }); const containerState = await identityState.storageArea.get(cookieStoreId); + // Nothing to do if (list.length === 0 && containerState.hiddenTabs.length === 0) { @@ -152,12 +165,15 @@ const backgroundLogic = { const showHiddenPromises = []; // Let's show the hidden tabs. - for (let object of containerState.hiddenTabs) { // eslint-disable-line prefer-const - showHiddenPromises.push(browser.tabs.create({ - url: object.url || DEFAULT_TAB, - windowId: newWindowObj.id, - cookieStoreId - })); + if (!this.unhideQueue.includes(cookieStoreId)) { + this.unhideQueue.push(cookieStoreId); + for (let object of containerState.hiddenTabs) { // eslint-disable-line prefer-const + showHiddenPromises.push(browser.tabs.create({ + url: object.url || DEFAULT_TAB, + windowId: newWindowObj.id, + cookieStoreId + })); + } } if (hiddenDefaultTabToClose) { @@ -176,7 +192,9 @@ const backgroundLogic = { browser.tabs.remove(tab.id); } } - return await identityState.storageArea.set(cookieStoreId, containerState); + const rv = await identityState.storageArea.set(cookieStoreId, containerState); + this.unhideQueue.splice(this.unhideQueue.indexOf(cookieStoreId), 1); + return rv; }, async _closeTabs(userContextId, windowId = false) { @@ -209,7 +227,9 @@ const backgroundLogic = { }); identitiesOutput[cookieStoreId] = { hasHiddenTabs: !!containerState.hiddenTabs.length, - hasOpenTabs: !!openTabs.length + hasOpenTabs: !!openTabs.length, + numberOfHiddenTabs: containerState.hiddenTabs.length, + numberOfOpenTabs: openTabs.length }; return; }); @@ -307,4 +327,3 @@ const backgroundLogic = { return `firefox-container-${userContextId}`; } }; - diff --git a/src/js/background/messageHandler.js b/src/js/background/messageHandler.js index 6e5fced..9fbe88e 100644 --- a/src/js/background/messageHandler.js +++ b/src/js/background/messageHandler.js @@ -3,7 +3,6 @@ const messageHandler = { // We use this to catch redirected tabs that have just opened // If this were in platform we would change how the tab opens based on "new tab" link navigations such as ctrl+click LAST_CREATED_TAB_TIMER: 2000, - unhideQueue: [], init() { // Handles messages from webextension code @@ -39,7 +38,7 @@ const messageHandler = { backgroundLogic.sortTabs(); break; case "showTabs": - this.unhideContainer(m.cookieStoreId); + backgroundLogic.unhideContainer(m.cookieStoreId); break; case "hideTabs": backgroundLogic.hideTabs({ @@ -156,7 +155,7 @@ const messageHandler = { this.incrementCountOfContainerTabsOpened(); } - this.unhideContainer(tab.cookieStoreId); + backgroundLogic.unhideContainer(tab.cookieStoreId); } setTimeout(() => { this.lastCreatedTab = null; @@ -182,17 +181,6 @@ const messageHandler = { } }, - async unhideContainer(cookieStoreId) { - if (!this.unhideQueue.includes(cookieStoreId)) { - this.unhideQueue.push(cookieStoreId); - // Unhide all hidden tabs - await backgroundLogic.showTabs({ - cookieStoreId - }); - this.unhideQueue.splice(this.unhideQueue.indexOf(cookieStoreId), 1); - } - }, - async onFocusChangedCallback(windowId) { assignManager.removeContextMenu(); // browserAction loses background color in new windows ... diff --git a/src/js/popup.js b/src/js/popup.js index 870b9a4..7593bea 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -162,7 +162,7 @@ const Logic = { async clearBrowserActionBadge() { const extensionInfo = await getExtensionInfo(); const storage = await browser.storage.local.get({browserActionBadgesClicked: []}); - browser.browserAction.setBadgeBackgroundColor({color: ""}); + browser.browserAction.setBadgeBackgroundColor({color: null}); browser.browserAction.setBadgeText({text: ""}); storage.browserActionBadgesClicked.push(extensionInfo.version); // use set and spread to create a unique array @@ -177,7 +177,9 @@ const Logic = { name: "Default", cookieStoreId, icon: "default-tab", - color: "default-tab" + color: "default-tab", + numberOfHiddenTabs: 0, + numberOfOpenTabs: 0 }; // Handle old style rejection with null and also Promise.reject new style try { @@ -248,6 +250,8 @@ const Logic = { if (stateObject) { identity.hasOpenTabs = stateObject.hasOpenTabs; identity.hasHiddenTabs = stateObject.hasHiddenTabs; + identity.numberOfHiddenTabs = stateObject.numberOfHiddenTabs; + identity.numberOfOpenTabs = stateObject.numberOfOpenTabs; } return identity; }); @@ -801,20 +805,44 @@ Logic.registerPanel(P_CONTAINER_INFO, { tr.classList.add("container-info-tab-row"); tr.innerHTML = escaped`
If you remove this container now, container tabs will be closed. Are you sure you want to remove this Container?
+Are you sure you want to remove this Container?