Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 50f5ebfcff | |||
| 0b760ce465 | |||
| bedebb7c0e | |||
| 9447792e53 | |||
| 8512794b43 | |||
| 081ea0bedb | |||
| d2c00a10cf | |||
| 56b85a8cdd | |||
| 4e4ed390e0 | |||
| 86edd8c8a2 | |||
| 4b56a2f0bb | |||
| 66be5e288d | |||
| 7ebed4521d | |||
| 68b1b2fe37 | |||
| 89719f7243 | |||
| 4d76c937fe | |||
| 649110ed45 | |||
| f4bcd30434 | |||
| c2ff3f00f2 | |||
| 6494b98157 | |||
| c371cd11d0 | |||
| 1b22753811 | |||
| e7af96b625 | |||
| 0c04b83207 | |||
| 6b73cee79e | |||
| d7688cb1f5 | |||
| c03df9d246 | |||
| a1d01f8ff2 | |||
| f0afc0da36 | |||
| fc070b2d0d | |||
| 899476e81a | |||
| 518f1cca89 | |||
| 997fe4db12 | |||
| a5f6f8381a | |||
| 46d76dfaa3 | |||
| 00a1ce9dca | |||
| b6f3c15999 | |||
| 024fb03c33 | |||
| de8d0b28ea | |||
| 8cffccccce | |||
| 7f31a92ede | |||
| b47291ae87 | |||
| 8de231f5e9 | |||
| a10d222ce7 | |||
| 487befda65 | |||
| 28222e510f | |||
| a2a11d053b | |||
| 5e99af0993 | |||
| 9c80781e3f | |||
| 2ed9eaee8a | |||
| c03c3c118c | |||
| 4bd412aa9b |
@@ -2,7 +2,7 @@
|
||||
|
||||
The Firefox Multi-Account Containers extension lets you carve out a separate box for each of your online lives – no more opening a different browser just to check your work email! [Learn More Here](https://blog.mozilla.org/firefox/introducing-firefox-multi-account-containers/)
|
||||
|
||||
[Available on addons.mozilla.org](https://addons.mozilla.org/en-GB/firefox/addon/multi-account-containers/)
|
||||
[Available on addons.mozilla.org](https://addons.mozilla.org/firefox/addon/multi-account-containers/)
|
||||
|
||||
For more info, see:
|
||||
|
||||
@@ -18,17 +18,43 @@ For more info, see:
|
||||
|
||||
## Development
|
||||
|
||||
1. `npm install`
|
||||
2. `./node_modules/web-ext/bin/web-ext run -s src/`
|
||||
### Running Locally
|
||||
|
||||
#### Via WebExtensions API (web-ext)
|
||||
|
||||
1. Install the [web-ext](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Getting_started_with_web-ext) tool.
|
||||
2. Run `web-ext run -s src/`. This launches Firefox and installs the extension automatically.
|
||||
|
||||
This tool provides some additional development features, such as [automatic reloading](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Getting_started_with_web-ext#Automatic_extension_reloading).
|
||||
|
||||
#### Via about:debugging in Firefox
|
||||
|
||||
1. Open the `about:debugging` page in Firefox.
|
||||
2. Click on `This Firefox`.
|
||||
3. Click on [Load Temporary Add-on](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox).
|
||||
4. Select `src/manifest.json`.
|
||||
|
||||
Here is a [video](https://www.youtube.com/watch?v=cer9EUKegG4) that demonstrates how to do this.
|
||||
|
||||
### Testing
|
||||
`npm run test`
|
||||
|
||||
or
|
||||
* Install dependencies:
|
||||
|
||||
`npm run lint`
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
for just the linter
|
||||
* Run all tests:
|
||||
|
||||
```
|
||||
npm run test
|
||||
```
|
||||
|
||||
* Only run the linter:
|
||||
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
There is a timeout test that sometimes fails on certain machines, so make sure to run the tests on your clone before you make any changes to see if you have this problem.
|
||||
|
||||
@@ -43,12 +69,12 @@ There is a timeout test that sometimes fails on certain machines, so make sure t
|
||||
#### Publish to AMO
|
||||
|
||||
1. `npm run-script build`
|
||||
2. [Upload the `.zip` to AMO](https://addons.mozilla.org/en-US/developers/addon/multi-account-containers/versions/submit/)
|
||||
2. [Upload the `.zip` to AMO](https://addons.mozilla.org/developers/addon/multi-account-containers/versions/submit/)
|
||||
|
||||
#### Publish to GitHub
|
||||
Finally, we also publish the release to GitHub for those followers.
|
||||
|
||||
1. Download the signed `.xpi` from [the addon versions page](https://addons.mozilla.org/en-US/developers/addon/multi-account-containers/versions)
|
||||
1. Download the signed `.xpi` from [the addon versions page](https://addons.mozilla.org/developers/addon/multi-account-containers/versions)
|
||||
2. [Make the new release on
|
||||
GitHub](https://github.com/mozilla/multi-account-containers/releases/new)
|
||||
* Use the version number for "Tag version" and "Release title"
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
"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": "7.0.0",
|
||||
"version": "7.4.0",
|
||||
"author": "Andrea Marchesini, Luke Crouch and Jonathan Kingston",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mozilla/multi-account-containers/issues"
|
||||
@@ -22,10 +22,10 @@
|
||||
"nyc": "^15.0.0",
|
||||
"sinon": "^7.5.0",
|
||||
"sinon-chai": "^3.3.0",
|
||||
"stylelint-order": "^4.0.0",
|
||||
"stylelint": "^13.5.0",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"web-ext": "^2.9.3",
|
||||
"stylelint-order": "^4.0.0",
|
||||
"web-ext": "^5.4.1",
|
||||
"webextensions-jsdom": "^1.2.1"
|
||||
},
|
||||
"homepage": "https://github.com/mozilla/multi-account-containers#readme",
|
||||
|
||||
@@ -18,7 +18,6 @@ main {
|
||||
button .container-name,
|
||||
#current-container-name {
|
||||
font-weight: bold;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1300px) {
|
||||
@@ -28,7 +27,7 @@ button .container-name,
|
||||
|
||||
/* for a mid sized window we have enough for this but not our image */
|
||||
.title {
|
||||
background-image: url("chrome://global/skin/icons/info.svg");
|
||||
background-image: url('chrome://global/skin/icons/info.svg');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +76,11 @@ dfn {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
#deny,
|
||||
#confirm {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.button-container > button {
|
||||
min-inline-size: 240px;
|
||||
}
|
||||
|
||||
+123
-2
@@ -691,6 +691,10 @@ h3.title {
|
||||
max-inline-size: 300px;
|
||||
}
|
||||
|
||||
.menu-item.drag-over td {
|
||||
border-block-start: 2px solid var(--text-normal-color);
|
||||
}
|
||||
|
||||
.disabled-menu-item {
|
||||
color: grey;
|
||||
cursor: default;
|
||||
@@ -703,12 +707,16 @@ h3.title {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.menu-text {
|
||||
.menu-item-name {
|
||||
display: flex;
|
||||
inline-size: calc(100% - 40px);
|
||||
line-height: 24px;
|
||||
max-inline-size: 260px;
|
||||
}
|
||||
|
||||
.menu-text {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
display: block;
|
||||
height: 16px;
|
||||
@@ -721,6 +729,7 @@ h3.title {
|
||||
}
|
||||
|
||||
/* Maintain 1:1 square ratio for Favicons of websites added to a specific container */
|
||||
#edit-sites-assigned .menu-icon,
|
||||
#container-info-table .menu-icon {
|
||||
inline-size: 16px;
|
||||
}
|
||||
@@ -926,3 +935,115 @@ tr > td > .trash-button {
|
||||
tr:hover > td > .trash-button {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.move-button {
|
||||
cursor: move;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
inline-size: 16px;
|
||||
margin-block-end: 4px;
|
||||
margin-block-start: 4px;
|
||||
margin-inline-end: 10px;
|
||||
margin-inline-start: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.move-button > img {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--title-text-color: #fff;
|
||||
--text-normal-color: #f9f9fa;
|
||||
--text-heading-color: #fff;
|
||||
}
|
||||
|
||||
html {
|
||||
background-color: #4a4a4a;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #fff;
|
||||
|
||||
--hr-grey: #38383d;
|
||||
--text-grey: #f9f9fa;
|
||||
}
|
||||
|
||||
h3.title {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.bottom-btn {
|
||||
background-color: #737373;
|
||||
border: solid 1px #737373;
|
||||
}
|
||||
|
||||
.btn-return.arrow-left {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.onboarding-title,
|
||||
.delete-container-confirm-title {
|
||||
color: #ededf0;
|
||||
}
|
||||
|
||||
input {
|
||||
border: solid 1px #737373;
|
||||
}
|
||||
|
||||
#edit-container-panel-name-input {
|
||||
background-color: #38383d;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.delete-container {
|
||||
background-color: #4a4a4a;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background-color: #737373;
|
||||
color: #f9f9fa;
|
||||
}
|
||||
|
||||
.cancel-button,
|
||||
.grey-button {
|
||||
background-color: #737373;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.button.secondary:hover,
|
||||
.button.secondary:focus {
|
||||
background-color: #676767;
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
border-block-end: solid 1px #4a4a4a;
|
||||
}
|
||||
|
||||
img.menu-icon,
|
||||
.menu-icon > img,
|
||||
.menu-arrow > img,
|
||||
.info-icon > img,
|
||||
.btn-return.arrow-left {
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
#edit-sites-assigned .menu-icon,
|
||||
#container-info-table .menu-icon {
|
||||
filter: invert(0);
|
||||
}
|
||||
|
||||
.truncate-text::after {
|
||||
background: #4a4a4a;
|
||||
mask-image: linear-gradient(to right, transparent, #4a4a4a 70%);
|
||||
}
|
||||
|
||||
[data-identity-color="grey"] {
|
||||
--identity-icon-color: #ededf0;
|
||||
}
|
||||
|
||||
[type="radio"]:checked + [data-identity-color="grey"] {
|
||||
--identity-icon-color: #616161;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="30px" height="30px" viewBox="0 0 30 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><script xmlns=""/>
|
||||
<defs/>
|
||||
<g id="All" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="hamburger-menu" fill="#858585">
|
||||
<g id="Group" transform="translate(2.000000, 6.000000)">
|
||||
<rect id="Rectangle-path" x="0" y="0" width="26" height="2"/>
|
||||
<rect id="Rectangle-path" x="0" y="8" width="26" height="2"/>
|
||||
<rect id="Rectangle-path" x="0" y="16" width="26" height="2"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 706 B |
@@ -51,6 +51,11 @@ window.assignManager = {
|
||||
return !!syncEnabled;
|
||||
},
|
||||
|
||||
async getReplaceTabEnabled() {
|
||||
const { replaceTabEnabled } = await browser.storage.local.get("replaceTabEnabled");
|
||||
return !!replaceTabEnabled;
|
||||
},
|
||||
|
||||
getByUrlKey(siteStoreKey) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.area.get([siteStoreKey]).then((storageResponse) => {
|
||||
@@ -233,9 +238,11 @@ window.assignManager = {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
const replaceTabEnabled = await this.storageArea.getReplaceTabEnabled();
|
||||
const removeTab = backgroundLogic.NEW_TAB_PAGES.has(tab.url)
|
||||
|| (messageHandler.lastCreatedTab
|
||||
&& messageHandler.lastCreatedTab.id === tab.id);
|
||||
&& messageHandler.lastCreatedTab.id === tab.id)
|
||||
|| replaceTabEnabled;
|
||||
const openTabId = removeTab ? tab.openerTabId : tab.id;
|
||||
|
||||
if (!this.canceledRequests[tab.id]) {
|
||||
@@ -691,7 +698,7 @@ window.assignManager = {
|
||||
|
||||
reloadPageInContainer(url, currentUserContextId, userContextId, index, active, neverAsk = false, openerTabId = null) {
|
||||
const cookieStoreId = backgroundLogic.cookieStoreId(userContextId);
|
||||
const loadPage = browser.extension.getURL("confirm-page.html");
|
||||
const loadPage = browser.runtime.getURL("confirm-page.html");
|
||||
// False represents assignment is not permitted
|
||||
// If the user has explicitly checked "Never Ask Again" on the warning page we will send them straight there
|
||||
if (neverAsk) {
|
||||
|
||||
@@ -22,7 +22,7 @@ const backgroundLogic = {
|
||||
},
|
||||
|
||||
async getExtensionInfo() {
|
||||
const manifestPath = browser.extension.getURL("manifest.json");
|
||||
const manifestPath = browser.runtime.getURL("manifest.json");
|
||||
const response = await fetch(manifestPath);
|
||||
const extensionInfo = await response.json();
|
||||
return extensionInfo;
|
||||
|
||||
@@ -24,7 +24,7 @@ async function addMessage(message) {
|
||||
divElement.innerText = message.text;
|
||||
|
||||
const imageElement = document.createElement("img");
|
||||
const imagePath = browser.extension.getURL("/img/container-site-d-24.png");
|
||||
const imagePath = browser.runtime.getURL("/img/container-site-d-24.png");
|
||||
const response = await fetch(imagePath);
|
||||
const blob = await response.blob();
|
||||
const objectUrl = URL.createObjectURL(blob);
|
||||
|
||||
+10
-10
@@ -16,25 +16,24 @@ async function requestPermissions() {
|
||||
|
||||
async function enableDisableSync() {
|
||||
const checkbox = document.querySelector("#syncCheck");
|
||||
if (checkbox.checked) {
|
||||
await browser.storage.local.set({syncEnabled: true});
|
||||
} else {
|
||||
await browser.storage.local.set({syncEnabled: false});
|
||||
}
|
||||
await browser.storage.local.set({syncEnabled: !!checkbox.checked});
|
||||
browser.runtime.sendMessage({ method: "resetSync" });
|
||||
}
|
||||
|
||||
async function enableDisableReplaceTab() {
|
||||
const checkbox = document.querySelector("#replaceTabCheck");
|
||||
await browser.storage.local.set({replaceTabEnabled: !!checkbox.checked});
|
||||
}
|
||||
|
||||
async function setupOptions() {
|
||||
const hasPermission = await browser.permissions.contains({permissions: ["bookmarks"]});
|
||||
const { syncEnabled } = await browser.storage.local.get("syncEnabled");
|
||||
const { replaceTabEnabled } = await browser.storage.local.get("replaceTabEnabled");
|
||||
if (hasPermission) {
|
||||
document.querySelector("#bookmarksPermissions").checked = true;
|
||||
}
|
||||
if (syncEnabled) {
|
||||
document.querySelector("#syncCheck").checked = true;
|
||||
} else {
|
||||
document.querySelector("#syncCheck").checked = false;
|
||||
}
|
||||
document.querySelector("#syncCheck").checked = !!syncEnabled;
|
||||
document.querySelector("#replaceTabCheck").checked = !!replaceTabEnabled;
|
||||
setupContainerShortcutSelects();
|
||||
}
|
||||
|
||||
@@ -82,6 +81,7 @@ function resetOnboarding() {
|
||||
document.addEventListener("DOMContentLoaded", setupOptions);
|
||||
document.querySelector("#bookmarksPermissions").addEventListener( "change", requestPermissions);
|
||||
document.querySelector("#syncCheck").addEventListener( "change", enableDisableSync);
|
||||
document.querySelector("#replaceTabCheck").addEventListener( "change", enableDisableReplaceTab);
|
||||
document.querySelector("button").addEventListener("click", resetOnboarding);
|
||||
|
||||
for (let i=0; i < NUMBER_OF_KEYBOARD_SHORTCUTS; i++) {
|
||||
|
||||
+224
-124
@@ -10,6 +10,8 @@ const DEFAULT_ICON = "circle";
|
||||
const NEW_CONTAINER_ID = "new";
|
||||
|
||||
const ONBOARDING_STORAGE_KEY = "onboarding-stage";
|
||||
const CONTAINER_ORDER_STORAGE_KEY = "container-order";
|
||||
const CONTAINER_DRAG_DATA_TYPE = "firefox-container";
|
||||
|
||||
// List of panels
|
||||
const P_ONBOARDING_1 = "onboarding1";
|
||||
@@ -30,9 +32,16 @@ const P_CONTAINER_DELETE = "containerDelete";
|
||||
const P_CONTAINERS_ACHIEVEMENT = "containersAchievement";
|
||||
const P_CONTAINER_ASSIGNMENTS = "containerAssignments";
|
||||
|
||||
function addRemoveSiteIsolation() {
|
||||
const identity = Logic.currentIdentity();
|
||||
browser.runtime.sendMessage({
|
||||
method: "addRemoveSiteIsolation",
|
||||
cookieStoreId: identity.cookieStoreId
|
||||
});
|
||||
}
|
||||
|
||||
async function getExtensionInfo() {
|
||||
const manifestPath = browser.extension.getURL("manifest.json");
|
||||
const manifestPath = browser.runtime.getURL("manifest.json");
|
||||
const response = await fetch(manifestPath);
|
||||
const extensionInfo = await response.json();
|
||||
return extensionInfo;
|
||||
@@ -185,16 +194,29 @@ const Logic = {
|
||||
elementToEnable.classList.remove("disabled-menu-item");
|
||||
},
|
||||
|
||||
async saveContainerOrder(rows) {
|
||||
const containerOrder = {};
|
||||
rows.forEach((node, index) => {
|
||||
return containerOrder[node.dataset.containerId] = index;
|
||||
});
|
||||
await browser.storage.local.set({
|
||||
[CONTAINER_ORDER_STORAGE_KEY]: containerOrder
|
||||
});
|
||||
},
|
||||
|
||||
async refreshIdentities() {
|
||||
const [identities, state] = await Promise.all([
|
||||
const [identities, state, containerOrderStorage] = await Promise.all([
|
||||
browser.contextualIdentities.query({}),
|
||||
browser.runtime.sendMessage({
|
||||
method: "queryIdentitiesState",
|
||||
message: {
|
||||
windowId: browser.windows.WINDOW_ID_CURRENT
|
||||
}
|
||||
})
|
||||
}),
|
||||
browser.storage.local.get([CONTAINER_ORDER_STORAGE_KEY])
|
||||
]);
|
||||
const containerOrder =
|
||||
containerOrderStorage && containerOrderStorage[CONTAINER_ORDER_STORAGE_KEY];
|
||||
this._identities = identities.map((identity) => {
|
||||
const stateObject = state[identity.cookieStoreId];
|
||||
if (stateObject) {
|
||||
@@ -204,8 +226,11 @@ const Logic = {
|
||||
identity.numberOfOpenTabs = stateObject.numberOfOpenTabs;
|
||||
identity.isIsolated = stateObject.isIsolated;
|
||||
}
|
||||
if (containerOrder) {
|
||||
identity.order = containerOrder[identity.cookieStoreId];
|
||||
}
|
||||
return identity;
|
||||
});
|
||||
}).sort((i1, i2) => i1.order - i2.order);
|
||||
},
|
||||
|
||||
getPanelSelector(panel) {
|
||||
@@ -219,14 +244,16 @@ const Logic = {
|
||||
},
|
||||
|
||||
async showPanel(panel, currentIdentity = null, backwards = false) {
|
||||
// Invalid panel... ?!?
|
||||
if (!(panel in this._panels)) {
|
||||
throw new Error("Something really bad happened. Unknown panel: " + panel);
|
||||
}
|
||||
if (!backwards || !this._currentPanel) {
|
||||
this._previousPanelPath.push(this._currentPanel);
|
||||
}
|
||||
|
||||
// If invalid panel, reset panels.
|
||||
if (!(panel in this._panels)) {
|
||||
panel = P_CONTAINERS_LIST;
|
||||
this._previousPanelPath = [];
|
||||
}
|
||||
|
||||
this._currentPanel = panel;
|
||||
|
||||
this._currentIdentity = currentIdentity;
|
||||
@@ -348,6 +375,77 @@ const Logic = {
|
||||
});
|
||||
this._listenerSet = true;
|
||||
}
|
||||
},
|
||||
|
||||
shortcutListener(e){
|
||||
function openNewContainerTab(identity) {
|
||||
try {
|
||||
browser.tabs.create({
|
||||
cookieStoreId: identity.cookieStoreId
|
||||
});
|
||||
window.close();
|
||||
} catch (e) {
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
const identities = Logic.identities();
|
||||
if ((e.keyCode >= 49 && e.keyCode <= 57) &&
|
||||
Logic._currentPanel === "containersList") {
|
||||
const identity = identities[e.keyCode - 49];
|
||||
if (identity) {
|
||||
openNewContainerTab(identity);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
keyboardNavListener(e){
|
||||
const panelSelector = Logic.getPanelSelector(Logic._panels[Logic._currentPanel]);
|
||||
const selectables = [...document.querySelectorAll(`${panelSelector} .keyboard-nav[tabindex='0']`)];
|
||||
const element = document.activeElement;
|
||||
const backButton = document.querySelector(`${panelSelector} .keyboard-nav-back`);
|
||||
const index = selectables.indexOf(element) || 0;
|
||||
function next() {
|
||||
const nextElement = selectables[index + 1];
|
||||
if (nextElement) {
|
||||
nextElement.focus();
|
||||
}
|
||||
}
|
||||
function previous() {
|
||||
const previousElement = selectables[index - 1];
|
||||
if (previousElement) {
|
||||
previousElement.focus();
|
||||
}
|
||||
}
|
||||
switch (e.keyCode) {
|
||||
case 40:
|
||||
next();
|
||||
break;
|
||||
case 38:
|
||||
previous();
|
||||
break;
|
||||
case 39:
|
||||
{
|
||||
if(element){
|
||||
element.click();
|
||||
}
|
||||
|
||||
// If one Container is highlighted,
|
||||
if (element.classList.contains("keyboard-right-arrow-override")) {
|
||||
element.querySelector(".menu-right-float").click();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 37:
|
||||
{
|
||||
if(backButton){
|
||||
backButton.click();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -560,71 +658,10 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
document.addEventListener("keydown", (e) => {
|
||||
function openNewContainerTab(identity) {
|
||||
try {
|
||||
browser.tabs.create({
|
||||
cookieStoreId: identity.cookieStoreId
|
||||
});
|
||||
window.close();
|
||||
} catch (e) {
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
const identities = Logic.identities();
|
||||
const selectables = [...document.querySelectorAll(".open-newtab[tabindex='0']")];
|
||||
const element = document.activeElement;
|
||||
const index = selectables.indexOf(element) || 0;
|
||||
function next() {
|
||||
const nextElement = selectables[index + 1];
|
||||
if (nextElement) {
|
||||
nextElement.focus();
|
||||
}
|
||||
}
|
||||
function previous() {
|
||||
const previousElement = selectables[index - 1];
|
||||
if (previousElement) {
|
||||
previousElement.focus();
|
||||
}
|
||||
}
|
||||
switch (e.keyCode) {
|
||||
case 40:
|
||||
next();
|
||||
break;
|
||||
case 38:
|
||||
previous();
|
||||
break;
|
||||
case 39:
|
||||
{
|
||||
const showTabs = element.parentNode.querySelector(".show-tabs");
|
||||
if(showTabs) {
|
||||
showTabs.click();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 37:
|
||||
{
|
||||
const hideTabs = document.querySelector(".panel-back-arrow");
|
||||
if(hideTabs) {
|
||||
hideTabs.click();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if ((e.keyCode >= 49 && e.keyCode <= 57) &&
|
||||
Logic._currentPanel === "containersList") {
|
||||
const identity = identities[e.keyCode - 49];
|
||||
if (identity) {
|
||||
openNewContainerTab(identity);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
unregister() {
|
||||
|
||||
},
|
||||
|
||||
// This method is called when the panel is shown.
|
||||
@@ -633,19 +670,21 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
||||
|
||||
Logic.identities().forEach(identity => {
|
||||
const tr = document.createElement("tr");
|
||||
tr.classList.add("menu-item", "hover-highlight");
|
||||
tr.classList.add("menu-item", "hover-highlight", "keyboard-nav", "keyboard-right-arrow-override");
|
||||
tr.setAttribute("tabindex", "0");
|
||||
const td = document.createElement("td");
|
||||
const openTabs = identity.numberOfOpenTabs || "" ;
|
||||
|
||||
td.innerHTML = Utils.escaped`
|
||||
<div class="menu-icon">
|
||||
<div class="usercontext-icon"
|
||||
data-identity-icon="${identity.icon}"
|
||||
data-identity-color="${identity.color}">
|
||||
td.innerHTML = Utils.escaped`
|
||||
<div class="menu-item-name">
|
||||
<div class="menu-icon">
|
||||
<div class="usercontext-icon"
|
||||
data-identity-icon="${identity.icon}"
|
||||
data-identity-color="${identity.color}">
|
||||
</div>
|
||||
</div>
|
||||
<span class="menu-text">${identity.name}</span>
|
||||
</div>
|
||||
<span class="menu-text">${identity.name}</span>
|
||||
<span class="menu-right-float">
|
||||
<span class="container-count">${openTabs}</span>
|
||||
<span class="menu-arrow">
|
||||
@@ -657,31 +696,46 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
||||
|
||||
tr.appendChild(td);
|
||||
|
||||
Utils.addEnterHandler(tr, () => {
|
||||
const openInThisContainer = tr.querySelector(".menu-item-name");
|
||||
Utils.addEnterHandler(openInThisContainer, () => {
|
||||
try {
|
||||
browser.tabs.create({
|
||||
cookieStoreId: identity.cookieStoreId
|
||||
});
|
||||
window.close();
|
||||
} catch (e) {
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
|
||||
Utils.addEnterOnlyHandler(tr, () => {
|
||||
try {
|
||||
browser.tabs.create({
|
||||
cookieStoreId: identity.cookieStoreId
|
||||
});
|
||||
window.close();
|
||||
} catch (e) {
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
|
||||
// Select only the ">" from the container list
|
||||
const showPanelButton = tr.querySelector(".menu-right-float");
|
||||
|
||||
Utils.addEnterHandler(showPanelButton, () => {
|
||||
Logic.showPanel(P_CONTAINER_INFO, identity);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
const list = document.querySelector("#identities-list");
|
||||
|
||||
list.innerHTML = "";
|
||||
list.appendChild(fragment);
|
||||
/* Not sure why extensions require a focus for the doorhanger,
|
||||
however it allows us to have a tabindex before the first selected item
|
||||
*/
|
||||
// const focusHandler = () => {
|
||||
// const identityList = list.querySelector("tr .clickable");
|
||||
// if (identityList) {
|
||||
// // otherwise this throws an error when there are no containers present.
|
||||
// identityList.focus();
|
||||
// document.removeEventListener("focus", focusHandler);
|
||||
// }
|
||||
// };
|
||||
// document.addEventListener("focus", focusHandler);
|
||||
// /* If the user mousedown's first then remove the focus handler */
|
||||
// document.addEventListener("mousedown", () => {
|
||||
// document.removeEventListener("focus", focusHandler);
|
||||
// });
|
||||
|
||||
document.addEventListener("keydown", Logic.keyboardNavListener);
|
||||
document.addEventListener("keydown", Logic.shortcutListener);
|
||||
return Promise.resolve();
|
||||
},
|
||||
});
|
||||
@@ -749,8 +803,8 @@ Logic.registerPanel(P_CONTAINER_INFO, {
|
||||
});
|
||||
// Populating the panel: name and icon
|
||||
document.getElementById("container-info-title").textContent = identity.name;
|
||||
|
||||
const alwaysOpen = document.querySelector("#always-open-in-info-panel");
|
||||
|
||||
const alwaysOpen = document.querySelector("#always-open-in-info-panel");
|
||||
Utils.addEnterHandler(alwaysOpen, async () => {
|
||||
Utils.alwaysOpenInContainer(identity);
|
||||
window.close();
|
||||
@@ -822,7 +876,7 @@ Logic.registerPanel(P_CONTAINER_INFO, {
|
||||
for (let tab of tabs) { // eslint-disable-line prefer-const
|
||||
const tr = document.createElement("tr");
|
||||
fragment.appendChild(tr);
|
||||
tr.classList.add("menu-item", "hover-highlight");
|
||||
tr.classList.add("menu-item", "hover-highlight", "keyboard-nav");
|
||||
tr.setAttribute("tabindex", "0");
|
||||
tr.innerHTML = Utils.escaped`
|
||||
<td>
|
||||
@@ -841,7 +895,7 @@ Logic.registerPanel(P_CONTAINER_INFO, {
|
||||
window.close();
|
||||
});
|
||||
|
||||
const closeTab = document.querySelector(".trash-button");
|
||||
const closeTab = tr.querySelector(".trash-button");
|
||||
if (closeTab) {
|
||||
Utils.addEnterHandler(closeTab, async (e) => {
|
||||
await browser.tabs.remove(Number(e.target.id));
|
||||
@@ -883,11 +937,11 @@ Logic.registerPanel(OPEN_NEW_CONTAINER_PICKER, {
|
||||
|
||||
Logic.identities().forEach(identity => {
|
||||
const tr = document.createElement("tr");
|
||||
tr.classList.add("menu-item", "hover-highlight");
|
||||
tr.classList.add("menu-item", "hover-highlight", "keyboard-nav");
|
||||
tr.setAttribute("tabindex", "0");
|
||||
const td = document.createElement("td");
|
||||
|
||||
td.innerHTML = Utils.escaped`
|
||||
td.innerHTML = Utils.escaped`
|
||||
<div class="menu-icon">
|
||||
<div class="usercontext-icon"
|
||||
data-identity-icon="${identity.icon}"
|
||||
@@ -942,7 +996,7 @@ Logic.registerPanel(MANAGE_CONTAINERS_PICKER, {
|
||||
|
||||
document.getElementById("new-container-div").innerHTML = Utils.escaped`
|
||||
<table class="menu">
|
||||
<tr class="menu-item hover-highlight" id="new-container" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" id="new-container" tabindex="0">
|
||||
<td>
|
||||
<div class="menu-icon"><img alt="New Container" src="/img/new-16.svg" />
|
||||
</div>
|
||||
@@ -959,23 +1013,70 @@ Logic.registerPanel(MANAGE_CONTAINERS_PICKER, {
|
||||
|
||||
Logic.identities().forEach(identity => {
|
||||
const tr = document.createElement("tr");
|
||||
tr.classList.add("menu-item", "hover-highlight");
|
||||
tr.classList.add("menu-item", "hover-highlight", "keyboard-nav");
|
||||
tr.setAttribute("tabindex", "0");
|
||||
const td = document.createElement("td");
|
||||
|
||||
td.innerHTML = Utils.escaped`
|
||||
td.innerHTML = Utils.escaped`
|
||||
<div class="menu-icon hover-highlight">
|
||||
<div class="usercontext-icon"
|
||||
data-identity-icon="${identity.icon}"
|
||||
data-identity-color="${identity.color}">
|
||||
</div>
|
||||
</div>
|
||||
<span class="menu-text">${identity.name}</span>`;
|
||||
<span class="menu-text">${identity.name}</span>
|
||||
<span class="move-button">
|
||||
<img
|
||||
class="pop-button-image"
|
||||
src="/img/container-move.svg"
|
||||
/>
|
||||
</span>`;
|
||||
|
||||
fragment.appendChild(tr);
|
||||
|
||||
tr.appendChild(td);
|
||||
|
||||
tr.draggable = true;
|
||||
tr.dataset.containerId = identity.cookieStoreId;
|
||||
tr.addEventListener("dragstart", (e) => {
|
||||
e.dataTransfer.setData(CONTAINER_DRAG_DATA_TYPE, identity.cookieStoreId);
|
||||
});
|
||||
tr.addEventListener("dragover", (e) => {
|
||||
if (e.dataTransfer.types.includes(CONTAINER_DRAG_DATA_TYPE)) {
|
||||
tr.classList.add("drag-over");
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
tr.addEventListener("dragenter", (e) => {
|
||||
if (e.dataTransfer.types.includes(CONTAINER_DRAG_DATA_TYPE)) {
|
||||
e.preventDefault();
|
||||
tr.classList.add("drag-over");
|
||||
}
|
||||
});
|
||||
tr.addEventListener("dragleave", (e) => {
|
||||
if (e.dataTransfer.types.includes(CONTAINER_DRAG_DATA_TYPE)) {
|
||||
e.preventDefault();
|
||||
tr.classList.remove("drag-over");
|
||||
}
|
||||
});
|
||||
tr.addEventListener("drop", async (e) => {
|
||||
e.preventDefault();
|
||||
const parent = tr.parentNode;
|
||||
const containerId = e.dataTransfer.getData(CONTAINER_DRAG_DATA_TYPE);
|
||||
let droppedElement;
|
||||
parent.childNodes.forEach((node) => {
|
||||
if (node.dataset.containerId === containerId) {
|
||||
droppedElement = node;
|
||||
}
|
||||
});
|
||||
if (droppedElement && droppedElement !== tr) {
|
||||
tr.classList.remove("drag-over");
|
||||
parent.insertBefore(droppedElement, tr);
|
||||
await Logic.saveContainerOrder(parent.childNodes);
|
||||
await Logic.refreshIdentities();
|
||||
}
|
||||
});
|
||||
|
||||
Utils.addEnterHandler(tr, () => {
|
||||
pickedFunction(identity);
|
||||
});
|
||||
@@ -1009,10 +1110,10 @@ Logic.registerPanel(REOPEN_IN_CONTAINER_PICKER, {
|
||||
const pickedFunction = function (identity) {
|
||||
const newUserContextId = Utils.userContextId(identity.cookieStoreId);
|
||||
Utils.reloadInContainer(
|
||||
currentTab.url,
|
||||
false,
|
||||
currentTab.url,
|
||||
false,
|
||||
newUserContextId,
|
||||
currentTab.index + 1,
|
||||
currentTab.index + 1,
|
||||
currentTab.active
|
||||
);
|
||||
window.close();
|
||||
@@ -1022,10 +1123,10 @@ Logic.registerPanel(REOPEN_IN_CONTAINER_PICKER, {
|
||||
|
||||
if (currentTab.cookieStoreId !== "firefox-default") {
|
||||
const tr = document.createElement("tr");
|
||||
tr.classList.add("menu-item", "hover-highlight");
|
||||
tr.classList.add("menu-item", "hover-highlight", "keyboard-nav");
|
||||
const td = document.createElement("td");
|
||||
|
||||
td.innerHTML = Utils.escaped`
|
||||
td.innerHTML = Utils.escaped`
|
||||
<div class="menu-icon hover-highlight">
|
||||
<div class="mac-icon">
|
||||
</div>
|
||||
@@ -1038,10 +1139,10 @@ Logic.registerPanel(REOPEN_IN_CONTAINER_PICKER, {
|
||||
|
||||
Utils.addEnterHandler(tr, () => {
|
||||
Utils.reloadInContainer(
|
||||
currentTab.url,
|
||||
false,
|
||||
currentTab.url,
|
||||
false,
|
||||
0,
|
||||
currentTab.index + 1,
|
||||
currentTab.index + 1,
|
||||
currentTab.active
|
||||
);
|
||||
window.close();
|
||||
@@ -1051,11 +1152,11 @@ Logic.registerPanel(REOPEN_IN_CONTAINER_PICKER, {
|
||||
Logic.identities().forEach(identity => {
|
||||
if (currentTab.cookieStoreId !== identity.cookieStoreId) {
|
||||
const tr = document.createElement("tr");
|
||||
tr.classList.add("menu-item", "hover-highlight");
|
||||
tr.classList.add("menu-item", "hover-highlight", "keyboard-nav");
|
||||
tr.setAttribute("tabindex", "0");
|
||||
const td = document.createElement("td");
|
||||
|
||||
td.innerHTML = Utils.escaped`
|
||||
td.innerHTML = Utils.escaped`
|
||||
<div class="menu-icon hover-highlight">
|
||||
<div class="usercontext-icon"
|
||||
data-identity-icon="${identity.icon}"
|
||||
@@ -1096,18 +1197,18 @@ Logic.registerPanel(ALWAYS_OPEN_IN_PICKER, {
|
||||
// This method is called when the panel is shown.
|
||||
prepare() {
|
||||
Logic.listenToPickerBackButton();
|
||||
document.getElementById("picker-title").textContent = "Reopen This Site in";
|
||||
document.getElementById("picker-title").textContent = "Always Open in";
|
||||
const fragment = document.createDocumentFragment();
|
||||
|
||||
document.getElementById("new-container-div").innerHTML = "";
|
||||
|
||||
Logic.identities().forEach(identity => {
|
||||
const tr = document.createElement("tr");
|
||||
tr.classList.add("menu-item", "hover-highlight");
|
||||
tr.classList.add("menu-item", "hover-highlight", "keyboard-nav");
|
||||
tr.setAttribute("tabindex", "0");
|
||||
const td = document.createElement("td");
|
||||
|
||||
td.innerHTML = Utils.escaped`
|
||||
td.innerHTML = Utils.escaped`
|
||||
<div class="menu-icon hover-highlight">
|
||||
<div class="usercontext-icon"
|
||||
data-identity-icon="${identity.icon}"
|
||||
@@ -1196,7 +1297,7 @@ Logic.registerPanel(P_CONTAINER_ASSIGNMENTS, {
|
||||
delete assignments[siteKey];
|
||||
this.showAssignedContainers(assignments);
|
||||
});
|
||||
trElement.classList.add("menu-item", "hover-highlight");
|
||||
trElement.classList.add("menu-item", "hover-highlight", "keyboard-nav");
|
||||
tableElement.appendChild(trElement);
|
||||
});
|
||||
}
|
||||
@@ -1213,6 +1314,9 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
||||
initialize() {
|
||||
this.initializeRadioButtons();
|
||||
Utils.addEnterHandler(document.querySelector("#close-container-edit-panel"), () => {
|
||||
// Resets listener from siteIsolation checkbox to keep the update queue to 0.
|
||||
const siteIsolation = document.querySelector("#site-isolation");
|
||||
siteIsolation.removeEventListener("change", addRemoveSiteIsolation, false);
|
||||
const formValues = new FormData(this._editForm);
|
||||
if (formValues.get("container-id") !== NEW_CONTAINER_ID) {
|
||||
this._submitForm();
|
||||
@@ -1308,14 +1412,10 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
||||
containerName.select();
|
||||
containerName.focus();
|
||||
});
|
||||
|
||||
const siteIsolation = document.querySelector("#site-isolation");
|
||||
siteIsolation.checked = !!identity.isIsolated;
|
||||
siteIsolation.addEventListener( "change", function() {
|
||||
browser.runtime.sendMessage({
|
||||
method: "addRemoveSiteIsolation",
|
||||
cookieStoreId: identity.cookieStoreId
|
||||
});
|
||||
});
|
||||
siteIsolation.addEventListener( "change", addRemoveSiteIsolation, false);
|
||||
[...document.querySelectorAll("[name='container-color']")].forEach(colorInput => {
|
||||
colorInput.checked = colorInput.value === identity.color;
|
||||
});
|
||||
|
||||
@@ -75,6 +75,15 @@ const Utils = {
|
||||
});
|
||||
},
|
||||
|
||||
addEnterOnlyHandler(element, handler) {
|
||||
element.addEventListener("keydown", (e) => {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
handler(e);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
userContextId(cookieStoreId = "") {
|
||||
const userContextId = cookieStoreId.replace("firefox-container-", "");
|
||||
return (userContextId !== cookieStoreId) ? Number(userContextId) : false;
|
||||
|
||||
+2
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Firefox Multi-Account Containers",
|
||||
"version": "7.0.0",
|
||||
"version": "7.4.0",
|
||||
"incognito": "not_allowed",
|
||||
"description": "Multi-Account 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.",
|
||||
"icons": {
|
||||
@@ -25,6 +25,7 @@
|
||||
"idle",
|
||||
"management",
|
||||
"storage",
|
||||
"unlimitedStorage",
|
||||
"tabs",
|
||||
"webRequestBlocking",
|
||||
"webRequest"
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
Enable Sync
|
||||
</label>
|
||||
<p><em>This setting allows you to sync your containers and site assignments across devices.</em></p>
|
||||
<h3>Tab behaviour:</h3>
|
||||
<label>
|
||||
<input type="checkbox" id="replaceTabCheck">
|
||||
Replace tab instead of creating a new one
|
||||
</label>
|
||||
<p><em>Replace the current tab if a page which is assigned to another container is opened (instead of keeping the current tab open).
|
||||
Opening tabs with middle mouse button is not affected.</em></p>
|
||||
<h3>Keyboard Shortcuts:</h3>
|
||||
<p><em>Edit which container is opened when using the numbered shortcuts.</em></p>
|
||||
<p><label>
|
||||
|
||||
+34
-33
@@ -13,7 +13,7 @@
|
||||
<p>
|
||||
Use containers to organize tasks, manage accounts, and keep your focus where you want it.
|
||||
</p>
|
||||
<a href="#" class="onboarding-button onboarding-start-button" tabindex="0">Get Started</a>
|
||||
<a href="#" class="onboarding-button onboarding-start-button keyboard-nav" tabindex="0">Get Started</a>
|
||||
</div>
|
||||
|
||||
<div class="hide panel onboarding security-onboarding-panel-1">
|
||||
@@ -22,49 +22,49 @@
|
||||
<p>
|
||||
Use containers to organize tasks, manage accounts, and store sensitive data.
|
||||
</p>
|
||||
<a href="#" class="onboarding-button onboarding-start-button" tabindex="0">Get Started</a>
|
||||
<a href="#" class="onboarding-button onboarding-start-button keyboard-nav" tabindex="0">Get Started</a>
|
||||
</div>
|
||||
|
||||
<div class="panel onboarding onboarding-panel-2 hide">
|
||||
<img class="onboarding-img" alt="How Containers Work" src="/img/onboarding-2.png" />
|
||||
<h3 class="onboarding-title">Put containers to work for you.</h3>
|
||||
<p>Features like color-coding and separate container tabs help you find things easily, focus your attention, and minimize distractions.</p>
|
||||
<a href="#" class="onboarding-button onboarding-next-button" tabindex="0">Next</a>
|
||||
<a href="#" class="onboarding-button onboarding-next-button keyboard-nav" tabindex="0">Next</a>
|
||||
</div>
|
||||
|
||||
<div class="panel onboarding security-onboarding-panel-2 hide">
|
||||
<img class="onboarding-img" alt="How Containers Work" src="/img/onboarding-2.png" />
|
||||
<h3 class="onboarding-title">Put containers to work for you.</h3>
|
||||
<p>Color-coding helps you categorize your online life, find things easily, and minimize distractions.</p>
|
||||
<a href="#" class="onboarding-button onboarding-next-button" tabindex="0">Next</a>
|
||||
<a href="#" class="onboarding-button onboarding-next-button keyboard-nav" tabindex="0">Next</a>
|
||||
</div>
|
||||
|
||||
<div class="panel onboarding onboarding-panel-3 hide">
|
||||
<img class="onboarding-img" alt="How Containers Work" src="/img/onboarding-3.png" />
|
||||
<h3 class="onboarding-title">A place for everything, and everything in its place.</h3>
|
||||
<p>Start with the containers we've created, or create your own.</p>
|
||||
<a href="#" class="onboarding-button onboarding-almost-done-button" tabindex="0">Next</a>
|
||||
<a href="#" class="onboarding-button onboarding-almost-done-button keyboard-nav" tabindex="0">Next</a>
|
||||
</div>
|
||||
|
||||
<div class="panel onboarding security-onboarding-panel-3 hide">
|
||||
<img class="onboarding-img" alt="How Containers Work" src="/img/onboarding-3-security.png" />
|
||||
<h3 class="onboarding-title">Set boundaries for your browsing.</h3>
|
||||
<p>Cookies are stored within a container, so you can segment sensitive data and browsing history to stay organized and to limit the impact of online trackers.</p>
|
||||
<a href="#" class="onboarding-button onboarding-almost-done-button" tabindex="0">Next</a>
|
||||
<a href="#" class="onboarding-button onboarding-almost-done-button keyboard-nav" tabindex="0">Next</a>
|
||||
</div>
|
||||
|
||||
<div class="panel onboarding onboarding-panel-4 hide" id="onboarding-panel-4">
|
||||
<img class="onboarding-img" alt="How to assign sites to containers" src="/img/onboarding-4.png" />
|
||||
<h3 class="onboarding-title">Always open sites in the containers you want.</h3>
|
||||
<p>Right-click inside a container tab to assign the site to always open in the container.</p>
|
||||
<a href="#" id="onboarding-done-button" class="onboarding-button" tabindex="0">Next</a>
|
||||
<a href="#" id="onboarding-done-button" class="onboarding-button keyboard-nav" tabindex="0">Next</a>
|
||||
</div>
|
||||
|
||||
<div class="panel onboarding onboarding-panel-5 hide" id="onboarding-panel-5">
|
||||
<img class="onboarding-img" alt="Long-press the New Tab button to create a new container tab." src="/img/onboarding-3.png" />
|
||||
<h3 class="onboarding-title">Container tabs when you need them.</h3>
|
||||
<p>Long-press the New Tab button to create a new container tab.</p>
|
||||
<a href="#" id="onboarding-longpress-button" class="onboarding-button" tabindex="0">Next</a>
|
||||
<a href="#" id="onboarding-longpress-button" class="onboarding-button keyboard-nav" tabindex="0">Next</a>
|
||||
</div>
|
||||
|
||||
<div class="panel onboarding onboarding-panel-6 hide" id="onboarding-panel-6">
|
||||
@@ -72,8 +72,8 @@
|
||||
<h3 class="onboarding-title">Syncing Containers is now Available!</h3>
|
||||
<p>Turn on Sync to share container and site assignments with any computer connected to your Firefox Account.</p>
|
||||
<div class="half-button-wrapper">
|
||||
<a herf="#" id="no-sync" class="half-onboarding-button grey-button" tabindex="0">Not Now</a>
|
||||
<a href="#" id="start-sync-button" class="half-onboarding-button" tabindex="0">Start Syncing</a>
|
||||
<a herf="#" id="no-sync" class="half-onboarding-button grey-button keyboard-nav" tabindex="0">Not Now</a>
|
||||
<a href="#" id="start-sync-button" class="half-onboarding-button keyboard-nav" tabindex="0">Start Syncing</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -82,8 +82,8 @@
|
||||
<h3 class="onboarding-title">Firefox Account is required to sync.</h3>
|
||||
<p>Click Sign In to confirm that your Firefox Account is active.</p>
|
||||
<div class="half-button-wrapper">
|
||||
<a herf="#" id="no-sign-in" class="half-onboarding-button grey-button" tabindex="0">Not Now</a>
|
||||
<a href="#" id="sign-in" class="half-onboarding-button" tabindex="0">Sign In</a>
|
||||
<a herf="#" id="no-sign-in" class="half-onboarding-button grey-button keyboard-nav" tabindex="0">Not Now</a>
|
||||
<a href="#" id="sign-in" class="half-onboarding-button keyboard-nav" tabindex="0">Sign In</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<a href="#" id="achievement-done-button" class="onboarding-button">Done</a>
|
||||
<a href="#" id="achievement-done-button" class="onboarding-button keyboard-nav">Done</a>
|
||||
</div>
|
||||
|
||||
<div class="panel menu-panel container-panel hide" id="container-panel">
|
||||
@@ -124,7 +124,7 @@
|
||||
</a>
|
||||
<hr>
|
||||
<table class="menu">
|
||||
<tr class="menu-item hover-highlight" id="open-new-tab-in" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" id="open-new-tab-in" tabindex="0">
|
||||
<td>
|
||||
<img class="menu-icon" alt="Open in New Tab" src="/img/tab-new-16.svg" />
|
||||
<span class="menu-text">Open New Tab in...</span>
|
||||
@@ -133,7 +133,7 @@
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="menu-item hover-highlight" id="reopen-site-in" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" id="reopen-site-in" tabindex="0">
|
||||
<td>
|
||||
<img class="menu-icon" alt="Open in New Tab" src="/img/refresh-16.svg" />
|
||||
<span class="menu-text">Reopen This Site in...</span>
|
||||
@@ -145,7 +145,7 @@
|
||||
</table>
|
||||
<hr>
|
||||
<table class="menu">
|
||||
<tr class="menu-item hover-highlight" id="sort-containers-link" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" id="sort-containers-link" tabindex="0">
|
||||
<td>
|
||||
<img class="menu-icon" alt="Open in New Tab" src="/img/sort-16_1.svg" />
|
||||
<span class="menu-text">Sort Tabs by Container</span>
|
||||
@@ -153,7 +153,7 @@
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="menu-item hover-highlight" id="always-open-in" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" id="always-open-in" tabindex="0">
|
||||
<td>
|
||||
<img class="menu-icon" alt="Open in New Tab" src="/img/container-openin-16.svg" />
|
||||
<span class="menu-text">Always Open This Site in...</span>
|
||||
@@ -171,13 +171,14 @@
|
||||
<table class="menu" id="identities-list">
|
||||
<tr class="menu-item hover-highlight">
|
||||
<td>
|
||||
<div class="menu-icon">
|
||||
<div class="usercontext-icon"
|
||||
data-identity-icon="pet"
|
||||
data-identity-color="blue">
|
||||
<div class="menu-item-name">
|
||||
<div class="menu-icon">
|
||||
<div class="usercontext-icon"
|
||||
data-identity-icon="pet"
|
||||
data-identity-color="blue"></div>
|
||||
</div>
|
||||
<span class="menu-text">Default</span>
|
||||
</div>
|
||||
<span class="menu-text">Default</span>
|
||||
<span class="menu-right-float">
|
||||
<span class="container-count">22</span>
|
||||
<span class="menu-arrow">
|
||||
@@ -188,7 +189,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="bottom-btn" id="manage-containers-link" tabindex="0">
|
||||
<div class="bottom-btn keyboard-nav hover-highlight" id="manage-containers-link" tabindex="0">
|
||||
Manage Containers
|
||||
</div>
|
||||
</div>
|
||||
@@ -198,10 +199,10 @@
|
||||
<h3 class="title" id="container-info-title">
|
||||
Personal
|
||||
</h3>
|
||||
<button class="btn-return arrow-left" id="close-container-info-panel" tabindex="0"></button>
|
||||
<button class="btn-return arrow-left keyboard-nav-back" id="close-container-info-panel" tabindex="0"></button>
|
||||
<hr>
|
||||
<table class="menu">
|
||||
<tr class="menu-item hover-highlight" id="open-new-tab-in-info" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" id="open-new-tab-in-info" tabindex="0">
|
||||
<td>
|
||||
<img class="menu-icon" alt="Open in New Tab" src="/img/tab-new-16.svg" />
|
||||
<span class="menu-text">Open New Tab in this Container</span>
|
||||
@@ -209,7 +210,7 @@
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="menu-item hover-highlight" id="hideorshow-container" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" id="hideorshow-container" tabindex="0">
|
||||
<td>
|
||||
<img id="container-info-hideorshow-icon" class="menu-icon" alt="Hide This Container" src="img/password-hide.svg" />
|
||||
<span id="container-info-hideorshow-label" class="menu-text">Hide This Container</span>
|
||||
@@ -217,7 +218,7 @@
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="menu-item hover-highlight" id="move-to-new-window" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" id="move-to-new-window" tabindex="0">
|
||||
<td>
|
||||
<img class="menu-icon" alt="Move Tabs to a New Window" src="/img/movetowindow-16.svg" />
|
||||
<span class="menu-text">Move Tabs to a New Window</span>
|
||||
@@ -225,7 +226,7 @@
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="menu-item hover-highlight hover-highlight" id="always-open" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" id="always-open" tabindex="0">
|
||||
<td>
|
||||
<img class="menu-icon" alt="Always Open Site in Container" src="/img/container-openin-16.svg" />
|
||||
<span class="menu-text" id="always-open-in-info-panel">Always Open Site in Container</span>
|
||||
@@ -240,7 +241,7 @@
|
||||
</div>
|
||||
<div class="scrollable">
|
||||
<table class="menu" id="container-info-table">
|
||||
<tr class="menu-item hover-highlight" tabindex="0">
|
||||
<tr class="menu-item hover-highlight keyboard-nav" tabindex="0">
|
||||
<td>
|
||||
<div class="favicon"><img class="menu-icon" src="https://www.mozilla.org/favicon.ico" /></div>
|
||||
<span class="menu-text truncate-text">www.mozillllllllllllllllllllllllllllllllllllla.org</span>
|
||||
@@ -249,7 +250,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="bottom-btn" id="manage-container-link">
|
||||
<div class="bottom-btn keyboard-nav hover-highlight" id="manage-container-link" tabindex="0">
|
||||
Manage This Container
|
||||
</div>
|
||||
</div>
|
||||
@@ -259,12 +260,12 @@
|
||||
<h3 class="title" id="picker-title">
|
||||
Multi-Account Containers
|
||||
</h3>
|
||||
<button class="btn-return arrow-left" id="close-container-picker-panel" tabindex="0"></button>
|
||||
<button class="btn-return arrow-left keyboard-nav-back" id="close-container-picker-panel" tabindex="0"></button>
|
||||
<hr>
|
||||
<div id="new-container-div"></div>
|
||||
<div class="scrollable identities-list">
|
||||
<table class="menu" id="picker-identities-list">
|
||||
<tr class="menu-item hover-highlight">
|
||||
<tr class="menu-item hover-highlight keyboard-nav">
|
||||
<td>
|
||||
<div class="menu-icon">
|
||||
<div class="usercontext-icon"
|
||||
@@ -305,7 +306,7 @@
|
||||
<input type="checkbox" class="site-isolation" id="site-isolation" name="site-isolation">
|
||||
<label for="site-isolation" class="options-label">Limit to Designated Sites</label>
|
||||
</div>
|
||||
<div class="container-options options-label manage-assigned-sites-list" id="manage-assigned-sites-list">Manage Site List...
|
||||
<div class="container-options options-label manage-assigned-sites-list" id="manage-assigned-sites-list" tabindex="0">Manage Site List...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+2
-1
@@ -87,7 +87,8 @@ const initializeWithTab = async (details = {
|
||||
"browserActionBadgesClicked": [],
|
||||
"onboarding-stage": 7,
|
||||
"achievements": [],
|
||||
"syncEnabled": true
|
||||
"syncEnabled": true,
|
||||
"replaceTabEnabled": false
|
||||
});
|
||||
window.browser.storage.local.set.resetHistory();
|
||||
window.browser.storage.sync.clear();
|
||||
|
||||
Reference in New Issue
Block a user