Compare commits

..

77 Commits

Author SHA1 Message Date
luke crouch a328e5bf91 Merge pull request #1509 from mozilla/october-2019-dot-release
Updated add-on to version 6.1.1
2019-10-02 16:35:19 -05:00
Maxx Crawford 46a55da277 Updated to version 6.1.1 2019-10-02 16:22:54 -05:00
Francis McKenzie 1746d8379b Improved comments in CSS 2019-09-23 23:09:05 +01:00
Francis McKenzie f57cf92f41 Bugfix: incorrect scrollbars/spacing when editing container with many assignments 2019-09-23 23:09:05 +01:00
Harry Twyford 54659f5c77 #1375 - Correct colors on confirmation page 2019-09-23 17:34:46 +01:00
Maxx Crawford 2badd22f41 Merge pull request #1485 from kendallcorner/master
Fixed #766 — Popup display expands to fit overflow menu
2019-09-20 16:54:47 -05:00
Kendall Werts 21b7386a94 probably a better solution than using a timeout 2019-08-28 08:39:53 -05:00
Kendall Werts 529b9bb482 forgot a semicolon 2019-08-27 12:22:25 -05:00
Kendall Werts 3adb333022 solving linter issue without breaking the fix. 2019-08-27 11:54:16 -05:00
Kendall Werts cc988a303e lack of px on the zero appears to break it. 2019-08-27 11:06:40 -05:00
Kendall Werts 46349e1a70 linted 2019-08-27 10:42:58 -05:00
Kendall Werts acff80a234 Merge branch 'master' of github.com:mozilla/multi-account-containers 2019-08-26 17:12:22 -05:00
Kendall Werts bbe655d879 fixed first panel issue 2019-08-26 17:06:48 -05:00
Kendall Werts 7cbace9cc9 fix for #766 issues with display in overflow menu 2019-08-26 14:47:02 -05:00
luke crouch 9372899bfa Merge pull request #1470 from kendallcorner/master
Default favicon now displays for Edit Containers panel (issue #1314)
2019-08-07 10:41:30 -05:00
Kendall Werts 4d42a74e66 Added class to empty div as requested 2019-08-06 20:39:46 -05:00
Kendall Werts 76f7a64cb8 fixed favicon url 2019-07-26 08:50:22 -05:00
Kendall Werts 1af8cf8222 fix for issue #1314 2019-07-25 13:38:17 -05:00
stoically 11a3b2facd Merge pull request #1435 from silverwind/dark-mode-icon
Support dark themes on icon - Fixes #1424
2019-07-17 16:47:41 +02:00
stoically bd993d2f84 Merge pull request #1451 from Arthaey/patch-1
Fix typo in a comment.
2019-07-17 16:42:28 +02:00
Arthaey Angosii cf9683174d Fix typo in a comment. 2019-07-07 18:01:33 -07:00
silverwind f617ca26bb Support dark themes on icon - Fixes #1424 2019-06-09 18:45:41 +02:00
ctgardner 41686fdf6c Revert "Increase timeout on flakey async test"
This reverts commit 154df62687.
2019-05-07 02:23:00 +01:00
ctgardner c67a985847 Increase timeout on flakey async test 2019-05-07 02:23:00 +01:00
ctgardner 639399925c Refactor async anonymous functions into arrow functions
- fixes #972
2019-05-07 02:23:00 +01:00
stoically 2ded900188 Reduce noise in issue template 2019-05-07 01:36:02 +01:00
Jonathan Kingston 3ae1803420 Bug 1539507 - Fix targeting of button click when button element isn't clicked. 2019-05-07 01:32:28 +01:00
luke crouch 17b2d8c773 Merge pull request #1371 from gliptak/patch-1
Bring CODE_OF_CONDUCT.md current
2019-04-23 12:14:45 -05:00
Gábor Lipták 7025c98e7b Bring CODE_OF_CONDUCT.md current 2019-04-15 14:24:16 -04:00
luke crouch 6f4d3c4327 Merge pull request #1329 from ShivangiKakkar/new-release
Fixes #1328: Adding new version
2019-01-23 13:59:19 -06:00
shivangikakkar 7833a6a79f adding new version 2019-01-23 23:30:04 +05:30
luke crouch c2f2d69ba1 Merge pull request #1327 from ShivangiKakkar/fixes-985
exempting `always open in` functionality for non-standard ports
2019-01-22 20:21:57 -06:00
shivangikakkar 42b0312790 exempting always open in functionality for non-standard ports 2019-01-19 02:02:27 +09:00
Jonathan Kingston cc42beeb5a Merge branch 'ShivangiKakkar-fixes-168' 2019-01-12 23:30:02 +00:00
Jonathan Kingston ea5669911b Merge branch 'fixes-168' of https://github.com/ShivangiKakkar/multi-account-containers into ShivangiKakkar-fixes-168 2019-01-12 23:28:49 +00:00
Shivangi Kakkar b4c2da5474 Merge branch 'master' into fixes-168 2019-01-11 10:33:54 +09:00
shivangikakkar 6d7086d541 added functions and cosmetic changes 2019-01-11 09:25:00 +09:00
shivangikakkar db0dba66b2 dynamically added close image icon in the title column 2019-01-11 04:06:08 +09:00
shivangikakkar 5b58168999 Refactored the logic to form warning message 2019-01-07 23:08:59 +00:00
groovecoder 4ed453d58e save ajv at 6.6.2 2019-01-07 23:08:59 +00:00
mingchia-andy-liu 66a9116524 Fix delete warning message #1051
- Include the number of tabs that will be closed when container is deleted
- Insert the warning message to the `span` tag that was originally there
2019-01-07 23:08:59 +00:00
Jonathan Kingston cb7ac6ca5e Merge pull request #1298 from aabbi/duplicate-tabs-791
Fixes #1109 , rest of #791
2019-01-04 14:40:46 +00:00
luke crouch a2995b6c66 Merge pull request #1292 from jonathanKingston/fix-missing-favicon
Add in missing favicon. Fixes #1285
2018-12-05 12:41:43 -06:00
luke crouch ed383c8dfc Merge pull request #1294 from jonathanKingston/badge-background-error
Remove badge background error. Fixes #1293
2018-12-05 09:09:34 -06:00
luke crouch df9b900db6 Merge pull request #1297 from jonathanKingston/6.0.1
Bump release to 6.0.1
2018-12-05 08:48:50 -06:00
luke crouch 8e611de605 Merge pull request #1295 from jonathanKingston/fix-missing-check-image
Fix missing assignment check mark. Fixes #1271
2018-12-05 08:47:02 -06:00
shivangikakkar 8af4c36fd0 removing inline css 2018-10-29 16:32:10 +05:30
shivangikakkar abc4e0cdcf review changes 2018-10-23 15:13:41 +05:30
aabbi b6dd32f683 moved unhiding container to background logic 2018-10-22 20:05:03 -04:00
Jonathan Kingston 0a437ff303 Bump release to 6.0.1. Fixes #1296 2018-10-21 22:33:08 +01:00
Jonathan Kingston f7f4c320a6 Fix missing assignment check mark. Fixes #1271 2018-10-21 22:22:48 +01:00
Jonathan Kingston 5813621fb9 Remove badge background error. Fixes #1293 2018-10-21 21:25:55 +01:00
Jonathan Kingston 56fc7407da Add in missing favicon. Fixes #1285 2018-10-21 21:13:57 +01:00
Jonathan Kingston 220b902144 Merge pull request #1275 from ShivangiKakkar/fixes-256
#256 disables edit-container button when no container is present
2018-10-21 19:45:44 +01:00
shivangikakkar c15eee22c6 implemented remove individual tabs just for visible state 2018-10-21 23:24:18 +05:30
shivangikakkar dcc3b76cda simplifying the solution 2018-10-21 17:12:56 +05:30
shivangikakkar 752d18ffca prevent event handler when edit containers disabled 2018-10-18 21:33:48 +05:30
luke crouch 97559dd08a Merge pull request #1281 from hritvi/npm_fixes
Fixes vulnerabilities in npm
2018-10-03 07:00:14 -05:00
hritvi 0e7363a87f npm fixes 2018-10-03 16:16:44 +05:30
hritvi 6c62c2f599 fixes vulnerabilities in npm 2018-10-03 16:14:36 +05:30
Jonathan Kingston 884e419a7c Merge pull request #1265 from ShivangiKakkar/fixes-1028
#1028 resolves focus name field on opening new container sub-panel
2018-10-02 18:18:05 +01:00
shivangikakkar d7586dd4c2 resolves #256 disables edit-container button when no container is present
resolve lint errors

review changes
2018-10-01 00:01:50 +05:30
shivangikakkar aada0419eb removing event loop and using requestAnimationFrame 2018-09-30 18:17:01 +05:30
shivangikakkar 1ea04587d9 resolves lint errors 2018-09-25 17:47:17 +05:30
luke crouch 3d1dcd33d1 Merge pull request #1262 from ShivangiKakkar/fixes-885
#885 disables move tab to a new window when only one tab is opened
2018-09-24 14:05:27 -05:00
shivangikakkar bfdbd8199f fixes-168, added ability to close a tab individually 2018-09-25 00:21:46 +05:30
shivangikakkar fe0810b048 restructuring the code acc to the review 2018-09-23 00:42:43 +05:30
shivangikakkar e1c1ac4bd9 adds back the unnecessarily removed new line 2018-09-21 14:31:54 +05:30
shivangikakkar 7f7f221a79 fix-#1028 resolves focus name field on opening new container sub-panel 2018-09-21 14:04:43 +05:30
shivangikakkar e57c556427 review changes 2018-09-20 23:40:22 +05:30
shivangikakkar dd57158ab5 #885 disables move tab to a new window when only one tab is opened 2018-09-20 21:34:19 +05:30
stoically 99db192792 Merge pull request #1170 from real-or-random/master
Update GitHub URLs
2018-03-31 00:04:37 +02:00
stoically fcbee854d0 Merge pull request #1172 from stoically/add-issue-template
Add ISSUE_TEMPLATE
2018-03-30 16:46:22 +02:00
stoically fae1336467 Add ISSUE_TEMPLATE 2018-03-30 16:43:24 +02:00
Tim Ruffing 655d8f3791 Update GitHub URLs 2018-03-29 13:45:05 +02:00
luke crouch dcc852bf17 Merge pull request #1120 from stoically/cancel-redirects-tabid-url
Cancel redirects for the same requestIds and urls if originating from the same tabId
2018-03-01 14:23:29 -06:00
stoically dab3005c6f Cancel redirects for the same requestIds and urls if originating from the same tabId
Fixes #940
2018-02-23 15:33:32 +01:00
22 changed files with 510 additions and 134 deletions
+27
View File
@@ -0,0 +1,27 @@
<!--
Feel free to ignore this Issue template if you just want to ask or suggest something. If you experience an Issue then please provide all asked information.
Also please make sure that:
- "Firefox will: Never remember history" in the Firefox Preferences/Options under "Privacy & Security > History" is NOT selected
- You are NOT using Firefox in a Private Window
- You can see a grayed out but ticked Checkbox with the description "Enable Container Tabs" in the Firefox Preferences/Options under "Tabs"
-->
- Multi-Account Containers Version:
- Operating System + Version:
- Firefox Version:
- Other installed Add-ons + Version + Enabled/Disabled-Status:
<!-- To be able to copy & paste the full list of your Add-ons navigate to "about:support" and scroll down to "Extensions" -->
### Actual behavior
### Expected behavior
### Steps to reproduce
1.
2.
3.
### Notes
+14 -2
View File
@@ -1,3 +1,15 @@
# Code Of Conduct
# Community Participation Guidelines
This add-on follows the [Mozilla Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/) for our code of conduct.
This repository is governed by Mozilla's code of conduct and etiquette guidelines.
For more details, please read the
[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
## How to Report
For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
<!--
## Project Specific Etiquette
In some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).
Please update for your project.
-->
+2 -2
View File
@@ -9,9 +9,9 @@ Everyone is welcome to contribute to containers. Reach out to team members if yo
If you find a bug with containers, please file a issue.
Check first if the bug might already exist: https://github.com/mozilla/testpilot-containers/issues
Check first if the bug might already exist: https://github.com/mozilla/multi-account-containers/issues
[Open an issue](https://github.com/mozilla/testpilot-containers/issues/new)
[Open an issue](https://github.com/mozilla/multi-account-containers/issues/new)
1. Visit about:support
2. Click "Copy raw data to clipboard" and paste into the bug. Alternatively copy the following sections into the issue:
+8 -9
View File
@@ -2,41 +2,40 @@
"name": "testpilot-containers",
"title": "Multi-Account Containers",
"description": "Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.",
"version": "6.0.0",
"version": "6.1.1",
"author": "Andrea Marchesini, Luke Crouch and Jonathan Kingston",
"bugs": {
"url": "https://github.com/mozilla/testpilot-containers/issues"
"url": "https://github.com/mozilla/multi-account-containers/issues"
},
"dependencies": {},
"devDependencies": {
"addons-linter": "^0.15.14",
"ajv": "^6.6.2",
"addons-linter": "^1.3.2",
"chai": "^4.1.2",
"deploy-txp": "^1.0.7",
"eslint": "^3.17.1",
"eslint-plugin-no-unsanitized": "^2.0.0",
"eslint-plugin-promise": "^3.4.0",
"htmllint-cli": "^0.0.5",
"htmllint-cli": "0.0.7",
"jsdom": "^11.6.2",
"json": "^9.0.6",
"mocha": "^5.0.0",
"npm-run-all": "^4.0.0",
"sinon": "^4.2.2",
"sinon": "^4.4.0",
"sinon-chai": "^2.14.0",
"stylelint": "^7.9.0",
"stylelint-config-standard": "^16.0.0",
"stylelint-order": "^0.3.0",
"web-ext": "^2.2.2"
},
"homepage": "https://github.com/mozilla/testpilot-containers#readme",
"homepage": "https://github.com/mozilla/multi-account-containers#readme",
"license": "MPL-2.0",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/mozilla/testpilot-containers.git"
"url": "git+https://github.com/mozilla/multi-account-containers.git"
},
"scripts": {
"build": "npm test && cd src && web-ext build --overwrite-dest",
"deploy": "deploy-txp",
"lint": "npm-run-all lint:*",
"lint:addon": "addons-linter src --self-hosted",
"lint:css": "stylelint src/css/*.css",
+9 -1
View File
@@ -47,7 +47,7 @@ html {
}
#redirect-url {
background: #efefef;
background: #efedf0; /* Grey 20 */
border-radius: 2px;
line-height: 1.5;
padding-block-end: 0.5rem;
@@ -56,6 +56,14 @@ html {
padding-inline-start: 0.5rem;
}
/* stylelint-disable media-feature-name-no-unknown */
@media (prefers-color-scheme: dark) {
#redirect-url {
background: #38383d; /* Grey 70 */
}
}
/* stylelint-enable */
#redirect-url img {
block-size: 16px;
inline-size: 16px;
+46 -13
View File
@@ -19,8 +19,13 @@ html {
body {
font-family: Roboto, Noto, "San Francisco", Ubuntu, "Segoe UI", "Fira Sans", message-box, Arial, sans-serif;
inline-size: 300px;
max-inline-size: 300px;
inline-size: calc(var(--overflow-size) + 299px);
max-inline-size: calc(var(--overflow-size) + 299px);
}
html,
body {
block-size: 100%; /* Bugfix: issue 948 */
}
:root {
@@ -45,6 +50,10 @@ body {
--small-text-size: 0.833rem; /* 10px */
--small-radius: 3px;
--icon-button-size: calc(calc(var(--block-line-separation-size) * 2) + 1.66rem); /* 20px */
--column-panel-inline-size: calc(var(--overflow-size) + 267px);
--inactive-opacity: 0.3;
--overflow-size: 1px;
--icon-fit: 8;
}
@media (min-resolution: 1dppx) {
@@ -234,7 +243,7 @@ table {
text-decoration: underline;
}
/* Panels keep everything togethert */
/* Panels keep everything together */
.panel {
display: flex;
flex-direction: column;
@@ -266,7 +275,7 @@ table {
.column-panel-content {
display: flex;
flex-direction: column;
inline-size: 268px;
inline-size: var(--column-panel-inline-size);
}
.column-panel-content .panel-footer {
@@ -537,7 +546,7 @@ span ~ .panel-header-text {
}
#current-tab > label > input:checked {
background-image: url("chrome://global/skin/in-content/check.svg#check-native");
background-image: url("/img/check.svg");
background-position: -1px -1px;
background-size: var(--icon-size);
}
@@ -575,7 +584,12 @@ span ~ .panel-header-text {
}
.edit-containers-panel .userContext-wrapper {
max-inline-size: 204px;
max-inline-size: calc(var(--overflow-size) + 203px);
}
.disable-edit-containers {
opacity: var(--inactive-opacity);
pointer-events: none;
}
.userContext-wrapper {
@@ -653,7 +667,11 @@ span ~ .panel-header-text {
/* Container info list */
.container-info-tab-title {
flex: 1;
display: flex;
}
.container-info-tab-row:hover .container-info-tab-title .truncate-text {
inline-size: calc(var(--column-panel-inline-size) - 58px);
}
#container-info-hideorshow {
@@ -670,6 +688,21 @@ span ~ .panel-header-text {
opacity: 0.3;
}
.container-close-tab {
transform: scale(0.7);
visibility: collapse;
}
.container-info-tab-row:hover .container-close-tab {
opacity: 0.5;
visibility: visible;
}
.container-info-tab-row .container-close-tab:hover {
opacity: 1;
visibility: visible;
}
.container-info-has-tabs,
.container-info-tab-row {
align-items: center;
@@ -696,10 +729,6 @@ span ~ .panel-header-text {
margin-inline-end: 0;
}
.container-info-tab-row td {
max-inline-size: 200px;
}
.container-info-list {
display: flex;
flex-direction: column;
@@ -761,8 +790,12 @@ span ~ .panel-header-text {
padding-inline-start: 16px;
}
.edit-container-panel .columns {
overflow: hidden; /* Bugfix: issue 948 */
}
#edit-sites-assigned {
flex: 1;
flex: 1000; /* Bugfix: issue 948 */
}
#edit-sites-assigned h3 {
@@ -800,7 +833,7 @@ span ~ .panel-header-text {
align-items: center;
block-size: 29px;
display: flex;
flex: 0 0 calc(100% / 8);
flex: 0 0 calc(100% / var(--icon-fit));
}
.radio-choice > .radio-container > label {
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 61 KiB

+6
View File
@@ -0,0 +1,6 @@
<!-- 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 xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#3c3c3c" d="M6 14a1 1 0 0 1-.707-.293l-3-3a1 1 0 0 1 1.414-1.414l2.157 2.157 6.316-9.023a1 1 0 0 1 1.639 1.146l-7 10a1 1 0 0 1-.732.427A.863.863 0 0 1 6 14z"/>
</svg>

After

Width:  |  Height:  |  Size: 477 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 7 7">
<polygon fill="#4c4c4c" points="5.8,0 3.5,2.4 1.2,0 0,1.2 2.4,3.5 0.1,5.8 1.2,7 3.5,4.7 5.8,7 7,5.8 4.7,3.5 7,1.2"/>
</svg>

After

Width:  |  Height:  |  Size: 183 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path fill="context-fill #bebebe" fill-opacity="context-fill-opacity" d="M12.9137931,3.0862069 L12.9137931,1.27586207 C12.9137931,0.84736528 12.5664278,0.5 12.137931,0.5 C11.7094342,0.5 11.362069,0.84736528 11.362069,1.27586207 L11.362069,1.27586207 L11.362069,3.0862069 L9.55172414,3.0862069 C9.12322735,3.0862069 8.77586207,3.43357218 8.77586207,3.86206897 C8.77586207,4.29056575 9.12322735,4.63793103 9.55172414,4.63793103 L11.362069,4.63793103 L11.362069,6.44827586 C11.362069,6.87677265 11.7094342,7.22413793 12.137931,7.22413793 L12.137931,7.22413793 C12.5664278,7.22413793 12.9137931,6.87677265 12.9137931,6.44827586 L12.9137931,6.44827586 L12.9137931,4.63793103 L14.7241379,4.63793103 C15.1526347,4.63793103 15.5,4.29056575 15.5,3.86206897 L15.5,3.86206897 C15.5,3.43357218 15.1526347,3.0862069 14.7241379,3.0862069 L14.7241379,3.0862069 L12.9137931,3.0862069 Z M0.5,9.76803178 C0.5,9.22007158 0.94118947,8.77586207 1.49216971,8.77586207 L6.23196822,8.77586207 C6.77992842,8.77586207 7.22413793,9.21705154 7.22413793,9.76803178 L7.22413793,14.5078303 C7.22413793,15.0557905 6.78294846,15.5 6.23196822,15.5 L1.49216971,15.5 C0.94420951,15.5 0.5,15.0588105 0.5,14.5078303 L0.5,9.76803178 Z M8.77586207,9.76803178 C8.77586207,9.22007158 9.21705154,8.77586207 9.76803178,8.77586207 L14.5078303,8.77586207 C15.0557905,8.77586207 15.5,9.21705154 15.5,9.76803178 L15.5,14.5078303 C15.5,15.0557905 15.0588105,15.5 14.5078303,15.5 L9.76803178,15.5 C9.22007158,15.5 8.77586207,15.0588105 8.77586207,14.5078303 L8.77586207,9.76803178 Z M0.5,1.49216971 C0.5,0.94420951 0.94118947,0.5 1.49216971,0.5 L6.23196822,0.5 C6.77992842,0.5 7.22413793,0.94118947 7.22413793,1.49216971 L7.22413793,6.23196822 C7.22413793,6.77992842 6.78294846,7.22413793 6.23196822,7.22413793 L1.49216971,7.22413793 C0.94420951,7.22413793 0.5,6.78294846 0.5,6.23196822 L0.5,1.49216971 Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

+52 -13
View File
@@ -12,7 +12,11 @@ const assignManager = {
getSiteStoreKey(pageUrl) {
const url = new window.URL(pageUrl);
const storagePrefix = "siteContainerMap@@_";
return `${storagePrefix}${url.hostname}`;
if (url.port === "80" || url.port === "443") {
return `${storagePrefix}${url.hostname}`;
} else {
return `${storagePrefix}${url.hostname}${url.port}`;
}
},
setExempted(pageUrl, tabId) {
@@ -147,22 +151,44 @@ const assignManager = {
|| (messageHandler.lastCreatedTab
&& messageHandler.lastCreatedTab.id === tab.id);
const openTabId = removeTab ? tab.openerTabId : tab.id;
// we decided to cancel the request at this point, register it as canceled request as early as possible
if (!this.canceledRequests[options.requestId]) {
this.canceledRequests[options.requestId] = true;
// register a cleanup for handled requestIds
// all relevant requests that come in that timeframe with the same requestId will be canceled
if (!this.canceledRequests[tab.id]) {
// we decided to cancel the request at this point, register canceled request
this.canceledRequests[tab.id] = {
requestIds: {
[options.requestId]: true
},
urls: {
[options.url]: true
}
};
// since webRequest onCompleted and onErrorOccurred are not 100% reliable (see #1120)
// we register a timer here to cleanup canceled requests, just to make sure we don't
// end up in a situation where certain urls in a tab.id stay canceled
setTimeout(() => {
delete this.canceledRequests[options.requestId];
if (this.canceledRequests[tab.id]) {
delete this.canceledRequests[tab.id];
}
}, 2000);
} else {
// if we see a request for the same requestId at this point then this is a redirect that we have to cancel to prevent opening two tabs
return {
cancel: true
};
let cancelEarly = false;
if (this.canceledRequests[tab.id].requestIds[options.requestId] ||
this.canceledRequests[tab.id].urls[options.url]) {
// same requestId or url from the same tab
// this is a redirect that we have to cancel early to prevent opening two tabs
cancelEarly = true;
}
// we decided to cancel the request at this point, register canceled request
this.canceledRequests[tab.id].requestIds[options.requestId] = true;
this.canceledRequests[tab.id].urls[options.url] = true;
if (cancelEarly) {
return {
cancel: true
};
}
}
this.reloadPageInContainer(
options.url,
userContextId,
@@ -203,6 +229,19 @@ const assignManager = {
browser.webRequest.onBeforeRequest.addListener((options) => {
return this.onBeforeRequest(options);
},{urls: ["<all_urls>"], types: ["main_frame"]}, ["blocking"]);
// Clean up canceled requests
browser.webRequest.onCompleted.addListener((options) => {
if (this.canceledRequests[options.tabId]) {
delete this.canceledRequests[options.tabId];
}
},{urls: ["<all_urls>"], types: ["main_frame"]});
browser.webRequest.onErrorOccurred.addListener((options) => {
if (this.canceledRequests[options.tabId]) {
delete this.canceledRequests[options.tabId];
}
},{urls: ["<all_urls>"], types: ["main_frame"]});
},
async _onClickedHandler(info, tab) {
+29 -10
View File
@@ -6,6 +6,7 @@ const backgroundLogic = {
"about:home",
"about:blank"
]),
unhideQueue: [],
async getExtensionInfo() {
const manifestPath = browser.extension.getURL("manifest.json");
@@ -112,6 +113,17 @@ const backgroundLogic = {
return list.concat(containerState.hiddenTabs);
},
async unhideContainer(cookieStoreId) {
if (!this.unhideQueue.includes(cookieStoreId)) {
this.unhideQueue.push(cookieStoreId);
await this.showTabs({
cookieStoreId
});
this.unhideQueue.splice(this.unhideQueue.indexOf(cookieStoreId), 1);
}
},
async moveTabsToWindow(options) {
const requiredArguments = ["cookieStoreId", "windowId"];
this.checkArgs(requiredArguments, options, "moveTabsToWindow");
@@ -123,6 +135,7 @@ const backgroundLogic = {
});
const containerState = await identityState.storageArea.get(cookieStoreId);
// Nothing to do
if (list.length === 0 &&
containerState.hiddenTabs.length === 0) {
@@ -152,12 +165,15 @@ const backgroundLogic = {
const showHiddenPromises = [];
// Let's show the hidden tabs.
for (let object of containerState.hiddenTabs) { // eslint-disable-line prefer-const
showHiddenPromises.push(browser.tabs.create({
url: object.url || DEFAULT_TAB,
windowId: newWindowObj.id,
cookieStoreId
}));
if (!this.unhideQueue.includes(cookieStoreId)) {
this.unhideQueue.push(cookieStoreId);
for (let object of containerState.hiddenTabs) { // eslint-disable-line prefer-const
showHiddenPromises.push(browser.tabs.create({
url: object.url || DEFAULT_TAB,
windowId: newWindowObj.id,
cookieStoreId
}));
}
}
if (hiddenDefaultTabToClose) {
@@ -176,7 +192,9 @@ const backgroundLogic = {
browser.tabs.remove(tab.id);
}
}
return await identityState.storageArea.set(cookieStoreId, containerState);
const rv = await identityState.storageArea.set(cookieStoreId, containerState);
this.unhideQueue.splice(this.unhideQueue.indexOf(cookieStoreId), 1);
return rv;
},
async _closeTabs(userContextId, windowId = false) {
@@ -200,7 +218,7 @@ const backgroundLogic = {
async queryIdentitiesState(windowId) {
const identities = await browser.contextualIdentities.query({});
const identitiesOutput = {};
const identitiesPromise = identities.map(async function (identity) {
const identitiesPromise = identities.map(async (identity) => {
const { cookieStoreId } = identity;
const containerState = await identityState.storageArea.get(cookieStoreId);
const openTabs = await browser.tabs.query({
@@ -209,7 +227,9 @@ const backgroundLogic = {
});
identitiesOutput[cookieStoreId] = {
hasHiddenTabs: !!containerState.hiddenTabs.length,
hasOpenTabs: !!openTabs.length
hasOpenTabs: !!openTabs.length,
numberOfHiddenTabs: containerState.hiddenTabs.length,
numberOfOpenTabs: openTabs.length
};
return;
});
@@ -307,4 +327,3 @@ const backgroundLogic = {
return `firefox-container-${userContextId}`;
}
};
+2 -14
View File
@@ -3,7 +3,6 @@ const messageHandler = {
// We use this to catch redirected tabs that have just opened
// If this were in platform we would change how the tab opens based on "new tab" link navigations such as ctrl+click
LAST_CREATED_TAB_TIMER: 2000,
unhideQueue: [],
init() {
// Handles messages from webextension code
@@ -39,7 +38,7 @@ const messageHandler = {
backgroundLogic.sortTabs();
break;
case "showTabs":
this.unhideContainer(m.cookieStoreId);
backgroundLogic.unhideContainer(m.cookieStoreId);
break;
case "hideTabs":
backgroundLogic.hideTabs({
@@ -156,7 +155,7 @@ const messageHandler = {
this.incrementCountOfContainerTabsOpened();
}
this.unhideContainer(tab.cookieStoreId);
backgroundLogic.unhideContainer(tab.cookieStoreId);
}
setTimeout(() => {
this.lastCreatedTab = null;
@@ -182,17 +181,6 @@ const messageHandler = {
}
},
async unhideContainer(cookieStoreId) {
if (!this.unhideQueue.includes(cookieStoreId)) {
this.unhideQueue.push(cookieStoreId);
// Unhide all hidden tabs
await backgroundLogic.showTabs({
cookieStoreId
});
this.unhideQueue.splice(this.unhideQueue.indexOf(cookieStoreId), 1);
}
},
async onFocusChangedCallback(windowId) {
assignManager.removeContextMenu();
// browserAction loses background color in new windows ...
+12 -5
View File
@@ -20,14 +20,21 @@ async function load() {
document.getElementById("redirect-form").addEventListener("submit", (e) => {
e.preventDefault();
const buttonTarget = e.explicitOriginalTarget;
switch (buttonTarget.id) {
case "confirm":
confirmSubmit(redirectUrl, cookieStoreId);
break;
let button = "confirm"; // Confirm is the form default.
let buttonTarget = e.explicitOriginalTarget;
if (buttonTarget.tagName !== "BUTTON") {
buttonTarget = buttonTarget.closest("button");
}
if (buttonTarget && buttonTarget.id) {
button = buttonTarget.id;
}
switch (button) {
case "deny":
denySubmit(redirectUrl);
break;
case "confirm":
confirmSubmit(redirectUrl, cookieStoreId);
break;
}
});
}
+126 -49
View File
@@ -162,7 +162,7 @@ const Logic = {
async clearBrowserActionBadge() {
const extensionInfo = await getExtensionInfo();
const storage = await browser.storage.local.get({browserActionBadgesClicked: []});
browser.browserAction.setBadgeBackgroundColor({color: ""});
browser.browserAction.setBadgeBackgroundColor({color: null});
browser.browserAction.setBadgeText({text: ""});
storage.browserActionBadgesClicked.push(extensionInfo.version);
// use set and spread to create a unique array
@@ -177,7 +177,9 @@ const Logic = {
name: "Default",
cookieStoreId,
icon: "default-tab",
color: "default-tab"
color: "default-tab",
numberOfHiddenTabs: 0,
numberOfOpenTabs: 0
};
// Handle old style rejection with null and also Promise.reject new style
try {
@@ -212,6 +214,27 @@ const Logic = {
return false;
},
async numTabs() {
const activeTabs = await browser.tabs.query({windowId: browser.windows.WINDOW_ID_CURRENT});
return activeTabs.length;
},
_disableMoveTabs(message) {
const moveTabsEl = document.querySelector("#container-info-movetabs");
const fragment = document.createDocumentFragment();
const incompatEl = document.createElement("div");
moveTabsEl.classList.remove("clickable");
moveTabsEl.setAttribute("title", message);
fragment.appendChild(incompatEl);
incompatEl.setAttribute("id", "container-info-movetabs-incompat");
incompatEl.textContent = message;
incompatEl.classList.add("container-info-tab-row");
moveTabsEl.parentNode.insertBefore(fragment, moveTabsEl.nextSibling);
},
async refreshIdentities() {
const [identities, state] = await Promise.all([
browser.contextualIdentities.query({}),
@@ -227,6 +250,8 @@ const Logic = {
if (stateObject) {
identity.hasOpenTabs = stateObject.hasOpenTabs;
identity.hasHiddenTabs = stateObject.hasHiddenTabs;
identity.numberOfHiddenTabs = stateObject.numberOfHiddenTabs;
identity.numberOfOpenTabs = stateObject.numberOfOpenTabs;
}
return identity;
});
@@ -370,7 +395,7 @@ Logic.registerPanel(P_ONBOARDING_1, {
initialize() {
// Let's move to the next panel.
[...document.querySelectorAll(".onboarding-start-button")].forEach(startElement => {
Logic.addEnterHandler(startElement, async function () {
Logic.addEnterHandler(startElement, async () => {
await Logic.setOnboardingStage(1);
Logic.showPanel(P_ONBOARDING_2);
});
@@ -394,7 +419,7 @@ Logic.registerPanel(P_ONBOARDING_2, {
initialize() {
// Let's move to the containers list panel.
[...document.querySelectorAll(".onboarding-next-button")].forEach(nextElement => {
Logic.addEnterHandler(nextElement, async function () {
Logic.addEnterHandler(nextElement, async () => {
await Logic.setOnboardingStage(2);
Logic.showPanel(P_ONBOARDING_3);
});
@@ -418,7 +443,7 @@ Logic.registerPanel(P_ONBOARDING_3, {
initialize() {
// Let's move to the containers list panel.
[...document.querySelectorAll(".onboarding-almost-done-button")].forEach(almostElement => {
Logic.addEnterHandler(almostElement, async function () {
Logic.addEnterHandler(almostElement, async () => {
await Logic.setOnboardingStage(3);
Logic.showPanel(P_ONBOARDING_4);
});
@@ -440,7 +465,7 @@ Logic.registerPanel(P_ONBOARDING_4, {
// This method is called when the object is registered.
initialize() {
// Let's move to the containers list panel.
Logic.addEnterHandler(document.querySelector("#onboarding-done-button"), async function () {
Logic.addEnterHandler(document.querySelector("#onboarding-done-button"), async () => {
await Logic.setOnboardingStage(4);
Logic.showPanel(P_ONBOARDING_5);
});
@@ -461,7 +486,7 @@ Logic.registerPanel(P_ONBOARDING_5, {
// This method is called when the object is registered.
initialize() {
// Let's move to the containers list panel.
Logic.addEnterHandler(document.querySelector("#onboarding-longpress-button"), async function () {
Logic.addEnterHandler(document.querySelector("#onboarding-longpress-button"), async () => {
await Logic.setOnboardingStage(5);
Logic.showPanel(P_CONTAINERS_LIST);
});
@@ -485,11 +510,13 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
Logic.showPanel(P_CONTAINER_EDIT, { name: Logic.generateIdentityName() });
});
Logic.addEnterHandler(document.querySelector("#edit-containers-link"), () => {
Logic.showPanel(P_CONTAINERS_EDIT);
Logic.addEnterHandler(document.querySelector("#edit-containers-link"), (e) => {
if (!e.target.classList.contains("disable-edit-containers")){
Logic.showPanel(P_CONTAINERS_EDIT);
}
});
Logic.addEnterHandler(document.querySelector("#sort-containers-link"), async function () {
Logic.addEnterHandler(document.querySelector("#sort-containers-link"), async () => {
try {
await browser.runtime.sendMessage({
method: "sortTabs"
@@ -632,7 +659,7 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
tr.appendChild(manage);
}
Logic.addEnterHandler(tr, async function (e) {
Logic.addEnterHandler(tr, async (e) => {
if (e.target.matches(".open-newtab")
|| e.target.parentNode.matches(".open-newtab")
|| e.type === "keydown") {
@@ -666,6 +693,13 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
document.addEventListener("mousedown", () => {
document.removeEventListener("focus", focusHandler);
});
/* If no container is present disable the Edit Containers button */
const editContainer = document.querySelector("#edit-containers-link");
if (Logic.identities().length === 0) {
editContainer.classList.add("disable-edit-containers");
} else {
editContainer.classList.remove("disable-edit-containers");
}
return Promise.resolve();
},
@@ -683,7 +717,7 @@ Logic.registerPanel(P_CONTAINER_INFO, {
Logic.showPreviousPanel();
});
Logic.addEnterHandler(document.querySelector("#container-info-hideorshow"), async function () {
Logic.addEnterHandler(document.querySelector("#container-info-hideorshow"), async () => {
const identity = Logic.currentIdentity();
try {
browser.runtime.sendMessage({
@@ -698,37 +732,31 @@ Logic.registerPanel(P_CONTAINER_INFO, {
});
// Check if the user has incompatible add-ons installed
let incompatible = false;
try {
const incompatible = await browser.runtime.sendMessage({
incompatible = await browser.runtime.sendMessage({
method: "checkIncompatibleAddons"
});
const moveTabsEl = document.querySelector("#container-info-movetabs");
if (incompatible) {
const fragment = document.createDocumentFragment();
const incompatEl = document.createElement("div");
moveTabsEl.classList.remove("clickable");
moveTabsEl.setAttribute("title", "Moving container tabs is incompatible with Pulse, PageShot, and SnoozeTabs.");
fragment.appendChild(incompatEl);
incompatEl.setAttribute("id", "container-info-movetabs-incompat");
incompatEl.textContent = "Incompatible with other Experiments.";
incompatEl.classList.add("container-info-tab-row");
moveTabsEl.parentNode.insertBefore(fragment, moveTabsEl.nextSibling);
} else {
Logic.addEnterHandler(moveTabsEl, async function () {
await browser.runtime.sendMessage({
method: "moveTabsToWindow",
windowId: browser.windows.WINDOW_ID_CURRENT,
cookieStoreId: Logic.currentIdentity().cookieStoreId,
});
window.close();
});
}
} catch (e) {
throw new Error("Could not check for incompatible add-ons.");
}
const moveTabsEl = document.querySelector("#container-info-movetabs");
const numTabs = await Logic.numTabs();
if (incompatible) {
Logic._disableMoveTabs("Moving container tabs is incompatible with Pulse, PageShot, and SnoozeTabs.");
return;
} else if (numTabs === 1) {
Logic._disableMoveTabs("Cannot move a tab from a single-tab window.");
return;
}
Logic.addEnterHandler(moveTabsEl, async () => {
await browser.runtime.sendMessage({
method: "moveTabsToWindow",
windowId: browser.windows.WINDOW_ID_CURRENT,
cookieStoreId: Logic.currentIdentity().cookieStoreId,
});
window.close();
});
},
// This method is called when the panel is shown.
@@ -777,20 +805,44 @@ Logic.registerPanel(P_CONTAINER_INFO, {
tr.classList.add("container-info-tab-row");
tr.innerHTML = escaped`
<td></td>
<td class="container-info-tab-title truncate-text" title="${tab.url}" >${tab.title}</td>`;
<td class="container-info-tab-title truncate-text" title="${tab.url}" ><div class="container-tab-title">${tab.title}</div></td>`;
tr.querySelector("td").appendChild(Utils.createFavIconElement(tab.favIconUrl));
document.getElementById("container-info-table").appendChild(fragment);
// On click, we activate this tab. But only if this tab is active.
if (!tab.hiddenState) {
const closeImage = document.createElement("img");
closeImage.src = "/img/container-close-tab.svg";
closeImage.className = "container-close-tab";
closeImage.title = "Close tab";
closeImage.id = tab.id;
const tabTitle = tr.querySelector(".container-info-tab-title");
tabTitle.appendChild(closeImage);
// On hover, we add truncate-text class to add close-tab-image after tab title truncates
const tabTitleHoverEvent = () => {
tabTitle.classList.toggle("truncate-text");
tr.querySelector(".container-tab-title").classList.toggle("truncate-text");
};
tr.addEventListener("mouseover", tabTitleHoverEvent);
tr.addEventListener("mouseout", tabTitleHoverEvent);
tr.classList.add("clickable");
Logic.addEnterHandler(tr, async function () {
Logic.addEnterHandler(tr, async () => {
await browser.tabs.update(tab.id, {active: true});
window.close();
});
}
}
document.getElementById("container-info-table").appendChild(fragment);
const closeTab = document.getElementById(tab.id);
if (closeTab) {
Logic.addEnterHandler(closeTab, async (e) => {
await browser.tabs.remove(Number(e.target.id));
window.close();
});
}
}
}
},
});
@@ -933,9 +985,9 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
const trElement = document.createElement("div");
/* 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}`;
const assumedUrl = `https://${site.hostname}/favicon.ico`;
trElement.innerHTML = escaped`
<img class="icon" src="${assumedUrl}/favicon.ico">
<div class="favicon"></div>
<div title="${site.hostname}" class="truncate-text hostname">
${site.hostname}
</div>
@@ -943,9 +995,10 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
class="pop-button-image delete-assignment"
src="/img/container-delete.svg"
/>`;
trElement.getElementsByClassName("favicon")[0].appendChild(Utils.createFavIconElement(assumedUrl));
const deleteButton = trElement.querySelector(".delete-assignment");
const that = this;
Logic.addEnterHandler(deleteButton, async function () {
Logic.addEnterHandler(deleteButton, async () => {
const userContextId = Logic.currentUserContextId();
// Lets show the message to the current tab
// TODO remove then when firefox supports arrow fn async
@@ -1001,6 +1054,11 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
document.querySelector("#edit-container-panel-name-input").value = identity.name || "";
document.querySelector("#edit-container-panel-usercontext-input").value = userContextId || NEW_CONTAINER_ID;
const containerName = document.querySelector("#edit-container-panel-name-input");
window.requestAnimationFrame(() => {
containerName.select();
containerName.focus();
});
[...document.querySelectorAll("[name='container-color']")].forEach(colorInput => {
colorInput.checked = colorInput.value === identity.color;
});
@@ -1025,7 +1083,7 @@ Logic.registerPanel(P_CONTAINER_DELETE, {
Logic.showPreviousPanel();
});
Logic.addEnterHandler(document.querySelector("#delete-container-ok-link"), async function () {
Logic.addEnterHandler(document.querySelector("#delete-container-ok-link"), async () => {
/* This promise wont resolve if the last tab was removed from the window.
as the message async callback stops listening, this isn't an issue for us however it might be in future
if you want to do anything post delete do it in the background script.
@@ -1045,9 +1103,17 @@ Logic.registerPanel(P_CONTAINER_DELETE, {
prepare() {
const identity = Logic.currentIdentity();
// Populating the panel: name and icon
// Populating the panel: name, icon, and warning message
document.getElementById("delete-container-name").textContent = identity.name;
const totalNumberOfTabs = identity.numberOfHiddenTabs + identity.numberOfOpenTabs;
let warningMessage = "";
if (totalNumberOfTabs > 0) {
const grammaticalNumTabs = totalNumberOfTabs > 1 ? "tabs" : "tab";
warningMessage = `If you remove this container now, ${totalNumberOfTabs} container ${grammaticalNumTabs} will be closed.`;
}
document.getElementById("delete-container-tab-warning").textContent = warningMessage;
const icon = document.getElementById("delete-container-icon");
icon.setAttribute("data-identity-icon", identity.icon);
icon.setAttribute("data-identity-color", identity.color);
@@ -1065,7 +1131,7 @@ Logic.registerPanel(P_CONTAINERS_ACHIEVEMENT, {
// This method is called when the object is registered.
initialize() {
// Set done and move to the containers list panel.
Logic.addEnterHandler(document.querySelector("#achievement-done-button"), async function () {
Logic.addEnterHandler(document.querySelector("#achievement-done-button"), async () => {
await Logic.setAchievementDone("manyContainersOpened");
Logic.showPanel(P_CONTAINERS_LIST);
});
@@ -1078,3 +1144,14 @@ Logic.registerPanel(P_CONTAINERS_ACHIEVEMENT, {
});
Logic.init();
window.addEventListener("resize", function () {
//for overflow menu
const difference = window.innerWidth - document.body.offsetWidth;
if (difference > 2) {
//if popup is in the overflow menu, window will be larger than 300px
const root = document.documentElement;
root.style.setProperty("--overflow-size", difference + "px");
root.style.setProperty("--icon-fit", "12");
}
});
+1 -1
View File
@@ -1,4 +1,4 @@
const DEFAULT_FAVICON = "moz-icon://goat?size=16";
const DEFAULT_FAVICON = "/img/blank-favicon.svg";
// TODO use export here instead of globals
window.Utils = {
+8 -3
View File
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Firefox Multi-Account Containers",
"version": "6.0.0",
"version": "6.1.1",
"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": {
@@ -16,7 +16,7 @@
}
},
"homepage_url": "https://testpilot.firefox.com/",
"homepage_url": "https://github.com/mozilla/multi-account-containers#readme",
"permissions": [
"<all_urls>",
@@ -47,7 +47,12 @@
"browser_style": true,
"default_icon": "img/container-site.svg",
"default_title": "Multi-Account Containers",
"default_popup": "popup.html"
"default_popup": "popup.html",
"theme_icons": [{
"light": "img/container-site-light.svg",
"dark": "img/container-site.svg",
"size": 32
}]
},
"background": {
+1 -1
View File
@@ -204,7 +204,7 @@
</div>
<div class="panel-content delete-container-confirm">
<h4 class="delete-container-confirm-title">Remove This Container</h4>
<p>If you remove this container now, <span id="delete-container-tab-count"></span> container tabs will be closed. Are you sure you want to remove this Container?</p>
<p><span id="delete-container-tab-warning"></span> Are you sure you want to remove this Container?</p>
</div>
<div class="panel-footer">
<a href="#" class="button expanded secondary footer-button cancel-button" id="delete-container-cancel-link">Cancel</a>
+3
View File
@@ -19,6 +19,9 @@ module.exports = () => {
},
onCompleted: {
addListener: sinon.stub()
},
onErrorOccurred: {
addListener: sinon.stub()
}
},
windows: {
+9 -7
View File
@@ -18,19 +18,21 @@ module.exports = {
});
},
async openNewTab(tab, options = {isAsync: true}) {
async openNewTab(tab, options = {}) {
if (options.resetHistory) {
background.browser.tabs.create.resetHistory();
background.browser.tabs.remove.resetHistory();
}
background.browser.tabs.get.resolves(tab);
background.browser.webRequest.onBeforeRequest.addListener.yield({
background.browser.tabs.onCreated.addListener.yield(tab);
const [promise] = background.browser.webRequest.onBeforeRequest.addListener.yield({
frameId: 0,
tabId: tab.id,
url: tab.url,
requestId: options.requestId
});
background.browser.tabs.onCreated.addListener.yield(tab);
if (!options.isAsync) {
return;
}
await nextTick();
return promise;
}
},
+139 -2
View File
@@ -22,8 +22,7 @@ describe("#940", () => {
active: true
};
helper.browser.openNewTab(newTab, {
requestId: 1,
isAsync: false
requestId: 1
});
// other addon sees the same request
@@ -40,4 +39,142 @@ describe("#940", () => {
background.browser.tabs.create.should.have.been.calledOnce;
});
});
describe("when redirects change requestId midflight", () => {
let promiseResults;
beforeEach(async () => {
// init
const activeTab = {
id: 1,
cookieStoreId: "firefox-container-1",
url: "https://www.youtube.com",
index: 0
};
await helper.browser.initializeWithTab(activeTab);
// assign the activeTab.url
await helper.popup.clickElementById("container-page-assigned");
// http://youtube.com
const newTab = {
id: 2,
cookieStoreId: "firefox-default",
url: "http://youtube.com",
index: 1,
active: true
};
const promise1 = helper.browser.openNewTab(newTab, {
requestId: 1
});
// https://youtube.com
const [promise2] = background.browser.webRequest.onBeforeRequest.addListener.yield({
frameId: 0,
tabId: newTab.id,
url: "https://youtube.com",
requestId: 1
});
// https://www.youtube.com
const [promise3] = background.browser.webRequest.onBeforeRequest.addListener.yield({
frameId: 0,
tabId: newTab.id,
url: "https://www.youtube.com",
requestId: 1
});
// https://www.youtube.com
const [promise4] = background.browser.webRequest.onBeforeRequest.addListener.yield({
frameId: 0,
tabId: newTab.id,
url: "https://www.youtube.com",
requestId: 2
});
promiseResults = await Promise.all([promise1, promise2, promise3, promise4]);
});
it("should not open two confirm pages", async () => {
// http://youtube.com is not assigned, no cancel, no reopening
expect(promiseResults[0]).to.deep.equal({});
// https://youtube.com is not assigned, no cancel, no reopening
expect(promiseResults[1]).to.deep.equal({});
// https://www.youtube.com is assigned, this triggers reopening, cancel
expect(promiseResults[2]).to.deep.equal({
cancel: true
});
// https://www.youtube.com is assigned, this was a redirect, cancel early, no reopening
expect(promiseResults[3]).to.deep.equal({
cancel: true
});
background.browser.tabs.create.should.have.been.calledOnce;
});
it("should uncancel after webRequest.onCompleted", async () => {
const [promise1] = background.browser.webRequest.onCompleted.addListener.yield({
tabId: 2
});
await promise1;
const [promise2] = background.browser.webRequest.onBeforeRequest.addListener.yield({
frameId: 0,
tabId: 2,
url: "https://www.youtube.com",
requestId: 123
});
await promise2;
background.browser.tabs.create.should.have.been.calledTwice;
});
it("should uncancel after webRequest.onErrorOccurred", async () => {
const [promise1] = background.browser.webRequest.onErrorOccurred.addListener.yield({
tabId: 2
});
await promise1;
// request to assigned url in same tab
const [promise2] = background.browser.webRequest.onBeforeRequest.addListener.yield({
frameId: 0,
tabId: 2,
url: "https://www.youtube.com",
requestId: 123
});
await promise2;
background.browser.tabs.create.should.have.been.calledTwice;
});
it("should uncancel after 2 seconds", async () => {
await new Promise(resolve => setTimeout(resolve, 2000));
// request to assigned url in same tab
const [promise2] = background.browser.webRequest.onBeforeRequest.addListener.yield({
frameId: 0,
tabId: 2,
url: "https://www.youtube.com",
requestId: 123
});
await promise2;
background.browser.tabs.create.should.have.been.calledTwice;
}).timeout(2002);
it("should not influence the canceled url in other tabs", async () => {
const newTab = {
id: 123,
cookieStoreId: "firefox-default",
url: "https://www.youtube.com",
index: 10,
active: true
};
await helper.browser.openNewTab(newTab, {
requestId: 321
});
background.browser.tabs.create.should.have.been.calledTwice;
});
});
});
+2 -2
View File
@@ -91,11 +91,11 @@ global.buildPopupDom = async (options = {}) => {
global.afterEach(() => {
if (global.background) {
global.background.dom.window.close();
delete global.background.dom;
delete global.background;
}
if (global.popup) {
global.popup.dom.window.close();
delete global.popup.dom;
delete global.popup;
}
});