Compare commits

...

80 Commits

Author SHA1 Message Date
Rafee 8edcb1587d Version upgrade 2024-09-10 10:57:47 -04:00
Rafee Rahman 97891f61b0 Merge pull request #2659 from dannycolin/bz#1823729
Fix bz#1823729 - Listen only for status on tab updated
2024-08-29 09:22:53 -04:00
Danny Colin 51ead29d2b Fix bz#1823729 - Listen only for status on tab updated 2024-08-28 13:52:55 -04:00
luke crouch a53eb64c03 Merge pull request #2654 from mozilla/feat-#303
#303: Reset cookies in site manager
2024-08-28 11:26:57 -05:00
Rafee c644a60e46 feat #303: ask for browsing data permission dynamically 2024-08-27 17:06:07 -04:00
Rafee 2cd38299e2 feat #303: confirmation page for clearing container storage, added destructive colors 2024-08-27 15:34:06 -04:00
luke crouch 077c7e08c8 Merge pull request #2649 from mozilla/2263-always-open-in-container-bug
Remember choice for default containers in the "Always open in" confirm page
2024-08-27 13:47:53 -05:00
Rafee 6bde0a78d7 fix #2603: remember choice when choosing 'previous' (deny) container option 2024-08-23 12:57:50 -04:00
Rafee 3debe8a36f feat #303: change individual cookie removal to browsingData api 2024-08-20 15:04:25 -04:00
Rafee 606e08d2b7 feat #303: Container storage deletion and confirmation popup 2024-08-20 13:47:36 -04:00
Danny Colin f9f5daf8f4 Merge pull request #2616 from dannycolin/bug1958
Fix #1958 - Propagate container list reordering in Firefox menus
2024-08-14 10:31:54 -04:00
Rafee ffbb740445 feat #303: reset cookies in site manager 2024-08-01 18:13:58 -04:00
Rafee cd343ab8c3 fix #2603: remember choice to always open in default containers 2024-07-23 11:42:01 -04:00
Danny Colin 1537e9f6f2 Merge pull request #2634 from mozilla/missingTranslation
Missing translation for a contextmenu item
2024-04-22 15:35:47 -04:00
Andrea Marchesini f94c00b68a Missing translation for a contextmenu item 2024-04-17 14:59:56 +02:00
Danny Colin 0acc48af48 Merge pull request #2628 from emilio/icon-macos-fix
Explicitly specify width and height in SVG icon.
2024-03-04 10:33:04 -05:00
Emilio Cobos Álvarez cb96bf385b Explicitly specify width and height in SVG icon.
To work around https://bugzil.la/1883166.
2024-03-02 02:39:13 +01:00
Danny Colin 6fd2b70032 Merge pull request #2622 from emilio/release-changes-back-to-main
Release changes back to main
2024-02-23 18:49:22 -05:00
maxxcrawford f5aec9cb5a Add latest strings 2024-02-23 20:41:34 +01:00
maxxcrawford 9469ed424e Bump version number to 8.1.3 2024-02-23 20:41:10 +01:00
Danny Colin 7305b54635 Fix #1958 - Propagate container list reordering in Firefox menus
Since Fx 123, we have a new API (contextualIdentities.move) that let
us reorder the container list everywhere in Firefox. This patch
looks if the API is supported by the client and propagate the change
if it's the case.
2024-02-13 13:56:45 -05:00
Danny Colin 018b458ef6 Merge pull request #2599 from abhillman/abhillman/shebang-bash-with-env
Use `/usr/bin/env` to find bash
2023-11-28 19:51:22 -05:00
Danny Colin 6573123af5 Merge pull request #2587 from dannycolin/issue2553-shortcut-preventdefault
Revert monitoring modifier in popup shortcuts
2023-11-20 09:40:09 -05:00
Aryeh Hillman 4a9bc37a46 Use /usr/bin/env to find bash
This enables `npm test` to successfully call scripts in `bin/` with
the `bash` binary specified by `PROFILE`.

---

Additional information:

In addition to potentially preferring an alternative version of bash
than the one in `/bin/bash`, some distributions forego storing bash in
`bin/` at all, such as `NixOS`:

```bash
$ cat /etc/os-release | rg '^NAME=' -r ''
NixOS
$ which bash
/run/current-system/sw/bin/bash
```
2023-11-17 15:55:12 -08:00
Danny Colin 59e951e5d2 Merge pull request #2578 from dannycolin/bug1852393-icon-in-toolbar-by-default
Add MAC icon in toolbar on install
2023-10-16 14:32:34 -04:00
Danny Colin 4d4851d058 Merge pull request #2577 from dannycolin/fxa-rebrand
Rebrand Firefox Account
2023-10-16 14:25:57 -04:00
Danny Colin dd574bbe99 Merge pull request #2558 from leodag/fix-pr-template
fix: correct pull request template placement
2023-10-14 18:38:00 -04:00
Leonardo Dagnino 6374a28932 fix: correct pull request template placement 2023-10-14 19:05:45 -03:00
Danny Colin 6a9afcf266 Revert monitoring modifier in popup shortcuts 2023-10-13 14:45:32 -04:00
Danny Colin bea1cdcf87 Merge pull request #2584 from emilio/icons
Use color-scheme-aware icons.
2023-10-10 22:13:40 -04:00
Emilio Cobos Álvarez 3779f86088 Make icons react to color-scheme properly.
Note that due to https://bugzilla.mozilla.org/show_bug.cgi?id=1779457 /
https://github.com/w3c/csswg-drafts/issues/7213, prefers-color-scheme
works fine even if the user has an explicitly light theme or so.

