From afffa57389dbbcfb6949ed2b361b20669d7abb36 Mon Sep 17 00:00:00 2001 From: Jonathan Kingston Date: Fri, 19 May 2017 16:43:43 +0100 Subject: [PATCH] Adding container assignment exemption on confirm prompt. Fixes #500 --- .stylelintrc | 2 +- webextension/background.js | 45 +++++++++++++---- webextension/confirm-page.html | 11 ++--- webextension/css/confirm-page.css | 40 +++++++++++++-- webextension/js/confirm-page.js | 82 +++++++++++++++++++++++++------ 5 files changed, 146 insertions(+), 34 deletions(-) diff --git a/.stylelintrc b/.stylelintrc index 656873f..cf506c8 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -11,7 +11,7 @@ "declaration-block-no-duplicate-properties": true, "order/declaration-block-properties-alphabetical-order": true, "property-blacklist": [ - "/height/", + "/(min[-]|max[-])height/", "/width/", "/top/", "/bottom/", diff --git a/webextension/background.js b/webextension/background.js index 8f4278c..979c164 100644 --- a/webextension/background.js +++ b/webextension/background.js @@ -70,6 +70,18 @@ const assignManager = { } }, + // We return here so the confirm page can load the tab when exempted + async _exemptTab(m) { + const pageUrl = m.pageUrl; + // If we have existing data and for some reason it hasn't been deleted etc lets update it + const siteSettings = await this.storageArea.get(pageUrl); + if (siteSettings) { + siteSettings.exempted.push(m.tabId); + await this.storageArea.set(pageUrl, siteSettings); + } + return true; + }, + init() { browser.contextMenus.onClicked.addListener((info, tab) => { const userContextId = this.getUserContextIdFromCookieStore(tab); @@ -81,7 +93,8 @@ const assignManager = { actionName = "added"; storageAction = this.storageArea.set(info.pageUrl, { userContextId, - neverAsk: false + neverAsk: false, + exempted: [] }); } else { actionName = "removed"; @@ -117,11 +130,12 @@ const assignManager = { const userContextId = this.getUserContextIdFromCookieStore(tab); if (!siteSettings || userContextId === siteSettings.userContextId - || tab.incognito) { + || tab.incognito + || siteSettings.exempted.includes(tab.id)) { return {}; } - this.reloadPageInContainer(options.url, siteSettings.userContextId, tab.index + 1, siteSettings.neverAsk); + this.reloadPageInContainer(options.url, userContextId, siteSettings.userContextId, tab.index + 1, siteSettings.neverAsk); this.calculateContextMenu(tab); /* Removal of existing tabs: @@ -209,11 +223,12 @@ const assignManager = { } }, - reloadPageInContainer(url, userContextId, index, neverAsk = false) { + reloadPageInContainer(url, currentUserContextId, userContextId, index, neverAsk = false) { + const cookieStoreId = backgroundLogic.cookieStoreId(userContextId); const loadPage = browser.extension.getURL("confirm-page.html"); // If the user has explicitly checked "Never Ask Again" on the warning page we will send them straight there if (neverAsk) { - browser.tabs.create({url, cookieStoreId: backgroundLogic.cookieStoreId(userContextId), index}); + browser.tabs.create({url, cookieStoreId, index}); backgroundLogic.sendTelemetryPayload({ event: "auto-reload-page-in-container", userContextId: userContextId, @@ -223,8 +238,17 @@ const assignManager = { event: "prompt-to-reload-page-in-container", userContextId: userContextId, }); - const confirmUrl = `${loadPage}?url=${url}`; - browser.tabs.create({url: confirmUrl, cookieStoreId: backgroundLogic.cookieStoreId(userContextId), index}).then(() => { + let confirmUrl = `${loadPage}?url=${encodeURIComponent(url)}&cookieStoreId=${cookieStoreId}`; + let currentCookieStoreId; + if (currentUserContextId) { + currentCookieStoreId = backgroundLogic.cookieStoreId(currentUserContextId); + confirmUrl += `¤tCookieStoreId=${currentCookieStoreId}`; + } + browser.tabs.create({ + url: confirmUrl, + cookieStoreId: currentCookieStoreId, + index + }).then(() => { // We don't want to sync this URL ever nor clutter the users history browser.history.deleteUrl({url: confirmUrl}); }).catch((e) => { @@ -354,7 +378,7 @@ const messageHandler = { LAST_CREATED_TAB_TIMER: 2000, init() { - // Handles messages from webextension/js/popup.js + // Handles messages from webextension code browser.runtime.onMessage.addListener((m) => { let response; @@ -372,11 +396,14 @@ const messageHandler = { case "neverAsk": assignManager._neverAsk(m); break; + case "exemptContainerAssignment": + response = assignManager._exemptTab(m); + break; } return response; }); - // Handles messages from index.js + // Handles messages from sdk code const port = browser.runtime.connect(); port.onMessage.addListener(m => { switch (m.type) { diff --git a/webextension/confirm-page.html b/webextension/confirm-page.html index 48e12f9..09d4852 100644 --- a/webextension/confirm-page.html +++ b/webextension/confirm-page.html @@ -8,22 +8,21 @@
-

