196 lines
5.1 KiB
JavaScript
196 lines
5.1 KiB
JavaScript
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();
|