First draft of popup panel for Firefox Preview

First draft of changes as discussed with Firefox
Preview people.

In order to allow testing/evaluating these changes,
the new advanced setting `uiFlavor` has been added.
Default to `unset`; and can currently only be set
to `fenix`.

The new setting takes effect at launch only. This
new setting is not to be mentioned in official
documentation for now.

This is ongoing work, not open to external feedback.
This commit is contained in:
Raymond Hill 2020-01-25 09:24:59 -05:00
parent 14d1d34a6c
commit 2b0316440e
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
7 changed files with 1736 additions and 1 deletions

View File

@ -95,6 +95,18 @@
"message":"or",
"description":"English: or"
},
"popupBlockedOnThisPage_v2":{
"message":"Blocked on this page",
"description":"For the new mobile-friendly popup design"
},
"popupBlockedSinceInstall_v2":{
"message":"Blocked since install",
"description":"For the new mobile-friendly popup design"
},
"popupDomainsConnected_v2":{
"message":"Domains connected",
"description":"For the new mobile-friendly popup design"
},
"popupTipDashboard":{
"message":"Open the dashboard",
"description":"English: Click to open the dashboard"
@ -167,6 +179,26 @@
"message":"Click to no longer disable JavaScript on this site",
"description":"Tooltip for the no-scripting per-site switch"
},
"popupNoLargeMedia_v2":{
"message":"Large media elements",
"description":"Tip for the no-large-media per-site switch"
},
"popupNoCosmeticFiltering_v2":{
"message":"Cosmetic filtering",
"description":"Tip for the no-cosmetic-filtering per-site switch"
},
"popupNoRemoteFonts_v2":{
"message":"Remote fonts",
"description":"Tip for the no-remote-fonts per-site switch"
},
"popupNoScripting_v2":{
"message":"JavaScript",
"description":"Tip for the no-scripting per-site switch"
},
"popupMoreButton_v2":{
"message":"More",
"description":"Label to be used to toggle overview panel"
},
"popupTipGlobalRules":{
"message":"Global rules: this column is for rules which apply to all sites.",
"description":"Tooltip when hovering the top-most cell of the global-rules column."

484
src/css/popup-fenix.css Normal file
View File

@ -0,0 +1,484 @@
body {
background-color: white;
border: 0;
margin: 0;
padding: 0;
white-space: nowrap;
}
h2 {
background-color: #eee;
border: 0;
color: #666;
cursor: pointer;
font-size: 100%;
font-weight: normal;
padding: 0.2em;
text-align: center;
}
a {
color: inherit;
text-decoration: none;
}
:focus {
outline: 0;
}
#main {
align-items: stretch;
display: flex;
flex-direction: column;
padding: 0;
position: relative;
width: 100%;
}
hr {
border: 0;
border-top: 1px solid #ddd;
margin: 0;
padding: 0;
}
.fa {
font-size: 120%;
}
#sticky {
background-color: white;
position: sticky;
top: 0;
z-index: 100;
}
#switch {
display: flex;
justify-content: center;
margin: 1em 0;
}
#switch .fa-icon {
fill: #0046ff;
cursor: pointer;
font-size: 700%;
margin: 0;
padding: 0;
}
#switch .fa-icon:hover {
opacity: 0.9;
}
body.off #switch .fa-icon {
fill: #ccc;
}
.itemRibbon {
display: grid;
grid-template: auto / auto auto;
padding: 1em 1em;
}
.itemRibbon > [data-i18n] + span {
justify-self: end;
}
.itemRibbon > .h-gutter {
display: inline-block;
height: 1em;
}
#basicStats {
}
.toolRibbon {
align-items: start;
display: grid;
grid-template: auto / 25% 25% 25% 25%;
justify-items: center;
margin: 1em 0;
white-space: normal;
}
.toolRibbon .tool {
display: flex;
flex-direction: column;
font-size: 1.4em;
min-width: 4em;
}
.toolRibbon [data-i18n] {
font-size: x-small;
margin-top: 0.8em;
text-align: center;
}
.tool {
color: #444;
cursor: pointer;
fill: #444;
padding: 0 0.5em;
unicode-bidi: embed;
visibility: hidden;
}
.tool.enabled {
visibility: visible;
}
.tool.enabled:hover {
color: #444;
fill: #444;
}
.statValue {
margin: 0;
}
#extraTools .fa-icon {
align-self: center;
position: relative;
}
#extraTools .fa-icon > .nope {
left: 50%;
position: absolute;
stroke: red;
stroke-width: 2;
transform: translateX(-50%);
visibility: hidden;
width: 1em;
}
#extraTools > span.on .fa-icon >.nope {
visibility: visible;
}
#extraTools > span:hover {
color: #222;
fill: #222;
}
#main:not(.dfEnabled) #moreButton .fa-icon {
transform: rotate(180deg);
}
#tooltip {
background-color: #ffffee;
border: 1px solid gray;
border-radius: 3px;
box-shadow: 1px 1px 3px gray;
box-sizing: border-box;
color: black;
cursor: pointer;
direction: ltr;
font: 12px sans-serif;
left: 5%;
line-height: 130%;
margin: 0.5em 0;
opacity: 0;
padding: 4px 6px;
pointer-events: none;
position: absolute;
text-align: center;
visibility: hidden;
white-space: pre-line;
width: 90%;
z-index: 100;
}
body[dir="rtl"] #tooltip {
direction: rtl;
}
#tooltip.show {
transition: opacity 0.15s 0.5s;
-webkit-transition: opacity 0.15s 0.5s;
visibility: visible;
opacity: 1;
}
#firewallContainer {
border: 0;
flex-shrink: 0;
font-family: "Noto Sans", sans-serif;
font-size: 85%;
margin: 0;
padding: 0;
overflow-y: auto;
overflow-x: hidden;
text-align: right;
}
#main:not(.dfEnabled) #firewallContainer {
display: none;
}
#firewallContainer > div {
border: 0;
direction: ltr;
display: flex;
justify-content: flex-end;
margin: 0;
margin-top: 1px;
padding: 0;
}
#firewallContainer > div:first-child {
margin-top: 0;
}
#firewallContainer > div:first-child ~ div[data-des="*"] {
display: none;
}
#firewallContainer:not(.expanded) > div.isSubDomain:not(.expandException):not(.isRootContext),
#firewallContainer.expanded > div.isSubDomain.expandException:not(.isRootContext) {
display: none;
}
#firewallContainer > div > span {
background-color: #e6e6e6;
border: none;
box-sizing: border-box;
-moz-box-sizing: border-box;
color: #000;
display: inline-flex;
flex-shrink: 0;
line-height: 2;
position: relative;
}
#firewallContainer > div:first-of-type > span:first-of-type {
cursor: pointer;
}
#firewallContainer > div > span:first-of-type {
justify-content: flex-end;
padding-right: 2px;
width: calc(100% - 4em);
}
#firewallContainer > div.isCname > span:first-of-type {
color: mediumblue;
}
#firewallContainer > div > span:first-of-type > sup {
color: #666;
display: none;
font-size: 80%;
font-weight: normal;
line-height: 1;
}
#firewallContainer > div.isDomain > span.isIDN:first-of-type > sup {
display: inline-block;
}
#firewallContainer > div.isDomain > span.isIDN:first-of-type > sup::before {
content: '\0416\2002';
}
#firewallContainer > div > span:first-of-type ~ span {
margin-left: 1px;
width: 4em;
}
#firewallContainer > div > span:nth-of-type(2) {
display: none;
}
#firewallContainer > div > span:nth-of-type(3),
#firewallContainer > div > span:nth-of-type(4) {
color: #444;
display: none;
font-family: monospace;
text-align: center;
}
#firewallContainer > div.isDomain > span:first-of-type {
font-weight: bold;
}
#firewallContainer > div:first-of-type > span:first-of-type::before {
color: #aaa;
content: '+';
padding-right: 0.25em;
}
#firewallContainer.expanded > div:first-of-type > span:first-of-type::before {
content: '\2012';
}
#firewallContainer > div[data-des="*"] > span:nth-of-type(3),
#firewallContainer > div.isSubDomain > span:nth-of-type(3),
#firewallContainer > div.isSubDomain.isRootContext > span:nth-of-type(3),
#firewallContainer.expanded > div:not(.expandException) > span:nth-of-type(3),
#firewallContainer:not(.expanded) > div.expandException > span:nth-of-type(3),
#firewallContainer:not(.expanded) > div.isDomain:not(.expandException) > span:nth-of-type(4),
#firewallContainer.expanded > div.isDomain.expandException > span:nth-of-type(4) {
display: inline-flex;
justify-content: space-between;
}
#firewallContainer > div > span[data-acount]::before,
#firewallContainer > div > span[data-bcount]::after {
content: ' ';
}
#firewallContainer > div > span[data-acount]::before {
padding-left: 0.1em;
}
#firewallContainer > div > span[data-acount="1"]::before {
content: '+';
}
#firewallContainer > div > span[data-acount="2"]::before {
content: '++';
}
#firewallContainer > div > span[data-acount="3"]::before {
content: '+++';
}
#firewallContainer > div > span[data-bcount]::after {
padding-right: 0.1em;
}
#firewallContainer > div > span[data-bcount="1"]::after {
content: '\2212';
}
#firewallContainer > div > span[data-bcount="2"]::after {
content: '\2212\2212';
}
#firewallContainer > div > span[data-bcount="3"]::after {
content: '\2212\2212\2212';
}
body.advancedUser #firewallContainer > div > span:first-of-type {
width: calc(100% - 8em);
}
body.advancedUser #firewallContainer > div > span:nth-of-type(2) {
display: inline-flex;
}
body.advancedUser #firewallContainer > div:first-child ~ div[data-des="*"] {
display: flex;
}
body.advancedUser #firewallContainer > div > span:first-of-type ~ span {
cursor: pointer;
}
/**
Small coloured label at the left of a row
*/
#firewallContainer > div.isRootContext > span:first-of-type::before,
#firewallContainer > div.allowed > span:first-of-type::before,
#firewallContainer > div.blocked > span:first-of-type::before,
#firewallContainer:not(.expanded) > div.isDomain.totalAllowed:not(.expandException) > span:first-of-type::before,
#firewallContainer:not(.expanded) > div.isDomain.totalBlocked:not(.expandException) > span:first-of-type::before,
#firewallContainer.expanded > div.isDomain.totalAllowed.expandException > span:first-of-type::before,
#firewallContainer.expanded > div.isDomain.totalBlocked.expandException > span:first-of-type::before {
box-sizing: border-box;
content: '';
display: inline-block;
height: 100%;
left: 0;
opacity: 0.4;
position: absolute;
width: 7px;
}
#firewallContainer > div.isRootContext > span:first-of-type::before {
background-color: rgb(127, 127, 127);
width: 14px !important;
}
/**
Source for color-blind color scheme from https://github.com/WyohKnott:
https://github.com/chrisaljoudi/uBlock/issues/467#issuecomment-95177219
*/
#firewallContainer > div.allowed > span:first-of-type::before,
#firewallContainer > div.isDomain.totalAllowed > span:first-of-type::before {
background-color: rgb(0, 160, 0);
}
#firewallContainer.colorBlind > div.allowed > span:first-of-type::before,
#firewallContainer.colorBlind > div.isDomain.totalAllowed > span:first-of-type::before {
background-color: rgb(255, 194, 57);
}
#firewallContainer > div.blocked > span:first-of-type::before,
#firewallContainer > div.isDomain.totalBlocked > span:first-of-type::before {
background-color: rgb(192, 0, 0);
}
#firewallContainer.colorBlind > div.blocked > span:first-of-type::before,
#firewallContainer.colorBlind > div.isDomain.totalBlocked > span:first-of-type::before {
background-color: rgb(0, 19, 110);
}
#firewallContainer > div.allowed.blocked > span:first-of-type::before,
#firewallContainer > div.isDomain.totalAllowed.totalBlocked > span:first-of-type::before {
background-color: rgb(192, 160, 0);
}
/* Rule cells */
body.advancedUser #firewallContainer > div > span.allowRule {
background-color: rgba(0, 160, 0, 0.3);
}
body.advancedUser #firewallContainer.colorBlind > div > span.allowRule {
background-color: rgba(255, 194, 57, 0.4);
}
body.advancedUser #firewallContainer > div > span.blockRule {
background-color: rgba(192, 0, 0, 0.3);
}
body.advancedUser #firewallContainer.colorBlind > div > span.blockRule {
background-color: rgba(0, 19, 110, 0.4);
}
body.advancedUser #firewallContainer > div > span.noopRule {
background-color: rgba(108, 108, 108, 0.3);
}
body.advancedUser #firewallContainer.colorBlind > div > span.noopRule {
background-color: rgba(96, 96, 96, 0.4);
}
body.advancedUser #firewallContainer > div > span.ownRule {
color: white;
}
body.advancedUser #firewallContainer > div > span.allowRule.ownRule {
background-color: rgba(0, 160, 0, 1);
}
body.advancedUser #firewallContainer.colorBlind > div > span.allowRule.ownRule {
background-color: rgba(255, 194, 57, 1);
}
body.advancedUser #firewallContainer > div > span.blockRule.ownRule {
background-color: rgba(192, 0, 0, 1);
}
body.advancedUser #firewallContainer.colorBlind > div > span.blockRule.ownRule {
background-color: rgba(0, 19, 110, 1);
}
body.advancedUser #firewallContainer > div > span.noopRule.ownRule {
background-color: rgba(108, 108, 108, 1);
}
#actionSelector {
bottom: 0;
left: 0;
position: absolute;
top: 0;
width: 4em;
z-index: 1;
}
#actionSelector > span {
display: inline-block;
height: 100%;
opacity: 0.2;
}
#actionSelector > span:first-of-type {
width: 33%;
}
#actionSelector > span:nth-of-type(2) {
width: 33.5%;
}
#actionSelector > span:nth-of-type(3) {
width: 33.5%;
}
#actionSelector > span:hover {
opacity: 0.75;
}
#actionSelector > span:first-of-type {
background-color: rgb(0, 160, 0);
}
#actionSelector.colorBlind > span:first-of-type {
background-color: rgb(255, 194, 57);
}
#actionSelector > span:nth-of-type(2) {
background-color: rgb(108, 108, 108);
}
#actionSelector > span:nth-of-type(3) {
background-color: rgb(192, 0, 0);
}
#actionSelector.colorBlind > span:nth-of-type(3) {
background-color: rgb(0, 19, 110);
}
#rulesetTools {
background-color: transparent;
border: 0;
box-sizing: border-box;
display: flex;
flex-direction: column;
height: 100%;
justify-content: space-evenly;
left: 0;
padding: 0.2em;
position: absolute;
top: 0;
}
#rulesetTools [id] {
background-color: #ffe;
border: 1px solid #ddc;
border-radius: 4px;
cursor: pointer;
fill: #888;
font-size: 1.8em;
padding: 0.2em 0.4em;
visibility: hidden;
}
#rulesetTools [id]:hover {
fill: black;
}
body.needReload #refresh,
body.needSave #saveRules,
body.needSave #revertRules {
visibility: visible;
}