Should we open this in your container?

+

Open this site in your assigned container?

- Looks like you requested: + You asked Firefox to always open for this site:

-

- You asked Firefox to always open in this type of container. Would you like to proceed?
-

+

Would you still like to open in this current container?




- + +
diff --git a/webextension/css/confirm-page.css b/webextension/css/confirm-page.css index a595e4c..24baa7c 100644 --- a/webextension/css/confirm-page.css +++ b/webextension/css/confirm-page.css @@ -4,11 +4,21 @@ } main { - background: url(/img/onboarding-1.png) no-repeat; + background: url(/img/onboarding-4.png) no-repeat; background-position: -10px -15px; - background-size: 285px; - margin-inline-start: -285px; - padding-inline-start: 285px; + background-size: 300px; + margin-inline-start: -350px; + padding-inline-start: 350px; +} + +.container-name { + font-weight: bold; +} + +button .container-name, +#current-container-name { + font-weight: bold; + text-transform: capitalize; } @media only screen and (max-width: 1300px) { @@ -36,6 +46,28 @@ html { word-break: break-all; } +#redirect-url { + background: #efefef; + 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; +} + +#redirect-url img { + block-size: 16px; + inline-size: 16px; + margin-inline-end: 6px; + offset-block-start: 3px; + position: relative; +} + dfn { font-style: normal; } + +.button-container > button { + min-inline-size: 240px; +} diff --git a/webextension/js/confirm-page.js b/webextension/js/confirm-page.js index d54dd06..5c5038b 100644 --- a/webextension/js/confirm-page.js +++ b/webextension/js/confirm-page.js @@ -1,10 +1,46 @@ -const redirectUrl = new URL(window.location).searchParams.get("url"); -document.getElementById("redirect-url").textContent = redirectUrl; -const redirectSite = new URL(redirectUrl).hostname; -document.getElementById("redirect-site").textContent = redirectSite; +async function load() { + const searchParams = new URL(window.location).searchParams; + const redirectUrl = decodeURIComponent(searchParams.get("url")); + const cookieStoreId = searchParams.get("cookieStoreId"); + const currentCookieStoreId = searchParams.get("currentCookieStoreId"); + const redirectUrlElement = document.getElementById("redirect-url"); + redirectUrlElement.textContent = redirectUrl; + createFavicon(redirectUrl, redirectUrlElement); -document.getElementById("redirect-form").addEventListener("submit", (e) => { - e.preventDefault(); + const container = await browser.contextualIdentities.get(cookieStoreId); + [...document.querySelectorAll(".container-name")].forEach((containerNameElement) => { + containerNameElement.textContent = container.name; + }); + + // If default container, button will default to normal HTML content + if (currentCookieStoreId) { + const currentContainer = await browser.contextualIdentities.get(currentCookieStoreId); + document.getElementById("current-container-name").textContent = currentContainer.name; + } + + document.getElementById("redirect-form").addEventListener("submit", (e) => { + e.preventDefault(); + const buttonTarget = e.explicitOriginalTarget; + switch (buttonTarget.id) { + case "confirm": + confirmSubmit(redirectUrl, cookieStoreId); + break; + case "deny": + denySubmit(redirectUrl); + break; + } + }); +} + +function createFavicon(pageUrl, redirectUrlElement) { + const origin = new URL(pageUrl).origin; + const imageElement = document.createElement("img"); + imageElement.src = `${origin}/favicon.ico`; + + redirectUrlElement.prepend(imageElement); +} + +function confirmSubmit(redirectUrl, cookieStoreId) { const neverAsk = document.getElementById("never-ask").checked; // Sending neverAsk message to background to store for next time we see this process if (neverAsk) { @@ -12,20 +48,38 @@ document.getElementById("redirect-form").addEventListener("submit", (e) => { method: "neverAsk", neverAsk: true, pageUrl: redirectUrl - }).then(() => { - redirect(); - }).catch(() => { - // Can't really do much here user will have to click it again }); } browser.runtime.sendMessage({ method: "sendTelemetryPayload", event: "click-to-reload-page-in-container", }); - redirect(); -}); + openInContainer(redirectUrl, cookieStoreId); +} -function redirect() { - const redirectUrl = document.getElementById("redirect-url").textContent; +async function denySubmit(redirectUrl) { + const tab = await browser.tabs.query({active: true}); + await browser.runtime.sendMessage({ + method: "exemptContainerAssignment", + tabId: tab[0].id, + pageUrl: redirectUrl + }); document.location.replace(redirectUrl); } + +load(); + +async function openInContainer(redirectUrl, cookieStoreId) { + const tabs = await browser.tabs.query({active: true}); + browser.runtime.sendMessage({ + method: "sendTelemetryPayload", + event: "click-to-reload-page-in-same-container", + }); + await browser.tabs.create({ + cookieStoreId, + url: redirectUrl + }); + if (tabs.length > 0) { + browser.tabs.remove(tabs[0].id); + } +}