Merge 747df1c425
into a60f5bb1be
This commit is contained in:
commit
c67f473927
6 changed files with 275 additions and 5 deletions
107
src/css/select-page.css
Normal file
107
src/css/select-page.css
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/* General Rules and Resets */
|
||||||
|
.title {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
background: url(/img/onboarding-4.png) no-repeat;
|
||||||
|
background-position: 200px 0;
|
||||||
|
background-size: 120px;
|
||||||
|
margin-inline-start: -350px;
|
||||||
|
padding-inline-start: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 900px) {
|
||||||
|
main {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for a mid sized window we have enough for this but not our image */
|
||||||
|
.title {
|
||||||
|
background-image: url('chrome://global/skin/icons/info.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
box-sizing: border-box;
|
||||||
|
font: message-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#redirect-url,
|
||||||
|
#redirect-origin {
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
/* max-inline-size is needed to force this text smaller than the layout at a mid-sized window */
|
||||||
|
max-inline-size: 40rem;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
#redirect-url {
|
||||||
|
background: #efedf0; /* Grey 20 */
|
||||||
|
border-radius: 2px;
|
||||||
|
line-height: 1.5;
|
||||||
|
padding-block-end: 0.5rem;
|
||||||
|
padding-block-start: 0.5rem;
|
||||||
|
padding-inline-end: 0.5rem;
|
||||||
|
padding-inline-start: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stylelint-disable media-feature-name-no-unknown */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
#redirect-url {
|
||||||
|
background: #38383d; /* Grey 70 */
|
||||||
|
color: #eee; /* White 20 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* stylelint-enable */
|
||||||
|
|
||||||
|
#redirect-url img {
|
||||||
|
block-size: 16px;
|
||||||
|
inline-size: 16px;
|
||||||
|
margin-inline-end: 6px;
|
||||||
|
offset-block-start: 3px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfn {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-label {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#redirect-identities {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 7.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#redirect-identities button {
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-basis: 180px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 7.5px;
|
||||||
|
height: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 7.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#redirect-identities button .primary {
|
||||||
|
flex-grow: 2;
|
||||||
|
flex-basis: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#redirect-identities button img {
|
||||||
|
position: relative;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
filter: url('/img/filters.svg#fill');
|
||||||
|
}
|
||||||
|
|
||||||
|
#redirect-identities button label {
|
||||||
|
position: relative;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
|
@ -56,6 +56,11 @@ window.assignManager = {
|
||||||
return !!replaceTabEnabled;
|
return !!replaceTabEnabled;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getContainerPromptEnabled() {
|
||||||
|
const { containerPromptEnabled } = await browser.storage.local.get("containerPromptEnabled");
|
||||||
|
return !!containerPromptEnabled;
|
||||||
|
},
|
||||||
|
|
||||||
getByUrlKey(siteStoreKey) {
|
getByUrlKey(siteStoreKey) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.area.get([siteStoreKey]).then((storageResponse) => {
|
this.area.get([siteStoreKey]).then((storageResponse) => {
|
||||||
|
@ -265,13 +270,18 @@ window.assignManager = {
|
||||||
const siteIsolatedReloadInDefault =
|
const siteIsolatedReloadInDefault =
|
||||||
await this._maybeSiteIsolatedReloadInDefault(siteSettings, tab);
|
await this._maybeSiteIsolatedReloadInDefault(siteSettings, tab);
|
||||||
|
|
||||||
if (!siteIsolatedReloadInDefault) {
|
// The site is not associated with a container and a container is not already
|
||||||
if (!siteSettings
|
// being used to access it. In this case, we want to prompt the user to select
|
||||||
|| userContextId === siteSettings.userContextId
|
// a container before continuing.
|
||||||
|| this.storageArea.isExempted(options.url, tab.id)) {
|
const containerPromptEnabled = await this.storageArea.getContainerPromptEnabled();
|
||||||
|
const promptReloadInContainer = containerPromptEnabled && !siteSettings && !userContextId;
|
||||||
|
|
||||||
|
if (!siteIsolatedReloadInDefault && !promptReloadInContainer) {
|
||||||
|
if (!siteSettings || userContextId === siteSettings.userContextId || this.storageArea.isExempted(options.url, tab.id)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const replaceTabEnabled = await this.storageArea.getReplaceTabEnabled();
|
const replaceTabEnabled = await this.storageArea.getReplaceTabEnabled();
|
||||||
const removeTab = backgroundLogic.NEW_TAB_PAGES.has(tab.url)
|
const removeTab = backgroundLogic.NEW_TAB_PAGES.has(tab.url)
|
||||||
|| (messageHandler.lastCreatedTab
|
|| (messageHandler.lastCreatedTab
|
||||||
|
@ -321,7 +331,15 @@ window.assignManager = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (siteIsolatedReloadInDefault) {
|
if (promptReloadInContainer)
|
||||||
|
{
|
||||||
|
this.promptReloadPageInContainer(
|
||||||
|
options.url,
|
||||||
|
tab.index + 1,
|
||||||
|
tab.active,
|
||||||
|
openTabId
|
||||||
|
);
|
||||||
|
} else if (siteIsolatedReloadInDefault) {
|
||||||
this.reloadPageInDefaultContainer(
|
this.reloadPageInDefaultContainer(
|
||||||
options.url,
|
options.url,
|
||||||
tab.index + 1,
|
tab.index + 1,
|
||||||
|
@ -339,6 +357,7 @@ window.assignManager = {
|
||||||
openTabId
|
openTabId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.calculateContextMenu(tab);
|
this.calculateContextMenu(tab);
|
||||||
|
|
||||||
/* Removal of existing tabs:
|
/* Removal of existing tabs:
|
||||||
|
@ -749,6 +768,22 @@ window.assignManager = {
|
||||||
browser.tabs.create({url, cookieStoreId, index, active, openerTabId});
|
browser.tabs.create({url, cookieStoreId, index, active, openerTabId});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
promptReloadPageInContainer(url, index, active, openerTabId = null) {
|
||||||
|
const loadPage = browser.runtime.getURL("select-page.html");
|
||||||
|
let confirmUrl = `${loadPage}?url=${this.encodeURLProperty(url)}`;
|
||||||
|
return browser.tabs.create({
|
||||||
|
url: confirmUrl,
|
||||||
|
openerTabId,
|
||||||
|
index,
|
||||||
|
active
|
||||||
|
}).then(async () => {
|
||||||
|
// We don't want to sync this URL ever nor clutter the users history
|
||||||
|
browser.history.deleteUrl({url: confirmUrl});
|
||||||
|
}).catch((e) => {
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
reloadPageInContainer(url, currentUserContextId, userContextId, index, active, neverAsk = false, openerTabId = null) {
|
reloadPageInContainer(url, currentUserContextId, userContextId, index, active, neverAsk = false, openerTabId = null) {
|
||||||
const cookieStoreId = backgroundLogic.cookieStoreId(userContextId);
|
const cookieStoreId = backgroundLogic.cookieStoreId(userContextId);
|
||||||
const loadPage = browser.runtime.getURL("confirm-page.html");
|
const loadPage = browser.runtime.getURL("confirm-page.html");
|
||||||
|
|
|
@ -53,6 +53,11 @@ async function enableDisableReplaceTab() {
|
||||||
await browser.storage.local.set({replaceTabEnabled: !!checkbox.checked});
|
await browser.storage.local.set({replaceTabEnabled: !!checkbox.checked});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function enableDisableContainerPrompt() {
|
||||||
|
const checkbox = document.querySelector("#containerPromptCheck");
|
||||||
|
await browser.storage.local.set({containerPromptEnabled: !!checkbox.checked});
|
||||||
|
}
|
||||||
|
|
||||||
async function changeTheme(event) {
|
async function changeTheme(event) {
|
||||||
const theme = event.currentTarget;
|
const theme = event.currentTarget;
|
||||||
await browser.storage.local.set({currentTheme: theme.value});
|
await browser.storage.local.set({currentTheme: theme.value});
|
||||||
|
@ -62,10 +67,12 @@ async function changeTheme(event) {
|
||||||
async function setupOptions() {
|
async function setupOptions() {
|
||||||
const { syncEnabled } = await browser.storage.local.get("syncEnabled");
|
const { syncEnabled } = await browser.storage.local.get("syncEnabled");
|
||||||
const { replaceTabEnabled } = await browser.storage.local.get("replaceTabEnabled");
|
const { replaceTabEnabled } = await browser.storage.local.get("replaceTabEnabled");
|
||||||
|
const { containerPromptEnabled } = await browser.storage.local.get("containerPromptEnabled");
|
||||||
const { currentThemeId } = await browser.storage.local.get("currentThemeId");
|
const { currentThemeId } = await browser.storage.local.get("currentThemeId");
|
||||||
|
|
||||||
document.querySelector("#syncCheck").checked = !!syncEnabled;
|
document.querySelector("#syncCheck").checked = !!syncEnabled;
|
||||||
document.querySelector("#replaceTabCheck").checked = !!replaceTabEnabled;
|
document.querySelector("#replaceTabCheck").checked = !!replaceTabEnabled;
|
||||||
|
document.querySelector("#containerPromptCheck").checked = !!containerPromptEnabled;
|
||||||
document.querySelector("#changeTheme").selectedIndex = currentThemeId;
|
document.querySelector("#changeTheme").selectedIndex = currentThemeId;
|
||||||
setupContainerShortcutSelects();
|
setupContainerShortcutSelects();
|
||||||
}
|
}
|
||||||
|
@ -123,6 +130,7 @@ browser.permissions.onRemoved.addListener(resetPermissionsUi);
|
||||||
document.addEventListener("DOMContentLoaded", setupOptions);
|
document.addEventListener("DOMContentLoaded", setupOptions);
|
||||||
document.querySelector("#syncCheck").addEventListener( "change", enableDisableSync);
|
document.querySelector("#syncCheck").addEventListener( "change", enableDisableSync);
|
||||||
document.querySelector("#replaceTabCheck").addEventListener( "change", enableDisableReplaceTab);
|
document.querySelector("#replaceTabCheck").addEventListener( "change", enableDisableReplaceTab);
|
||||||
|
document.querySelector("#containerPromptCheck").addEventListener( "change", enableDisableContainerPrompt);
|
||||||
document.querySelector("#changeTheme").addEventListener( "change", changeTheme);
|
document.querySelector("#changeTheme").addEventListener( "change", changeTheme);
|
||||||
|
|
||||||
maybeShowPermissionsWarningIcon();
|
maybeShowPermissionsWarningIcon();
|
||||||
|
|
83
src/js/select-page.js
Normal file
83
src/js/select-page.js
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
async function load() {
|
||||||
|
const searchParams = new URL(window.location).searchParams;
|
||||||
|
const redirectUrl = searchParams.get("url");
|
||||||
|
const redirectUrlElement = document.getElementById("redirect-url");
|
||||||
|
redirectUrlElement.textContent = redirectUrl;
|
||||||
|
appendFavicon(redirectUrl, redirectUrlElement);
|
||||||
|
|
||||||
|
const identities = await browser.contextualIdentities.query({});
|
||||||
|
const redirectFormElement = document.getElementById("redirect-identities");
|
||||||
|
|
||||||
|
identities.forEach(identity => {
|
||||||
|
const cookieStoreId = identity.cookieStoreId;
|
||||||
|
var containerButtonElement = document.createElement("button");
|
||||||
|
containerButtonElement.classList.add("button");
|
||||||
|
containerButtonElement.id = "container-" + identity.name;
|
||||||
|
containerButtonElement.setAttribute("container-id", cookieStoreId);
|
||||||
|
containerButtonElement.addEventListener("click", e => {
|
||||||
|
e.preventDefault();
|
||||||
|
selectContainer(redirectUrl, identity)
|
||||||
|
})
|
||||||
|
var containerIconElement = document.createElement("img");
|
||||||
|
containerIconElement.src = identity.iconUrl;
|
||||||
|
containerIconElement.alt = identity.icon;
|
||||||
|
containerIconElement.style.fill = identity.colorCode;
|
||||||
|
var containerLabelElement = document.createElement("label");
|
||||||
|
containerLabelElement.textContent = identity.name;
|
||||||
|
containerButtonElement.appendChild(containerIconElement);
|
||||||
|
containerButtonElement.appendChild(containerLabelElement);
|
||||||
|
redirectFormElement.appendChild(containerButtonElement);
|
||||||
|
})
|
||||||
|
|
||||||
|
document.querySelectorAll("[data-message-id]").forEach(el => {
|
||||||
|
const elementData = el.dataset;
|
||||||
|
el.textContent = browser.i18n.getMessage(elementData.messageId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendFavicon(pageUrl, redirectUrlElement) {
|
||||||
|
const origin = new URL(pageUrl).origin;
|
||||||
|
const favIconElement = Utils.createFavIconElement(`${origin}/favicon.ico`);
|
||||||
|
|
||||||
|
redirectUrlElement.prepend(favIconElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentTab() {
|
||||||
|
return browser.tabs.query({
|
||||||
|
active: true,
|
||||||
|
windowId: browser.windows.WINDOW_ID_CURRENT
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
load();
|
||||||
|
|
||||||
|
function selectContainer(redirectUrl, identity){
|
||||||
|
const neverAsk = document.getElementById("never-ask").checked;
|
||||||
|
if (neverAsk) {
|
||||||
|
assignContainer(redirectUrl, identity);
|
||||||
|
}
|
||||||
|
openInContainer(redirectUrl, identity.cookieStoreId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openInContainer(redirectUrl, cookieStoreId) {
|
||||||
|
const tab = await getCurrentTab();
|
||||||
|
await browser.tabs.create({
|
||||||
|
index: tab[0].index + 1,
|
||||||
|
cookieStoreId,
|
||||||
|
url: redirectUrl
|
||||||
|
});
|
||||||
|
if (tab.length > 0) {
|
||||||
|
browser.tabs.remove(tab[0].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function assignContainer(redirectUrl, identity) {
|
||||||
|
const currentTab = await Utils.currentTab();
|
||||||
|
const assignedUserContextId = Utils.userContextId(identity.cookieStoreId);
|
||||||
|
await Utils.setOrRemoveAssignment(
|
||||||
|
null,
|
||||||
|
redirectUrl,
|
||||||
|
assignedUserContextId,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
|
@ -57,6 +57,11 @@
|
||||||
<span class="bold" data-i18n-message-id="replaceTab"></span>
|
<span class="bold" data-i18n-message-id="replaceTab"></span>
|
||||||
</label>
|
</label>
|
||||||
<p><em data-i18n-message-id="replaceTabDescription"></em></p>
|
<p><em data-i18n-message-id="replaceTabDescription"></em></p>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="containerPromptCheck">
|
||||||
|
<span class="bold" data-i18n-message-id="containerPrompt"></span>
|
||||||
|
</label>
|
||||||
|
<p><em data-i18n-message-id="containerPromptDescription"></em></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
32
src/select-page.html
Normal file
32
src/select-page.html
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
<title data-i18n-message-id="confirmNavigationTitle"></title>
|
||||||
|
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="chrome://browser/skin/aboutNetError.css" type="text/css" media="all" />
|
||||||
|
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="chrome://global/skin/aboutNetError.css" type="text/css" media="all" />
|
||||||
|
<script type="text/javascript" src="./js/i18n.js"></script>
|
||||||
|
<link rel="stylesheet" href="/css/select-page.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<div class="title">
|
||||||
|
<h1 class="title-text" data-i18n-message-id="whichContainerDoYouWantToUse"></h1>
|
||||||
|
</div>
|
||||||
|
<form id="redirect-form">
|
||||||
|
<p data-message-id="noAssociatedContainer"></p>
|
||||||
|
<div id="redirect-url"></div>
|
||||||
|
<p data-i18n-message-id="whichContainerDoYouWantToOpen"></p>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<label for="never-ask" class="check-label">
|
||||||
|
<input id="never-ask" type="checkbox" />
|
||||||
|
<span data-i18n-message-id="rememberMyDecision"></span>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<div id="redirect-identities"></div>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
<script src="js/utils.js"></script>
|
||||||
|
<script src="js/select-page.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Reference in a new issue