Merge 2a4891846a
into 3b9da05e67
This commit is contained in:
commit
fa24459dcf
12 changed files with 479 additions and 140 deletions
|
@ -9,6 +9,7 @@ module.exports = {
|
|||
"webextensions": true
|
||||
},
|
||||
"globals": {
|
||||
"Utils": true,
|
||||
"CustomizableUI": true,
|
||||
"CustomizableWidgets": true,
|
||||
"SessionStore": true,
|
||||
|
|
|
@ -159,7 +159,7 @@ const assignManager = {
|
|||
//storageAction = this.storageArea.remove(info.pageUrl);
|
||||
remove = true;
|
||||
}
|
||||
await this._setOrRemoveAssignment(info.pageUrl, userContextId, remove);
|
||||
await this._setOrRemoveAssignment(tab.id, info.pageUrl, userContextId, remove);
|
||||
this.calculateContextMenu(tab);
|
||||
}
|
||||
},
|
||||
|
@ -192,7 +192,7 @@ const assignManager = {
|
|||
return true;
|
||||
},
|
||||
|
||||
async _setOrRemoveAssignment(pageUrl, userContextId, remove) {
|
||||
async _setOrRemoveAssignment(tabId, pageUrl, userContextId, remove) {
|
||||
let actionName;
|
||||
if (!remove) {
|
||||
await this.storageArea.set(pageUrl, {
|
||||
|
@ -205,11 +205,8 @@ const assignManager = {
|
|||
await this.storageArea.remove(pageUrl);
|
||||
actionName = "removed";
|
||||
}
|
||||
browser.notifications.create({
|
||||
type: "basic",
|
||||
title: "Containers",
|
||||
message: `Successfully ${actionName} site to always open in this container`,
|
||||
iconUrl: browser.extension.getURL("/img/onboarding-1.png")
|
||||
browser.tabs.sendMessage(tabId, {
|
||||
text: `Successfully ${actionName} site to always open in this container`
|
||||
});
|
||||
backgroundLogic.sendTelemetryPayload({
|
||||
event: `${actionName}-container-assignment`,
|
||||
|
@ -411,6 +408,15 @@ const messageHandler = {
|
|||
let response;
|
||||
|
||||
switch (m.method) {
|
||||
case "getContainers":
|
||||
response = browser.contextualIdentities.query({});
|
||||
break;
|
||||
case "openTab":
|
||||
response = browser.tabs.create({
|
||||
url: m.url,
|
||||
cookieStoreId: m.cookieStoreId
|
||||
});
|
||||
break;
|
||||
case "deleteContainer":
|
||||
response = backgroundLogic.deleteContainer(m.message.userContextId);
|
||||
break;
|
||||
|
@ -432,7 +438,7 @@ const messageHandler = {
|
|||
case "setOrRemoveAssignment":
|
||||
response = browser.tabs.get(m.tabId).then((tab) => {
|
||||
const userContextId = assignManager.getUserContextIdFromCookieStore(tab);
|
||||
return assignManager._setOrRemoveAssignment(tab.url, userContextId, m.value);
|
||||
return assignManager._setOrRemoveAssignment(tab.id, tab.url, userContextId, m.value);
|
||||
});
|
||||
break;
|
||||
case "exemptContainerAssignment":
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
</form>
|
||||
</main>
|
||||
|
||||
<script src="js/utils.js"></script>
|
||||
<script src="js/confirm-page.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
86
webextension/css/content.css
Normal file
86
webextension/css/content.css
Normal file
|
@ -0,0 +1,86 @@
|
|||
.container-notification {
|
||||
background: #33f70c;
|
||||
color: #003f07;
|
||||
display: block;
|
||||
inline-size: 100vw;
|
||||
offset-block-start: 0;
|
||||
offset-inline-start: 0;
|
||||
padding-block-end: 8px;
|
||||
padding-block-start: 8px;
|
||||
padding-inline-end: 8px;
|
||||
padding-inline-start: 8px;
|
||||
position: fixed;
|
||||
transform: translateY(-100%);
|
||||
transition: transform 0.3s cubic-bezier(0.07, 0.95, 0, 1) 0.3s;
|
||||
z-index: 999999999999;
|
||||
}
|
||||
|
||||
.container-notification img {
|
||||
block-size: 16px;
|
||||
inline-size: 16px;
|
||||
margin-inline-end: 3px;
|
||||
}
|
||||
|
||||
#containers-menu {
|
||||
background: #fcfcfc;
|
||||
border: 1px solid #979797;
|
||||
border-radius: 3px;
|
||||
box-shadow: 3px 3px 5px #91919166;
|
||||
font-family: Roboto, Noto, "San Francisco", Ubuntu, "Segoe UI", "Fira Sans", message-box, Arial, sans-serif;
|
||||
inline-size: 7rem;
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
z-index: 9999999;
|
||||
/* This is the area we allow users to move away from the menu without it closing
|
||||
*/
|
||||
margin: 4px;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
#containers-menu > li:first-of-type {
|
||||
border-radius: 3px 3px 0 0;
|
||||
}
|
||||
|
||||
#containers-menu > li:last-of-type {
|
||||
border: none;
|
||||
border-radius: 0 0 3px 3px;
|
||||
}
|
||||
|
||||
.dark-theme#containers-menu {
|
||||
background: #2b2f38;
|
||||
}
|
||||
|
||||
#containers-menu > li {
|
||||
align-items: center;
|
||||
border-block-end: 1px solid #979797;
|
||||
color: #434343;
|
||||
display: flex;
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#containers-menu > li > span {
|
||||
flex: 1;
|
||||
mask-image: linear-gradient(to left, transparent, black 1em);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dark-theme#containers-menu li {
|
||||
color: #92959b;
|
||||
}
|
||||
|
||||
#containers-menu li:hover,
|
||||
#containers-menu li:focus {
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
#containers-menu > li > .usercontext-icon {
|
||||
background-size: 16px;
|
||||
flex: 0 0 16px;
|
||||
margin-inline-end: 6px;
|
||||
max-block-size: 16px;
|
||||
min-block-size: 16px;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
body {
|
||||
inline-size: 300px;
|
||||
max-inline-size: 300px;
|
||||
font-family: Roboto, Noto, "San Francisco", Ubuntu, "Segoe UI", "Fira Sans", message-box, Arial, sans-serif;
|
||||
}
|
||||
|
||||
html {
|
||||
|
@ -11,6 +12,18 @@ html {
|
|||
:root {
|
||||
--font-size-heading: 16px;
|
||||
--primary-action-color: #248aeb;
|
||||
|
||||
--block-line-space-size: 6px;
|
||||
--block-line-separation-size: 10px;
|
||||
--inline-icon-space-size: 10px;
|
||||
/* Use for url and icon size */
|
||||
--block-url-label-size: 24px;
|
||||
--inline-start-size: 20px;
|
||||
--inline-button-size: 70px;
|
||||
|
||||
--title-text-color: #000;
|
||||
--small-text-size: 10px;
|
||||
--small-radius: 3p 3pxx;
|
||||
}
|
||||
|
||||
*,
|
||||
|
@ -51,95 +64,6 @@ table {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Color and icon helpers */
|
||||
[data-identity-color="blue"] {
|
||||
--identity-tab-color: #37adff;
|
||||
--identity-icon-color: #37adff;
|
||||
}
|
||||
|
||||
[data-identity-color="turquoise"] {
|
||||
--identity-tab-color: #00c79a;
|
||||
--identity-icon-color: #00c79a;
|
||||
}
|
||||
|
||||
[data-identity-color="green"] {
|
||||
--identity-tab-color: #51cd00;
|
||||
--identity-icon-color: #51cd00;
|
||||
}
|
||||
|
||||
[data-identity-color="yellow"] {
|
||||
--identity-tab-color: #ffcb00;
|
||||
--identity-icon-color: #ffcb00;
|
||||
}
|
||||
|
||||
[data-identity-color="orange"] {
|
||||
--identity-tab-color: #ff9f00;
|
||||
--identity-icon-color: #ff9f00;
|
||||
}
|
||||
|
||||
[data-identity-color="red"] {
|
||||
--identity-tab-color: #ff613d;
|
||||
--identity-icon-color: #ff613d;
|
||||
}
|
||||
|
||||
[data-identity-color="pink"] {
|
||||
--identity-tab-color: #ff4bda;
|
||||
--identity-icon-color: #ff4bda;
|
||||
}
|
||||
|
||||
[data-identity-color="purple"] {
|
||||
--identity-tab-color: #af51f5;
|
||||
--identity-icon-color: #af51f5;
|
||||
}
|
||||
|
||||
[data-identity-icon="fingerprint"] {
|
||||
--identity-icon: url("/img/usercontext.svg#fingerprint");
|
||||
}
|
||||
|
||||
[data-identity-icon="briefcase"] {
|
||||
--identity-icon: url("/img/usercontext.svg#briefcase");
|
||||
}
|
||||
|
||||
[data-identity-icon="dollar"] {
|
||||
--identity-icon: url("/img/usercontext.svg#dollar");
|
||||
}
|
||||
|
||||
[data-identity-icon="cart"] {
|
||||
--identity-icon: url("/img/usercontext.svg#cart");
|
||||
}
|
||||
|
||||
[data-identity-icon="circle"] {
|
||||
--identity-icon: url("/img/usercontext.svg#circle");
|
||||
}
|
||||
|
||||
[data-identity-icon="food"] {
|
||||
--identity-icon: url("/img/usercontext.svg#food");
|
||||
}
|
||||
|
||||
[data-identity-icon="gift"] {
|
||||
--identity-icon: url("/img/usercontext.svg#gift");
|
||||
}
|
||||
|
||||
[data-identity-icon="vacation"] {
|
||||
--identity-icon: url("/img/usercontext.svg#vacation");
|
||||
}
|
||||
|
||||
[data-identity-icon="fruit"] {
|
||||
--identity-icon: url("/img/usercontext.svg#fruit");
|
||||
}
|
||||
|
||||
[data-identity-icon="pet"] {
|
||||
--identity-icon: url("/img/usercontext.svg#pet");
|
||||
}
|
||||
|
||||
[data-identity-icon="tree"] {
|
||||
--identity-icon: url("/img/usercontext.svg#tree");
|
||||
}
|
||||
|
||||
[data-identity-icon="chill"] {
|
||||
--identity-icon: url("/img/usercontext.svg#chill");
|
||||
}
|
||||
|
||||
#current-tab [data-identity-icon="default-tab"] {
|
||||
background: center center no-repeat url("/img/blank-tab.svg");
|
||||
fill: currentColor;
|
||||
|
@ -373,6 +297,10 @@ manage things like container crud */
|
|||
|
||||
#container-panel #sort-containers-link {
|
||||
margin-inline-end: 16px;
|
||||
inline-size: var(--inline-button-size);
|
||||
color: var(--title-text-color);
|
||||
font-size: var(--small-text-size);
|
||||
border-radius: var(--small-radius);
|
||||
}
|
||||
|
||||
span ~ .panel-header-text {
|
||||
|
@ -469,18 +397,6 @@ span ~ .panel-header-text {
|
|||
flex: 0 0 48px;
|
||||
}
|
||||
|
||||
/* .userContext-icon is used natively, Bug 1333811 was raised to fix */
|
||||
.usercontext-icon {
|
||||
background-image: var(--identity-icon);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 20px 20px;
|
||||
block-size: 48px;
|
||||
fill: var(--identity-icon-color);
|
||||
filter: url('/img/filters.svg#fill');
|
||||
flex: 0 0 48px;
|
||||
}
|
||||
|
||||
.container-panel-row:hover .clickable .usercontext-icon,
|
||||
.container-panel-row:focus .clickable .usercontext-icon {
|
||||
background-image: url('/img/container-newtab.svg');
|
||||
|
@ -502,13 +418,13 @@ span ~ .panel-header-text {
|
|||
}
|
||||
|
||||
.panel-footer .pop-button {
|
||||
block-size: 54px;
|
||||
flex: 0 0 54px;
|
||||
block-size: 100%;
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.edit-containers-text {
|
||||
align-items: center;
|
||||
block-size: 54px;
|
||||
block-size: 100%;
|
||||
border-inline-end: solid 1px #d8d8d8;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
@ -517,7 +433,7 @@ span ~ .panel-header-text {
|
|||
|
||||
.edit-containers-text a {
|
||||
align-items: center;
|
||||
block-size: 54px;
|
||||
block-size: 100%;
|
||||
color: #0a0a0a;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
@ -529,6 +445,10 @@ span ~ .panel-header-text {
|
|||
margin-inline-end: 0.5rem;
|
||||
}
|
||||
|
||||
.container-info-tab-title {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#container-info-hideorshow {
|
||||
margin-block-start: 4px;
|
||||
}
|
||||
|
|
100
webextension/css/user-context.css
Normal file
100
webextension/css/user-context.css
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* Color and icon helpers */
|
||||
[data-identity-color="blue"] {
|
||||
--identity-tab-color: #37adff;
|
||||
--identity-icon-color: #37adff;
|
||||
}
|
||||
|
||||
[data-identity-color="turquoise"] {
|
||||
--identity-tab-color: #00c79a;
|
||||
--identity-icon-color: #00c79a;
|
||||
}
|
||||
|
||||
[data-identity-color="green"] {
|
||||
--identity-tab-color: #51cd00;
|
||||
--identity-icon-color: #51cd00;
|
||||
}
|
||||
|
||||
[data-identity-color="yellow"] {
|
||||
--identity-tab-color: #ffcb00;
|
||||
--identity-icon-color: #ffcb00;
|
||||
}
|
||||
|
||||
[data-identity-color="orange"] {
|
||||
--identity-tab-color: #ff9f00;
|
||||
--identity-icon-color: #ff9f00;
|
||||
}
|
||||
|
||||
[data-identity-color="red"] {
|
||||
--identity-tab-color: #ff613d;
|
||||
--identity-icon-color: #ff613d;
|
||||
}
|
||||
|
||||
[data-identity-color="pink"] {
|
||||
--identity-tab-color: #ff4bda;
|
||||
--identity-icon-color: #ff4bda;
|
||||
}
|
||||
|
||||
[data-identity-color="purple"] {
|
||||
--identity-tab-color: #af51f5;
|
||||
--identity-icon-color: #af51f5;
|
||||
}
|
||||
|
||||
[data-identity-icon="fingerprint"] {
|
||||
--identity-icon: url("/img/usercontext.svg#fingerprint");
|
||||
}
|
||||
|
||||
[data-identity-icon="briefcase"] {
|
||||
--identity-icon: url("/img/usercontext.svg#briefcase");
|
||||
}
|
||||
|
||||
[data-identity-icon="dollar"] {
|
||||
--identity-icon: url("/img/usercontext.svg#dollar");
|
||||
}
|
||||
|
||||
[data-identity-icon="cart"] {
|
||||
--identity-icon: url("/img/usercontext.svg#cart");
|
||||
}
|
||||
|
||||
[data-identity-icon="circle"] {
|
||||
--identity-icon: url("/img/usercontext.svg#circle");
|
||||
}
|
||||
|
||||
[data-identity-icon="food"] {
|
||||
--identity-icon: url("/img/usercontext.svg#food");
|
||||
}
|
||||
|
||||
[data-identity-icon="gift"] {
|
||||
--identity-icon: url("/img/usercontext.svg#gift");
|
||||
}
|
||||
|
||||
[data-identity-icon="vacation"] {
|
||||
--identity-icon: url("/img/usercontext.svg#vacation");
|
||||
}
|
||||
|
||||
[data-identity-icon="fruit"] {
|
||||
--identity-icon: url("/img/usercontext.svg#fruit");
|
||||
}
|
||||
|
||||
[data-identity-icon="pet"] {
|
||||
--identity-icon: url("/img/usercontext.svg#pet");
|
||||
}
|
||||
|
||||
[data-identity-icon="tree"] {
|
||||
--identity-icon: url("/img/usercontext.svg#tree");
|
||||
}
|
||||
|
||||
[data-identity-icon="chill"] {
|
||||
--identity-icon: url("/img/usercontext.svg#chill");
|
||||
}
|
||||
|
||||
/* .userContext-icon is used natively, Bug 1333811 was raised to fix */
|
||||
.usercontext-icon {
|
||||
background-image: var(--identity-icon);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 20px 20px;
|
||||
block-size: 48px;
|
||||
fill: var(--identity-icon-color);
|
||||
filter: url('/img/filters.svg#fill');
|
||||
flex: 0 0 48px;
|
||||
}
|
|
@ -5,7 +5,7 @@ async function load() {
|
|||
const currentCookieStoreId = searchParams.get("currentCookieStoreId");
|
||||
const redirectUrlElement = document.getElementById("redirect-url");
|
||||
redirectUrlElement.textContent = redirectUrl;
|
||||
createFavicon(redirectUrl, redirectUrlElement);
|
||||
appendFavicon(redirectUrl, redirectUrlElement);
|
||||
|
||||
const container = await browser.contextualIdentities.get(cookieStoreId);
|
||||
[...document.querySelectorAll(".container-name")].forEach((containerNameElement) => {
|
||||
|
@ -32,12 +32,11 @@ async function load() {
|
|||
});
|
||||
}
|
||||
|
||||
function createFavicon(pageUrl, redirectUrlElement) {
|
||||
function appendFavicon(pageUrl, redirectUrlElement) {
|
||||
const origin = new URL(pageUrl).origin;
|
||||
const imageElement = document.createElement("img");
|
||||
imageElement.src = `${origin}/favicon.ico`;
|
||||
const favIconElement = Utils.createFavIconElement(`${origin}/favicon.ico`);
|
||||
|
||||
redirectUrlElement.prepend(imageElement);
|
||||
redirectUrlElement.prepend(favIconElement);
|
||||
}
|
||||
|
||||
function confirmSubmit(redirectUrl, cookieStoreId) {
|
||||
|
|
196
webextension/js/content-script.js
Normal file
196
webextension/js/content-script.js
Normal file
|
@ -0,0 +1,196 @@
|
|||
async function delayAnimation(delay = 350) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, delay);
|
||||
});
|
||||
}
|
||||
|
||||
async function doAnimation(element, property, value) {
|
||||
return new Promise((resolve) => {
|
||||
const handler = () => {
|
||||
resolve();
|
||||
element.removeEventListener("transitionend", handler);
|
||||
};
|
||||
element.addEventListener("transitionend", handler);
|
||||
window.requestAnimationFrame(() => {
|
||||
element.style[property] = value;
|
||||
});
|
||||
});
|
||||
}
|
||||
/*
|
||||
async function awaitEvent(eventName) {
|
||||
return new Promise((resolve) => {
|
||||
const handler = () => {
|
||||
resolve();
|
||||
divElement.removeEventListener(eventName, handler);
|
||||
};
|
||||
divElement.addEventListener(eventName, handler);
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
async function addMessage(message) {
|
||||
const divElement = document.createElement("div");
|
||||
divElement.classList.add("container-notification");
|
||||
// For the eager eyed, this is an experiment. It is however likely that a website will know it is "contained" anyway
|
||||
divElement.innerText = message.text;
|
||||
|
||||
const imageElement = document.createElement("img");
|
||||
imageElement.src = browser.extension.getURL("/img/container-site-d-24.png");
|
||||
divElement.prepend(imageElement);
|
||||
|
||||
document.body.appendChild(divElement);
|
||||
|
||||
await delayAnimation(100);
|
||||
await doAnimation(divElement, "transform", "translateY(0)");
|
||||
await delayAnimation(2000);
|
||||
await doAnimation(divElement, "transform", "translateY(-100%)");
|
||||
|
||||
divElement.remove();
|
||||
}
|
||||
|
||||
browser.runtime.onMessage.addListener((message) => {
|
||||
addMessage(message);
|
||||
});
|
||||
|
||||
|
||||
const menuClickHandler = {
|
||||
menuElement: null,
|
||||
lastUrl: null,
|
||||
linkSelector:"a[href]",
|
||||
|
||||
init() {
|
||||
this.createMenu();
|
||||
|
||||
document.addEventListener("keydown", this);
|
||||
document.addEventListener("click", this);
|
||||
},
|
||||
|
||||
handleEvent(e) {
|
||||
switch(e.type) {
|
||||
case "keydown":
|
||||
if (this.isMenuOpen()) {
|
||||
if (e.key === "Escape") {
|
||||
this.menuClose();
|
||||
}
|
||||
}
|
||||
if (e.altKey && (e.shiftKey || e.key === "Shift")) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.addOpenListeners();
|
||||
}
|
||||
break;
|
||||
case "keyup":
|
||||
if (e.altKey && (e.shiftKey || e.key === "Shift")) {
|
||||
this.removeOpenListeners();
|
||||
}
|
||||
break;
|
||||
case "click":
|
||||
if (this.isMenuOpen() &&
|
||||
(e.target.closest(this.linkSelector) || e.target.matches(this.linkSelector))) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
} else {
|
||||
this.menuClose();
|
||||
}
|
||||
this.removeOpenListeners();
|
||||
break;
|
||||
case "mousedown":
|
||||
if (this.isMenuOpen()) {
|
||||
if (!e.target.closest("#containers-menu")) {
|
||||
this.menuClose();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (e.target.closest(this.linkSelector) ||
|
||||
e.target.matches(this.linkSelector)) {
|
||||
// Prevent text selection
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.lastUrl = e.target.href;
|
||||
this.showMenu(e);
|
||||
}
|
||||
/*
|
||||
setTimeout(() => {
|
||||
this.removeOpenListeners();
|
||||
}, 1000);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
addOpenListeners() {
|
||||
document.addEventListener("mousedown", this);
|
||||
document.addEventListener("keyup", this);
|
||||
},
|
||||
|
||||
removeOpenListeners() {
|
||||
document.removeEventListener("mousedown", this);
|
||||
document.removeEventListener("keyup", this);
|
||||
},
|
||||
|
||||
isMenuOpen() {
|
||||
return !this.menuElement.hidden;
|
||||
},
|
||||
|
||||
menuOpen() {
|
||||
this.menuElement.hidden = false;
|
||||
},
|
||||
|
||||
menuClose() {
|
||||
this.menuElement.hidden = true;
|
||||
},
|
||||
|
||||
getContainers() {
|
||||
return browser.runtime.sendMessage({
|
||||
method: "getContainers"
|
||||
});
|
||||
},
|
||||
|
||||
async createMenu() {
|
||||
if (this.menuElement) {
|
||||
return this.menuElement;
|
||||
}
|
||||
const menuElement = document.createElement("ul");
|
||||
menuElement.id = "containers-menu";
|
||||
menuElement.hidden = true;
|
||||
const containers = await this.getContainers();
|
||||
containers.forEach((container) => {
|
||||
const containerElement = document.createElement("li");
|
||||
const spanElement = document.createElement("span");
|
||||
spanElement.innerText = container.name;
|
||||
containerElement.appendChild(spanElement);
|
||||
containerElement.setAttribute("tabindex", 0);
|
||||
const iconElement = document.createElement("div");
|
||||
iconElement.classList.add("usercontext-icon");
|
||||
iconElement.setAttribute("data-identity-icon", container.icon);
|
||||
iconElement.setAttribute("data-identity-color", container.color);
|
||||
containerElement.prepend(iconElement);
|
||||
menuElement.appendChild(containerElement);
|
||||
containerElement.addEventListener("click", (e) => {
|
||||
this.openContainer(container);
|
||||
});
|
||||
});
|
||||
document.body.appendChild(menuElement);
|
||||
this.menuElement = menuElement;
|
||||
return menuElement;
|
||||
},
|
||||
|
||||
async showMenu(e) {
|
||||
const menuElement = await this.createMenu();
|
||||
this.menuOpen();
|
||||
menuElement.style.top = `${e.clientY}px`;
|
||||
menuElement.style.left = `${e.clientX}px`;
|
||||
menuElement.querySelector("div").focus();
|
||||
},
|
||||
|
||||
openContainer(container) {
|
||||
return browser.runtime.sendMessage({
|
||||
method: "openTab",
|
||||
url: this.lastUrl,
|
||||
cookieStoreId: container.cookieStoreId
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
menuClickHandler.init();
|
|
@ -18,7 +18,6 @@ const P_CONTAINERS_EDIT = "containersEdit";
|
|||
const P_CONTAINER_INFO = "containerInfo";
|
||||
const P_CONTAINER_EDIT = "containerEdit";
|
||||
const P_CONTAINER_DELETE = "containerDelete";
|
||||
const DEFAULT_FAVICON = "moz-icon://goat?size=16";
|
||||
|
||||
/**
|
||||
* Escapes any occurances of &, ", <, > or / with XML entities.
|
||||
|
@ -446,22 +445,9 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
|||
const siteSettings = await Logic.getAssignment(currentTab);
|
||||
this.setupAssignmentCheckbox(siteSettings);
|
||||
const currentPage = document.getElementById("current-page");
|
||||
const favIconUrl = currentTab.favIconUrl || "";
|
||||
currentPage.innerHTML = escaped`
|
||||
<img class="offpage" src="${favIconUrl}" /> ${currentTab.title}
|
||||
`;
|
||||
|
||||
const imageElement = currentPage.querySelector("img");
|
||||
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);
|
||||
currentPage.innerHTML = escaped`${currentTab.title}`;
|
||||
const favIconElement = Utils.createFavIconElement(currentTab.favIconUrl || "");
|
||||
currentPage.prepend(favIconElement);
|
||||
|
||||
const currentContainer = document.getElementById("current-container");
|
||||
currentContainer.innerText = identity.name;
|
||||
|
@ -537,8 +523,14 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
|||
/* Not sure why extensions require a focus for the doorhanger,
|
||||
however it allows us to have a tabindex before the first selected item
|
||||
*/
|
||||
document.addEventListener("focus", () => {
|
||||
const focusHandler = () => {
|
||||
list.querySelector("tr").focus();
|
||||
document.removeEventListener("focus", focusHandler);
|
||||
};
|
||||
document.addEventListener("focus", focusHandler);
|
||||
/* If the user mousedown's first then remove the focus handler */
|
||||
document.addEventListener("mousedown", () => {
|
||||
document.removeEventListener("focus", focusHandler);
|
||||
});
|
||||
|
||||
return Promise.resolve();
|
||||
|
@ -645,8 +637,9 @@ Logic.registerPanel(P_CONTAINER_INFO, {
|
|||
fragment.appendChild(tr);
|
||||
tr.classList.add("container-info-tab-row");
|
||||
tr.innerHTML = escaped`
|
||||
<td><img class="icon" src="${tab.favicon}" /></td>
|
||||
<td></td>
|
||||
<td class="container-info-tab-title truncate-text">${tab.title}</td>`;
|
||||
tr.querySelector("td").appendChild(Utils.createFavIconElement(tab.favicon));
|
||||
|
||||
// On click, we activate this tab. But only if this tab is active.
|
||||
if (tab.active) {
|
||||
|
|
23
webextension/js/utils.js
Normal file
23
webextension/js/utils.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
const DEFAULT_FAVICON = "moz-icon://goat?size=16";
|
||||
|
||||
// TODO use export here instead of globals
|
||||
window.Utils = {
|
||||
|
||||
createFavIconElement(url) {
|
||||
const imageElement = document.createElement("img");
|
||||
imageElement.classList.add("icon", "offpage");
|
||||
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;
|
||||
}
|
||||
|
||||
};
|
|
@ -26,7 +26,6 @@
|
|||
"contextualIdentities",
|
||||
"history",
|
||||
"idle",
|
||||
"notifications",
|
||||
"storage",
|
||||
"tabs",
|
||||
"webRequestBlocking",
|
||||
|
@ -54,5 +53,19 @@
|
|||
|
||||
"background": {
|
||||
"scripts": ["background.js"]
|
||||
}
|
||||
},
|
||||
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["js/content-script.js"],
|
||||
"css": ["css/user-context.css", "css/content.css"]
|
||||
}
|
||||
],
|
||||
|
||||
"web_accessible_resources": [
|
||||
"/img/container-site-d-24.png",
|
||||
"/img/usercontext.svg",
|
||||
"/img/filters.svg"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<title>Containers browserAction Popup</title>
|
||||
<link rel="stylesheet" href="/css/user-context.css">
|
||||
<link rel="stylesheet" href="/css/popup.css">
|
||||
</head>
|
||||
<body>
|
||||
|
@ -148,7 +149,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="js/utils.js"></script>
|
||||
<script src="js/popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Add table
Reference in a new issue