Merge branch 'main' into backup-restore-containers

This commit is contained in:
Minigugus 2022-06-06 19:52:20 +02:00 committed by GitHub
commit 84f197dbd1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 746 additions and 511 deletions

View file

@ -19,6 +19,7 @@ module.exports = {
"OS": true, "OS": true,
"ADDON_UNINSTALL": true, "ADDON_UNINSTALL": true,
"ADDON_DISABLE": true, "ADDON_DISABLE": true,
"CONTAINER_ORDER_STORAGE_KEY": true,
"proxifiedContainers": true, "proxifiedContainers": true,
"MozillaVPN": true, "MozillaVPN": true,
"MozillaVPN_Background": true "MozillaVPN_Background": true

View file

@ -1,27 +0,0 @@
<!--
Feel free to ignore this Issue template if you just want to ask or suggest something. If you experience an Issue then please provide all asked information.
Also please make sure that:
- "Firefox will: Never remember history" in the Firefox Preferences/Options under "Privacy & Security > History" is NOT selected
- You are NOT using Firefox in a Private Window
- You can see a grayed out but ticked Checkbox with the description "Enable Container Tabs" in the Firefox Preferences/Options under "Tabs"
-->
- Multi-Account Containers Version:
- Operating System + Version:
- Firefox Version:
- Other installed Add-ons + Version + Enabled/Disabled-Status:
<!-- To be able to copy & paste the full list of your Add-ons navigate to "about:support" and scroll down to "Extensions" -->
### Actual behavior
### Expected behavior
### Steps to reproduce
1.
2.
3.
### Notes

53
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View file

@ -0,0 +1,53 @@
name: Bug Report
description: Report a problem in Multi-Account Containers
labels: [bug]
body:
- type: checkboxes
id: before-bug-report
attributes:
label: Before submitting a bug report
options:
- label: "I updated to the latest version of Multi-Account Container and tested if I can reproduce the issue"
required: true
- label: "I searched for existing reports to see if it hasn\'t already been reported"
required: true
- type: textarea
id: about_support
attributes:
label: "Provide a copy of Troubleshooting Information page"
description: "To get a copy of the Troubleshooting Information page, type *about:support* in the address bar and click on the *Copy text to clipboard* button."
validations:
required: true
- type: textarea
id: step_to_reproduce
attributes:
label: "Step to reproduce"
description: "Provide a list of steps you did to trigger this bug"
placeholder: |
1. I opened ...
2. I clicked on ...
3. ...
validations:
required: true
- type: textarea
id: actual_behavior
attributes:
label: "Actual behavior"
description: "Provide a description of what is currently happening"
validations:
required: true
- type: textarea
id: expected_behavior
attributes:
label: "Expected behavior"
description: "Provide a description of what should happen"
validations:
required: true
- type: textarea
id: additional_informations
attributes:
label: "Additional informations"
description: "Provide any other information revelant to this issue"
validations:
required: false

17
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1,17 @@
blank_issues_enabled: false
contact_links:
- name: "Explore our help articles"
url: "https://support.mozilla.org/kb/containers"
about: "Dig into the knowledge base, tips and tricks, troubleshooting, and so much more."
- name: "Ask a support question"
url: "https://support.mozilla.org/questions/new/desktop/form"
about: "Get support from our contributors or staff members."
- name: "Submit new ideas"
url: "https://connect.mozilla.org/t5/discussions/how-to-submit-a-great-idea-in-five-easy-steps/td-p/24"
about: "Have an idea for a new product feature? Share it with our community and staff members!"
- name: "Discussions"
url: "https://connect.mozilla.org/t5/discussions/bd-p/discussions"
about: "Give feedback and participate in meaningful conversations with the community and Mozilla employees"
- name: "Discover more awesome tools"
url: "https://www.mozilla.org/firefox/products/"
about: "Learn more about other products from Mozilla"

View file

@ -9,16 +9,16 @@ on:
- main - main
- production - production
schedule: schedule:
- cron: '0 2 * * *' # Daily at 2AM UTC - cron: '0 2 * * *' # Daily at 2AM UTC
jobs: jobs:
builds: builds:
name: Builds name: Builds
runs-on: ubuntu-20.04 runs-on: ubuntu-latest
steps: steps:
- name: Clone repository - name: Clone repository
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Create the package - name: Create the package
shell: bash shell: bash
@ -26,7 +26,7 @@ jobs:
./bin/build-addon.sh nightly.xpi ./bin/build-addon.sh nightly.xpi
- name: Uploading - name: Uploading
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v3
with: with:
name: ${{matrix.config.name}} Build name: ${{matrix.config.name}} Build
path: src/web-ext-artifacts path: src/web-ext-artifacts

28
.github/workflows/test.yaml vendored Normal file
View file

@ -0,0 +1,28 @@
name: Test
on:
push:
branches:
- main
- production
pull_request:
branches:
jobs:
test:
name: Run tests
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: Set up node
uses: actions/setup-node@v3
with:
node-version: lts/*
- name: Install dependencies
run: npm install --legacy-peer-deps
- name: Run tests
run: npm run test

View file

@ -1,10 +0,0 @@
language: node_js
node_js:
- "lts/*"
notifications:
irc:
- "ircs://irc.mozilla.org:6697/#testpilot-containers-bots"
install:
- npm install --legacy-peer-deps

View file

@ -1,10 +1,12 @@
# Multi-Account Containers # Multi-Account Containers
[![Test](https://github.com/mozilla/multi-account-containers/actions/workflows/test.yaml/badge.svg)](https://github.com/mozilla/multi-account-containers/actions/workflows/test.yaml)
The Firefox Multi-Account Containers extension lets you carve out a separate box for each of your online lives no more opening a different browser just to check your work email! [Learn More Here](https://blog.mozilla.org/firefox/introducing-firefox-multi-account-containers/) The Firefox Multi-Account Containers extension lets you carve out a separate box for each of your online lives no more opening a different browser just to check your work email! [Learn More Here](https://blog.mozilla.org/firefox/introducing-firefox-multi-account-containers/)
[Available on addons.mozilla.org](https://addons.mozilla.org/firefox/addon/multi-account-containers/) [Available on addons.mozilla.org](https://addons.mozilla.org/firefox/addon/multi-account-containers/)
For more info, see: For more info, see:
* [Test Pilot Product Hypothesis Document](https://docs.google.com/document/d/1WQdHTVXROk7dYkSFluc6_hS44tqZjIrG9I-uPyzevE8/edit#) * [Test Pilot Product Hypothesis Document](https://docs.google.com/document/d/1WQdHTVXROk7dYkSFluc6_hS44tqZjIrG9I-uPyzevE8/edit#)
* [Shield Product Hypothesis Document](https://docs.google.com/document/d/1vMD-fH_5hGDDqNvpRZk12_RhCN2WAe4_yaBamaNdtik/edit#) * [Shield Product Hypothesis Document](https://docs.google.com/document/d/1vMD-fH_5hGDDqNvpRZk12_RhCN2WAe4_yaBamaNdtik/edit#)
@ -13,7 +15,7 @@ For more info, see:
## Requirements ## Requirements
* node 7+ (for jpm) * node 7+ (for jpm)
* Firefox 57+ * Firefox 91.1.0+
## Development ## Development
@ -43,7 +45,7 @@ Here is a [video](https://www.youtube.com/watch?v=cer9EUKegG4) that demonstrates
* Install dependencies: * Install dependencies:
``` ```
npm install npm install --legacy-peer-deps
``` ```
* Run all tests: * Run all tests:

View file

@ -2,7 +2,7 @@
"name": "testpilot-containers", "name": "testpilot-containers",
"title": "Multi-Account Containers", "title": "Multi-Account Containers",
"description": "Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.", "description": "Containers helps you keep all the parts of your online life contained in different tabs. Custom labels and color-coded tabs help keep different activities — like online shopping, travel planning, or checking work email — separate.",
"version": "8.0.4", "version": "8.0.7",
"author": "Andrea Marchesini, Luke Crouch, Lesley Norton, Kendall Werts, Maxx Crawford, Jonathan Kingston", "author": "Andrea Marchesini, Luke Crouch, Lesley Norton, Kendall Werts, Maxx Crawford, Jonathan Kingston",
"bugs": { "bugs": {
"url": "https://github.com/mozilla/multi-account-containers/issues" "url": "https://github.com/mozilla/multi-account-containers/issues"

File diff suppressed because it is too large Load diff

View file

@ -197,12 +197,17 @@ window.assignManager = {
return {}; return {};
} }
// proxyDNS only works for SOCKS proxies
if (["socks", "socks4"].includes(result.proxy.type)) {
result.proxy.proxyDNS = true;
}
if (!result.proxy.mozProxyEnabled) { if (!result.proxy.mozProxyEnabled) {
return [{ ...result.proxy, proxyDNS: true }]; return result.proxy;
} }
// Let's add the isolation key. // Let's add the isolation key.
return [{ ...result.proxy, connectionIsolationKey: "" + MozillaVPN_Background.isolationKey, proxyDNS: true }]; return [{ ...result.proxy, connectionIsolationKey: "" + MozillaVPN_Background.isolationKey }];
}, },
// Before a request is handled by the browser we decide if we should // Before a request is handled by the browser we decide if we should

View file

@ -1,4 +1,9 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const DEFAULT_TAB = "about:newtab"; const DEFAULT_TAB = "about:newtab";
const backgroundLogic = { const backgroundLogic = {
NEW_TAB_PAGES: new Set([ NEW_TAB_PAGES: new Set([
"about:startpage", "about:startpage",
@ -168,7 +173,7 @@ const backgroundLogic = {
if ("isIsolated" in containerState || remove) { if ("isIsolated" in containerState || remove) {
delete containerState.isIsolated; delete containerState.isIsolated;
} else { } else {
containerState.isIsolated = "locked"; containerState.isIsolated = "locked";
} }
return await identityState.storageArea.set(cookieStoreId, containerState); return await identityState.storageArea.set(cookieStoreId, containerState);
} catch (error) { } catch (error) {
@ -381,19 +386,29 @@ const backgroundLogic = {
continue; continue;
} }
const userContextId = backgroundLogic.getUserContextIdFromCookieStoreId(tab.cookieStoreId); if (!map.has(tab.cookieStoreId)) {
if (!map.has(userContextId)) { const userContextId = backgroundLogic.getUserContextIdFromCookieStoreId(tab.cookieStoreId);
map.set(userContextId, []); map.set(tab.cookieStoreId, { order: userContextId, tabs: [] });
} }
map.get(userContextId).push(tab); map.get(tab.cookieStoreId).tabs.push(tab);
}
const containerOrderStorage = await browser.storage.local.get([CONTAINER_ORDER_STORAGE_KEY]);
const containerOrder =
containerOrderStorage && containerOrderStorage[CONTAINER_ORDER_STORAGE_KEY];
if (containerOrder) {
map.forEach((obj, key) => {
obj.order = (key in containerOrder) ? containerOrder[key] : -1;
});
} }
// Let's sort the map. // Let's sort the map.
const sortMap = new Map([...map.entries()].sort((a, b) => a[0] > b[0])); const sortMap = new Map([...map.entries()].sort((a, b) => a[1].order > b[1].order));
// Let's move tabs. // Let's move tabs.
sortMap.forEach(tabs => { sortMap.forEach(obj => {
for (const tab of tabs) { for (const tab of obj.tabs) {
++pos; ++pos;
browser.tabs.move(tab.id, { browser.tabs.move(tab.id, {
windowId: windowObj.id, windowId: windowObj.id,

View file

@ -66,11 +66,11 @@ const MozillaVPN_Background = {
// Handle responses from MozillaVPN client // Handle responses from MozillaVPN client
async handleResponse(response) { async handleResponse(response) {
MozillaVPN_Background._installed = true;
if (response.error && response.error === "vpn-client-down") { if (response.error && response.error === "vpn-client-down") {
MozillaVPN_Background._connected = false; MozillaVPN_Background._connected = false;
return; return;
} }
MozillaVPN_Background._installed = true;
if (response.servers) { if (response.servers) {
const servers = response.servers.countries; const servers = response.servers.countries;
browser.storage.local.set({ [MozillaVPN_Background.MOZILLA_VPN_SERVERS_KEY]: servers}); browser.storage.local.set({ [MozillaVPN_Background.MOZILLA_VPN_SERVERS_KEY]: servers});

View file

@ -103,11 +103,20 @@ async function restoreContainers(event) {
restoreInput.value = ""; restoreInput.value = "";
} }
async function changeTheme(event) {
const theme = event.currentTarget;
await browser.storage.local.set({currentTheme: theme.value});
await browser.storage.local.set({currentThemeId: theme.selectedIndex});
}
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 { 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("#changeTheme").selectedIndex = currentThemeId;
setupContainerShortcutSelects(); setupContainerShortcutSelects();
} }
@ -165,6 +174,8 @@ 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("#containersRestoreInput").addEventListener( "change", restoreContainers); document.querySelector("#containersRestoreInput").addEventListener( "change", restoreContainers);
document.querySelector("#changeTheme").addEventListener( "change", changeTheme);
maybeShowPermissionsWarningIcon(); maybeShowPermissionsWarningIcon();
for (let i=0; i < NUMBER_OF_KEYBOARD_SHORTCUTS; i++) { for (let i=0; i < NUMBER_OF_KEYBOARD_SHORTCUTS; i++) {
document.querySelector("#open_container_"+i) document.querySelector("#open_container_"+i)

View file

@ -32,6 +32,9 @@ async function init() {
list.appendChild(fragment); list.appendChild(fragment);
MozillaVPN.handleContainerList(identities); MozillaVPN.handleContainerList(identities);
// Set the theme
Utils.applyTheme();
} }
init(); init();

View file

@ -10,7 +10,6 @@ const DEFAULT_ICON = "circle";
const NEW_CONTAINER_ID = "new"; const NEW_CONTAINER_ID = "new";
const ONBOARDING_STORAGE_KEY = "onboarding-stage"; const ONBOARDING_STORAGE_KEY = "onboarding-stage";
const CONTAINER_ORDER_STORAGE_KEY = "container-order";
const CONTAINER_DRAG_DATA_TYPE = "firefox-container"; const CONTAINER_DRAG_DATA_TYPE = "firefox-container";
// List of panels // List of panels
@ -52,6 +51,7 @@ async function getExtensionInfo() {
return extensionInfo; return extensionInfo;
} }
// This object controls all the panels, identities and many other things. // This object controls all the panels, identities and many other things.
const Logic = { const Logic = {
_identities: [], _identities: [],
@ -66,6 +66,9 @@ const Logic = {
method: "MozillaVPN_attemptPort" method: "MozillaVPN_attemptPort"
}), }),
// Set the theme
Utils.applyTheme();
// Remove browserAction "upgraded" badge when opening panel // Remove browserAction "upgraded" badge when opening panel
this.clearBrowserActionBadge(); this.clearBrowserActionBadge();
@ -1244,6 +1247,7 @@ Logic.registerPanel(REOPEN_IN_CONTAINER_PICKER, {
if (currentTab.cookieStoreId !== "firefox-default") { if (currentTab.cookieStoreId !== "firefox-default") {
const tr = document.createElement("tr"); const tr = document.createElement("tr");
tr.classList.add("menu-item", "hover-highlight", "keyboard-nav"); tr.classList.add("menu-item", "hover-highlight", "keyboard-nav");
tr.setAttribute("tabindex", "0");
const td = document.createElement("td"); const td = document.createElement("td");
td.innerHTML = Utils.escaped` td.innerHTML = Utils.escaped`
@ -1492,7 +1496,7 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
} else { } else {
MozillaVPN.handleMozillaCtaClick("mac-edit-container-panel-btn"); MozillaVPN.handleMozillaCtaClick("mac-edit-container-panel-btn");
} }
}); });
this.switch.addEventListener("click", async() => { this.switch.addEventListener("click", async() => {
@ -1547,6 +1551,7 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
this.updateProxyDependentUi(proxy); this.updateProxyDependentUi(proxy);
} else { } else {
this.switch.checked = false; this.switch.checked = false;
this.updateProxyDependentUi({});
return; return;
} }
}); });
@ -1677,7 +1682,6 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
this.currentCityName.textContent = proxyInfo.cityName; this.currentCityName.textContent = proxyInfo.cityName;
this.countryCode = proxyInfo.countryCode; this.countryCode = proxyInfo.countryCode;
} }
return;
} }
expandUi() { expandUi() {
@ -1892,6 +1896,7 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
if (proxyPermissionEnabled) { if (proxyPermissionEnabled) {
const proxyData = await proxifiedContainers.retrieve(identity.cookieStoreId); const proxyData = await proxifiedContainers.retrieve(identity.cookieStoreId);
if (proxyData && proxyData.proxy.mozProxyEnabled && !mozillaVpnConnected) { if (proxyData && proxyData.proxy.mozProxyEnabled && !mozillaVpnConnected) {
mozillaVpnUi.updateProxyDependentUi({});
return; return;
} }
const proxy = proxyData ? proxyData.proxy : {}; const proxy = proxyData ? proxyData.proxy : {};
@ -2243,15 +2248,6 @@ Logic.registerPanel(P_CONTAINER_DELETE, {
// Populating the panel: name, icon, and warning message // Populating the panel: name, icon, and warning message
document.getElementById("container-delete-title").textContent = identity.name; document.getElementById("container-delete-title").textContent = identity.name;
const totalNumberOfTabs = identity.numberOfHiddenTabs + identity.numberOfOpenTabs;
let warningMessage = "";
if (totalNumberOfTabs > 0) {
const grammaticalNumTabs = totalNumberOfTabs > 1 ? "tabs" : "tab";
warningMessage = `If you remove this container now, ${totalNumberOfTabs} container ${grammaticalNumTabs} will be closed.`;
}
document.getElementById("delete-container-tab-warning").textContent = warningMessage;
return Promise.resolve(null); return Promise.resolve(null);
}, },
}); });

View file

@ -44,7 +44,7 @@ proxifiedContainers = {
// Parses a proxy description string of the format type://host[:port] or type://username:password@host[:port] (port is optional) // Parses a proxy description string of the format type://host[:port] or type://username:password@host[:port] (port is optional)
parseProxy(proxy_str, mozillaVpnData = null) { parseProxy(proxy_str, mozillaVpnData = null) {
const proxyRegexp = /(?<type>(https?)|(socks4?)):\/\/(\b(?<username>\w+):(?<password>\w+)@)?(?<host>((?:\d{1,3}\.){3}\d{1,3}\b)|(\b([\w.-]+)+))(:(?<port>\d+))?/; const proxyRegexp = /(?<type>(https?)|(socks4?)):\/\/(\b(?<username>[\w-]+):(?<password>[\w-]+)@)?(?<host>((?:\d{1,3}\.){3}\d{1,3}\b)|(\b([\w.-]+)+))(:(?<port>\d+))?/;
const matches = proxyRegexp.exec(proxy_str); const matches = proxyRegexp.exec(proxy_str);
if (!matches) { if (!matches) {
return false; return false;

View file

@ -2,6 +2,9 @@
const DEFAULT_FAVICON = "/img/blank-favicon.svg"; const DEFAULT_FAVICON = "/img/blank-favicon.svg";
// eslint-disable-next-line
const CONTAINER_ORDER_STORAGE_KEY = "container-order";
// TODO use export here instead of globals // TODO use export here instead of globals
const Utils = { const Utils = {
@ -166,6 +169,26 @@ const Utils = {
false false
); );
}, },
/* Theme helper
*
* First, we look if there's a theme already set in the local storage. If
* there isn't one, we set the theme based on `prefers-color-scheme`.
* */
getTheme(currentTheme, window) {
if (typeof currentTheme !== "undefined" && currentTheme !== "auto") {
return currentTheme;
}
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
return "dark";
}
return "light";
},
async applyTheme() {
const { currentTheme } = await browser.storage.local.get("currentTheme");
const popup = document.getElementsByTagName("html")[0];
const theme = Utils.getTheme(currentTheme, window);
popup.setAttribute("data-theme", theme);
}
}; };
window.Utils = Utils; window.Utils = Utils;