View File

@ -68,6 +68,7 @@ const µBlock = (( ) => { // jshint ignore:line
selfieAfter: 3,
strictBlockingBypassDuration: 120,
suspendTabsUntilReady: 'unset',
uiFlavor: 'unset',
updateAssetBypassBrowserCache: false,
userResourcesLocation: 'unset',
};

View File

@ -23,7 +23,7 @@
/******************************************************************************/
let faIconsInit = function(root) {
const faIconsInit = function(root) {
const icons = (root || document).querySelectorAll('.fa-icon');
for ( const icon of icons ) {
if ( icon.firstChild === null || icon.firstChild.nodeType !== 3 ) {

1125
src/js/popup-fenix.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -339,6 +339,19 @@ initializeTabs();
// active tab.
µb.contextMenu.update();
// Maybe install non-default popup document
if (
browser.browserAction instanceof Object &&
browser.browserAction.setPopup instanceof Function
) {
const uiFlavor = µb.hiddenSettings.uiFlavor;
if ( uiFlavor !== 'unset' && /\w+/.test(uiFlavor) ) {
browser.browserAction.setPopup({
popup: vAPI.getURL(`popup-${uiFlavor}.html`)
});
}
}
// https://github.com/uBlockOrigin/uBlock-issues/issues/717
// Prevent the extension from being restarted mid-session.
browser.runtime.onUpdateAvailable.addListener(details => {

80
src/popup-fenix.html Normal file
View File

@ -0,0 +1,80 @@
<!DOCTYPE html>
<html id="uBO-popup-panel">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/common.css" type="text/css">
<link rel="stylesheet" href="css/fa-icons.css" type="text/css">
<link rel="stylesheet" href="css/popup-fenix.css" type="text/css">
<title data-i18n="extName"></title>
</head>
<body>
<div id="main" class="tooltipContainer">
<div id="sticky">
<div id="switch" role="button" aria-label data-tip-position="under" tabindex="0">
<span class="fa-icon">power-off</span>
</div>
<div id="rulesetTools">
<span id="refresh" class="fa-icon">refresh</span>
<span id="saveRules" class="fa-icon" data-i18n-tip="popupTipSaveRules" data-tip-position="under">lock</span>
<span id="revertRules" class="fa-icon" data-i18n-tip="popupTipRevertRules" data-tip-position="under">eraser</span>
</div>
<hr>
</div>
<div id="basicTools" class="toolRibbon">
<span id="gotoZap" class="fa-icon tool">bolt<span data-i18n="popupTipZapper"></span></span>
<span id="gotoPick" class="fa-icon tool">eye-dropper<span data-i18n="popupTipPicker"></span></span>
<a href="logger-ui.html#_" class="fa-icon tool enabled" aria-label="data-tip" target="uBOLogger" tabindex="0">list-alt<span data-i18n="popupTipLog"></span></a>
<a href="dashboard.html" class="fa-icon tool enabled" aria-label="data-tip" target="uBODashboard" tabindex="0">sliders<span data-i18n="popupTipDashboard"></span></a>
</div>
<hr>
<div id="basicStats" class="itemRibbon">
<span data-i18n="popupBlockedOnThisPage_v2"></span><span></span>
<span class="h-gutter"></span><span></span>
<span data-i18n="popupBlockedSinceInstall_v2"></span><span></span>
<span class="h-gutter"></span><span></span>
<span data-i18n="popupDomainsConnected_v2"></span><span></span>
</div>
<hr>
<div id="extraTools" class="toolRibbon">
<span id="no-large-media" class="hnSwitch tool enabled" role="button" aria-label tabindex="0"><span class="fa-icon fa-icon-badged">film<svg class="nope" viewBox="0 0 20 20"><path d="M1,1 19,19M1,19 19,1" /></svg></span><span data-i18n="popupNoLargeMedia_v2"></span></span>
<span id="no-cosmetic-filtering" class="hnSwitch tool enabled" role="button" aria-label tabindex="0"><span class="fa-icon fa-icon-badged">eye-slash<svg class="nope" viewBox="0 0 20 20"><path d="M1,1 19,19M1,19 19,1" /></svg></span><span data-i18n="popupNoCosmeticFiltering_v2"></span></span>
<span id="no-remote-fonts" class="hnSwitch tool enabled" role="button" aria-label tabindex="0"><span class="fa-icon fa-icon-badged">font<svg class="nope" viewBox="0 0 20 20"><path d="M1,1 19,19M1,19 19,1" /></svg></span><span data-i18n="popupNoRemoteFonts_v2"></span></span>
<span id="no-scripting" class="hnSwitch tool enabled" role="button" aria-label tabindex="0"><span class="fa-icon fa-icon-badged">code<svg class="nope" viewBox="0 0 20 20"><path d="M1,1 19,19M1,19 19,1" /></svg></span><span data-i18n="popupNoScripting_v2"></span></span>
</div>
<hr>
<div id="moreButton" class="itemRibbon">
<span data-i18n="popupMoreButton_v2"></span><span class="fa-icon">angle-up</span>
</div>
<div id="firewallContainer">
<div data-des="*" data-type="*"><span data-i18n="popupAnyRulePrompt"></span><span data-src="/" data-i18n-tip="popupTipGlobalRules" data-tip-position="under"> </span><span data-src="." data-i18n-tip="popupTipLocalRules" data-tip-position="under"> </span></div>
<div data-des="*" data-type="image"><span data-i18n="popupImageRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
<div data-des="*" data-type="3p"><span data-i18n="popup3pAnyRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
<div data-des="*" data-type="inline-script"><span data-i18n="popupInlineScriptRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
<div data-des="*" data-type="1p-script"><span data-i18n="popup1pScriptRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
<div data-des="*" data-type="3p-script"><span data-i18n="popup3pScriptRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
<div data-des="*" data-type="3p-frame"><span data-i18n="popup3pFrameRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
</div>
</div>
<div id="templates" style="display: none">
<div data-des="" data-type="*"><span><sup></sup><span></span></span><span data-src="/"></span><span data-src="."></span><span data-src="."></span></div>
<div id="actionSelector"><span id="dynaAllow"></span><span id="dynaNoop"></span><span id="dynaBlock"></span></div>
<div id="hotspotTip"></div>
<div id="tooltip"></div>
</div>
<script src="js/fa-icons.js"></script>
<script src="lib/punycode.js"></script>
<script src="js/vapi.js"></script>
<script src="js/vapi-common.js"></script>
<script src="js/vapi-client.js"></script>
<script src="js/udom.js"></script>
<script src="js/i18n.js"></script>
<script src="js/popup-fenix.js"></script>
</body>
</html>