This fixes #2583 entirely.
2023-10-09 00:57:23 +02:00
Emilio Cobos Álvarez bb24647ff3 Make usercontext.svg use color-scheme-aware colors.
Fixes the individual icons in #2583.
2023-10-09 00:45:37 +02:00
Danny Colin 60466258b8 Rebrand Firefox Account
* Change Firefox Account to account
* Add brand=mozilla to accounts.firefox.com URLs
2023-10-02 13:13:17 -04:00
Danny Colin dd4020069c Add MAC icon in toolbar on install 2023-09-23 19:31:01 -04:00
luke crouch 60b40a2d9f Merge pull request #2562 from mozilla/fix-issue-template
Fix issue template
2023-08-11 09:57:42 -05:00
Danny Colin 1142c73812 Fix issue template
There's an escape character that breaks our issue template and prevents it to be parsed by Github. This patch removes it.
2023-08-10 14:05:34 -04:00
Danny Colin f20688c453 Merge pull request #2543 from dannycolin/i18n-remove-hardcoded-strings
Fix missing i18n strings in the UI
2023-06-27 21:33:52 -04:00
Danny Colin f85d75188a Fix missing i18n strings in the UI
This patch fix all the missing i18n strings in the UI. It also
standardize the main title to "Firefox Multi-Account Containers"
everywhere we use it in the addon.
2023-06-19 19:41:10 -04:00
Danny Colin dae7d92595 Merge pull request #2501 from dannycolin/popup-shortcuts
Rework shortcut listener logic for the addon popup
2023-06-17 16:00:37 -04:00
Danny Colin ef10307898 Rework shortcut listener logic for the addon popup
- Add Slash shortcut to focus search input
- Use event.code instead of event.keyCode
- Cancel [0-9] shortcuts when modified is pressed
- Cancel [0-9] shortcuts when search input is focused
2023-06-17 15:58:04 -04:00
Danny Colin b29ba2094e Merge pull request #2492 from dannycolin/bug-2457-sort-shortcut
Fix 2457 - add shortcut for sorting tabs by container
2023-06-08 11:55:27 -04:00
Andrea Marchesini f7e9deebda Merge pull request #2505 from mozilla/dependabot/npm_and_yarn/cacheable-request-10.2.7
Bump cacheable-request from 10.2.3 to 10.2.7
2023-03-11 05:05:23 -05:00
Danny Colin 473495ec0c Merge pull request #2509 from drien/main
Add `file:` protocol to non-permissible protocol list
2023-02-23 18:03:55 -05:00
Adrien Delessert 38cdf0a98c Merge branch 'mozilla:main' into main 2023-02-23 17:55:44 -05:00
Maxx Crawford 69bfac12de Merge pull request #2511 from mozilla/revert-2506-npx-test-fix-fix
Fix Build and Test Github CI Scripts
2023-02-22 11:26:39 -06:00
Maxx Crawford 2dfd1ee4bb Update build script to use npx instead of npm bin bash scripting 2023-02-22 11:23:45 -06:00
Danny Colin 37e0caec25 Merge pull request #2506 from mozilla/npx-test-fix
Fix failing test install by replacing $(npm bin) with npx
2023-02-20 11:39:50 -05:00
Adrien Delessert 2894de1127 Add file: protocol to non-permissible list 2023-02-16 12:39:44 -05:00
Maxx Crawford e71cd19883 Fix failing test install by replacing (npm bin) with npx 2023-02-13 13:14:54 -06:00
dependabot[bot] caa52cebf4 Bump cacheable-request from 10.2.3 to 10.2.7
Bumps [cacheable-request](https://github.com/jaredwray/cacheable-request) from 10.2.3 to 10.2.7.
- [Release notes](https://github.com/jaredwray/cacheable-request/releases)
- [Commits](https://github.com/jaredwray/cacheable-request/commits)

---
updated-dependencies:
- dependency-name: cacheable-request
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-11 00:28:54 +00:00
Danny Colin 0bcac2a741 Merge pull request #2499 from mozilla/dependabot/npm_and_yarn/fast-json-patch-and-addons-linter-and-web-ext-3.1.1
Bump fast-json-patch, addons-linter and web-ext
2023-02-07 14:30:48 -05:00
dependabot[bot] 1445c9c3db Bump fast-json-patch, addons-linter and web-ext
Bumps [fast-json-patch](https://github.com/Starcounter-Jack/JSON-Patch) to 3.1.1 and updates ancestor dependencies [fast-json-patch](https://github.com/Starcounter-Jack/JSON-Patch), [addons-linter](https://github.com/mozilla/addons-linter) and [web-ext](https://github.com/mozilla/web-ext). These dependencies need to be updated together.


Updates `fast-json-patch` from 2.2.1 to 3.1.1
- [Release notes](https://github.com/Starcounter-Jack/JSON-Patch/releases)
- [Commits](https://github.com/Starcounter-Jack/JSON-Patch/compare/v2.2.1...3.1.1)

Updates `addons-linter` from 5.24.0 to 5.28.0
- [Release notes](https://github.com/mozilla/addons-linter/releases)
- [Commits](https://github.com/mozilla/addons-linter/compare/5.24.0...5.28.0)

Updates `web-ext` from 7.4.0 to 7.5.0
- [Release notes](https://github.com/mozilla/web-ext/releases)
- [Commits](https://github.com/mozilla/web-ext/compare/7.4.0...7.5.0)

---
updated-dependencies:
- dependency-name: fast-json-patch
  dependency-type: indirect
- dependency-name: addons-linter
  dependency-type: direct:development
- dependency-name: web-ext
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-06 21:47:50 +00:00
Danny Colin e2628a20ac Merge pull request #2497 from mozilla/dependabot/npm_and_yarn/http-cache-semantics-4.1.1
Bump http-cache-semantics from 4.1.0 to 4.1.1
2023-02-06 16:46:01 -05:00
dependabot[bot] a30499ecfd Bump http-cache-semantics from 4.1.0 to 4.1.1
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-04 19:49:54 +00:00
Danny Colin c948a9501d Fix 2457 - add shortcut for sorting tabs by container 2023-01-23 18:49:39 -05:00
Danny Colin a91c6b09a9 Merge pull request #2427 from mozilla/add-helper-dev-scripts
Add remove/restore scripts for nested .git folder
2023-01-09 19:11:07 -05:00
Danny Colin 0b2347834c Merge pull request #2485 from mozilla/dependabot/npm_and_yarn/json5-2.2.3
Bump json5 from 2.2.1 to 2.2.3
2023-01-09 19:08:53 -05:00
dependabot[bot] d5e14aa628 Bump json5 from 2.2.1 to 2.2.3
Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 17:46:13 +00:00
Danny Colin 95f598c25c Merge pull request #2476 from mozilla/dependabot/npm_and_yarn/got-and-addons-linter-12.5.3
Bump got and addons-linter
2022-12-14 12:02:51 -05:00
Danny Colin 16a6e21bc5 Merge pull request #2475 from mozilla/dependabot/npm_and_yarn/express-and-addons-linter--removed
Bump express and addons-linter
2022-12-14 12:02:13 -05:00
Danny Colin 781b1caeb5 Merge pull request #2473 from mozilla/dependabot/npm_and_yarn/decode-uri-component-0.2.2
Bump decode-uri-component from 0.2.0 to 0.2.2
2022-12-14 11:59:59 -05:00
dependabot[bot] c9786f28da Bump decode-uri-component from 0.2.0 to 0.2.2
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-14 16:57:32 +00:00
dependabot[bot] 2196098512 Bump got and addons-linter
Bumps [got](https://github.com/sindresorhus/got) to 12.5.3 and updates ancestor dependency [addons-linter](https://github.com/mozilla/addons-linter). These dependencies need to be updated together.


Updates `got` from 8.3.2 to 12.5.3
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v8.3.2...v12.5.3)

Updates `addons-linter` from 3.23.0 to 5.24.0
- [Release notes](https://github.com/mozilla/addons-linter/releases)
- [Commits](https://github.com/mozilla/addons-linter/compare/3.23.0...5.24.0)

---
updated-dependencies:
- dependency-name: got
  dependency-type: indirect
- dependency-name: addons-linter
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-14 16:57:23 +00:00
dependabot[bot] 31e1f4478d Bump express and addons-linter
Removes [express](https://github.com/expressjs/express). It's no longer used after updating ancestor dependency [addons-linter](https://github.com/mozilla/addons-linter). These dependencies need to be updated together.


Removes `express`

Updates `addons-linter` from 3.23.0 to 5.24.0
- [Release notes](https://github.com/mozilla/addons-linter/releases)
- [Commits](https://github.com/mozilla/addons-linter/compare/3.23.0...5.24.0)

---
updated-dependencies:
- dependency-name: express
  dependency-type: indirect
- dependency-name: addons-linter
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-14 16:57:20 +00:00
Danny Colin 12fab97d62 Merge pull request #2461 from mozilla/dependabot/npm_and_yarn/minimatch-and-mocha-3.1.2
Bump minimatch and mocha
2022-12-14 11:56:42 -05:00
dependabot[bot] e45883d6bc Bump minimatch and mocha
Bumps [minimatch](https://github.com/isaacs/minimatch) to 3.1.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `minimatch` from 3.0.4 to 3.1.2
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

Updates `mocha` from 6.2.3 to 10.1.0
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v6.2.3...v10.1.0)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
- dependency-name: mocha
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-29 17:07:03 +00:00
Danny Colin 6594a061d6 Merge pull request #2460 from mozilla/version-bump-package-json
version bump package json
2022-11-29 12:05:29 -05:00
Danny Colin 65a36ee5be Merge pull request #2428 from dannycolin/radio-hover-css
Fix broken radio focus styling in light mode
2022-11-29 12:05:10 -05:00
Maxx Crawford 00fd9b7aab Merge pull request #2432 from dannycolin/update-l10n
update l10n to get the missing strings in 8.1.0 build
2022-11-29 10:14:07 -06:00
Maxx Crawford 4d1acc1d8e Generate package-lock.json locally with correct versions of node, npm 2022-11-29 10:09:32 -06:00
Danny Colin 2f99ec4613 Merge pull request #2450 from dannycolin/revert-2231
Backout #2231 from 8.1.0
2022-11-29 10:47:59 -05:00
Maxx Crawford 0070f9c942 Bump version number to 8.1.1 2022-11-29 09:44:07 -06:00
Maxx Crawford 00beddc4cd Add package-lock.json to tracked files 2022-11-29 09:43:50 -06:00
Danny Colin 8e7d9f7574 Revert "Excluding containers from sync with RegExp"
This reverts commit bf31fa9196.
2022-11-18 23:40:58 -05:00
Danny Colin 06c897583b Revert "Fix empty sync exclude regexp behavior (#2383)"
This reverts commit e5fa98d69e.
2022-11-18 23:40:46 -05:00
Danny Colin f41139402e update l10n 2022-10-26 13:55:06 -04:00
Danny Colin c4b0823526 bump version to 8.1.1 2022-10-20 17:58:06 -04:00
Danny Colin 5ccf55cbd1 Fix broken radio focus styling in light mode 2022-10-20 14:57:18 -04:00
Maxx Crawford 7256456463 Add missing build script to package.json and ignore root build directory 2022-10-20 09:47:51 -05:00
Maxx Crawford 035450ae96 Add remove/restore scripts for nested .git folder
The /src/_locales/.github folder causes `web-ext run` to fail when running the npm dev script. This folder removal isn't tracked or surfaced during local dev work when working from the root directory.
2022-10-20 09:29:51 -05:00
31 changed files with 25478 additions and 233 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ body:
options:
- label: "I updated to the latest version of Multi-Account Container and tested if I can reproduce the issue"
required: true
- label: "I searched for existing reports to see if it hasn\'t already been reported"
- label: "I searched for existing reports to see if it hasn't already been reported"
required: true
- type: textarea
id: step_to_reproduce
+1 -1
View File
@@ -1,5 +1,4 @@
.DS_Store
package-lock.json
node_modules
README.html
*.xpi
@@ -9,6 +8,7 @@ README.html
addon.env
src/web-ext-artifacts/*
web-ext-artifacts
# JetBrains IDE files
.idea
+2 -2
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/env bash
# 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
@@ -32,4 +32,4 @@ rm -rf $TMPDIR/src/_locales/.github || die
print G "done."
print Y "Running the test..."
$(npm bin)/addons-linter $TMPDIR/src || die
npx addons-linter $TMPDIR/src || die
+2 -2
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/env bash
# 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
@@ -23,4 +23,4 @@ if [[ $# -gt 0 ]]; then
EXTRA_PARAMS="--filename $1"
fi
$(npm bin)/web-ext build --overwrite-dest $EXTRA_PARAMS || die
npx web-ext build --overwrite-dest $EXTRA_PARAMS || die
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/env bash
# 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
+25098
View File
File diff suppressed because it is too large Load Diff
+8 -5
View File
@@ -2,14 +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": "8.1.0",
"version": "8.2.0",
"author": "Andrea Marchesini, Luke Crouch, Lesley Norton, Kendall Werts, Maxx Crawford, Jonathan Kingston",
"bugs": {
"url": "https://github.com/mozilla/multi-account-containers/issues"
},
"dependencies": {},
"devDependencies": {
"addons-linter": "^3.23.0",
"addons-linter": "^5.28.0",
"ajv": "^6.6.3",
"chai": "^4.2.0",
"eslint": "^7.32.0",
@@ -17,7 +17,7 @@
"eslint-plugin-promise": "^5.2.0",
"htmllint-cli": "0.0.7",
"json": ">=10.0.0",
"mocha": "^6.2.2",
"mocha": "^10.1.0",
"npm-run-all": "^4.0.0",
"nyc": "^15.0.0",
"sinon": "^7.5.0",
@@ -25,7 +25,7 @@
"stylelint": "^13.5.0",
"stylelint-config-standard": "^20.0.0",
"stylelint-order": "^4.0.0",
"web-ext": "^7.1.1",
"web-ext": "^7.5.0",
"webextensions-jsdom": "^1.2.1"
},
"homepage": "https://github.com/mozilla/multi-account-containers#readme",
@@ -36,13 +36,16 @@
"url": "git+https://github.com/mozilla/multi-account-containers.git"
},
"scripts": {
"dev": "web-ext run -s src/",
"build": "web-ext build -s src/",
"dev": "npm run remove-locales-github && web-ext run -s src/",
"lint": "npm-run-all lint:*",
"lint:addon": "./bin/addons-linter.sh",
"lint:css": "stylelint src/css/*.css",
"lint:html": "htmllint *.html",
"lint:js": "eslint .",
"package": "rm -rf src/web-ext-artifacts && npm run build && mv src/web-ext-artifacts/firefox_multi-account_containers-*.zip addon.xpi",
"restore-locales-github": "cd src/_locales && git restore .github/",
"remove-locales-github": "rm -rf src/_locales/.github",
"test": "npm run lint && npm run coverage",
"test:once": "mocha test/**/*.test.js",
"test:watch": "npm run test:once -- --watch",
-10
View File
@@ -37,16 +37,6 @@ form {
margin-block: 4px 8px;
}
.settings-group-column {
display: flex;
flex-direction: column;
}
.settings-group-column label,
.settings-group-column p {
margin-block: 4px 8px;
}
input[type="checkbox"] {
margin-inline: 0 8px;
margin-block: 1px auto;
+72 -15
View File
@@ -107,8 +107,9 @@
--toggle-on-bg-focus-color: #0060df;
--toggle-on-border-color: #0060df;
--toggle-on-handle-bg-color: #fff;
--usercontext-bg-hover-color: #e0e0e6;
--usercontext-bg-active-color: #e0e0e6;
--usercontext-bg-hover-color: #f0f0fa;
--usercontext-bg-focus-color: #e0e0e6;
--usercontext-bg-active-color: #cfcfd8;
--moz-vpn-tout-shadow: 0 0 7px 0 #9498a25e;
}
@@ -227,6 +228,7 @@ body {
/* Hack for menu icons to use a light color without affecting container icons */
[data-theme="light"] img.delete-assignment,
[data-theme="dark"] img.reset-assignment,
[data-theme="dark"] .trash-button,
[data-theme="dark"] img.menu-icon,
[data-theme="dark"] .menu-icon > img,
@@ -235,6 +237,7 @@ body {
filter: invert(1);
}
[data-theme="dark"] img.clear-storage-icon,
[data-theme="dark"] img.delete-assignment,
[data-theme="dark"] #edit-sites-assigned .menu-icon,
[data-theme="dark"] #container-info-table .menu-icon {
@@ -284,9 +287,33 @@ table {
display: none !important;
}
.popup-notification-card {
opacity: 0;
pointer-events: none;
transition: opacity 2s;
border-radius: 4px;
font-size: 12px;
position: absolute;
inset-block-start: 0;
inset-inline-start: 0;
padding-block: 8px;
padding-inline: 8px;
margin-block: 8px;
margin-inline: 8px;
inline-size: calc(100vw - 25px);
background-color: var(--button-bg-active-color-secondary);
z-index: 3;
}
.is-shown {
pointer-events: auto;
opacity: 1;
transition: opacity 0s;
}
/* effect borrowed from tabs in firefox, ensure that the element flexes to the full width */
.truncate-text {
inline-size: calc(100vw - 80px);
inline-size: calc(100vw - 100px);
overflow: hidden;
position: relative;
white-space: nowrap;
@@ -1504,8 +1531,9 @@ input[type=text] {
min-block-size: 500px;
}
.delete-container-panel {
min-block-size: 300px;
.delete-container-panel,
.clear-container-storage-panel {
min-block-size: 500px;
}
.panel.onboarding,
@@ -1793,12 +1821,14 @@ manage things like container crud */
margin-inline-end: 0;
}
.delete-container-confirm {
.delete-container-confirm,
.clear-container-storage-confirm {
padding-inline-end: 20px;
padding-inline-start: 20px;
}
.delete-container-confirm-title {
.delete-container-confirm-title,
.clear-container-storage-confirm-title {
color: var(--text-color-primary);
font-size: var(--font-size-heading);
}
@@ -1884,15 +1914,25 @@ manage things like container crud */
margin-inline: auto;
}
/* When focusing the element add a thin blue highlight to match input fields. This gives a distinction to other selected radio items */
.radio-choice > .radio-container > [type="radio"]:focus + label {
outline: solid 1px var(--input-border-focus-color);
-moz-outline-radius: 100%;
}
.radio-choice > .radio-container > [type="radio"]:checked + label {
background-color: var(--usercontext-bg-focus-color);
border-radius: 100%;
}
/* When focusing the element add a thin blue highlight to match input fields. This gives a distinction to other selected radio items */
.radio-choice > .radio-container > [type="radio"]:focus + label {
outline: solid 1px var(--input-border-focus-color);
-moz-outline-radius: 100%;
.radio-choice > .radio-container > [type="radio"]:checked + label:hover {
background-color: var(--usercontext-bg-hover-color);
border-radius: 100%;
}
.radio-choice > .radio-container > [type="radio"]:checked + label:active {
background-color: var(--usercontext-bg-active-color);
border-radius: 100%;
}
.edit-container-panel fieldset {
@@ -2162,6 +2202,11 @@ hr {
text-align: center;
}
.confirmation-destructive-ok-btn {
background-color: var(--button-destructive-bg-color);
color: var(--button-destructive-text-color);
}
.delete-btn {
background-color: var(--button-destructive-bg-color);
block-size: 32px;
@@ -2292,7 +2337,8 @@ input {
font-weight: bolder;
}
.delete-warning {
.delete-warning,
.clear-container-storage-warning {
padding-block-end: 8px;
padding-block-start: 8px;
padding-inline-end: 0;
@@ -2303,7 +2349,8 @@ input {
* rules grouped together at the beginning of the file
*/
/* stylelint-disable no-descending-specificity */
.trash-button {
.trash-button,
.reset-button {
display: inline-block;
block-size: 20px;
inline-size: 20px;
@@ -2312,11 +2359,21 @@ input {
text-align: center;
}
tr > td > .trash-button {
.reset-button {
margin-inline-end: 12px;
}
.tooltip-wrapper:hover .site-settings-tooltip {
display: block;
}
tr > td > .trash-button,
tr > td > .reset-button {
display: none;
}
tr:hover > td > .trash-button {
tr:hover > td > .trash-button,
tr:hover > td > .reset-button {
display: block;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

@@ -1,9 +0,0 @@
<!-- 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/. --><svg data-name="Flat (For Export)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<style>rect,path {fill: rgba(249, 249, 250, 0.8);}</style>
<rect x="1" y="1" width="6" height="6" rx="1"/>
<path d="M14.75 3H13V1.25A0.25 0.25 0 0 0 12.75 1h-1.5A0.25 0.25 0 0 0 11 1.25V3H9.25A0.25 0.25 0 0 0 9 3.25v1.5A0.25 0.25 0 0 0 9.25 5H11v1.75A0.25 0.25 0 0 0 11.25 7h1.5A0.25 0.25 0 0 0 13 6.75V5h1.75A0.25 0.25 0 0 0 15 4.75v-1.5A0.25 0.25 0 0 0 14.75 3z" fill-rule="evenodd"/>
<rect x="1" y="9" width="6" height="6" rx="1"/>
<rect x="9" y="9" width="6" height="6" rx="1"/>
</svg>

Before

Width:  |  Height:  |  Size: 801 B

+9 -3
View File
@@ -1,7 +1,13 @@
<svg data-name="Flat (For Export)" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<style>rect,path {fill: rgba(24, 25, 26, 01);}</style>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<style>
:root { color-scheme: light dark; }
rect, path { fill: rgb(24, 25, 26); }
@media (prefers-color-scheme: dark) {
rect, path { fill: rgba(249, 249, 250, 0.8); }
}
</style>
<rect x="1" y="1" width="6" height="6" rx="1"/>
<path d="M14.75 3H13V1.25A0.25 0.25 0 0 0 12.75 1h-1.5A0.25 0.25 0 0 0 11 1.25V3H9.25A0.25 0.25 0 0 0 9 3.25v1.5A0.25 0.25 0 0 0 9.25 5H11v1.75A0.25 0.25 0 0 0 11.25 7h1.5A0.25 0.25 0 0 0 13 6.75V5h1.75A0.25 0.25 0 0 0 15 4.75v-1.5A0.25 0.25 0 0 0 14.75 3z" fill-rule="evenodd"/>
<rect x="1" y="9" width="6" height="6" rx="1"/>
<rect x="9" y="9" width="6" height="6" rx="1"/>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 727 B

+1
View File
@@ -4,6 +4,7 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;">
<style>
:root { color-scheme: light dark; }
path, circle, g {
fill: menutext;
}

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

+20 -4
View File
@@ -165,11 +165,17 @@ window.assignManager = {
_neverAsk(m) {
const pageUrl = m.pageUrl;
if (m.neverAsk === true) {
if (m.defaultContainer === true) {
this.storageArea.remove(pageUrl);
return;
}
// If we have existing data and for some reason it hasn't been
// deleted etc lets update it
this.storageArea.get(pageUrl).then((siteSettings) => {
if (siteSettings) {
siteSettings.neverAsk = true;
siteSettings.userContextId = backgroundLogic.getUserContextIdFromCookieStoreId(m.cookieStoreId);
this.storageArea.set(pageUrl, siteSettings);
}
}).catch((e) => {
@@ -571,6 +577,16 @@ window.assignManager = {
return true;
},
async _resetCookiesForSite(hostname, cookieStoreId) {
const hostNameTruncated = hostname.replace(/^www\./, ""); // Remove "www." from the hostname
await browser.browsingData.removeCookies({
cookieStoreId: cookieStoreId,
hostnames: [hostNameTruncated] // This does not remove cookies from associated domains. To remove all cookies, we have a container storage removal option.
});
return true;
},
async _setOrRemoveAssignment(tabId, pageUrl, userContextId, remove) {
let actionName;
// https://github.com/mozilla/testpilot-containers/issues/626
@@ -678,7 +694,7 @@ window.assignManager = {
}
browser.contextMenus.create({
id: menuId,
title: "Always Open in This Container",
title: browser.i18n.getMessage("alwaysOpenSiteInContainer"),
checked,
type: "checkbox",
contexts: ["all"],
@@ -692,13 +708,13 @@ window.assignManager = {
browser.contextMenus.create({
id: this.MENU_HIDE_ID,
title: "Hide This Container",
title: browser.i18n.getMessage("hideThisContainer"),
contexts: ["all"],
});
browser.contextMenus.create({
id: this.MENU_MOVE_ID,
title: "Move Tabs to a New Window",
title: browser.i18n.getMessage("moveTabsToANewWindow"),
contexts: ["all"],
});
},
@@ -764,7 +780,7 @@ window.assignManager = {
async initBookmarksMenu() {
browser.contextMenus.create({
id: this.OPEN_IN_CONTAINER,
title: "Open Bookmark in Container Tab",
title: browser.i18n.getMessage("openBookmarkInContainerTab"),
contexts: ["bookmark"],
});
+35 -13
View File
@@ -14,7 +14,13 @@ const backgroundLogic = {
NUMBER_OF_KEYBOARD_SHORTCUTS: 10,
unhideQueue: [],
init() {
browser.commands.onCommand.addListener(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];
@@ -27,7 +33,20 @@ const backgroundLogic = {
browser.permissions.onAdded.addListener(permissions => this.resetPermissions(permissions));
browser.permissions.onRemoved.addListener(permissions => this.resetPermissions(permissions));
backgroundLogic.setSyncExclusion();
// Update Translation in Manifest
browser.runtime.onInstalled.addListener(this.updateTranslationInManifest);
browser.runtime.onStartup.addListener(this.updateTranslationInManifest);
},
updateTranslationInManifest() {
for (let index = 0; index < 10; index++) {
const ajustedIndex = 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}`)
});
}
},
resetPermissions(permissions) {
@@ -56,6 +75,19 @@ const backgroundLogic = {
return extensionInfo;
},
// Remove container data (cookies, localStorage and cache)
async deleteContainerDataOnly(userContextId) {
await browser.browsingData.removeCookies({
cookieStoreId: this.cookieStoreId(userContextId)
});
await browser.browsingData.removeLocalStorage({
cookieStoreId: this.cookieStoreId(userContextId)
});
return {done: true, userContextId};
},
getUserContextIdFromCookieStoreId(cookieStoreId) {
if (!cookieStoreId) {
return false;
@@ -124,7 +156,8 @@ const backgroundLogic = {
// We can't open these we just have to throw them away
if (protocol === "about:"
|| protocol === "chrome:"
|| protocol === "moz-extension:") {
|| protocol === "moz-extension:"
|| protocol === "file:") {
return false;
}
return true;
@@ -400,17 +433,6 @@ const backgroundLogic = {
cookieStoreId(userContextId) {
if(userContextId === 0) return "firefox-default";
return `firefox-container-${userContextId}`;
},
async setSyncExclusion() {
// Default container sync exclude regexp to "^tmp\d+$" to prevent
// https://github.com/mozilla/multi-account-containers/issues/1675
// https://github.com/stoically/temporary-containers/issues/371
// for future users of the MAC + TC combination.
const { syncExcludeRegExp } = await browser.storage.local.get("syncExcludeRegExp");
if (syncExcludeRegExp === undefined) {
browser.storage.local.set({syncExcludeRegExp: "^tmp\\d+$"});
}
}
};
+12 -4
View File
@@ -23,6 +23,9 @@ const messageHandler = {
case "deleteContainer":
response = backgroundLogic.deleteContainer(m.message.userContextId);
break;
case "deleteContainerDataOnly":
response = backgroundLogic.deleteContainerDataOnly(m.message.userContextId);
break;
case "createOrUpdateContainer":
response = backgroundLogic.createOrUpdateContainer(m.message);
break;
@@ -45,6 +48,9 @@ const messageHandler = {
// m.url is the assignment to be removed/added
response = assignManager._setOrRemoveAssignment(m.tabId, m.url, m.userContextId, m.value);
break;
case "resetCookiesForSite":
response = assignManager._resetCookiesForSite(m.pageUrl, m.cookieStoreId);
break;
case "sortTabs":
backgroundLogic.sortTabs();
break;
@@ -90,10 +96,10 @@ const messageHandler = {
break;
case "assignAndReloadInContainer":
tab = await assignManager.reloadPageInContainer(
m.url,
m.url,
m.currentUserContextId,
m.newUserContextId,
m.tabIndex,
m.newUserContextId,
m.tabIndex,
m.active,
true
);
@@ -220,7 +226,9 @@ const messageHandler = {
// if it's a container tab wait for it to complete and
// unhide other tabs from this container
if (tab.cookieStoreId.startsWith("firefox-container")) {
browser.tabs.onUpdated.addListener(this.tabUpdateHandler);
browser.tabs.onUpdated.addListener(this.tabUpdateHandler, {
properties: ["status"]
});
}
}
}
-46
View File
@@ -128,15 +128,9 @@ const sync = {
await sync.checkForListenersMaybeAdd();
async function updateSyncIdentities() {
const excludeRegExp = await getExcludeRegExp();
const identities = await browser.contextualIdentities.query({});
for (const identity of identities) {
// skip excluded identities
if (excludeRegExpMatchesIdentity(excludeRegExp, identity)) {
continue;
}
delete identity.colorCode;
delete identity.iconUrl;
identity.macAddonUUID = await identityState.lookupMACaddonUUID(identity.cookieStoreId);
@@ -333,7 +327,6 @@ async function restore() {
*/
async function reconcileIdentities(){
if (SYNC_DEBUG) console.log("reconcileIdentities");
const excludeRegExp = await getExcludeRegExp();
// first delete any from the deleted list
const deletedIdentityList =
@@ -343,14 +336,6 @@ async function reconcileIdentities(){
const deletedCookieStoreId =
await identityState.lookupCookieStoreId(deletedUUID);
if (deletedCookieStoreId){
if (excludeRegExp) {
const deletedIdentity = await identityState.get(deletedCookieStoreId);
// skip excluded identities
if (excludeRegExpMatchesIdentity(excludeRegExp, deletedIdentity)) {
continue;
}
}
try{
await browser.contextualIdentities.remove(deletedCookieStoreId);
} catch (error) {
@@ -365,11 +350,6 @@ async function reconcileIdentities(){
await sync.storageArea.getIdentities();
// find any local dupes created on sync storage and delete from sync storage
for (const localIdentity of localIdentities) {
// skip excluded identities
if (excludeRegExpMatchesIdentity(excludeRegExp, localIdentity)) {
continue;
}
const syncIdentitiesOfName = syncIdentitiesRemoveDupes
.filter(identity => identity.name === localIdentity.name);
if (syncIdentitiesOfName.length > 1) {
@@ -383,11 +363,6 @@ async function reconcileIdentities(){
await sync.storageArea.getIdentities();
// now compare all containers for matching names.
for (const syncIdentity of syncIdentities) {
// skip excluded identities
if (excludeRegExpMatchesIdentity(excludeRegExp, syncIdentity)) {
continue;
}
if (syncIdentity.macAddonUUID){
const localMatch = localIdentities.find(
localIdentity => localIdentity.name === syncIdentity.name
@@ -603,24 +578,3 @@ async function setAssignmentWithUUID(assignedSite, urlKey) {
}
throw new Error (`No cookieStoreId found for: ${uuid}, ${urlKey}`);
}
// Retrieve the sync exclude regexp from local storage.
async function getExcludeRegExp() {
const { syncExcludeRegExp } = await browser.storage.local.get("syncExcludeRegExp");
if (syncExcludeRegExp) {
return new RegExp(syncExcludeRegExp, "i");
} else {
return false;
}
}
// Matching the provided exclude regexp against the provided identity and return
// true if they match.
function excludeRegExpMatchesIdentity(excludeRegExp, identity) {
if (excludeRegExp && identity.name.match(excludeRegExp)) {
if (SYNC_DEBUG) console.log(`Exclude regexp matches identity '${identity.name}'`);
return true;
} else {
return false;
}
}
+20 -3
View File
@@ -7,14 +7,16 @@ async function load() {
redirectUrlElement.textContent = redirectUrl;
appendFavicon(redirectUrl, redirectUrlElement);
// Option for staying on the previous container
document.getElementById("deny").addEventListener("click", (e) => {
e.preventDefault();
denySubmit(redirectUrl);
denySubmit(redirectUrl, currentCookieStoreId);
});
// Option for going to the default container (no container)
document.getElementById("deny-no-container").addEventListener("click", (e) => {
e.preventDefault();
denySubmit(redirectUrl);
denySubmit(redirectUrl, currentCookieStoreId);
});
const container = await browser.contextualIdentities.get(cookieStoreId);
@@ -27,6 +29,7 @@ async function load() {
el.textContent = browser.i18n.getMessage(elementData.messageId, containerName);
});
// Option for going to newly selected container
document.getElementById("confirm").addEventListener("click", (e) => {
e.preventDefault();
confirmSubmit(redirectUrl, cookieStoreId);
@@ -59,6 +62,7 @@ function confirmSubmit(redirectUrl, cookieStoreId) {
browser.runtime.sendMessage({
method: "neverAsk",
neverAsk: true,
cookieStoreId: cookieStoreId,
pageUrl: redirectUrl
});
}
@@ -72,8 +76,21 @@ function getCurrentTab() {
});
}
async function denySubmit(redirectUrl) {
async function denySubmit(redirectUrl, currentCookieStoreId) {
const tab = await getCurrentTab();
const currentContainer = currentCookieStoreId ? await browser.contextualIdentities.get(currentCookieStoreId) : null;
const neverAsk = document.getElementById("never-ask").checked;
if (neverAsk) {
await browser.runtime.sendMessage({
method: "neverAsk",
neverAsk: true,
cookieStoreId: currentCookieStoreId,
pageUrl: redirectUrl,
defaultContainer: !currentContainer
});
}
await browser.runtime.sendMessage({
method: "exemptContainerAssignment",
tabId: tab[0].id,
+2 -1
View File
@@ -24,11 +24,12 @@ async function addMessage(message) {
divElement.innerText = message.text;
const imageElement = document.createElement("img");
const imagePath = browser.runtime.getURL("/img/container-site-d-24.png");
const imagePath = browser.runtime.getURL("/img/multiaccountcontainer-16.svg");
const response = await fetch(imagePath);
const blob = await response.blob();
const objectUrl = URL.createObjectURL(blob);
imageElement.src = objectUrl;
imageElement.width = imageElement.height = 24;
divElement.prepend(imageElement);
document.body.appendChild(divElement);
-7
View File
@@ -63,12 +63,10 @@ async function setupOptions() {
const { syncEnabled } = await browser.storage.local.get("syncEnabled");
const { replaceTabEnabled } = await browser.storage.local.get("replaceTabEnabled");
const { currentThemeId } = await browser.storage.local.get("currentThemeId");
const { syncExcludeRegExp } = await browser.storage.local.get("syncExcludeRegExp");
document.querySelector("#syncCheck").checked = !!syncEnabled;
document.querySelector("#replaceTabCheck").checked = !!replaceTabEnabled;
document.querySelector("#changeTheme").selectedIndex = currentThemeId;
document.querySelector("#syncExcludeRegExp").value = syncExcludeRegExp || "";
setupContainerShortcutSelects();
}
@@ -122,15 +120,10 @@ async function resetPermissionsUi() {
browser.permissions.onAdded.addListener(resetPermissionsUi);
browser.permissions.onRemoved.addListener(resetPermissionsUi);
function updateSyncExcludeRegExp(event) {
browser.storage.local.set({syncExcludeRegExp: event.target.value});
}
document.addEventListener("DOMContentLoaded", setupOptions);
document.querySelector("#syncCheck").addEventListener( "change", enableDisableSync);
document.querySelector("#replaceTabCheck").addEventListener( "change", enableDisableReplaceTab);
document.querySelector("#changeTheme").addEventListener( "change", changeTheme);
document.querySelector("#syncExcludeRegExp").addEventListener( "change", updateSyncExcludeRegExp);
maybeShowPermissionsWarningIcon();
for (let i=0; i < NUMBER_OF_KEYBOARD_SHORTCUTS; i++) {
+120 -9
View File
@@ -32,6 +32,7 @@ const P_CONTAINER_EDIT = "containerEdit";
const P_CONTAINER_DELETE = "containerDelete";
const P_CONTAINERS_ACHIEVEMENT = "containersAchievement";
const P_CONTAINER_ASSIGNMENTS = "containerAssignments";
const P_CLEAR_CONTAINER_STORAGE = "clearContainerStorage";
const P_MOZILLA_VPN_SERVER_LIST = "moz-vpn-server-list";
const P_ADVANCED_PROXY_SETTINGS = "advanced-proxy-settings-panel";
@@ -122,6 +123,19 @@ const Logic = {
},
notify(i18nOpts) {
const notificationCards = document.querySelectorAll(".popup-notification-card");
const text = browser.i18n.getMessage(i18nOpts.messageId, i18nOpts.placeholders);
notificationCards.forEach(notificationCard => {
notificationCard.textContent = text;
notificationCard.classList.add("is-shown");
setTimeout(() => {
notificationCard.classList.remove("is-shown");
}, 2000);
});
},
async showAchievementOrContainersListPanel() {
// Do we need to show an achievement panel?
let showAchievements = false;
@@ -211,6 +225,11 @@ const Logic = {
async saveContainerOrder(rows) {
const containerOrder = {};
rows.forEach((node, index) => {
if (typeof browser.contextualIdentities.move === "function") {
browser.contextualIdentities.move(
node.dataset.containerId, index);
}
return containerOrder[node.dataset.containerId] = index;
});
await browser.storage.local.set({
@@ -396,7 +415,11 @@ const Logic = {
},
shortcutListener(e){
function openNewContainerTab(identity) {
function openTopContainers() {
const identities = Logic.identities();
const key = e.code.substring(5);
const identity = e.code === "Digit0" ? identities[9] : identities[key - 1];
try {
browser.tabs.create({
cookieStoreId: identity.cookieStoreId
@@ -406,12 +429,34 @@ const Logic = {
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);
// We monitor if the search input is focused so we can disable opening
// containers by typing a digit between 0-9 while the popup is open.
const searchInput = document.getElementById("search-terms");
let isSearchInputFocused = false;
if (document.activeElement === searchInput) {
isSearchInputFocused = true;
}
if (Logic._currentPanel === "containersList" && !isSearchInputFocused) {
switch(e.code) {
case "Digit0":
case "Digit1":
case "Digit2":
case "Digit3":
case "Digit4":
case "Digit5":
case "Digit6":
case "Digit7":
case "Digit8":
case "Digit9":
openTopContainers();
break;
case "Slash":
document.getElementById("search-terms").focus();
e.preventDefault();
break;
}
}
},
@@ -640,7 +685,7 @@ Logic.registerPanel(P_ONBOARDING_7, {
// Let's move to the containers list panel.
Utils.addEnterHandler(document.querySelector("#sign-in"), async () => {
browser.tabs.create({
url: "https://accounts.firefox.com/?service=sync&action=email&context=fx_desktop_v3&entrypoint=multi-account-containers&utm_source=addon&utm_medium=panel&utm_campaign=container-sync",
url: "https://accounts.firefox.com/?service=sync&action=email&context=fx_desktop_v3&entrypoint=multi-account-containers&utm_source=addon&utm_medium=panel&utm_campaign=container-sync&brand=mozilla",
});
await Logic.setOnboardingStage(7);
Logic.showPanel(P_ONBOARDING_8);
@@ -940,6 +985,7 @@ Logic.registerPanel(P_CONTAINER_INFO, {
Utils.alwaysOpenInContainer(identity);
window.close();
});
// Show or not the has-tabs section.
for (let trHasTabs of document.getElementsByClassName("container-info-has-tabs")) { // eslint-disable-line prefer-const
trHasTabs.style.display = !identity.hasHiddenTabs && !identity.hasOpenTabs ? "none" : "";
@@ -963,6 +1009,13 @@ Logic.registerPanel(P_CONTAINER_INFO, {
Utils.addEnterHandler(manageContainer, async () => {
Logic.showPanel(P_CONTAINER_EDIT, identity);
});
const clearContainerStorageButton = document.getElementById("clear-container-storage-info");
Utils.addEnterHandler(clearContainerStorageButton, async () => {
const granted = await browser.permissions.request({ permissions: ["browsingData"] });
if (granted) {
Logic.showPanel(P_CLEAR_CONTAINER_STORAGE, identity);
}
});
return this.buildOpenTabTable(tabs);
},
@@ -1424,11 +1477,14 @@ Logic.registerPanel(P_CONTAINER_ASSIGNMENTS, {
/* As we don't have the full or correct path the best we can assume is the path is HTTPS and then replace with a broken icon later if it doesn't load.
This is pending a better solution for favicons from web extensions */
const assumedUrl = `https://${site.hostname}/favicon.ico`;
const resetSiteCookiesInfo = browser.i18n.getMessage("clearSiteCookiesTooltipInfo");
const deleteSiteInfo = browser.i18n.getMessage("deleteSiteTooltipInfo");
trElement.innerHTML = Utils.escaped`
<td>
<div class="favicon"></div>
<span title="${site.hostname}" class="menu-text truncate-text">${site.hostname}</span>
<img class="trash-button delete-assignment" src="/img/container-delete.svg" />
<img title="${resetSiteCookiesInfo}" class="reset-button reset-assignment" src="/img/refresh-16.svg" />
<img title="${deleteSiteInfo}" class="trash-button delete-assignment" src="/img/container-delete.svg" />
</td>`;
trElement.getElementsByClassName("favicon")[0].appendChild(Utils.createFavIconElement(assumedUrl));
const deleteButton = trElement.querySelector(".trash-button");
@@ -1440,6 +1496,20 @@ Logic.registerPanel(P_CONTAINER_ASSIGNMENTS, {
delete assignments[siteKey];
this.showAssignedContainers(assignments);
});
const resetButton = trElement.querySelector(".reset-button");
Utils.addEnterHandler(resetButton, async () => {
const cookieStoreId = Logic.currentCookieStoreId();
const granted = await browser.permissions.request({ permissions: ["browsingData"] });
if (!granted) {
return;
}
const result = await Utils.resetCookiesForSite(site.hostname, cookieStoreId);
if (result === true) {
Logic.notify({messageId: "cookiesClearedSuccess", placeholders: [site.hostname]});
} else {
Logic.notify({messageId: "cookiesCouldNotBeCleared", placeholders: [site.hostname]});
}
});
trElement.classList.add("menu-item", "hover-highlight", "keyboard-nav");
tableElement.appendChild(trElement);
});
@@ -2215,6 +2285,47 @@ Logic.registerPanel(P_MOZILLA_VPN_SERVER_LIST, {
}
});
// P_CLEAR_CONTAINER_STORAGE: Page for confirming container storage removal.
// ----------------------------------------------------------------------------
Logic.registerPanel(P_CLEAR_CONTAINER_STORAGE, {
panelSelector: "#clear-container-storage-panel",
// This method is called when the object is registered.
initialize() {
Utils.addEnterHandler(document.querySelector("#clear-container-storage-cancel-link"), () => {
const identity = Logic.currentIdentity();
Logic.showPanel(P_CONTAINER_INFO, identity, false, false);
});
Utils.addEnterHandler(document.querySelector("#close-clear-container-storage-panel"), () => {
const identity = Logic.currentIdentity();
Logic.showPanel(P_CONTAINER_INFO, identity, false, false);
});
Utils.addEnterHandler(document.querySelector("#clear-container-storage-ok-link"), async () => {
const identity = Logic.currentIdentity();
const userContextId = Utils.userContextId(identity.cookieStoreId);
const result = await browser.runtime.sendMessage({
method: "deleteContainerDataOnly",
message: { userContextId }
});
if (result.done === true) {
Logic.notify({messageId: "storageWasClearedConfirmation", placeholders: [identity.name]});
}
Logic.showPanel(P_CONTAINER_INFO, identity, false, false);
});
},
// This method is called when the panel is shown.
prepare() {
const identity = Logic.currentIdentity();
// Populating the panel: name, icon, and warning message
document.getElementById("container-clear-storage-title").textContent = identity.name;
return Promise.resolve(null);
},
});
// P_CONTAINER_DELETE: Delete a container.
// ----------------------------------------------------------------------------
+8
View File
@@ -138,6 +138,14 @@ const Utils = {
});
},
resetCookiesForSite(pageUrl, cookieStoreId) {
return browser.runtime.sendMessage({
method: "resetCookiesForSite",
pageUrl,
cookieStoreId,
});
},
async reloadInContainer(url, currentUserContextId, newUserContextId, tabIndex, active) {
return await browser.runtime.sendMessage({
method: "reloadInContainer",
+27 -18
View File
@@ -1,12 +1,12 @@
{
"manifest_version": 2,
"name": "Firefox Multi-Account Containers",
"version": "8.1.0",
"version": "8.2.0",
"incognito": "not_allowed",
"description": "__MSG_extensionDescription__",
"icons": {
"48": "img/container-site-d-48.png",
"96": "img/container-site-d-96.png"
"48": "img/multiaccountcontainer-16.svg",
"96": "img/multiaccountcontainer-16.svg"
},
"homepage_url": "https://github.com/mozilla/multi-account-containers#readme",
"permissions": [
@@ -26,6 +26,7 @@
],
"optional_permissions": [
"bookmarks",
"browsingData",
"nativeMessaging",
"proxy"
],
@@ -41,77 +42,85 @@
"default": "Ctrl+Period",
"mac": "MacCtrl+Period"
},
"description": "Open containers panel"
"description": "__MSG_openContainerPanel__"
},
"sort_tabs": {
"suggested_key": {
"default": "Ctrl+Comma",
"mac": "MacCtrl+Comma"
},
"description": "__MSG_sortTabsByContainer__"
},
"open_container_0": {
"suggested_key": {
"default": "Ctrl+Shift+1"
},
"description": "Container Shortcut 1"
"description": "__MSG_containerShortcut__"
},
"open_container_1": {
"suggested_key": {
"default": "Ctrl+Shift+2"
},
"description": "Container Shortcut 2"
"description": "__MSG_containerShortcut__"
},
"open_container_2": {
"suggested_key": {
"default": "Ctrl+Shift+3"
},
"description": "Container Shortcut 3"
"description": "__MSG_containerShortcut__"
},
"open_container_3": {
"suggested_key": {
"default": "Ctrl+Shift+4"
},
"description": "Container Shortcut 4"
"description": "__MSG_containerShortcut__"
},
"open_container_4": {
"suggested_key": {
"default": "Ctrl+Shift+5"
},
"description": "Container Shortcut 5"
"description": "__MSG_containerShortcut__"
},
"open_container_5": {
"suggested_key": {
"default": "Ctrl+Shift+6"
},
"description": "Container Shortcut 6"
"description": "__MSG_containerShortcut__"
},
"open_container_6": {
"suggested_key": {
"default": "Ctrl+Shift+7"
},
"description": "Container Shortcut 7"
"description": "__MSG_containerShortcut__"
},
"open_container_7": {
"suggested_key": {
"default": "Ctrl+Shift+8"
},
"description": "Container Shortcut 8"
"description": "__MSG_containerShortcut__"
},
"open_container_8": {
"suggested_key": {
"default": "Ctrl+Shift+9"
},
"description": "Container Shortcut 9"
"description": "__MSG_containerShortcut__"
},
"open_container_9": {
"suggested_key": {
"default": "Ctrl+Shift+0"
},
"description": "Container Shortcut 10"
"description": "__MSG_containerShortcut__"
}
},
"browser_action": {
"browser_style": true,
"default_icon": "img/multiaccountcontainer-16.svg",
"default_title": "Multi-Account Containers",
"default_title": "Firefox Multi-Account Containers",
"default_popup": "popup.html",
"default_area": "navbar",
"theme_icons": [
{
"light": "img/multiaccountcontainer-16-dark.svg",
"light": "img/multiaccountcontainer-16.svg",
"dark": "img/multiaccountcontainer-16.svg",
"size": 32
}
@@ -120,7 +129,7 @@
"page_action": {
"browser_style": true,
"default_icon": "img/container-openin-16.svg",
"default_title": "Always open this in a Container",
"default_title": "__MSG_alwaysOpenSiteInContainer__",
"default_popup": "pageActionPopup.html",
"pinned": false,
"show_matches": ["*://*/*"]
@@ -144,7 +153,7 @@
],
"default_locale": "en",
"web_accessible_resources": [
"/img/container-site-d-24.png"
"/img/multiaccountcontainer-16.svg"
],
"options_ui": {
"page": "options.html",
+1 -10
View File
@@ -40,7 +40,7 @@
</div>
</div>
</div>
<h3 data-i18n-message-id="firefoxAccountsSync"></h3>
<h3 data-i18n-message-id="sync"></h3>
<div class="settings-group">
<label>
<input type="checkbox" id="syncCheck">
@@ -48,15 +48,6 @@
</label>
<p><em data-i18n-message-id="enableSyncDescription"></em></p>
</div>
<div class="settings-group-column">
<label for="syncExcludeRegExp">
<span class="bold" data-i18n-message-id="syncExclude"></span>
</label>
<input id="syncExcludeRegExp"
data-i18n-attribute="placeholder"
data-i18n-attribute-message-id="syncExcludePlaceholder">
<p><em data-i18n-message-id="syncExcludeDescription"></em></p>
</div>
<h3 data-i18n-message-id="tabBehavior"></h3>
+1 -1
View File
@@ -1,7 +1,7 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Multi-Account Containers</title>
<title>Firefox Multi-Account Containers</title>
<script type="text/javascript" src="./js/i18n.js"></script>
<link rel="stylesheet" type="text/css" href="css/popup.css">
+36 -7
View File
@@ -1,7 +1,7 @@
<html data-theme="auto">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Multi-Account Containers</title>
<title>Firefox Multi-Account Containers</title>
<script type="text/javascript" src="./js/i18n.js"></script>
<link rel="stylesheet" href="./css/popup.css">
</head>
@@ -44,7 +44,7 @@
<div class="panel onboarding onboarding-panel-6 hide" id="onboarding-panel-6">
<img class="onboarding-img" alt="" src="/img/Sync.svg" />
<h3 class="onboarding-title" data-i18n-message-id="onboarding-6-header"></h3>
<p data-i18n-message-id="onboarding-6-description"></p>
<p data-i18n-message-id="onboarding-6-description-2"></p>
<div class="half-button-wrapper">
<a href="#" id="no-sync" class="half-onboarding-button grey-button keyboard-nav" tabindex="0" data-i18n-message-id="notNow"></a>
<a href="#" id="start-sync-button" class="half-onboarding-button keyboard-nav" tabindex="0" data-i18n-message-id="startSyncing"></a>
@@ -53,8 +53,8 @@
<div class="panel onboarding onboarding-panel-7 hide" id="onboarding-panel-7">
<img class="onboarding-img" alt="" src="/img/Account.svg" />
<h3 class="onboarding-title" data-i18n-message-id="onboarding-7-header"></h3>
<p data-i18n-message-id="onboarding-7-description"></p>
<h3 class="onboarding-title" data-i18n-message-id="onboarding-7-header-2"></h3>
<p data-i18n-message-id="onboarding-7-description-2"></p>
<div class="half-button-wrapper">
<a href="#" id="no-sign-in" class="half-onboarding-button grey-button keyboard-nav" tabindex="0" data-i18n-message-id="notNow"></a>
<a href="#" id="sign-in" class="half-onboarding-button keyboard-nav" tabindex="0" data-i18n-message-id="signIn"></a>
@@ -107,7 +107,8 @@
</div>
<div class="panel menu-panel container-panel hide" id="container-panel">
<h3 class="title">Multi-Account Containers</h3>
<span class="popup-notification-card"></span>
<h3 class="title">Firefox Multi-Account Containers</h3>
<a href="#" class="info-icon" id="info-icon" tabindex="10">
<img data-i18n-attribute-message-id="info" data-i18n-attribute="alt" alt="" src="/img/info.svg" / >
</a>
@@ -209,6 +210,7 @@
<div class="hide panel menu-panel container-info-panel" id="container-info-panel" tabindex="-1">
<span class="popup-notification-card"></span>
<h3 class="title" id="container-info-title" data-i18n-attribute-message-id="personal"></h3>
<button class="btn-return arrow-left controller keyboard-nav-back" id="close-container-info-panel" tabindex="0"></button>
<hr>
@@ -245,6 +247,14 @@
</span>
</td>
</tr>
<tr class="menu-item hover-highlight keyboard-nav" id="clear-container-storage" tabindex="0">
<td>
<img class="menu-icon clear-storage-icon" alt="" src="img/container-delete.svg" />
<span class="menu-text" id="clear-container-storage-info" data-i18n-message-id="clearContainerStorage"></span>
<span class="menu-arrow">
</span>
</td>
</tr>
</table>
<hr>
<div class="sub-header-wrapper">
@@ -267,8 +277,9 @@
<div class="panel menu-panel container-picker-panel hide" id="container-picker-panel">
<span class="popup-notification-card"></span>
<h3 class="title" id="picker-title">
Multi-Account Containers
Firefox Multi-Account Containers
</h3>
<button class="btn-return arrow-left controller keyboard-nav-back" id="close-container-picker-panel" tabindex="0"></button>
<hr>
@@ -291,6 +302,7 @@
</div>
<div class="panel menu-panel edit-container-panel hide" id="edit-container-panel">
<span class="popup-notification-card"></span>
<h3 class="title" id="container-edit-title" data-i18n-message-id="default"></h3>
<button class="btn-return arrow-left controller" id="close-container-edit-panel"></button>
<hr>
@@ -381,6 +393,7 @@
</div>
<div class="panel menu-panel edit-container-assignments hide" id="edit-container-assignments">
<span class="popup-notification-card"></span>
<h3 class="title" id="edit-assignments-title" data-i18n-message-id="default"></h3>
<button class="btn-return arrow-left controller" id="close-container-assignment-panel"></button>
<hr>
@@ -410,7 +423,23 @@
</div>
<div class="panel-footer">
<a href="#" class="button expanded secondary footer-button cancel-button" data-i18n-message-id="cancel" id="delete-container-cancel-link"></a>
<a href="#" class="button expanded primary footer-button" data-i18n-message-id="ok" id="delete-container-ok-link"></a>
<a href="#" class="button expanded confirmation-destructive-ok-btn footer-button alert-text" data-i18n-message-id="ok" id="delete-container-ok-link"></a>
</div>
</div>
<div class="hide panel clear-container-storage-panel" id="clear-container-storage-panel">
<h3 class="title" id="container-clear-storage-title" data-i18n-message-id="default">
</h3>
<button class="btn-return arrow-left controller" id="close-clear-container-storage-panel"></button>
<hr>
<div class="panel-content clear-container-storage-confirm">
<h4 class="clear-container-storage-confirm-title" data-i18n-message-id="clearContainerStoragePanelTitle"></h4>
<p class="clear-container-storage-warning" data-i18n-message-id="clearContainerStorageConfirmation"></p>
</div>
<div class="panel-footer">
<a href="#" class="button expanded secondary footer-button cancel-button" data-i18n-message-id="cancel" id="clear-container-storage-cancel-link"></a>
<a href="#" class="button expanded confirmation-destructive-ok-btn footer-button alert-text" data-i18n-message-id="ok" id="clear-container-storage-ok-link"></a>
</div>
</div>
-60
View File
@@ -187,50 +187,6 @@ describe("Sync", function() {
this.syncHelper.lookupIdentityBy(identities, {name: "Mozilla"});
(mozillaContainer.icon === "pet").should.be.true;
});
it("excludeEmptyTest", async function() {
await this.syncHelper.stopSyncListeners();
await this.syncHelper.setState({}, LOCAL_DATA, TEST_CONTAINERS, []);
await this.syncHelper.unsetExcludeRegexp();
await this.webExt.background.window.sync.runSync();
// We excluded nothing, so all identities should be part of the sync storage.
const identities = await this.syncHelper.getIdentitiesFromSyncStorage();
TEST_CONTAINERS.length.should.equal(identities.length);
});
it("excludeOutgoingTest", async function() {
await this.syncHelper.stopSyncListeners();
await this.syncHelper.setState({}, LOCAL_DATA, TEST_CONTAINERS, []);
// Our outgoing container is the last test container.
const outgoingContainerName = TEST_CONTAINERS.at(-1).name;
await this.syncHelper.setExcludeRegexp(`^${outgoingContainerName}$`);
await this.webExt.background.window.sync.runSync();
// We excluded an outgoing container, so its identity should not be part of the sync storage.
const identities = await this.syncHelper.getIdentitiesFromSyncStorage();
this.syncHelper.lookupIdentityBy(identities, {name: outgoingContainerName}).should.be.false;
});
it("excludeIncomingTest", async function() {
await this.syncHelper.stopSyncListeners();
await this.syncHelper.setState(SYNC_DATA, LOCAL_DATA, TEST_CONTAINERS, []);
// Our incoming container is the first that's in the sync storage but not in the local storage
const incomingContainerName = Object.values(SYNC_DATA).find((sync_container) =>
!TEST_CONTAINERS.find((local_container) => sync_container.name === local_container.name)
).name;
await this.syncHelper.setExcludeRegexp(`^${incomingContainerName}$`);
await this.webExt.background.window.sync.runSync();
// We excluded an incoming container, so its identity should not be part of the local storage.
const identities = await this.webExt.browser.contextualIdentities.query({});
this.syncHelper.lookupIdentityBy(identities, {name: incomingContainerName}).should.be.false;
});
});
class SyncTestHelper {
@@ -268,15 +224,7 @@ class SyncTestHelper {
}
return;
}
async setExcludeRegexp(syncExcludeRegExp) {
await this.webExt.browser.storage.local.set({syncExcludeRegExp});
}
async unsetExcludeRegexp() {
await this.webExt.browser.storage.local.remove("syncExcludeRegExp");
}
async removeAllContainers() {
const identities = await this.webExt.browser.contextualIdentities.query({});
for (const identity of identities) {
@@ -284,14 +232,6 @@ class SyncTestHelper {
}
}
async getIdentitiesFromSyncStorage() {
const storage = await this.webExt.browser.storage.sync.get();
const identities = Object.fromEntries(
Object.entries(storage).filter(([key]) => key.startsWith("identity@@"))
);
return Object.values(identities);
}
lookupIdentityBy(identities, options) {
for (const identity of identities) {
if (options && options.name) {