Merge branch 'mozilla:main' into sort-containers-extension-shortcut
This commit is contained in:
commit
44b9fca225
12 changed files with 26534 additions and 154 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
|||
.DS_Store
|
||||
package-lock.json
|
||||
node_modules
|
||||
README.html
|
||||
*.xpi
|
||||
|
|
26514
package-lock.json
generated
Normal file
26514
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@
|
|||
"name": "testpilot-containers",
|
||||
"title": "Multi-Account Containers",
|
||||
"description": "Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.",
|
||||
"version": "8.1.0",
|
||||
"version": "8.1.1",
|
||||
"author": "Andrea Marchesini, Luke Crouch, Lesley Norton, Kendall Werts, Maxx Crawford, Jonathan Kingston",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mozilla/multi-account-containers/issues"
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 26e17db70ce276ab5ccb5ae582e5c142f12ba655
|
||||
Subproject commit 417e6294ed767914b617a5e56ccbe67482df181c
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1884,15 +1885,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 {
|
||||
|
|
|
@ -39,7 +39,6 @@ const backgroundLogic = {
|
|||
|
||||
browser.permissions.onAdded.addListener(permissions => this.resetPermissions(permissions));
|
||||
browser.permissions.onRemoved.addListener(permissions => this.resetPermissions(permissions));
|
||||
backgroundLogic.setSyncExclusion();
|
||||
},
|
||||
|
||||
resetPermissions(permissions) {
|
||||
|
@ -412,17 +411,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+$"});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Firefox Multi-Account Containers",
|
||||
"version": "8.1.0",
|
||||
"version": "8.1.1",
|
||||
"incognito": "not_allowed",
|
||||
"description": "__MSG_extensionDescription__",
|
||||
"icons": {
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue