Merge pull request #2225 from mozilla/make-proxy/nativeMessaging-optional
Make proxy & nativeMessaging permissions optional
This commit is contained in:
commit
4651126fc1
16 changed files with 574 additions and 178 deletions
|
@ -5,3 +5,6 @@ node_js:
|
|||
notifications:
|
||||
irc:
|
||||
- "ircs://irc.mozilla.org:6697/#testpilot-containers-bots"
|
||||
|
||||
install:
|
||||
- npm install --legacy-peer-deps
|
||||
|
|
|
@ -11,7 +11,7 @@ git submodule init || die
|
|||
git submodule update --remote --depth 1 src/_locales || die
|
||||
|
||||
print Y "Installing dependencies..."
|
||||
npm install || die
|
||||
npm install --legacy-peer-deps || die
|
||||
|
||||
print Y "Running tests..."
|
||||
npm test
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"addons-linter": "^1.3.2",
|
||||
"addons-linter": "^3.23.0",
|
||||
"ajv": "^6.6.3",
|
||||
"chai": "^4.2.0",
|
||||
"eslint": "^6.6.0",
|
||||
"eslint-plugin-no-unsanitized": "^2.0.0",
|
||||
"eslint-plugin-promise": "^3.4.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-no-unsanitized": "^4.0.0",
|
||||
"eslint-plugin-promise": "^5.2.0",
|
||||
"htmllint-cli": "0.0.7",
|
||||
"json": ">=10.0.0",
|
||||
"mocha": "^6.2.2",
|
||||
|
|
|
@ -1,29 +1,122 @@
|
|||
body {
|
||||
background: #fff;
|
||||
color: #202023;
|
||||
}
|
||||
--grey10: #e7e7e7;
|
||||
|
||||
h3 {
|
||||
margin-block-start: 2.5rem;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
background: #fff;
|
||||
color: rgb(74, 74, 79);
|
||||
font-size: 13px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
h3:first-of-type {
|
||||
margin-block-start: 1rem;
|
||||
margin-block-start: 2.5rem;
|
||||
}
|
||||
|
||||
p,
|
||||
label {
|
||||
color: rgb(74, 74, 79);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
label > span {
|
||||
padding-inline-end: 4px;
|
||||
}
|
||||
|
||||
.settings-group {
|
||||
margin-block-end: 16px;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
|
||||
.settings-group p {
|
||||
margin-inline-start: 24px;
|
||||
margin-block: 4px 8px;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
margin-inline: 0 8px;
|
||||
margin-block: 1px auto;
|
||||
inline-size: 16px;
|
||||
block-size: 16px;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-inline: 0 auto;
|
||||
}
|
||||
|
||||
.keyboard-shortcut {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
max-inline-size: 70%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.moz-vpn-proxy-permissions {
|
||||
margin-block: 0 2rem;
|
||||
padding-block-end: 1rem;
|
||||
border-block-end: 1px solid var(--grey10);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
h3.moz-vpn-proxy-permissions-title {
|
||||
margin-block-start: 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.warning-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.warning-icon.show-warning::before {
|
||||
background-image: url("/img/warning.svg");
|
||||
background-size: 24px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
content: "";
|
||||
display: block;
|
||||
block-size: 24px;
|
||||
inline-size: 24px;
|
||||
margin-inline-end: 0.5rem;
|
||||
}
|
||||
|
||||
.moz-vpn-proxy-permissions-title::before,
|
||||
.moz-vpn-proxy-permissions-title::after {
|
||||
background-color: var(--grey10);
|
||||
content: "";
|
||||
height: 1px;
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
|
||||
h3.moz-vpn-proxy-permissions-title::before {
|
||||
margin-inline-end: 2rem;
|
||||
margin-inline-start: -50%;
|
||||
}
|
||||
|
||||
h3.moz-vpn-proxy-permissions-title::after {
|
||||
margin-inline-start: 2rem;
|
||||
margin-inline-end: -50%;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background: #202023;
|
||||
background: #23212a;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
p,
|
||||
label {
|
||||
p {
|
||||
color: rgb(177, 177, 179);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -445,6 +445,7 @@ input:checked + .slider::before {
|
|||
/* Primary CTA Buttons */
|
||||
|
||||
.primary-cta {
|
||||
block-size: 32px;
|
||||
background-color: var(--primaryCtaDefault);
|
||||
border: transparent;
|
||||
border-radius: 4px;
|
||||
|
@ -481,10 +482,6 @@ input:checked + .slider::before {
|
|||
transition: opacity 0.1s ease-in-out, max-height 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
#moz-vpn-tout.disappear {
|
||||
animation: hideTout 0.2s ease-in forwards;
|
||||
}
|
||||
|
||||
@keyframes appear {
|
||||
0% {
|
||||
opacity: 0;
|
||||
|
@ -497,22 +494,6 @@ input:checked + .slider::before {
|
|||
}
|
||||
}
|
||||
|
||||
@keyframes hideTout {
|
||||
0% {
|
||||
transform: translateY(0%);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(20%);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mozilla VPN Controller UI in Container Management Panel */
|
||||
|
||||
.moz-vpn-content,
|
||||
|
@ -522,9 +503,6 @@ input:checked + .slider::before {
|
|||
flex-direction: column;
|
||||
padding-block: 16px;
|
||||
transition: max-height 0.3s ease-in-out, padding-block-end 0.2s ease-in-out;
|
||||
|
||||
/* max-block-size: 56px; */
|
||||
min-block-size: 56px;
|
||||
box-shadow: 0 0 0 1px var(--hr-grey);
|
||||
}
|
||||
|
||||
|
@ -610,7 +588,8 @@ input.proxies {
|
|||
|
||||
.moz-vpn-cta {
|
||||
block-size: 32px;
|
||||
margin-block: 16px;
|
||||
margin-block-start: 16px;
|
||||
margin-block-end: 4px;
|
||||
margin-inline: var(--marginInline);
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -685,6 +664,7 @@ input.proxies {
|
|||
max-block-size: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
display: none;
|
||||
background-color: var(--bgColor);
|
||||
transition: max-height 0.2s ease-in-out, opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
|
||||
}
|
||||
|
@ -713,6 +693,7 @@ input.proxies {
|
|||
}
|
||||
|
||||
.expanded .collapsible-content {
|
||||
display: flex;
|
||||
max-block-size: 500px;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
|
@ -1337,6 +1318,44 @@ input[type=text] {
|
|||
min-block-size: 360px;
|
||||
}
|
||||
|
||||
.panel.onboarding-panel-8.optional-permissions-disabled {
|
||||
min-block-size: 420px;
|
||||
margin-block-end: 0;
|
||||
margin-inline: 0;
|
||||
}
|
||||
|
||||
.optional-permissions-disabled #moz-vpn-fw-onboarding-done {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.moz-vpn-permissions {
|
||||
padding-block: var(--marginInline);
|
||||
padding-inline: var(--marginInline);
|
||||
background-color: #cececf1c;
|
||||
border-block-start: 1px solid var(--hr-grey);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.optional-permissions-disabled .moz-vpn-permissions {
|
||||
display: block;
|
||||
inline-size: 100%;
|
||||
}
|
||||
|
||||
.moz-vpn-onboarding-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-inline: var(--marginInline);
|
||||
padding-block-end: var(--marginInline);
|
||||
}
|
||||
|
||||
.moz-vpn-permissions-copy {
|
||||
padding-inline: 20px;
|
||||
font-size: 12px;
|
||||
margin-block-end: 16px;
|
||||
}
|
||||
|
||||
.panel-content {
|
||||
flex: 1;
|
||||
padding-block-start: 16px;
|
||||
|
@ -1363,8 +1382,7 @@ input[type=text] {
|
|||
.onboarding-title {
|
||||
color: #43484e;
|
||||
font-size: var(--font-size-heading);
|
||||
margin-block-end: 0;
|
||||
margin-block-start: 0;
|
||||
margin-block: 12px;
|
||||
margin-inline-end: 0;
|
||||
margin-inline-start: 0;
|
||||
max-inline-size: 80%;
|
||||
|
@ -1518,9 +1536,7 @@ manage things like container crud */
|
|||
/* Panel footer */
|
||||
.panel-footer {
|
||||
align-items: center;
|
||||
background: #efefef;
|
||||
block-size: var(--footerHeight);
|
||||
border-block-end: 1px solid #d8d8d8;
|
||||
color: #000;
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
|
@ -1994,6 +2010,24 @@ input {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.info-icon-alert::after {
|
||||
block-size: 12px;
|
||||
inline-size: 12px;
|
||||
background-color: var(--alertColor);
|
||||
content: "1";
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
inset-block: -5px;
|
||||
inset-inline-end: -6px;
|
||||
box-shadow: 0 0 1px #00000075;
|
||||
font-size: 8px;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.delete-warning {
|
||||
padding-block-end: 8px;
|
||||
padding-block-start: 8px;
|
||||
|
@ -2031,6 +2065,36 @@ tr:hover > td > .trash-button {
|
|||
margin-inline-start: 8px;
|
||||
}
|
||||
|
||||
/* ----- Permissions Overlay ---------- */
|
||||
|
||||
#advanced-proxy-settings-panel,
|
||||
.advanced-proxy-panel-content {
|
||||
position: absolute;
|
||||
inset-block: 0;
|
||||
inset-inline: 0;
|
||||
}
|
||||
|
||||
.permissions-overlay {
|
||||
position: absolute;
|
||||
inset-inline: 0 0;
|
||||
inset-block-start: 40px;
|
||||
inset-block-end: 0;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
flex-direction: column;
|
||||
background-color: white;
|
||||
padding-block: 2.25rem;
|
||||
padding-inline: 2.25rem;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#enable-proxy-permissions {
|
||||
text-align: center;
|
||||
font-family: var(--fontMetropolis);
|
||||
font-size: 14px;
|
||||
margin-block-start: 1rem;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--iconCloseX: url("/img/close-light.svg");
|
||||
|
@ -2061,6 +2125,10 @@ tr:hover > td > .trash-button {
|
|||
--text-grey: #fefffe;
|
||||
}
|
||||
|
||||
.permissions-overlay {
|
||||
background-color: #494755;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background-color: var(--controllerActive);
|
||||
}
|
||||
|
@ -2069,6 +2137,10 @@ tr:hover > td > .trash-button {
|
|||
box-shadow: 0 0 21px 3px #323139;
|
||||
}
|
||||
|
||||
.moz-vpn-permissions {
|
||||
background-color: #322f3e;
|
||||
}
|
||||
|
||||
.blue-link {
|
||||
color: #36abfc;
|
||||
}
|
||||
|
@ -2152,10 +2224,6 @@ tr:hover > td > .trash-button {
|
|||
background-color: #676767;
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
border-block-end: solid 1px #4a4a4a;
|
||||
}
|
||||
|
||||
input[type="text"]:focus {
|
||||
box-shadow: 0 0 0 3px var(--blue50);
|
||||
border-color: var(--blue30);
|
||||
|
|
3
src/img/warning.svg
Normal file
3
src/img/warning.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18.6929 16.0119L13.7399 6.10586C13.5739 5.77358 13.3185 5.49411 13.0025 5.29878C12.6866 5.10346 12.3224 5 11.9509 5C11.5795 5 11.2153 5.10346 10.8993 5.29878C10.5834 5.49411 10.328 5.77358 10.1619 6.10586L5.20894 16.0159C5.0575 16.3206 4.98633 16.659 5.00217 16.999C5.01801 17.3389 5.12033 17.6692 5.29946 17.9586C5.47858 18.2479 5.72858 18.4868 6.0258 18.6526C6.32302 18.8183 6.65762 18.9055 6.99794 18.9059H16.9029C17.2439 18.906 17.5792 18.819 17.8771 18.6531C18.1749 18.4872 18.4255 18.2479 18.6048 17.9579C18.7842 17.668 18.8864 17.337 18.9018 16.9964C18.9172 16.6557 18.8453 16.3169 18.6929 16.0119V16.0119ZM10.9509 8.90586C10.9509 8.64065 11.0563 8.38629 11.2438 8.19876C11.4314 8.01122 11.6857 7.90586 11.9509 7.90586C12.2162 7.90586 12.4705 8.01122 12.658 8.19876C12.8456 8.38629 12.9509 8.64065 12.9509 8.90586V12.9059C12.9509 13.1711 12.8456 13.4254 12.658 13.613C12.4705 13.8005 12.2162 13.9059 11.9509 13.9059C11.6857 13.9059 11.4314 13.8005 11.2438 13.613C11.0563 13.4254 10.9509 13.1711 10.9509 12.9059V8.90586ZM11.9509 17.1559C11.7037 17.1559 11.462 17.0826 11.2565 16.9452C11.0509 16.8078 10.8907 16.6126 10.7961 16.3842C10.7015 16.1558 10.6767 15.9045 10.725 15.662C10.7732 15.4195 10.8922 15.1968 11.0671 15.022C11.2419 14.8472 11.4646 14.7281 11.7071 14.6799C11.9496 14.6317 12.2009 14.6564 12.4293 14.751C12.6577 14.8456 12.8529 15.0058 12.9903 15.2114C13.1276 15.417 13.2009 15.6586 13.2009 15.9059C13.2009 16.2374 13.0692 16.5553 12.8348 16.7897C12.6004 17.0242 12.2825 17.1559 11.9509 17.1559V17.1559Z" fill="#FF4F5E" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -382,6 +382,12 @@ window.assignManager = {
|
|||
return currentContainerState && currentContainerState.isIsolated;
|
||||
},
|
||||
|
||||
maybeAddProxyListeners() {
|
||||
if (browser.proxy) {
|
||||
browser.proxy.onRequest.addListener(this.handleProxifiedRequest, {urls: ["<all_urls>"]});
|
||||
}
|
||||
},
|
||||
|
||||
init() {
|
||||
browser.contextMenus.onClicked.addListener((info, tab) => {
|
||||
info.bookmarkId ?
|
||||
|
@ -390,7 +396,7 @@ window.assignManager = {
|
|||
});
|
||||
|
||||
// Before anything happens we decide if the request should be proxified
|
||||
browser.proxy.onRequest.addListener(this.handleProxifiedRequest, {urls: ["<all_urls>"]});
|
||||
this.maybeAddProxyListeners();
|
||||
|
||||
// Before a request is handled by the browser we decide if we should
|
||||
// route through a different container
|
||||
|
|
|
@ -19,6 +19,28 @@ const backgroundLogic = {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
browser.permissions.onAdded.addListener(permissions => this.resetPermissions(permissions));
|
||||
browser.permissions.onRemoved.addListener(permissions => this.resetPermissions(permissions));
|
||||
},
|
||||
|
||||
resetPermissions(permissions) {
|
||||
permissions.permissions.forEach(async permission => {
|
||||
switch (permission) {
|
||||
case "bookmarks":
|
||||
assignManager.resetBookmarksMenuItem();
|
||||
break;
|
||||
|
||||
case "nativeMessaging":
|
||||
await MozillaVPN_Background.removeMozillaVpnProxies();
|
||||
await browser.runtime.reload();
|
||||
break;
|
||||
|
||||
case "proxy":
|
||||
assignManager.maybeAddProxyListeners();
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async getExtensionInfo() {
|
||||
|
|
|
@ -20,9 +20,6 @@ const messageHandler = {
|
|||
case "resetSync":
|
||||
response = sync.resetSync();
|
||||
break;
|
||||
case "resetBookmarksContext":
|
||||
response = assignManager.resetBookmarksMenuItem();
|
||||
break;
|
||||
case "deleteContainer":
|
||||
response = backgroundLogic.deleteContainer(m.message.userContextId);
|
||||
break;
|
||||
|
|
|
@ -100,6 +100,19 @@ const MozillaVPN_Background = {
|
|||
get isolationKey() {
|
||||
return this._isolationKey;
|
||||
},
|
||||
|
||||
async removeMozillaVpnProxies() {
|
||||
const proxies = await proxifiedContainers.retrieveAll();
|
||||
if (!proxies) {
|
||||
return;
|
||||
}
|
||||
for (const proxyObj of proxies) {
|
||||
const { proxy } = proxyObj;
|
||||
if (proxy.countryCode !== undefined) {
|
||||
await proxifiedContainers.delete(proxyObj.cookieStoreId);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
MozillaVPN_Background.init();
|
||||
|
|
|
@ -5,6 +5,11 @@ const MozillaVPN = {
|
|||
const mozillaVpnInstalled = await browser.runtime.sendMessage({ method: "MozillaVPN_getInstallationStatus" });
|
||||
this.handleStatusIndicatorsInContainerLists(mozillaVpnInstalled);
|
||||
|
||||
const permissionsEnabled = await this.bothPermissionsEnabled();
|
||||
if (!permissionsEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const proxies = await this.getProxies(identities);
|
||||
if (Object.keys(proxies).length === 0) {
|
||||
return;
|
||||
|
@ -156,6 +161,10 @@ const MozillaVPN = {
|
|||
};
|
||||
},
|
||||
|
||||
async bothPermissionsEnabled() {
|
||||
return await browser.permissions.contains({ permissions: ["proxy", "nativeMessaging"] });
|
||||
},
|
||||
|
||||
|
||||
async getProxyWarnings(proxyObj) {
|
||||
if (!proxyObj) {
|
||||
|
@ -245,7 +254,7 @@ const MozillaVPN = {
|
|||
randomInteger = (randomInteger - server.weight);
|
||||
}
|
||||
return nextServer;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
window.MozillaVPN = MozillaVPN;
|
||||
|
|
|
@ -1,17 +1,45 @@
|
|||
const NUMBER_OF_KEYBOARD_SHORTCUTS = 10;
|
||||
|
||||
async function requestPermissions() {
|
||||
const checkbox = document.querySelector("#bookmarksPermissions");
|
||||
if (checkbox.checked) {
|
||||
const granted = await browser.permissions.request({permissions: ["bookmarks"]});
|
||||
if (!granted) {
|
||||
checkbox.checked = false;
|
||||
async function setUpCheckBoxes() {
|
||||
document.querySelectorAll("[data-permission-id]").forEach(async(el) => {
|
||||
const permissionId = el.dataset.permissionId;
|
||||
const permissionEnabled = await browser.permissions.contains({ permissions: [permissionId] });
|
||||
el.checked = !!permissionEnabled;
|
||||
});
|
||||
}
|
||||
|
||||
function disablePermissionsInputs() {
|
||||
document.querySelectorAll("[data-permission-id").forEach(el => {
|
||||
el.disabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
function enablePermissionsInputs() {
|
||||
document.querySelectorAll("[data-permission-id").forEach(el => {
|
||||
el.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
document.querySelectorAll("[data-permission-id").forEach(async(el) => {
|
||||
const permissionId = el.dataset.permissionId;
|
||||
el.addEventListener("change", async() => {
|
||||
if (el.checked) {
|
||||
disablePermissionsInputs();
|
||||
const granted = await browser.permissions.request({ permissions: [permissionId] });
|
||||
if (!granted) {
|
||||
el.checked = false;
|
||||
enablePermissionsInputs();
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
await browser.permissions.remove({permissions: ["bookmarks"]});
|
||||
}
|
||||
browser.runtime.sendMessage({ method: "resetBookmarksContext" });
|
||||
await browser.permissions.remove({ permissions: [permissionId] });
|
||||
});
|
||||
});
|
||||
|
||||
async function maybeShowPermissionsWarningIcon() {
|
||||
const bothMozillaVpnPermissionsEnabled = await MozillaVPN.bothPermissionsEnabled();
|
||||
const permissionsWarningEl = document.querySelector(".warning-icon");
|
||||
permissionsWarningEl.classList.toggle("show-warning", !bothMozillaVpnPermissionsEnabled);
|
||||
}
|
||||
|
||||
async function enableDisableSync() {
|
||||
|
@ -26,12 +54,8 @@ async function enableDisableReplaceTab() {
|
|||
}
|
||||
|
||||
async function setupOptions() {
|
||||
const hasPermission = await browser.permissions.contains({permissions: ["bookmarks"]});
|
||||
const { syncEnabled } = await browser.storage.local.get("syncEnabled");
|
||||
const { replaceTabEnabled } = await browser.storage.local.get("replaceTabEnabled");
|
||||
if (hasPermission) {
|
||||
document.querySelector("#bookmarksPermissions").checked = true;
|
||||
}
|
||||
document.querySelector("#syncCheck").checked = !!syncEnabled;
|
||||
document.querySelector("#replaceTabCheck").checked = !!replaceTabEnabled;
|
||||
setupContainerShortcutSelects();
|
||||
|
@ -78,13 +102,36 @@ function resetOnboarding() {
|
|||
browser.storage.local.set({"onboarding-stage": 0});
|
||||
}
|
||||
|
||||
async function resetPermissionsUi() {
|
||||
await maybeShowPermissionsWarningIcon();
|
||||
await setUpCheckBoxes();
|
||||
enablePermissionsInputs();
|
||||
}
|
||||
|
||||
browser.permissions.onAdded.addListener(resetPermissionsUi);
|
||||
browser.permissions.onRemoved.addListener(resetPermissionsUi);
|
||||
|
||||
document.addEventListener("DOMContentLoaded", setupOptions);
|
||||
document.querySelector("#bookmarksPermissions").addEventListener( "change", requestPermissions);
|
||||
document.querySelector("#syncCheck").addEventListener( "change", enableDisableSync);
|
||||
document.querySelector("#replaceTabCheck").addEventListener( "change", enableDisableReplaceTab);
|
||||
document.querySelector("button").addEventListener("click", resetOnboarding);
|
||||
|
||||
maybeShowPermissionsWarningIcon();
|
||||
for (let i=0; i < NUMBER_OF_KEYBOARD_SHORTCUTS; i++) {
|
||||
document.querySelector("#open_container_"+i)
|
||||
.addEventListener("change", storeShortcutChoice);
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelectorAll("[data-btn-id]").forEach(btn => {
|
||||
btn.addEventListener("click", () => {
|
||||
switch (btn.dataset.btnId) {
|
||||
case "reset-onboarding":
|
||||
resetOnboarding();
|
||||
break;
|
||||
case "moz-vpn-learn-more":
|
||||
browser.tabs.create({
|
||||
url: MozillaVPN.attachUtmParameters("https://support.mozilla.org/kb/protect-your-container-tabs-mozilla-vpn", "options-learn-more")
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
resetPermissionsUi();
|
||||
|
|
202
src/js/popup.js
202
src/js/popup.js
|
@ -643,14 +643,29 @@ Logic.registerPanel(P_ONBOARDING_8, {
|
|||
|
||||
// This method is called when the object is registered.
|
||||
initialize() {
|
||||
Utils.addEnterHandler(document.querySelector("#onboarding-done-btn"), async () => {
|
||||
await Logic.setOnboardingStage(8);
|
||||
Logic.showPanel(P_CONTAINERS_LIST);
|
||||
document.querySelectorAll(".onboarding-done").forEach(el => {
|
||||
Utils.addEnterHandler(el, async () => {
|
||||
await Logic.setOnboardingStage(8);
|
||||
Logic.showPanel(P_CONTAINERS_LIST);
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// This method is called when the panel is shown.
|
||||
prepare() {
|
||||
async prepare() {
|
||||
const mozillaVpnPermissionsEnabled = await MozillaVPN.bothPermissionsEnabled();
|
||||
if (!mozillaVpnPermissionsEnabled) {
|
||||
const panel = document.querySelector(".onboarding-panel-8");
|
||||
panel.classList.add("optional-permissions-disabled");
|
||||
|
||||
Utils.addEnterHandler(panel.querySelector("#onboarding-enable-permissions"), async () => {
|
||||
const granted = await browser.permissions.request({ permissions: ["proxy", "nativeMessaging"] });
|
||||
if (granted) {
|
||||
await Logic.setOnboardingStage(8);
|
||||
}
|
||||
});
|
||||
}
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
});
|
||||
|
@ -662,24 +677,7 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
|||
|
||||
// This method is called when the object is registered.
|
||||
async initialize() {
|
||||
const mozillaVpnToutName = "moz-tout-main-panel";
|
||||
|
||||
await browser.runtime.sendMessage({ method: "MozillaVPN_queryStatus" });
|
||||
Utils.addEnterHandler(document.querySelector("#moz-vpn-learn-more"), () => {
|
||||
MozillaVPN.handleMozillaCtaClick("mac-main-panel-btn");
|
||||
window.close();
|
||||
});
|
||||
Utils.addEnterHandler(document.querySelector(".dismiss-moz-vpn-tout"), async() => {
|
||||
const { mozillaVpnHiddenToutsList } = await browser.storage.local.get("mozillaVpnHiddenToutsList");
|
||||
if (typeof(mozillaVpnHiddenToutsList) === "undefined") {
|
||||
await browser.storage.local.set({ "mozillaVpnHiddenToutsList": [] });
|
||||
}
|
||||
document.querySelector("#moz-vpn-tout").classList.add("disappear");
|
||||
mozillaVpnHiddenToutsList.push({
|
||||
name: mozillaVpnToutName
|
||||
});
|
||||
await browser.storage.local.set({ mozillaVpnHiddenToutsList });
|
||||
});
|
||||
Utils.addEnterHandler(document.querySelector("#manage-containers-link"), (e) => {
|
||||
if (!e.target.classList.contains("disable-edit-containers")) {
|
||||
Logic.showPanel(MANAGE_CONTAINERS_PICKER);
|
||||
|
@ -694,9 +692,6 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
|||
Utils.addEnterHandler(document.querySelector("#always-open-in"), () => {
|
||||
Logic.showPanel(ALWAYS_OPEN_IN_PICKER);
|
||||
});
|
||||
Utils.addEnterHandler(document.querySelector("#info-icon"), () => {
|
||||
browser.runtime.openOptionsPage();
|
||||
});
|
||||
Utils.addEnterHandler(document.querySelector("#sort-containers-link"), async () => {
|
||||
try {
|
||||
await browser.runtime.sendMessage({
|
||||
|
@ -708,16 +703,58 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
|||
}
|
||||
});
|
||||
|
||||
const mozillaVpnToutName = "moz-tout-main-panel";
|
||||
const mozillaVpnPermissionsWarningDotName = "moz-permissions-warning-dot";
|
||||
|
||||
let { mozillaVpnHiddenToutsList } = await browser.storage.local.get("mozillaVpnHiddenToutsList");
|
||||
if (typeof(mozillaVpnHiddenToutsList) === "undefined") {
|
||||
await browser.storage.local.set({ "mozillaVpnHiddenToutsList": [] });
|
||||
mozillaVpnHiddenToutsList = [];
|
||||
}
|
||||
|
||||
// Decide whether to show Mozilla VPN tout
|
||||
const mozVpnTout = document.getElementById("moz-vpn-tout");
|
||||
const mozillaVpnInstalled = await browser.runtime.sendMessage({ method: "MozillaVPN_getInstallationStatus" });
|
||||
if (mozillaVpnInstalled) {
|
||||
return mozVpnTout.remove();
|
||||
const mozillaVpnToutShouldBeHidden = mozillaVpnHiddenToutsList.find(tout => tout.name === mozillaVpnToutName);
|
||||
if (mozillaVpnInstalled || mozillaVpnToutShouldBeHidden) {
|
||||
mozVpnTout.remove();
|
||||
}
|
||||
const { mozillaVpnHiddenToutsList } = await browser.storage.local.get("mozillaVpnHiddenToutsList");
|
||||
const mozillaVpnToutShouldBeHidden = mozillaVpnHiddenToutsList && mozillaVpnHiddenToutsList.find(tout => tout.name === mozillaVpnToutName);
|
||||
if (mozillaVpnToutShouldBeHidden) {
|
||||
return mozVpnTout.remove();
|
||||
|
||||
// Add handlers if tout is visible
|
||||
const mozVpnDismissTout = document.querySelector(".dismiss-moz-vpn-tout");
|
||||
if (mozVpnDismissTout) {
|
||||
Utils.addEnterHandler((mozVpnDismissTout), async() => {
|
||||
mozVpnTout.remove();
|
||||
mozillaVpnHiddenToutsList.push({
|
||||
name: mozillaVpnToutName
|
||||
});
|
||||
await browser.storage.local.set({ mozillaVpnHiddenToutsList });
|
||||
});
|
||||
|
||||
Utils.addEnterHandler(document.querySelector("#moz-vpn-learn-more"), () => {
|
||||
MozillaVPN.handleMozillaCtaClick("mac-main-panel-btn");
|
||||
window.close();
|
||||
});
|
||||
}
|
||||
|
||||
// Badge Options icon if both nativeMessaging and/or proxy permissions are disabled
|
||||
const bothMozillaVpnPermissionsEnabled = await MozillaVPN.bothPermissionsEnabled();
|
||||
const warningDotShouldBeHidden = mozillaVpnHiddenToutsList.find(tout => tout.name === mozillaVpnPermissionsWarningDotName);
|
||||
const optionsIcon = document.getElementById("info-icon");
|
||||
if (optionsIcon && !bothMozillaVpnPermissionsEnabled && !warningDotShouldBeHidden) {
|
||||
optionsIcon.classList.add("info-icon-alert");
|
||||
}
|
||||
|
||||
Utils.addEnterHandler((document.querySelector("#info-icon")), async() => {
|
||||
browser.runtime.openOptionsPage();
|
||||
if (!mozillaVpnHiddenToutsList.find(tout => tout.name === mozillaVpnPermissionsWarningDotName)) {
|
||||
optionsIcon.classList.remove("info-icon-alert");
|
||||
mozillaVpnHiddenToutsList.push({
|
||||
name: mozillaVpnPermissionsWarningDotName
|
||||
});
|
||||
}
|
||||
await browser.storage.local.set({ mozillaVpnHiddenToutsList });
|
||||
});
|
||||
},
|
||||
|
||||
unregister() {
|
||||
|
@ -799,7 +836,6 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
|
|||
Utils.addEnterHandler(showPanelButton, () => {
|
||||
Logic.showPanel(P_CONTAINER_INFO, identity);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
const list = document.querySelector("#identities-list");
|
||||
|
@ -1438,18 +1474,25 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
async connectedCallback() {
|
||||
const { mozillaVpnHiddenToutsList } = await browser.storage.local.get("mozillaVpnHiddenToutsList");
|
||||
const mozillaVpnCollapseEditContainerTout = mozillaVpnHiddenToutsList && mozillaVpnHiddenToutsList.find(tout => tout.name === this.toutName);
|
||||
const mozillaVpnInstalled = await browser.runtime.sendMessage({ method: "MozillaVPN_getInstallationStatus" });
|
||||
|
||||
this.hideShowButton.addEventListener("click", this);
|
||||
|
||||
if (mozillaVpnCollapseEditContainerTout) {
|
||||
if (mozillaVpnCollapseEditContainerTout && !mozillaVpnInstalled) {
|
||||
this.collapseUi();
|
||||
}
|
||||
|
||||
// Add listeners
|
||||
if (!this.classList.contains("has-attached-listeners")) {
|
||||
|
||||
this.primaryCta.addEventListener("click", () => {
|
||||
MozillaVPN.handleMozillaCtaClick("mac-edit-container-panel-btn");
|
||||
const bothMozillaVpnPermissionsEnabled = await MozillaVPN.bothPermissionsEnabled();
|
||||
this.primaryCta.addEventListener("click", async() => {
|
||||
if (!bothMozillaVpnPermissionsEnabled && mozillaVpnInstalled) {
|
||||
await browser.permissions.request({ permissions: ["proxy", "nativeMessaging"] });
|
||||
} else {
|
||||
MozillaVPN.handleMozillaCtaClick("mac-edit-container-panel-btn");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
this.switch.addEventListener("click", async() => {
|
||||
|
@ -1502,7 +1545,6 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
await proxifiedContainers.set(id.cookieStoreId, proxy);
|
||||
this.switch.checked = true;
|
||||
this.updateProxyDependentUi(proxy);
|
||||
|
||||
} else {
|
||||
this.switch.checked = false;
|
||||
return;
|
||||
|
@ -1518,24 +1560,35 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
const mozillaVpnInstalled = await browser.runtime.sendMessage({ method: "MozillaVPN_getInstallationStatus" });
|
||||
const mozillaVpnConnected = await browser.runtime.sendMessage({ method: "MozillaVPN_getConnectionStatus" });
|
||||
|
||||
if (!mozillaVpnInstalled) {
|
||||
this.subtitle.textContent = browser.i18n.getMessage("integrateContainers");
|
||||
|
||||
this.hideEls(this.switch, this.switchLabel, this.currentServerButton);
|
||||
this.subtitle.textContent = browser.i18n.getMessage("protectThisContainer");
|
||||
this.primaryCta.addEventListener("click", this);
|
||||
const bothMozillaVpnPermissionsEnabled = await MozillaVPN.bothPermissionsEnabled();
|
||||
|
||||
} else {
|
||||
|
||||
// Mozilla VPN installed...
|
||||
if (mozillaVpnInstalled && !bothMozillaVpnPermissionsEnabled) {
|
||||
this.subtitle.style.flex = "1 1 100%";
|
||||
this.classList.remove("show-server-button");
|
||||
this.subtitle.textContent = browser.i18n.getMessage("additionalPermissionNeeded");
|
||||
this.hideEls(this.hideShowButton, this.switch, this.switchLabel, this.currentServerButton);
|
||||
this.primaryCta.style.display = "block";
|
||||
this.primaryCta.textContent = browser.i18n.getMessage("enable");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mozillaVpnInstalled) {
|
||||
// Hide cta and hide/show button
|
||||
this.hideEls(this.primaryCta, this.hideShowButton);
|
||||
|
||||
// Update subtitle
|
||||
this.subtitle.textContent = mozillaVpnConnected ? browser.i18n.getMessage("useCustomLocation") : browser.i18n.getMessage("mozillaVpnMustBeOn");
|
||||
this.subtitle.style.flex = "1 1 80%";
|
||||
this.currentServerButton.style.display = "flex";
|
||||
}
|
||||
|
||||
if (!mozillaVpnConnected) {
|
||||
if (mozillaVpnConnected) {
|
||||
[this.switchLabel, this.switch].forEach(el => {
|
||||
el.style.display = "inline-block";
|
||||
});
|
||||
} else {
|
||||
this.hideEls(this.switch, this.switchLabel, this.currentServerButton);
|
||||
this.switch.checked = false;
|
||||
}
|
||||
|
@ -1589,10 +1642,8 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
}
|
||||
|
||||
async updateProxyDependentUi(proxyInfo) {
|
||||
const containerHasProxy = typeof(proxyInfo) !== "undefined";
|
||||
|
||||
const mozillaVpnProxyLocationAvailable = (proxy) => {
|
||||
return typeof(proxy.countryCode) !== "undefined" && typeof(proxyInfo.cityName) !== "undefined";
|
||||
return typeof(proxy) !== "undefined" && typeof(proxy.countryCode) !== "undefined" && typeof(proxy.cityName) !== "undefined";
|
||||
};
|
||||
|
||||
const mozillaVpnProxyIsEnabled = (proxy) => {
|
||||
|
@ -1605,7 +1656,7 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
|
||||
const mozillaVpnConnected = await browser.runtime.sendMessage({ method: "MozillaVPN_getConnectionStatus" });
|
||||
if (
|
||||
!containerHasProxy ||
|
||||
!proxyInfo ||
|
||||
!mozillaVpnProxyLocationAvailable(proxyInfo) ||
|
||||
!mozillaVpnConnected
|
||||
) {
|
||||
|
@ -1620,7 +1671,7 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
}
|
||||
|
||||
// Populate inputs and server button with current or previously stored mozilla vpn proxy
|
||||
if(containerHasProxy && mozillaVpnProxyLocationAvailable(proxyInfo)) {
|
||||
if(proxyInfo && mozillaVpnProxyLocationAvailable(proxyInfo)) {
|
||||
this.currentCountryFlag.style.backgroundImage = `url("./img/flags/${proxyInfo.countryCode.toUpperCase()}.png")`;
|
||||
this.currentCountryFlag.style.backgroundImage = proxyInfo.countryCode + ".png";
|
||||
this.currentCityName.textContent = proxyInfo.cityName;
|
||||
|
@ -1631,12 +1682,10 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
|
||||
expandUi() {
|
||||
this.classList.add("expanded");
|
||||
this.style.maxHeight = 500 + "px";
|
||||
}
|
||||
|
||||
collapseUi() {
|
||||
this.classList.remove("expanded");
|
||||
this.style.maxHeight = 56 + "px";
|
||||
}
|
||||
|
||||
hideEls(...els) {
|
||||
|
@ -1673,6 +1722,10 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
customElements.define("moz-vpn-container-ui", MozVpnContainerUi);
|
||||
const mozillaVpnUi = document.querySelector("moz-vpn-container-ui");
|
||||
mozillaVpnUi.updateMozVpnStatusDependentUi();
|
||||
|
||||
browser.permissions.onAdded.addListener(() => { mozillaVpnUi.updateMozVpnStatusDependentUi(); });
|
||||
browser.permissions.onRemoved.addListener(() => { mozillaVpnUi.updateMozVpnStatusDependentUi(); });
|
||||
|
||||
const advancedProxySettingsButton = document.querySelector(".advanced-proxy-settings-btn");
|
||||
Utils.addEnterHandler(advancedProxySettingsButton, () => {
|
||||
Logic.showPanel(P_ADVANCED_PROXY_SETTINGS, this.getEditInProgressIdentity(), false, false);
|
||||
|
@ -1835,23 +1888,22 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
|
|||
return;
|
||||
}
|
||||
|
||||
const proxyData = await proxifiedContainers.retrieve(identity.cookieStoreId);
|
||||
if (proxyData) {
|
||||
if (proxyData.proxy && proxyData.proxy.mozProxyEnabled && !mozillaVpnConnected) {
|
||||
const proxyPermissionEnabled = await browser.permissions.contains({ permissions: ["proxy"] });
|
||||
if (proxyPermissionEnabled) {
|
||||
const proxyData = await proxifiedContainers.retrieve(identity.cookieStoreId);
|
||||
if (proxyData && proxyData.proxy.mozProxyEnabled && !mozillaVpnConnected) {
|
||||
return;
|
||||
}
|
||||
mozillaVpnUi.updateProxyDependentUi(proxyData.proxy);
|
||||
return;
|
||||
const proxy = proxyData ? proxyData.proxy : {};
|
||||
mozillaVpnUi.updateProxyDependentUi(proxy);
|
||||
}
|
||||
|
||||
mozillaVpnUi.updateProxyDependentUi({});
|
||||
},
|
||||
});
|
||||
|
||||
Logic.registerPanel(P_ADVANCED_PROXY_SETTINGS, {
|
||||
panelSelector: "#advanced-proxy-settings-panel",
|
||||
|
||||
initialize(){
|
||||
async initialize() {
|
||||
this._proxyForm = document.querySelector(".advanced-proxy-panel-content");
|
||||
this._advancedProxyInput = this._proxyForm.querySelector("#edit-advanced-proxy-input");
|
||||
const clearAdvancedProxyInput = this._proxyForm.querySelector("#clear-advanced-proxy-input");
|
||||
|
@ -1931,6 +1983,40 @@ Logic.registerPanel(P_ADVANCED_PROXY_SETTINGS, {
|
|||
const identity = Logic.currentIdentity();
|
||||
const advancedProxyInput = document.getElementById("edit-advanced-proxy-input");
|
||||
|
||||
const proxyPermissionEnabled = await browser.permissions.contains({ permissions: ["proxy"] });
|
||||
if (!proxyPermissionEnabled) {
|
||||
|
||||
// Restrict tabbing inside advanced proxy panel to proxy permissions ui
|
||||
const panel = document.getElementById("advanced-proxy-settings-panel");
|
||||
const clickableEls = panel.querySelectorAll("button, a, input");
|
||||
clickableEls.forEach(el => {
|
||||
if (!el.dataset.tabGroup && el.id !== "advanced-proxy-settings-return") {
|
||||
el.setAttribute("tabindex", "-1");
|
||||
el.disabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Show proxy permission overlay
|
||||
const permissionsOverlay = document.getElementById("permissions-overlay");
|
||||
permissionsOverlay.style.display = "flex";
|
||||
|
||||
// Add "enable" button handling
|
||||
const enableProxyPermissionsButton = document.getElementById("enable-proxy-permissions");
|
||||
|
||||
enableProxyPermissionsButton.addEventListener("click", async() => {
|
||||
const granted = await browser.permissions.request({ permissions: ["proxy"] });
|
||||
if (granted) {
|
||||
permissionsOverlay.style.display = "none";
|
||||
// restore normal panel tabbing
|
||||
clickableEls.forEach(el => {
|
||||
el.tabindex = "0";
|
||||
el.disabled = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// reset input
|
||||
const resetProxyInput = () => {
|
||||
if (!advancedProxyInput) {
|
||||
|
|
|
@ -18,16 +18,16 @@
|
|||
"history",
|
||||
"idle",
|
||||
"management",
|
||||
"nativeMessaging",
|
||||
"storage",
|
||||
"unlimitedStorage",
|
||||
"tabs",
|
||||
"webRequestBlocking",
|
||||
"webRequest",
|
||||
"proxy"
|
||||
"webRequest"
|
||||
],
|
||||
"optional_permissions": [
|
||||
"bookmarks"
|
||||
"bookmarks",
|
||||
"nativeMessaging",
|
||||
"proxy"
|
||||
],
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
|
|
|
@ -4,85 +4,119 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="text/javascript" src="./js/i18n.js"></script>
|
||||
<script type="text/javascript" src="./js/mozillaVpn.js"></script>
|
||||
<script type="text/javascript" src="./js/proxified-containers.js"></script>
|
||||
<link rel="stylesheet" href="css/options.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form>
|
||||
<h3 data-i18n-message-id="optionalPermissions"></h3>
|
||||
<label >
|
||||
<input type="checkbox" id="bookmarksPermissions">
|
||||
<span data-i18n-message-id="enableBookMarkMenus"></span>
|
||||
|
||||
</label>
|
||||
<p><em data-i18n-message-id="enableBookMarkMenusDescription"></em></p>
|
||||
<div class="settings-group">
|
||||
<label class="permission">
|
||||
<input type="checkbox" data-permission-id="bookmarks" id="bookmarksPermissions">
|
||||
<span class="bold" data-i18n-message-id="enableBookMarkMenus"></span>
|
||||
</label>
|
||||
<p><em data-i18n-message-id="enableBookMarkMenusDescription"></em></p>
|
||||
</div>
|
||||
<div id="moz-vpn-proxy-permissions" class="moz-vpn-proxy-permissions">
|
||||
<h3 class="moz-vpn-proxy-permissions-title">
|
||||
<span data-i18n-message-id="mozillaVpnAndProxyPermissionsTitle" class="warning-icon"></span>
|
||||
</h3>
|
||||
<div class="moz-vpn-proxy-permissions-content">
|
||||
<div class="settings-group">
|
||||
<label class="permission">
|
||||
<input type="checkbox" data-permission-id="nativeMessaging">
|
||||
<span class="bold" data-i18n-message-id="nativeMessagingPermissionTitle"></span>
|
||||
</label>
|
||||
<p><em data-i18n-message-id="nativeMessagingPermissionDescription"></em></p>
|
||||
</div>
|
||||
<div class="settings-group">
|
||||
<label class="permission">
|
||||
<input type="checkbox" data-permission-id="proxy">
|
||||
<span class="bold" data-i18n-message-id="proxyPermissionTitle"></span>
|
||||
</label>
|
||||
<p><em data-i18n-message-id="proxyPermissionDescription"></em></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 data-i18n-message-id="firefoxAccountsSync"></h3>
|
||||
<label>
|
||||
<input type="checkbox" id="syncCheck">
|
||||
<span data-i18n-message-id="enableSync"></span>
|
||||
</label>
|
||||
<p><em data-i18n-message-id="enableSyncDescription"></em></p>
|
||||
<div class="settings-group">
|
||||
<label>
|
||||
<input type="checkbox" id="syncCheck">
|
||||
<span class="bold" data-i18n-message-id="enableSync"></span>
|
||||
</label>
|
||||
<p><em data-i18n-message-id="enableSyncDescription"></em></p>
|
||||
</div>
|
||||
|
||||
<h3 data-i18n-message-id="tabBehavior"></h3>
|
||||
<label>
|
||||
<input type="checkbox" id="replaceTabCheck">
|
||||
<span data-i18n-message-id="replaceTab"></span>
|
||||
</label>
|
||||
<p><em data-i18n-message-id="replaceTabDescription"></em></p>
|
||||
|
||||
<div class="settings-group">
|
||||
<label>
|
||||
<input type="checkbox" id="replaceTabCheck">
|
||||
<span class="bold" data-i18n-message-id="replaceTab"></span>
|
||||
</label>
|
||||
<p><em data-i18n-message-id="replaceTabDescription"></em></p>
|
||||
</div>
|
||||
|
||||
<h3 data-i18n-message-id="keyboardShortCuts"></h3>
|
||||
<p><em data-i18n-message-id="editWhichContainer"></em></p>
|
||||
<p><label>
|
||||
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="1"></span>
|
||||
<select id="open_container_0">
|
||||
</select>
|
||||
</label></p>
|
||||
<p><label>
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="2"></span>
|
||||
<select id="open_container_1">
|
||||
</select>
|
||||
</label></p>
|
||||
<p><label>
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="3"></span>
|
||||
<select id="open_container_2">
|
||||
</select>
|
||||
</label></p>
|
||||
<p><label>
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="4"></span>
|
||||
<select id="open_container_3">
|
||||
</select>
|
||||
</label></p>
|
||||
<p><label>
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="5"></span>
|
||||
<select id="open_container_4">
|
||||
</select>
|
||||
</label></p>
|
||||
<p><label>
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="6"></span>
|
||||
<select id="open_container_5">
|
||||
</select>
|
||||
</label></p>
|
||||
<p><label>
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="7"></span>
|
||||
<select id="open_container_6">
|
||||
</select>
|
||||
</label></p>
|
||||
<p><label>
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="8"></span>
|
||||
<select id="open_container_7">
|
||||
</select>
|
||||
</label></p>
|
||||
<p><label>
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="9"></span>
|
||||
<select id="open_container_8">
|
||||
</select>
|
||||
</label></p>
|
||||
<p><label>
|
||||
<p><label class="keyboard-shortcut">
|
||||
<span data-i18n-message-id="keyboardShortCut" data-i18n-placeholder="10"></span>
|
||||
<select id="open_container_9">
|
||||
</select>
|
||||
</label></p>
|
||||
<h3 data-i18n-message-id="onboarding"></h3>
|
||||
<button data-i18n-message-id="resetOnboardingPanels"></button>
|
||||
<button data-btn-id="reset-onboarding" data-i18n-message-id="resetOnboardingPanels"></button>
|
||||
<p><em data-i18n-message-id="onboardingToggle"></em></p>
|
||||
<h3>Mozilla VPN</h3>
|
||||
<button data-btn-id="moz-vpn-learn-more" data-i18n-message-id="learnMore"></button>
|
||||
</form>
|
||||
<script src="js/options.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -62,11 +62,22 @@
|
|||
</div>
|
||||
|
||||
<div class="panel onboarding onboarding-panel-8 hide" id="onboarding-panel-8">
|
||||
<img class="onboarding-img" alt="" src="/img/moz-vpn-onboarding.svg" />
|
||||
<h3 class="onboarding-title" data-i18n-message-id="proxyNowAvailable"></h3>
|
||||
<p data-i18n-message-id="onboarding-8-description"></p>
|
||||
<div class="half-button-wrapper">
|
||||
<a href="#" id="onboarding-done-btn" class="half-onboarding-button keyboard-nav" tabindex="0" data-i18n-message-id="done"></a>
|
||||
<div class="moz-vpn-onboarding-content">
|
||||
<img class="onboarding-img" alt="" src="/img/moz-vpn-onboarding.svg" />
|
||||
<h3 class="onboarding-title" data-i18n-message-id="proxyNowAvailable"></h3>
|
||||
<p data-i18n-message-id="onboarding-8-description"></p>
|
||||
</div>
|
||||
<div id="moz-vpn-fw-onboarding-done" class="half-button-wrapper">
|
||||
<a id="moz-vpn-fw-onboarding-done" href="#" class="half-onboarding-button keyboard-nav onboarding-done" tabindex="0" data-i18n-message-id="done"></a>
|
||||
</div>
|
||||
<div class="moz-vpn-permissions">
|
||||
<div class="moz-vpn-permissions-copy">
|
||||
<span data-i18n-message-id="mozillaVpnRequiresAdditionalPermissions"></span>
|
||||
</div>
|
||||
<div class="half-button-wrapper">
|
||||
<a href="#" id="permissions-not-now" class="half-onboarding-button grey-button keyboard-nav onboarding-done" tabindex="0" data-i18n-message-id="notNow"></a>
|
||||
<a href="#" id="onboarding-enable-permissions" class="half-onboarding-button keyboard-nav" tabindex="0" data-i18n-message-id="enable"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -98,7 +109,7 @@
|
|||
<div class="panel menu-panel container-panel hide" id="container-panel">
|
||||
<h3 class="title">Multi-Account Containers</h3>
|
||||
<a href="#" class="info-icon" id="info-icon" tabindex="10">
|
||||
<img data-i18n-attribute-message-id="info" data-i18n-attribute="alt" alt="" ="info" src="/img/info.svg" / >
|
||||
<img data-i18n-attribute-message-id="info" data-i18n-attribute="alt" alt="" src="/img/info.svg" / >
|
||||
</a>
|
||||
<hr>
|
||||
<table class="menu">
|
||||
|
@ -170,18 +181,18 @@
|
|||
</table>
|
||||
</div>
|
||||
<div id="moz-vpn-tout" class="moz-vpn-content expanded">
|
||||
<div class="flx-row button-wrapper">
|
||||
<h4 class="moz-vpn-logo">Mozilla VPN</h4>
|
||||
<button class="controller dismiss-moz-vpn-tout" tab-index="0"></button>
|
||||
</div>
|
||||
<div class="collapsible-content flx-col controller-collapsible-content">
|
||||
<div class="flx-row flx-space-between">
|
||||
<span class="moz-vpn-subtitle" data-i18n-message-id="protectYourContainers"></span>
|
||||
</div>
|
||||
<button id="moz-vpn-learn-more" class="moz-vpn-cta primary-cta" data-i18n-message-id="learnMore"></button>
|
||||
</div>
|
||||
<div class="flx-row button-wrapper">
|
||||
<h4 class="moz-vpn-logo">Mozilla VPN</h4>
|
||||
<button class="controller dismiss-moz-vpn-tout" tab-index="0"></button>
|
||||
</div>
|
||||
<v-padding-hack-footer></v-padding-hack-footer> <!--presents last container from getting covered up by the 'manage containers button' when list is long-->
|
||||
<div class="collapsible-content flx-col controller-collapsible-content">
|
||||
<div class="flx-row flx-space-between">
|
||||
<span class="moz-vpn-subtitle" data-i18n-message-id="integrateContainers"></span>
|
||||
</div>
|
||||
<button id="moz-vpn-learn-more" class="moz-vpn-cta primary-cta" data-i18n-message-id="getMozillaVpn"></button>
|
||||
</div>
|
||||
</div>
|
||||
<v-padding-hack-footer></v-padding-hack-footer> <!--prevents last container from getting covered up by the 'manage containers button' when list is long-->
|
||||
<div class="bottom-btn keyboard-nav controller" id="manage-containers-link" tabindex="0" data-i18n-message-id="manageContainers"></div>
|
||||
</div>
|
||||
|
||||
|
@ -324,7 +335,7 @@
|
|||
<span class="slider round"></span>
|
||||
</label>
|
||||
</div>
|
||||
<button id="get-mozilla-vpn" class="moz-vpn-cta primary-cta" data-i18n-message-id="learnMore"></button>
|
||||
<button id="get-mozilla-vpn" class="moz-vpn-cta primary-cta" data-i18n-message-id="getMozillaVpn"></button>
|
||||
<button id="moz-vpn-current-server" class="controller">
|
||||
<span class="current-country-flag"></span>
|
||||
<span class="current-city-name"></span>
|
||||
|
@ -437,6 +448,10 @@
|
|||
<button id="submit-advanced-proxy" class="primary-cta apply-to-container" data-i18n-message-id="applyToContainer"></button>
|
||||
<a id="advanced-proxy-settings-learn-more" href="" class="blue-link" data-i18n-message-id="learnMore"></a>
|
||||
</form>
|
||||
<div id="permissions-overlay" class="permissions-overlay" data-tab-group="proxy-disabled">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/utils.js"></script>
|
||||
<script src="js/popup.js"></script>
|
||||
|
|
Loading…
Add table
Reference in a new issue