View file

@ -1,7 +1,7 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "Firefox Multi-Account Containers", "name": "Firefox Multi-Account Containers",
"version": "8.0.4", "version": "8.0.7",
"incognito": "not_allowed", "incognito": "not_allowed",
"description": "__MSG_extensionDescription__", "description": "__MSG_extensionDescription__",
"icons": { "icons": {

View file

@ -77,6 +77,24 @@
</fieldset> </fieldset>
</div> </div>
<!--
TODO
- Add data-i18n
-->
<h3 data-i18n-message-id="theme"></h3>
<p><label class="keyboard-shortcut">
<span data-i18n-message-id="chooseTheme"></span>
<select id="changeTheme" name="changeTheme">
<option value="auto" selected data-i18n-message-id="themeAuto">
</option>
<option value="light" data-i18n-message-id="themeLight">
</option>
<option value="dark" data-i18n-message-id="themeDark">
</option>
</select>
</label></p>
<h3 data-i18n-message-id="keyboardShortCuts"></h3> <h3 data-i18n-message-id="keyboardShortCuts"></h3>
<p><em data-i18n-message-id="editWhichContainer"></em></p> <p><em data-i18n-message-id="editWhichContainer"></em></p>

View file

@ -1,4 +1,4 @@
<html> <html data-theme="auto">
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Multi-Account Containers</title> <title>Multi-Account Containers</title>
@ -251,7 +251,7 @@
</table> </table>
</div> </div>
<v-padding-hack-footer></v-padding-hack-footer> <v-padding-hack-footer></v-padding-hack-footer>
<div class="bottom-btn keyboard-nav hover-highlight" id="manage-container-link" tabindex="0" data-i18n-message-id="manageThisContainer"></div> <div class="bottom-btn keyboard-nav hover-highlight controller" id="manage-container-link" tabindex="0" data-i18n-message-id="manageThisContainer"></div>
</div> </div>
@ -299,7 +299,7 @@
<legend class="form-header" data-i18n-message-id="icon"></legend> <legend class="form-header" data-i18n-message-id="icon"></legend>
</fieldset> </fieldset>
<fieldset class="proxies"> <!---- PROXIES --> <fieldset class="proxies"> <!---- PROXIES -->
<input type="text" class="proxies" name="container-proxy" id="edit-container-panel-proxy" maxlength="50" placeholder="type://host:port" hidden/> <input type="text" class="proxies" name="container-proxy" id="edit-container-panel-proxy" placeholder="type://host:port" hidden/>
<input type="text" class="proxies" name="moz-proxy-enabled" id="moz-proxy-enabled" maxlength="5" hidden/> <input type="text" class="proxies" name="moz-proxy-enabled" id="moz-proxy-enabled" maxlength="5" hidden/>
<input type="text" class="proxies" name="country-code" id="country-code-input" maxlength="5" hidden/> <input type="text" class="proxies" name="country-code" id="country-code-input" maxlength="5" hidden/>
<input type="text" class="proxies" name="city-name" id="city-name-input" maxlength="5" hidden/> <input type="text" class="proxies" name="city-name" id="city-name-input" maxlength="5" hidden/>
@ -342,10 +342,11 @@
</button> </button>
</div> </div>
</moz-vpn-container-ui> </moz-vpn-container-ui>
<button id="advanced-proxy-settings-btn" class="proxy-section advanced-proxy-settings-btn controller"> <button id="advanced-proxy-settings-btn" class="proxy-section advanced-proxy-settings-btn">
<span class="advanced-proxy-settings-btn-label" data-i18n-message-id="advancedProxySettings"></span> <span class="advanced-proxy-settings-btn-label" data-i18n-message-id="advancedProxySettings"></span>
<span id="advanced-proxy-address"></span> <span id="advanced-proxy-address"></span>
</button> </button>
<hr>
<button class="delete-container delete-btn alert-text" id="delete-container-button" data-i18n-message-id="deleteThisContainer"></button> <button class="delete-container delete-btn alert-text" id="delete-container-button" data-i18n-message-id="deleteThisContainer"></button>
<!-- TODO get UX / CONTENT on how to message about unavailable proxies --> <!-- TODO get UX / CONTENT on how to message about unavailable proxies -->
@ -394,7 +395,6 @@
<hr> <hr>
<div class="panel-content delete-container-confirm"> <div class="panel-content delete-container-confirm">
<h4 class="delete-container-confirm-title" data-i18n-message-id="removeThisContainer"></h4> <h4 class="delete-container-confirm-title" data-i18n-message-id="removeThisContainer"></h4>
<p class="delete-warning" id="delete-container-tab-warning"></p>
<p class="delete-warning" data-i18n-message-id="removeThisContainerConfirmation"></p> <p class="delete-warning" data-i18n-message-id="removeThisContainerConfirmation"></p>
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
@ -441,7 +441,7 @@
<form class="advanced-proxy-panel-content"> <form class="advanced-proxy-panel-content">
<label class="advanced-proxy-input-label" for="container-proxy" data-i18n-message-id="advancedProxySettings"></label> <label class="advanced-proxy-input-label" for="container-proxy" data-i18n-message-id="advancedProxySettings"></label>
<div class="advanced-proxy-input-wrapper"> <div class="advanced-proxy-input-wrapper">
<input id="edit-advanced-proxy-input" class="proxy-host primary-input" name="container-proxy" type="text" maxlength="50" placeholder="type://host:port" /> <input id="edit-advanced-proxy-input" class="proxy-host primary-input" name="container-proxy" type="text" placeholder="type://host:port" />
<button id="clear-advanced-proxy-input" class="controller" data-i18n-attribute="value" data-i18n-attribute-message-id="clearproxylabel"></button> <button id="clear-advanced-proxy-input" class="controller" data-i18n-attribute="value" data-i18n-attribute-message-id="clearproxylabel"></button>
<span class="proxy-validity" data-i18n-message-id="invalidProxyAlert"></span> <span class="proxy-validity" data-i18n-message-id="invalidProxyAlert"></span>
</div> </div>
@ -450,7 +450,7 @@
</form> </form>
<div id="permissions-overlay" class="permissions-overlay" data-tab-group="proxy-disabled"> <div id="permissions-overlay" class="permissions-overlay" data-tab-group="proxy-disabled">
<p data-tab-group="proxy-disabled" data-i18n-message-id="additionalPermissionNeeded"></p> <p data-tab-group="proxy-disabled" data-i18n-message-id="additionalPermissionNeeded"></p>
<button id="enable-proxy-permissions" class="primary-cta" data-tab-group="proxy-disabled">Enable</button> <button id="enable-proxy-permissions" class="primary-cta" data-tab-group="proxy-disabled" data-i18n-message-id="enable"></button>
</div> </div>
</div> </div>
<script src="js/utils.js"></script> <script src="js/utils.js"></script>