added some checks on sync and some error handling for bad site assignment info
This commit is contained in:
parent
9de6df6157
commit
5ae7a395a1
4 changed files with 285 additions and 163 deletions
|
@ -107,6 +107,31 @@ const assignManager = {
|
|||
}
|
||||
return sites;
|
||||
},
|
||||
|
||||
/*
|
||||
* Looks for abandoned site assignments. If there is no identity with
|
||||
* the site assignment's userContextId (cookieStoreId), then the assignment
|
||||
* is removed.
|
||||
*/
|
||||
async cleanup() {
|
||||
const identitiesList = await browser.contextualIdentities.query({});
|
||||
const macConfigs = await this.area.get();
|
||||
for(const configKey of Object.keys(macConfigs)) {
|
||||
if (configKey.includes("siteContainerMap@@_")) {
|
||||
const cookieStoreId =
|
||||
"firefox-container-" + macConfigs[configKey].userContextId;
|
||||
const match = identitiesList.find(
|
||||
localIdentity => localIdentity.cookieStoreId === cookieStoreId
|
||||
);
|
||||
if (!match) {
|
||||
await this.remove(configKey.replace(/^siteContainerMap@@_/, "https://"));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_neverAsk(m) {
|
||||
|
|
|
@ -51,9 +51,7 @@ const sync = {
|
|||
|
||||
async backup(options) {
|
||||
// remove listeners to avoid an infinite loop!
|
||||
await browser.storage.onChanged.removeListener(
|
||||
sync.storageArea.onChangedListener);
|
||||
await removeContextualIdentityListeners();
|
||||
await sync.checkForListenersMaybeRemove();
|
||||
|
||||
await updateSyncIdentities();
|
||||
await updateCookieStoreIdMap();
|
||||
|
@ -71,9 +69,8 @@ const sync = {
|
|||
console.log("inLocal:", localStorage);
|
||||
console.log("idents: ", await browser.contextualIdentities.query({}));
|
||||
}
|
||||
browser.storage.onChanged.addListener(
|
||||
sync.storageArea.onChangedListener);
|
||||
addContextualIdentityListeners();
|
||||
|
||||
await sync.checkForListenersMaybeAdd();
|
||||
|
||||
async function updateSyncIdentities() {
|
||||
const identities = await browser.contextualIdentities.query({});
|
||||
|
@ -93,9 +90,8 @@ const sync = {
|
|||
}
|
||||
|
||||
async function updateDeletedIdentityList(deletedIdentityUUID) {
|
||||
let { deletedIdentityList } =
|
||||
await sync.storageArea.get("deletedIdentityList");
|
||||
if (!deletedIdentityList) deletedIdentityList = [];
|
||||
const deletedIdentityList =
|
||||
await sync.storageArea.getDeletedIdentityList();
|
||||
if (
|
||||
deletedIdentityList.find(element => element === deletedIdentityUUID)
|
||||
) return;
|
||||
|
@ -104,74 +100,91 @@ const sync = {
|
|||
}
|
||||
|
||||
async function addToDeletedSitesList(siteStoreKey) {
|
||||
let { deletedSiteList } =
|
||||
await sync.storageArea.get("deletedSiteList");
|
||||
if (!deletedSiteList) deletedSiteList = [];
|
||||
const deletedSiteList =
|
||||
await sync.storageArea.getDeletedSiteList();
|
||||
if (deletedSiteList.find(element => element === siteStoreKey)) return;
|
||||
deletedSiteList.push(siteStoreKey);
|
||||
await sync.storageArea.set({ deletedSiteList });
|
||||
}
|
||||
|
||||
async function removeFromDeletedSitesList(siteStoreKey) {
|
||||
let { deletedSiteList } =
|
||||
await sync.storageArea.get("deletedSiteList");
|
||||
if (!deletedSiteList) return;
|
||||
deletedSiteList = deletedSiteList
|
||||
const deletedSiteList =
|
||||
await sync.storageArea.getDeletedSiteList();
|
||||
const newDeletedSiteList = deletedSiteList
|
||||
.filter(element => element !== siteStoreKey);
|
||||
await sync.storageArea.set({ deletedSiteList });
|
||||
await sync.storageArea.set({ deletedSiteList: newDeletedSiteList });
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Ensures all sync info matches. But maybe we shouldn't even use
|
||||
* sync info that doesn't match.
|
||||
*/
|
||||
async cleanup() {
|
||||
console.log("cleanupSync");
|
||||
browser.storage.onChanged.removeListener(
|
||||
sync.storageArea.onChangedListener);
|
||||
const identitiesList =
|
||||
await sync.storageArea.getIdentities();
|
||||
const cookieStoreIDmap =
|
||||
await sync.storageArea.getCookieStoreIDMap();
|
||||
for(const cookieStoreId of Object.keys(cookieStoreIDmap)) {
|
||||
const match = identitiesList
|
||||
.find(syncIdentity =>
|
||||
syncIdentity.cookieStoreId === cookieStoreId
|
||||
);
|
||||
if (!match) {
|
||||
delete cookieStoreIDmap[cookieStoreId];
|
||||
await sync.storageArea.set({ cookieStoreIDmap });
|
||||
console.log("removed ", cookieStoreId, " from sync list");
|
||||
}
|
||||
}
|
||||
await browser.storage.onChanged.addListener(
|
||||
sync.storageArea.onChangedListener);
|
||||
},
|
||||
|
||||
onChangedListener(changes, areaName) {
|
||||
if (areaName === "sync") sync.runSync();
|
||||
if (areaName === "sync") sync.errorHandledRunSync();
|
||||
},
|
||||
|
||||
async addToDeletedList(changeInfo) {
|
||||
const identity = changeInfo.contextualIdentity;
|
||||
console.log("addToDeletedList", identity.cookieStoreId);
|
||||
const deletedUUID =
|
||||
await identityState.lookupMACaddonUUID(identity.cookieStoreId);
|
||||
await identityState.storageArea.remove(identity.cookieStoreId);
|
||||
console.log(deletedUUID);
|
||||
sync.storageArea.backup({uuid: deletedUUID});
|
||||
},
|
||||
|
||||
async checkSyncForMismatches() {
|
||||
const cookieStoreIDmap = await this.getCookieStoreIDMap();
|
||||
const identities = await this.getIdentities();
|
||||
for (const cookieStoreId of Object.keys(cookieStoreIDmap)) {
|
||||
const match = identities.find(identity =>
|
||||
identity.cookieStoreId === cookieStoreId
|
||||
);
|
||||
if (!match) return false;
|
||||
// if one has no match, this is bad data.
|
||||
console.log("Bad Data, skipping");
|
||||
}
|
||||
return !(Object.entries(cookieStoreIDmap).length === 0);
|
||||
}
|
||||
},
|
||||
|
||||
init() {
|
||||
const errorHandledRunSync = () => {
|
||||
this.runSync().catch((error)=> {
|
||||
console.error("Error from runSync", error);
|
||||
});
|
||||
};
|
||||
browser.runtime.onInstalled.addListener(errorHandledRunSync);
|
||||
browser.runtime.onStartup.addListener(errorHandledRunSync);
|
||||
browser.runtime.onInstalled.addListener(this.errorHandledRunSync);
|
||||
browser.runtime.onStartup.addListener(this.errorHandledRunSync);
|
||||
},
|
||||
|
||||
async errorHandledRunSync () {
|
||||
sync.runSync().catch(async (error)=> {
|
||||
console.error("Error from runSync", error);
|
||||
sync.checkForListenersMaybeAdd();
|
||||
});
|
||||
},
|
||||
|
||||
async checkForListenersMaybeAdd() {
|
||||
const hasStorageListener =
|
||||
await browser.storage.onChanged.hasListener(
|
||||
sync.storageArea.onChangedListener
|
||||
);
|
||||
|
||||
if (! await hasContextualIdentityListeners()) {
|
||||
addContextualIdentityListeners();
|
||||
}
|
||||
|
||||
if (! hasStorageListener) {
|
||||
browser.storage.onChanged.addListener(
|
||||
sync.storageArea.onChangedListener);
|
||||
}
|
||||
},
|
||||
|
||||
async checkForListenersMaybeRemove() {
|
||||
const hasStorageListener =
|
||||
await browser.storage.onChanged.hasListener(
|
||||
sync.storageArea.onChangedListener
|
||||
);
|
||||
|
||||
if (await hasContextualIdentityListeners()) {
|
||||
removeContextualIdentityListeners();
|
||||
}
|
||||
|
||||
if (hasStorageListener) {
|
||||
browser.storage.onChanged.removeListener(
|
||||
sync.storageArea.onChangedListener);
|
||||
}
|
||||
},
|
||||
|
||||
async runSync() {
|
||||
|
@ -182,21 +195,19 @@ const sync = {
|
|||
console.log("inLocal: ", localInfo);
|
||||
console.log("indents: ", await browser.contextualIdentities.query({}));
|
||||
}
|
||||
browser.storage.onChanged.removeListener(
|
||||
sync.storageArea.onChangedListener);
|
||||
removeContextualIdentityListeners();
|
||||
await sync.checkForListenersMaybeRemove();
|
||||
console.log("runSync");
|
||||
await identityState.storageArea.cleanup();
|
||||
|
||||
if (await sync.storageArea.hasSyncStorage()){
|
||||
await sync.storageArea.cleanup();
|
||||
console.log("storage found, attempting to restore ...");
|
||||
await restore();
|
||||
return;
|
||||
}
|
||||
console.log("no sync storage, backing up...");
|
||||
await identityState.storageArea.cleanup();
|
||||
await assignManager.storageArea.cleanup();
|
||||
|
||||
const hasSyncStorage = await sync.storageArea.hasSyncStorage();
|
||||
const dataIsReliable = await sync.storageArea.checkSyncForMismatches();
|
||||
if (hasSyncStorage && dataIsReliable) await restore();
|
||||
|
||||
await sync.storageArea.backup();
|
||||
return; },
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
sync.init();
|
||||
|
@ -205,7 +216,7 @@ async function restore() {
|
|||
console.log("restore");
|
||||
await reconcileIdentities();
|
||||
await reconcileSiteAssignments();
|
||||
await sync.storageArea.backup();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -224,7 +235,13 @@ async function reconcileIdentities(){
|
|||
const deletedCookieStoreId =
|
||||
await identityState.lookupCookieStoreId(deletedUUID);
|
||||
if (deletedCookieStoreId){
|
||||
await browser.contextualIdentities.remove(deletedCookieStoreId);
|
||||
try{
|
||||
await browser.contextualIdentities.remove(deletedCookieStoreId);
|
||||
} catch (error) {
|
||||
// if the identity we are deleting is not there, that's fine.
|
||||
console.error("Error deleting contextualIdentity", deletedCookieStoreId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,23 +308,32 @@ async function ifUUIDMatch(syncIdentity, localCookieStoreID) {
|
|||
icon: syncIdentity.icon
|
||||
};
|
||||
if (SYNC_DEBUG) {
|
||||
const getIdent =
|
||||
try {
|
||||
const getIdent =
|
||||
await browser.contextualIdentities.get(localCookieStoreID);
|
||||
if (getIdent.name !== identityInfo.name) {
|
||||
console.log(getIdent.name, "Change name: ", identityInfo.name);
|
||||
}
|
||||
if (getIdent.color !== identityInfo.color) {
|
||||
console.log(getIdent.name, "Change color: ", identityInfo.color);
|
||||
}
|
||||
if (getIdent.icon !== identityInfo.icon) {
|
||||
console.log(getIdent.name, "Change icon: ", identityInfo.icon);
|
||||
if (getIdent.name !== identityInfo.name) {
|
||||
console.log(getIdent.name, "Change name: ", identityInfo.name);
|
||||
}
|
||||
if (getIdent.color !== identityInfo.color) {
|
||||
console.log(getIdent.name, "Change color: ", identityInfo.color);
|
||||
}
|
||||
if (getIdent.icon !== identityInfo.icon) {
|
||||
console.log(getIdent.name, "Change icon: ", identityInfo.icon);
|
||||
}
|
||||
} catch (error) {
|
||||
//if this fails, there is probably differing sync info.
|
||||
console.error("Error getting info on CI", error);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// update the local container with the sync data
|
||||
await browser.contextualIdentities
|
||||
.update(localCookieStoreID, identityInfo);
|
||||
return;
|
||||
await browser.contextualIdentities
|
||||
.update(localCookieStoreID, identityInfo);
|
||||
return;
|
||||
} catch (error) {
|
||||
// If this fails, sync info is off.
|
||||
console.error("Error udpating CI", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function ifNoMatch(syncIdentity){
|
||||
|
@ -351,34 +377,43 @@ async function reconcileSiteAssignments() {
|
|||
|
||||
for(const urlKey of Object.keys(assignedSitesFromSync)) {
|
||||
const assignedSite = assignedSitesFromSync[urlKey];
|
||||
const syncUUID =
|
||||
await lookupSyncSiteAssigmentIdentityUUID(
|
||||
assignedSite, cookieStoreIDmap, urlKey
|
||||
);
|
||||
if (syncUUID) {
|
||||
try{
|
||||
const syncUUID =
|
||||
await lookupSyncSiteAssigmentIdentityUUID(
|
||||
assignedSite, cookieStoreIDmap, urlKey
|
||||
);
|
||||
if (syncUUID) {
|
||||
// Sync is truth.
|
||||
// Not even looking it up. Just overwrite
|
||||
console.log("new assignment ", assignedSite, ": ",
|
||||
assignedSite.userContextId);
|
||||
const newUUID = cookieStoreIDmap[
|
||||
"firefox-container-" + assignedSite.userContextId
|
||||
];
|
||||
await setAssignmentWithUUID(newUUID, assignedSite, urlKey);
|
||||
continue;
|
||||
}
|
||||
console.log("new assignment ", assignedSite, ": ",
|
||||
assignedSite.userContextId);
|
||||
const newUUID = cookieStoreIDmap[
|
||||
"firefox-container-" + assignedSite.userContextId
|
||||
];
|
||||
|
||||
// if there's no syncUUID, something is wrong, since these site
|
||||
// assignments are from sync
|
||||
throw new Error("Sync storage not aligned");
|
||||
await setAssignmentWithUUID(newUUID, assignedSite, urlKey);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
// this is probably old or incorrect site info in Sync
|
||||
// skip and move on.
|
||||
//console.error("Error assigning site", error);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async function lookupSyncSiteAssigmentIdentityUUID(
|
||||
assignedSite,
|
||||
cookieStoreIDmap,
|
||||
urlKey
|
||||
){
|
||||
const syncCookieStoreId =
|
||||
"firefox-container-" + assignedSite.userContextId;
|
||||
return cookieStoreIDmap[syncCookieStoreId];
|
||||
const uuid = cookieStoreIDmap[syncCookieStoreId];
|
||||
if (!uuid) throw new Error (`No syncUUID found for : ${urlKey}`);
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,4 +449,13 @@ function removeContextualIdentityListeners(listenerList) {
|
|||
browser.contextualIdentities.onCreated.removeListener(listenerList[0]);
|
||||
browser.contextualIdentities.onRemoved.removeListener(listenerList[1]);
|
||||
browser.contextualIdentities.onUpdated.removeListener(listenerList[2]);
|
||||
}
|
||||
}
|
||||
|
||||
async function hasContextualIdentityListeners(listenerList) {
|
||||
if(!listenerList) listenerList = syncCIListenerList;
|
||||
return (
|
||||
await browser.contextualIdentities.onCreated.hasListener(listenerList[0]) &&
|
||||
await browser.contextualIdentities.onRemoved.hasListener(listenerList[1]) &&
|
||||
await browser.contextualIdentities.onUpdated.hasListener(listenerList[2])
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,32 @@
|
|||
browser.tests = {
|
||||
async runAll() {
|
||||
await this.testIdentityStateCleanup();
|
||||
await this.test1();
|
||||
await this.testReconcileSiteAssignments();
|
||||
await this.testInitialSync();
|
||||
await this.test2();
|
||||
await this.dupeTest();
|
||||
},
|
||||
// more unit tests
|
||||
// if site assignment has no valid cookieStoreId, delete on local
|
||||
|
||||
async resetForManualTests() {
|
||||
await browser.tests.stopSyncListeners();
|
||||
console.log("reset");
|
||||
await this.setState({}, LOCAL_DATA, TEST_CONTAINERS, []);
|
||||
},
|
||||
|
||||
async testIdentityStateCleanup() {
|
||||
await browser.tests.stopSyncListeners();
|
||||
console.log("Testing the cleanup of local storage");
|
||||
|
||||
await this.setState({}, LOCAL_DATA, TEST_CONTAINERS);
|
||||
await this.setState({}, LOCAL_DATA, TEST_CONTAINERS, []);
|
||||
|
||||
await browser.storage.local.set({
|
||||
"identitiesState@@_firefox-container-5": {
|
||||
"hiddenTabs": []
|
||||
}
|
||||
});
|
||||
console.log("local storage set: ", await browser.storage.local.get());
|
||||
|
||||
await identityState.storageArea.cleanup();
|
||||
|
||||
|
@ -28,11 +44,76 @@ browser.tests = {
|
|||
}
|
||||
console.log("Finished!");
|
||||
},
|
||||
async test1() {
|
||||
|
||||
async testAssignManagerCleanup() {
|
||||
await browser.tests.stopSyncListeners();
|
||||
console.log("Testing the cleanup of local storage");
|
||||
|
||||
await this.setState({}, LOCAL_DATA, TEST_CONTAINERS, []);
|
||||
|
||||
await browser.storage.local.set({
|
||||
"siteContainerMap@@_www.goop.com": {
|
||||
"userContextId": "5",
|
||||
"neverAsk": true,
|
||||
"hostname": "www.goop.com"
|
||||
}
|
||||
});
|
||||
console.log("local storage set: ", await browser.storage.local.get());
|
||||
|
||||
await assignManager.storageArea.cleanup();
|
||||
|
||||
await browser.storage.local.set({
|
||||
"identitiesState@@_firefox-container-5": {
|
||||
"hiddenTabs": []
|
||||
}
|
||||
});
|
||||
|
||||
const macConfigs = await browser.storage.local.get();
|
||||
const assignments = [];
|
||||
for(const configKey of Object.keys(macConfigs)) {
|
||||
if (configKey.includes("siteContainerMap@@_")) {
|
||||
assignments.push(configKey);
|
||||
}
|
||||
}
|
||||
|
||||
console.assert(assignments.length === 0, "There should be 0 identity entries");
|
||||
|
||||
console.log("Finished!");
|
||||
},
|
||||
|
||||
async testReconcileSiteAssignments() {
|
||||
await browser.tests.stopSyncListeners();
|
||||
console.log("Testing reconciling Site Assignments");
|
||||
|
||||
const newSyncData = DUPE_TEST_SYNC;
|
||||
// add some bad data.
|
||||
newSyncData.assignedSites["siteContainerMap@@_www.linkedin.com"] = {
|
||||
"userContextId": "1",
|
||||
"neverAsk": true,
|
||||
"hostname": "www.linkedin.com"
|
||||
};
|
||||
|
||||
newSyncData.deletedSiteList = ["siteContainerMap@@_www.google.com"];
|
||||
|
||||
await this.setState(
|
||||
newSyncData,
|
||||
LOCAL_DATA,
|
||||
TEST_CONTAINERS,
|
||||
SITE_ASSIGNMENT_TEST
|
||||
);
|
||||
|
||||
await sync.runSync();
|
||||
|
||||
const assignedSites = await assignManager.storageArea.getAssignedSites();
|
||||
console.assert(Object.keys(assignedSites).length === 5, "There should be 5 assigned sites");
|
||||
console.log("Finished!");
|
||||
},
|
||||
|
||||
async testInitialSync() {
|
||||
await browser.tests.stopSyncListeners();
|
||||
console.log("Testing new install with no sync");
|
||||
|
||||
await this.setState({}, LOCAL_DATA, TEST_CONTAINERS);
|
||||
await this.setState({}, LOCAL_DATA, TEST_CONTAINERS, []);
|
||||
|
||||
await sync.runSync();
|
||||
|
||||
|
@ -106,7 +187,7 @@ browser.tests = {
|
|||
|
||||
async dupeTest() {
|
||||
await browser.tests.stopSyncListeners();
|
||||
console.log("Test state from duped sync");
|
||||
console.log("Test state from sync that duped everything initially");
|
||||
|
||||
await this.setState(
|
||||
DUPE_TEST_SYNC,
|
||||
|
@ -176,30 +257,42 @@ browser.tests = {
|
|||
}
|
||||
return false;
|
||||
},
|
||||
async setState(syncData, localData, indentityData, assignmentData){
|
||||
|
||||
/*
|
||||
* Sets the state of sync storage, local storage, and the identities.
|
||||
* SyncDat and localData (without identities or site assignments) get
|
||||
* set to sync and local storage respectively. IdentityData creates
|
||||
* new identities (after all have been removed), and assignmentData
|
||||
* is used along with the new identities' cookieStoreIds to create
|
||||
* site assignments in local storage.
|
||||
*/
|
||||
async setState(syncData, localData, identityData, assignmentData){
|
||||
await this.removeAllContainers();
|
||||
await browser.storage.sync.clear();
|
||||
await browser.storage.sync.set(syncData);
|
||||
await browser.storage.local.clear();
|
||||
for (let i=0; i < indentityData.length; i++) {
|
||||
await browser.storage.local.set(localData);
|
||||
for (let i=0; i < identityData.length; i++) {
|
||||
//build identities
|
||||
const newIdentity =
|
||||
await browser.contextualIdentities.create(indentityData[i]);
|
||||
await browser.contextualIdentities.create(identityData[i]);
|
||||
// fill identies with site assignments
|
||||
if (assignmentData && assignmentData[i]) {
|
||||
localData[assignmentData[i]] = {
|
||||
const data = {
|
||||
"userContextId":
|
||||
String(
|
||||
newIdentity.cookieStoreId.replace(/^firefox-container-/, "")
|
||||
),
|
||||
"neverAsk": true
|
||||
};
|
||||
|
||||
await browser.storage.local.set({[assignmentData[i]]: data});
|
||||
}
|
||||
}
|
||||
await browser.storage.local.set(localData);
|
||||
console.log("local storage set: ", await browser.storage.local.get());
|
||||
return;
|
||||
},
|
||||
|
||||
async removeAllContainers() {
|
||||
const identities = await browser.contextualIdentities.query({});
|
||||
for (const identity of identities) {
|
||||
|
@ -254,6 +347,7 @@ const TEST_ASSIGNMENTS = [
|
|||
"siteContainerMap@@_www.linkedin.com",
|
||||
"siteContainerMap@@_reddit.com"
|
||||
];
|
||||
|
||||
const LOCAL_DATA = {
|
||||
"browserActionBadgesClicked": [ "6.1.1" ],
|
||||
"containerTabsOpened": 7,
|
||||
|
@ -313,23 +407,6 @@ const SYNC_DATA = {
|
|||
},
|
||||
"assignedSites": {}
|
||||
};
|
||||
browser.resetMAC2 = async function () {
|
||||
// for debugging and testing: remove all containers except the default 4 and the first one created
|
||||
browser.tests.stopSyncListeners();
|
||||
|
||||
// sync state after FF1 (default + 1)
|
||||
await browser.storage.sync.clear();
|
||||
const syncData = {"cookieStoreIDmap":{"firefox-container-1":"4dc76734-5b71-4f2e-85d0-1cb199ae3821","firefox-container-2":"30308b8d-393c-4375-b9a1-afc59f0dea79","firefox-container-3":"7419c94d-85d7-4d76-94c0-bacef1de722f","firefox-container-4":"2b9fe881-e552-4df9-8cab-922f4688bb68","firefox-container-6":"db7f622e-682b-4556-968a-6e2542ff3b26"},"assignedSites":{"siteContainerMap@@_twitter.com":{"userContextId":"1","neverAsk":!0},"siteContainerMap@@_www.facebook.com":{"userContextId":"2","neverAsk":!0},"siteContainerMap@@_www.linkedin.com":{"userContextId":"4","neverAsk":!1}},"identities":[{"name":"Personal","icon":"fingerprint","iconUrl":"resource://usercontext-content/fingerprint.svg","color":"blue","colorCode":"#37adff","cookieStoreId":"firefox-container-1"},{"name":"Work","icon":"briefcase","iconUrl":"resource://usercontext-content/briefcase.svg","color":"orange","colorCode":"#ff9f00","cookieStoreId":"firefox-container-2"},{"name":"Banking","icon":"dollar","iconUrl":"resource://usercontext-content/dollar.svg","color":"green","colorCode":"#51cd00","cookieStoreId":"firefox-container-3"},{"name":"Shopping","icon":"cart","iconUrl":"resource://usercontext-content/cart.svg","color":"pink","colorCode":"#ff4bda","cookieStoreId":"firefox-container-4"},{"name":"Container #01","icon":"chill","iconUrl":"resource://usercontext-content/chill.svg","color":"green","colorCode":"#51cd00","cookieStoreId":"firefox-container-6"}]};
|
||||
browser.storage.sync.set(syncData);
|
||||
|
||||
// FF2 (intial sync w/ default 4 + 1 with some changes)
|
||||
browser.contextualIdentities.update("firefox-container-2", {color:"purple"});
|
||||
browser.contextualIdentities.update("firefox-container-4", {icon:"pet"});
|
||||
browser.storage.local.clear();
|
||||
const localData = {"browserActionBadgesClicked":["6.1.1"],"containerTabsOpened":7,"identitiesState@@_firefox-container-1":{"hiddenTabs":[]},"identitiesState@@_firefox-container-2":{"hiddenTabs":[]},"identitiesState@@_firefox-container-3":{"hiddenTabs":[]},"identitiesState@@_firefox-container-4":{"hiddenTabs":[]},"identitiesState@@_firefox-container-6":{"hiddenTabs":[]},"identitiesState@@_firefox-default":{"hiddenTabs":[]},"onboarding-stage":5,"siteContainerMap@@_developer.mozilla.org":{"userContextId":"6","neverAsk":!1},"siteContainerMap@@_twitter.com":{"userContextId":"1","neverAsk":!0},"siteContainerMap@@_www.linkedin.com":{"userContextId":"4","neverAsk":!1}};
|
||||
browser.storage.local.set(localData);
|
||||
|
||||
};
|
||||
|
||||
const DUPE_TEST_SYNC = {
|
||||
"identities": [
|
||||
|
@ -439,6 +516,13 @@ const DUPE_TEST_ASSIGNMENTS = [
|
|||
"siteContainerMap@@_www.linkedin.com"
|
||||
];
|
||||
|
||||
const SITE_ASSIGNMENT_TEST = [
|
||||
"siteContainerMap@@_developer.mozilla.org",
|
||||
"siteContainerMap@@_www.facebook.com",
|
||||
"siteContainerMap@@_www.google.com",
|
||||
"siteContainerMap@@_bugzilla.mozilla.org"
|
||||
];
|
||||
|
||||
const DUPE_TEST_IDENTS = [
|
||||
{
|
||||
"name": "Personal",
|
||||
|
@ -471,38 +555,3 @@ const DUPE_TEST_IDENTS = [
|
|||
"color": "yellow",
|
||||
}
|
||||
];
|
||||
browser.resetMAC3 = async function () {
|
||||
// for debugging and testing: remove all containers except the default 4 and the first one created
|
||||
browser.tests.stopSyncListeners();
|
||||
|
||||
// sync state after FF2 synced
|
||||
await browser.storage.sync.clear();
|
||||
const syncData = {"assignedSites":{"siteContainerMap@@_developer.mozilla.org":{"userContextId":"6","neverAsk":!1,"hostname":"developer.mozilla.org"},"siteContainerMap@@_twitter.com":{"userContextId":"1","neverAsk":!0,"hostname":"twitter.com"},"siteContainerMap@@_www.facebook.com":{"userContextId":"2","neverAsk":!0,"hostname":"www.facebook.com"},"siteContainerMap@@_www.linkedin.com":{"userContextId":"4","neverAsk":!1,"hostname":"www.linkedin.com"},"siteContainerMap@@_reddit.com": {"userContextId": "7","neverAsk": true}},"cookieStoreIDmap":{"firefox-container-1":"4dc76734-5b71-4f2e-85d0-1cb199ae3821","firefox-container-2":"30308b8d-393c-4375-b9a1-afc59f0dea79","firefox-container-3":"7419c94d-85d7-4d76-94c0-bacef1de722f","firefox-container-4":"2b9fe881-e552-4df9-8cab-922f4688bb68","firefox-container-6":"db7f622e-682b-4556-968a-6e2542ff3b26","firefox-container-7":"ceb06672-76c0-48c4-959e-f3a3ee8358b6"},"identities":[{"name":"Personal","icon":"fingerprint","iconUrl":"resource://usercontext-content/fingerprint.svg","color":"blue","colorCode":"#37adff","cookieStoreId":"firefox-container-1"},{"name":"Work","icon":"briefcase","iconUrl":"resource://usercontext-content/briefcase.svg","color":"orange","colorCode":"#ff9f00","cookieStoreId":"firefox-container-2"},{"name":"Banking","icon":"dollar","iconUrl":"resource://usercontext-content/dollar.svg","color":"purple","colorCode":"#af51f5","cookieStoreId":"firefox-container-3"},{"name":"Shopping","icon":"cart","iconUrl":"resource://usercontext-content/cart.svg","color":"pink","colorCode":"#ff4bda","cookieStoreId":"firefox-container-4"},{"name":"Container #01","icon":"chill","iconUrl":"resource://usercontext-content/chill.svg","color":"green","colorCode":"#51cd00","cookieStoreId":"firefox-container-6"},{"name":"Container #02","icon":"vacation","iconUrl":"resource://usercontext-content/vacation.svg","color":"yellow","colorCode":"#ffcb00","cookieStoreId":"firefox-container-7"}]};
|
||||
browser.storage.sync.set(syncData);
|
||||
|
||||
// FF1 with updates from FF2 (intial sync w/ default 4 + 1 with some changes)
|
||||
browser.contextualIdentities.update("firefox-container-3", {color:"purple", icon:"fruit"});
|
||||
//browser.contextualIdentities.create({name: "Container #02", icon: "vacation", color: "yellow"});
|
||||
browser.storage.local.clear();
|
||||
const localData = {"beenSynced":!0,"browserActionBadgesClicked":["6.1.1"],"containerTabsOpened":7,"identitiesState@@_firefox-container-1":{"hiddenTabs":[],"macAddonUUID":"4dc76734-5b71-4f2e-85d0-1cb199ae3821"},"identitiesState@@_firefox-container-2":{"hiddenTabs":[],"macAddonUUID":"30308b8d-393c-4375-b9a1-afc59f0dea79"},"identitiesState@@_firefox-container-3":{"hiddenTabs":[],"macAddonUUID":"7419c94d-85d7-4d76-94c0-bacef1de722f"},"identitiesState@@_firefox-container-4":{"hiddenTabs":[],"macAddonUUID":"2b9fe881-e552-4df9-8cab-922f4688bb68"},"identitiesState@@_firefox-container-6":{"hiddenTabs":[],"macAddonUUID":"db7f622e-682b-4556-968a-6e2542ff3b26"},"identitiesState@@_firefox-default":{"hiddenTabs":[]},"onboarding-stage":5,"siteContainerMap@@_developer.mozilla.org":{"userContextId":"6","neverAsk":!1},"siteContainerMap@@_twitter.com":{"userContextId":"1","neverAsk":!0},"siteContainerMap@@_www.facebook.com":{"userContextId":"2","neverAsk":!0},"siteContainerMap@@_www.linkedin.com":{"userContextId":"4","neverAsk":!1}};
|
||||
browser.storage.local.set(localData);
|
||||
|
||||
};
|
||||
|
||||
browser.resetMAC4 = async function () {
|
||||
// for debugging and testing: remove all containers except the default 4 and the first one created
|
||||
browser.tests.stopSyncListeners();
|
||||
|
||||
// sync state after FF2 synced
|
||||
await browser.storage.sync.clear();
|
||||
const syncData = {"assignedSites":{"siteContainerMap@@_developer.mozilla.org":{"userContextId":"6","neverAsk":!1,"hostname":"developer.mozilla.org"},"siteContainerMap@@_twitter.com":{"userContextId":"1","neverAsk":!0,"hostname":"twitter.com"},"siteContainerMap@@_www.facebook.com":{"userContextId":"2","neverAsk":!0,"hostname":"www.facebook.com"},"siteContainerMap@@_www.linkedin.com":{"userContextId":"4","neverAsk":!1,"hostname":"www.linkedin.com"},"siteContainerMap@@_reddit.com": {"userContextId": "7","neverAsk": true}},"cookieStoreIDmap":{"firefox-container-1":"4dc76734-5b71-4f2e-85d0-1cb199ae3821","firefox-container-2":"30308b8d-393c-4375-b9a1-afc59f0dea79","firefox-container-3":"7419c94d-85d7-4d76-94c0-bacef1de722f","firefox-container-4":"2b9fe881-e552-4df9-8cab-922f4688bb68","firefox-container-6":"db7f622e-682b-4556-968a-6e2542ff3b26","firefox-container-7":"ceb06672-76c0-48c4-959e-f3a3ee8358b6"},"identities":[{"name":"Personal","icon":"fingerprint","iconUrl":"resource://usercontext-content/fingerprint.svg","color":"blue","colorCode":"#37adff","cookieStoreId":"firefox-container-1"},{"name":"Work","icon":"briefcase","iconUrl":"resource://usercontext-content/briefcase.svg","color":"orange","colorCode":"#ff9f00","cookieStoreId":"firefox-container-2"},{"name":"Banking","icon":"dollar","iconUrl":"resource://usercontext-content/dollar.svg","color":"purple","colorCode":"#af51f5","cookieStoreId":"firefox-container-3"},{"name":"Shopping","icon":"cart","iconUrl":"resource://usercontext-content/cart.svg","color":"pink","colorCode":"#ff4bda","cookieStoreId":"firefox-container-4"},{"name":"Container #01","icon":"chill","iconUrl":"resource://usercontext-content/chill.svg","color":"green","colorCode":"#51cd00","cookieStoreId":"firefox-container-6"},{"name":"Container #02","icon":"vacation","iconUrl":"resource://usercontext-content/vacation.svg","color":"yellow","colorCode":"#ffcb00","cookieStoreId":"firefox-container-7"}]};
|
||||
browser.storage.sync.set(syncData);
|
||||
|
||||
// FF1 with updates from FF2 (intial sync w/ default 4 + 1 with some changes)
|
||||
browser.contextualIdentities.update("firefox-container-3", {color:"purple", icon:"fruit"});
|
||||
//browser.contextualIdentities.create({name: "Container #02", icon: "vacation", color: "yellow"});
|
||||
browser.storage.local.clear();
|
||||
const localData = {"beenSynced":!0,"browserActionBadgesClicked":["6.1.1"],"containerTabsOpened":7,"identitiesState@@_firefox-container-1":{"hiddenTabs":[],"macAddonUUID":"4dc76734-5b71-4f2e-85d0-1cb199ae3821"},"identitiesState@@_firefox-container-2":{"hiddenTabs":[],"macAddonUUID":"30308b8d-393c-4375-b9a1-afc59f0dea79"},"identitiesState@@_firefox-container-3":{"hiddenTabs":[],"macAddonUUID":"7419c94d-85d7-4d76-94c0-bacef1de722f"},"identitiesState@@_firefox-container-4":{"hiddenTabs":[],"macAddonUUID":"2b9fe881-e552-4df9-8cab-922f4688bb68"},"identitiesState@@_firefox-container-6":{"hiddenTabs":[],"macAddonUUID":"db7f622e-682b-4556-968a-6e2542ff3b26"},"identitiesState@@_firefox-default":{"hiddenTabs":[]},"onboarding-stage":5,"siteContainerMap@@_developer.mozilla.org":{"userContextId":"6","neverAsk":!1},"siteContainerMap@@_twitter.com":{"userContextId":"1","neverAsk":!0},"siteContainerMap@@_www.facebook.com":{"userContextId":"2","neverAsk":!0},"siteContainerMap@@_www.linkedin.com":{"userContextId":"4","neverAsk":!1}};
|
||||
browser.storage.local.set(localData);
|
||||
|
||||
};
|
|
@ -724,8 +724,12 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
|||
however it allows us to have a tabindex before the first selected item
|
||||
*/
|
||||
const focusHandler = () => {
|
||||
list.querySelector("tr .clickable").focus();
|
||||
document.removeEventListener("focus", focusHandler);
|
||||
const identityList = list.querySelector("tr .clickable");
|
||||
if (identityList) {
|
||||
// otherwise this throws an error when there are no containers present.
|
||||
identityList.focus();
|
||||
document.removeEventListener("focus", focusHandler);
|
||||
}
|
||||
};
|
||||
document.addEventListener("focus", focusHandler);
|
||||
/* If the user mousedown's first then remove the focus handler */
|
||||
|
|
Loading…
Add table
Reference in a new issue