8ef5cbd81b
Now opens in the newly opened tab (after it has been reopened in the correct container). It also does not provide a toast when removing sites from the edit assignments panel, becuase user will most likely not be on that site when editing the panel, so it has been throwing an error. Error should go away.
130 lines
3.6 KiB
JavaScript
130 lines
3.6 KiB
JavaScript
const DEFAULT_FAVICON = "/img/blank-favicon.svg";
|
|
|
|
// TODO use export here instead of globals
|
|
const Utils = {
|
|
|
|
createFavIconElement(url) {
|
|
const imageElement = document.createElement("img");
|
|
imageElement.classList.add("icon", "offpage", "menu-icon");
|
|
imageElement.src = url;
|
|
const loadListener = (e) => {
|
|
e.target.classList.remove("offpage");
|
|
e.target.removeEventListener("load", loadListener);
|
|
e.target.removeEventListener("error", errorListener);
|
|
};
|
|
const errorListener = (e) => {
|
|
e.target.src = DEFAULT_FAVICON;
|
|
};
|
|
imageElement.addEventListener("error", errorListener);
|
|
imageElement.addEventListener("load", loadListener);
|
|
return imageElement;
|
|
},
|
|
/**
|
|
* Escapes any occurances of &, ", <, > or / with XML entities.
|
|
*
|
|
* @param {string} str
|
|
* The string to escape.
|
|
* @return {string} The escaped string.
|
|
*/
|
|
escapeXML(str) {
|
|
const replacements = { "&": "&", "\"": """, "'": "'", "<": "<", ">": ">", "/": "/" };
|
|
return String(str).replace(/[&"'<>/]/g, m => replacements[m]);
|
|
},
|
|
|
|
/**
|
|
* A tagged template function which escapes any XML metacharacters in
|
|
* interpolated values.
|
|
*
|
|
* @param {Array<string>} strings
|
|
* An array of literal strings extracted from the templates.
|
|
* @param {Array} values
|
|
* An array of interpolated values extracted from the template.
|
|
* @returns {string}
|
|
* The result of the escaped values interpolated with the literal
|
|
* strings.
|
|
*/
|
|
escaped(strings, ...values) {
|
|
const result = [];
|
|
|
|
for (const [i, string] of strings.entries()) {
|
|
result.push(string);
|
|
if (i < values.length)
|
|
result.push(this.escapeXML(values[i]));
|
|
}
|
|
|
|
return result.join("");
|
|
},
|
|
|
|
async currentTab() {
|
|
const activeTabs = await browser.tabs.query({ active: true, windowId: browser.windows.WINDOW_ID_CURRENT });
|
|
if (activeTabs.length > 0) {
|
|
return activeTabs[0];
|
|
}
|
|
return false;
|
|
},
|
|
|
|
addEnterHandler(element, handler) {
|
|
element.addEventListener("click", (e) => {
|
|
handler(e);
|
|
});
|
|
element.addEventListener("keydown", (e) => {
|
|
if (e.keyCode === 13) {
|
|
e.preventDefault();
|
|
handler(e);
|
|
}
|
|
});
|
|
},
|
|
|
|
userContextId(cookieStoreId = "") {
|
|
const userContextId = cookieStoreId.replace("firefox-container-", "");
|
|
return (userContextId !== cookieStoreId) ? Number(userContextId) : false;
|
|
},
|
|
|
|
setOrRemoveAssignment(tabId, url, userContextId, value) {
|
|
return browser.runtime.sendMessage({
|
|
method: "setOrRemoveAssignment",
|
|
tabId,
|
|
url,
|
|
userContextId,
|
|
value
|
|
});
|
|
},
|
|
|
|
async reloadInContainer(url, currentUserContextId, newUserContextId, tabIndex, active) {
|
|
return await browser.runtime.sendMessage({
|
|
method: "reloadInContainer",
|
|
url,
|
|
currentUserContextId,
|
|
newUserContextId,
|
|
tabIndex,
|
|
active
|
|
});
|
|
},
|
|
|
|
async alwaysOpenInContainer(identity) {
|
|
let currentTab = await this.currentTab();
|
|
const assignedUserContextId = this.userContextId(identity.cookieStoreId);
|
|
if (currentTab.cookieStoreId !== identity.cookieStoreId) {
|
|
return await browser.runtime.sendMessage({
|
|
method: "assignAndReloadInContainer",
|
|
url: currentTab.url,
|
|
currentUserContextId: false,
|
|
newUserContextId: assignedUserContextId,
|
|
tabIndex: currentTab.index +1,
|
|
active:currentTab.active
|
|
});
|
|
} else {
|
|
currentTab = await this.currentTab();
|
|
Utils.setOrRemoveAssignment(
|
|
currentTab.id,
|
|
currentTab.url,
|
|
assignedUserContextId,
|
|
false
|
|
);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
|
|
window.Utils = Utils; |