diff --git a/src/_locales b/src/_locales
index 30aab7b..6f74e69 160000
--- a/src/_locales
+++ b/src/_locales
@@ -1 +1 @@
-Subproject commit 30aab7b6d876f02d22186bb534e84eefd8e1a2da
+Subproject commit 6f74e692138082d0f6de4c40e6c2d1f5fe717005
diff --git a/src/js/background/backgroundLogic.js b/src/js/background/backgroundLogic.js
index fb90ba6..34c7696 100644
--- a/src/js/background/backgroundLogic.js
+++ b/src/js/background/backgroundLogic.js
@@ -2,6 +2,8 @@
* 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/. */
+/* global MAC_CONSTANTS */
+
const DEFAULT_TAB = "about:newtab";
const backgroundLogic = {
@@ -11,22 +13,33 @@ const backgroundLogic = {
"about:home",
"about:blank"
]),
- NUMBER_OF_KEYBOARD_SHORTCUTS: 10,
+ NUMBER_OF_KEYBOARD_SHORTCUTS: MAC_CONSTANTS.NUMBER_OF_KEYBOARD_SHORTCUTS,
unhideQueue: [],
- init() {
- browser.commands.onCommand.addListener(function (command) {
+ init() {
+ browser.commands.onCommand.addListener(async function (command) {
if (command === "sort_tabs") {
backgroundLogic.sortTabs();
return;
}
for (let i=0; i < backgroundLogic.NUMBER_OF_KEYBOARD_SHORTCUTS; i++) {
- const key = "open_container_" + i;
- const cookieStoreId = identityState.keyboardShortcut[key];
+ const key = MAC_CONSTANTS.OPEN_CONTAINER_PREFIX + i;
+ const reopenKey = MAC_CONSTANTS.REOPEN_IN_CONTAINER_PREFIX + i;
if (command === key) {
- if (cookieStoreId === "none") return;
- browser.tabs.create({cookieStoreId});
+ const cookieStoreId = identityState.keyboardShortcut[key];
+ if (cookieStoreId && cookieStoreId !== "none") {
+ browser.tabs.create({cookieStoreId});
+ }
+ return;
+ }
+
+ if (command === reopenKey) {
+ const cookieStoreId = identityState.keyboardShortcut[reopenKey];
+ if (cookieStoreId && cookieStoreId !== "none") {
+ backgroundLogic.reopenInContainer(cookieStoreId);
+ }
+ return;
}
}
});
@@ -69,6 +82,23 @@ const backgroundLogic = {
}
},
+ async reopenInContainer(cookieStoreId) {
+ const currentTab = await browser.tabs.query({ active: true, currentWindow: true });
+
+ if (currentTab.length > 0) {
+ const tab = currentTab[0];
+
+ browser.tabs.create({
+ url: tab.url,
+ cookieStoreId,
+ index: tab.index + 1,
+ active: tab.active
+ });
+
+ browser.tabs.remove(tab.id);
+ }
+ },
+
/**
* We left an achievement entry in storage during a user research study in
* version 8.3.1. This method removes that entry to prevent broken logic in
@@ -84,11 +114,15 @@ const backgroundLogic = {
},
updateTranslationInManifest() {
- for (let index = 0; index < 10; index++) {
- const ajustedIndex = index + 1; // We want to start from 1 instead of 0 in the UI.
+ for (let index = 0; index < MAC_CONSTANTS.NUMBER_OF_KEYBOARD_SHORTCUTS; index++) {
+ const adjustedIndex = index + 1; // We want to start from 1 instead of 0 in the UI.
browser.commands.update({
- name: `open_container_${index}`,
- description: browser.i18n.getMessage("containerShortcut", `${ajustedIndex}`)
+ name: `${MAC_CONSTANTS.OPEN_CONTAINER_PREFIX}${index}`,
+ description: browser.i18n.getMessage("containerShortcut", `${adjustedIndex}`)
+ });
+ browser.commands.update({
+ name: `${MAC_CONSTANTS.REOPEN_IN_CONTAINER_PREFIX}${index}`,
+ description: browser.i18n.getMessage("reopenInContainerShortcut", `${adjustedIndex}`)
});
}
},
diff --git a/src/js/background/constants.js b/src/js/background/constants.js
new file mode 100644
index 0000000..f7f547c
--- /dev/null
+++ b/src/js/background/constants.js
@@ -0,0 +1,10 @@
+/* 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/. */
+
+// Shared constants for background scripts
+window.MAC_CONSTANTS = {
+ OPEN_CONTAINER_PREFIX: "open_container_",
+ REOPEN_IN_CONTAINER_PREFIX: "reopen_in_container_",
+ NUMBER_OF_KEYBOARD_SHORTCUTS: 10,
+};
diff --git a/src/js/background/identityState.js b/src/js/background/identityState.js
index 9114240..8d3d52f 100644
--- a/src/js/background/identityState.js
+++ b/src/js/background/identityState.js
@@ -1,3 +1,8 @@
+/* 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/. */
+
+/* global MAC_CONSTANTS */
window.identityState = {
keyboardShortcut: {},
storageArea: {
@@ -50,18 +55,22 @@ window.identityState = {
async loadKeyboardShortcuts () {
const identities = await browser.contextualIdentities.query({});
- for (let i=0; i < backgroundLogic.NUMBER_OF_KEYBOARD_SHORTCUTS; i++) {
- const key = "open_container_" + i;
- const storageObject = await this.area.get(key);
- if (storageObject[key]){
- identityState.keyboardShortcut[key] = storageObject[key];
- continue;
+ for (let i=0; i < MAC_CONSTANTS.NUMBER_OF_KEYBOARD_SHORTCUTS; i++) {
+ const openKey = MAC_CONSTANTS.OPEN_CONTAINER_PREFIX + i;
+ const reopenKey = MAC_CONSTANTS.REOPEN_IN_CONTAINER_PREFIX + i;
+
+ for (const key of [openKey, reopenKey]) {
+ const storageObject = await this.area.get(key);
+
+ if (storageObject[key]){
+ identityState.keyboardShortcut[key] = storageObject[key];
+ } else if (identities[i]) {
+ identityState.keyboardShortcut[key] = identities[i].cookieStoreId;
+ } else {
+ identityState.keyboardShortcut[key] = "none";
+ }
}
- if (identities[i]) {
- identityState.keyboardShortcut[key] = identities[i].cookieStoreId;
- continue;
- }
- identityState.keyboardShortcut[key] = "none";
+
}
return identityState.keyboardShortcut;
},
diff --git a/src/js/background/index.html b/src/js/background/index.html
index 818dbb4..6922190 100644
--- a/src/js/background/index.html
+++ b/src/js/background/index.html
@@ -15,6 +15,7 @@
-->
+
diff --git a/src/manifest.json b/src/manifest.json
index 94de8ed..6215b1c 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -109,6 +109,36 @@
"default": "Ctrl+Shift+0"
},
"description": "__MSG_containerShortcut__"
+ },
+ "reopen_in_container_0": {
+ "description": "__MSG_reopenInContainerShortcut__"
+ },
+ "reopen_in_container_1": {
+ "description": "__MSG_reopenInContainerShortcut__"
+ },
+ "reopen_in_container_2": {
+ "description": "__MSG_reopenInContainerShortcut__"
+ },
+ "reopen_in_container_3": {
+ "description": "__MSG_reopenInContainerShortcut__"
+ },
+ "reopen_in_container_4": {
+ "description": "__MSG_reopenInContainerShortcut__"
+ },
+ "reopen_in_container_5": {
+ "description": "__MSG_reopenInContainerShortcut__"
+ },
+ "reopen_in_container_6": {
+ "description": "__MSG_reopenInContainerShortcut__"
+ },
+ "reopen_in_container_7": {
+ "description": "__MSG_reopenInContainerShortcut__"
+ },
+ "reopen_in_container_8": {
+ "description": "__MSG_reopenInContainerShortcut__"
+ },
+ "reopen_in_container_9": {
+ "description": "__MSG_reopenInContainerShortcut__"
}
},
"browser_action": {
diff --git a/test/features/reopen-shortcuts.test.js b/test/features/reopen-shortcuts.test.js
new file mode 100644
index 0000000..c9d0b9f
--- /dev/null
+++ b/test/features/reopen-shortcuts.test.js
@@ -0,0 +1,44 @@
+const {initializeWithTab} = require("../common");
+
+describe("Reopen Shortcuts Feature", function () {
+ beforeEach(async function () {
+ // Initialize with a tab in the default container
+ this.webExt = await initializeWithTab({
+ cookieStoreId: "firefox-default",
+ url: "https://example.com"
+ });
+ });
+
+ afterEach(function () {
+ this.webExt.destroy();
+ });
+
+ describe("when using keyboard shortcut to reopen in container", function () {
+ beforeEach(async function () {
+ // Simulate the keyboard shortcut command
+ await this.webExt.background.browser.commands.onCommand.addListener.firstCall.args[0]("reopen_in_container_0");
+ });
+
+ it("should open the page in the assigned container and close the original tab", async function () {
+ this.webExt.background.browser.tabs.create.should.have.been.calledWithMatch({
+ url: "https://example.com",
+ cookieStoreId: "firefox-container-1",
+ index: 1,
+ active: true
+ });
+
+ this.webExt.background.browser.tabs.remove.should.have.been.called;
+ });
+ });
+
+ describe("when container is set to 'none'", function () {
+ beforeEach(async function () {
+ await this.webExt.background.browser.commands.onCommand.addListener.firstCall.args[0]("reopen_in_container_9");
+ });
+
+ it("should not reopen the tab", function () {
+ this.webExt.background.browser.tabs.create.should.not.have.been.called;
+ this.webExt.background.browser.tabs.remove.should.not.have.been.called;
+ });
+ });
+});