Skip to content

Commit 8d445e7

Browse files
committed
Add widget to filter firewall rows in popup panel
This replaces the limited "visually enhance rows" togglers.
1 parent 189bdd6 commit 8d445e7

File tree

3 files changed

+160
-57
lines changed

3 files changed

+160
-57
lines changed

src/css/popup-fenix.css

Lines changed: 87 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ body.mobile.no-tooltips .toolRibbon .tool {
267267
max-width: 460px;
268268
min-width: var(--popup-firewall-min-width);
269269
padding: 0;
270+
position: relative;
270271
overflow-y: auto;
271272
}
272273
:root.desktop #firewall {
@@ -275,18 +276,80 @@ body.mobile.no-tooltips .toolRibbon .tool {
275276
:root.desktop body.vMin #firewall {
276277
max-height: 100vh;
277278
}
279+
#firewall > * {
280+
direction: ltr;
281+
}
282+
#firewall > section {
283+
align-items: flex-start;
284+
display: flex;
285+
left: 0;
286+
position: absolute;
287+
z-index: 100;
288+
}
289+
#firewall > section .fa-icon {
290+
color: var(--ink-4);
291+
fill: var(--ink-4);
292+
font-size: 150%;
293+
padding: var(--popup-gap-thin);
294+
}
295+
#firewall > section:hover .fa-icon {
296+
color: var(--ink-1);
297+
fill: var(--ink-1);
298+
}
299+
#firewall.showBlocked > section .fa-icon,
300+
#firewall.showAllowed > section .fa-icon,
301+
#firewall.hideBlocked > section .fa-icon,
302+
#firewall.hideAllowed > section .fa-icon,
303+
#firewall.show3pScript > section .fa-icon,
304+
#firewall.show3pFrame > section .fa-icon,
305+
#firewall.hide3pScript > section .fa-icon,
306+
#firewall.hide3pFrame > section .fa-icon {
307+
color: rgb(var(--primary-70));
308+
fill: rgb(var(--primary-70));
309+
}
310+
#firewall > section .filterExpressions {
311+
background-color: var(--surface-0);
312+
border: 1px solid var(--border-4);
313+
display: none;
314+
}
315+
#firewall > section:hover .filterExpressions {
316+
display: flex;
317+
flex-direction: column;
318+
}
319+
#firewall > section .filterExpressions div {
320+
border-bottom: 1px dotted #ddd;
321+
padding: 0.25em;
322+
}
323+
#firewall > section .filterExpressions span {
324+
cursor: default;
325+
display: inline-flex;
326+
margin: 0 0.25em 0 0;
327+
padding: 0.5em;
328+
white-space: nowrap;
329+
border: 1px solid var(--surface-0);
330+
}
331+
#firewall > section .filterExpressions span:last-of-type {
332+
margin: 0;
333+
}
334+
:root:not(.mobile) #firewall > section .filterExpressions span:not(.on):hover {
335+
background-color: rgb(var(--primary-70) / 15%);
336+
border: 1px solid rgb(var(--primary-70));
337+
}
338+
#firewall > section .filterExpressions span.on {
339+
background-color: rgb(var(--primary-70) / 40%);
340+
border: 1px solid rgb(var(--primary-70));
341+
}
278342
#firewall > div {
279343
border: 0;
280-
direction: ltr;
281344
display: flex;
282345
margin: 0;
283346
margin-top: 1px;
284347
padding: 0;
285348
}
286-
#firewall > div:first-child {
349+
#firewall > div:first-of-type {
287350
margin-top: 0;
288351
}
289-
#firewall > div:first-child ~ div[data-des="*"] {
352+
#firewall > div:first-of-type ~ div[data-des="*"] {
290353
display: none;
291354
}
292355
#firewall:not(.expanded) > div.isSubdomain:not(.expandException):not(.isRootContext),
@@ -302,12 +365,20 @@ body.mobile.no-tooltips .toolRibbon .tool {
302365
padding: 0.4em 0;
303366
position: relative;
304367
}
305-
#firewall > div:first-of-type > span:first-of-type {
368+
#firewall > div:first-of-type span[data-i18n] {
306369
cursor: pointer;
307370
flex-direction: unset;
371+
flex-grow: 1;
372+
}
373+
#firewall > div:first-of-type span[data-i18n]::before {
374+
color: var(--ink-3);
375+
content: '+';
376+
padding-right: 0.25em;
377+
}
378+
#firewall.expanded > div:first-of-type span[data-i18n]::before {
379+
content: '\2012';
308380
}
309381
#firewall > div > span:first-of-type {
310-
align-items: flex-end;
311382
flex-direction: column;
312383
flex-grow: 1;
313384
justify-content: flex-end;
@@ -320,36 +391,18 @@ body.mobile.no-tooltips .toolRibbon .tool {
320391
#firewall > div[data-des="*"] > span:first-of-type {
321392
flex-direction: row;
322393
}
323-
#firewall > div[data-des="*"] > span:first-of-type > span.filter {
324-
flex-grow: 1;
325-
padding-inline-start: 2px;
326-
-webkit-padding-start: 2px;
327-
text-align: left;
328-
}
329-
#firewall:not(.has3pScript) > [data-type="3p-script"] .filter,
330-
#firewall:not(.has3pFrame) > [data-type="3p-frame"] .filter {
331-
display: none;
332-
}
333-
#firewall > [data-des="*"] .filter::after {
334-
content: '\22EF';
335-
}
336-
#firewall.show3pScript > [data-type="3p-script"] .filter::after,
337-
#firewall.show3pFrame > [data-type="3p-frame"] .filter::after {
338-
content: '\2191';
339-
}
340-
#firewall.hide3pScript > [data-type="3p-script"] .filter::after,
341-
#firewall.hide3pFrame > [data-type="3p-frame"] .filter::after {
342-
content: '\2193';
343-
}
344-
#firewall.show3pScript > div:not([data-des="*"]):not(.hasScript),
345-
#firewall.show3pScript > div:not([data-des="*"]):not(.is3p),
394+
#firewall.show3pScript:not(.show3pFrame) > div:not([data-des="*"]).is3p:not(.hasScript),
395+
#firewall.show3pFrame:not(.show3pScript) > div:not([data-des="*"]).is3p:not(.hasFrame),
396+
#firewall.show3pScript.show3pFrame > div:not([data-des="*"]).is3p:not(.hasScript):not(.hasFrame),
346397
#firewall.hide3pScript > div:not([data-des="*"]).is3p.hasScript,
347-
#firewall.show3pFrame > div:not([data-des="*"]):not(.hasFrame),
348-
#firewall.show3pFrame > div:not([data-des="*"]):not(.is3p),
349398
#firewall.hide3pFrame > div:not([data-des="*"]).is3p.hasFrame,
350-
#firewall.show3pScript.show3pFrame > div:not([data-des="*"]).hasScript:not(.hasFrame),
351-
#firewall.show3pScript.show3pFrame > div:not([data-des="*"]).hasFrame:not(.hasScript) {
352-
opacity: 0.5;
399+
#firewall.showBlocked > div:not([data-des="*"]).is3p:not(.totalBlocked):not(.blocked),
400+
#firewall.showAllowed > div:not([data-des="*"]).is3p:not(.totalAllowed):not(.allowed),
401+
#firewall.hideBlocked > div:not([data-des="*"]).is3p.totalBlocked,
402+
#firewall.hideBlocked > div:not([data-des="*"]).is3p.blocked,
403+
#firewall.hideAllowed > div:not([data-des="*"]).is3p.totalAllowed,
404+
#firewall.hideAllowed > div:not([data-des="*"]).is3p.allowed {
405+
display: none;
353406
}
354407
#firewall > div.isCname > span:first-of-type {
355408
color: var(--popup-cell-cname-ink);
@@ -389,14 +442,6 @@ body.mobile.no-tooltips .toolRibbon .tool {
389442
color: var(--ink-3);
390443
content: '\2026\A0';
391444
}
392-
#firewall > div:first-of-type > span:first-of-type::before {
393-
color: var(--ink-3);
394-
content: '+';
395-
padding-right: 0.25em;
396-
}
397-
#firewall.expanded > div:first-of-type > span:first-of-type::before {
398-
content: '\2012';
399-
}
400445
#firewall > div[data-des="*"] > span:nth-of-type(3),
401446
#firewall > div.isSubdomain > span:nth-of-type(3),
402447
#firewall > div.isSubdomain.isRootContext > span:nth-of-type(3),
@@ -453,7 +498,7 @@ body.advancedUser #firewall > div > span:first-of-type {
453498
body.advancedUser #firewall > div > span:nth-of-type(2) {
454499
display: inline-flex;
455500
}
456-
body.advancedUser #firewall > div:first-child ~ div[data-des="*"] {
501+
body.advancedUser #firewall > div:first-of-type ~ div[data-des="*"] {
457502
display: flex;
458503
}
459504
body.advancedUser #firewall > div > span:first-of-type ~ span {

src/js/popup-fenix.js

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,75 @@ const reIP = /(\d|\])$/;
457457

458458
/******************************************************************************/
459459

460+
function filterFirewallRows() {
461+
const firewallElem = qs$('#firewall');
462+
const elems = qsa$('#firewall .filterExpressions span[data-expr]');
463+
let not = false;
464+
for ( const elem of elems ) {
465+
const on = dom.cl.has(elem, 'on');
466+
switch ( elem.dataset.expr ) {
467+
case 'not':
468+
not = on;
469+
break;
470+
case 'blocked':
471+
dom.cl.toggle(firewallElem, 'showBlocked', !not && on);
472+
dom.cl.toggle(firewallElem, 'hideBlocked', not && on);
473+
break;
474+
case 'allowed':
475+
dom.cl.toggle(firewallElem, 'showAllowed', !not && on);
476+
dom.cl.toggle(firewallElem, 'hideAllowed', not && on);
477+
break;
478+
case 'script':
479+
dom.cl.toggle(firewallElem, 'show3pScript', !not && on);
480+
dom.cl.toggle(firewallElem, 'hide3pScript', not && on);
481+
break;
482+
case 'frame':
483+
dom.cl.toggle(firewallElem, 'show3pFrame', !not && on);
484+
dom.cl.toggle(firewallElem, 'hide3pFrame', not && on);
485+
break;
486+
default:
487+
break;
488+
}
489+
}
490+
}
491+
492+
dom.on('#firewall .filterExpressions', 'click', 'span[data-expr]', ev => {
493+
const target = ev.target;
494+
dom.cl.toggle(target, 'on');
495+
switch ( target.dataset.expr ) {
496+
case 'blocked':
497+
if ( dom.cl.has(target, 'on') === false ) { break; }
498+
dom.cl.remove('#firewall .filterExpressions span[data-expr="allowed"]', 'on');
499+
break;
500+
case 'allowed':
501+
if ( dom.cl.has(target, 'on') === false ) { break; }
502+
dom.cl.remove('#firewall .filterExpressions span[data-expr="blocked"]', 'on');
503+
break;
504+
}
505+
filterFirewallRows();
506+
const elems = qsa$('#firewall .filterExpressions span[data-expr]');
507+
const filters = Array.from(elems) .map(el => dom.cl.has(el, 'on') ? '1' : '0');
508+
filters.unshift('00');
509+
vAPI.localStorage.setItem('firewallFilters', filters.join(' '));
510+
});
511+
512+
{
513+
vAPI.localStorage.getItemAsync('firewallFilters').then(v => {
514+
if ( v === null ) { return; }
515+
const filters = v.split(' ');
516+
if ( filters.shift() !== '00' ) { return; }
517+
if ( filters.every(v => v === '0') ) { return; }
518+
const elems = qsa$('#firewall .filterExpressions span[data-expr]');
519+
for ( let i = 0; i < elems.length; i++ ) {
520+
if ( filters[i] === '0' ) { continue; }
521+
dom.cl.add(elems[i], 'on');
522+
}
523+
filterFirewallRows();
524+
});
525+
}
526+
527+
/******************************************************************************/
528+
460529
const renderPrivacyExposure = function() {
461530
const allDomains = {};
462531
let allDomainCount = 0;
@@ -1435,15 +1504,3 @@ dom.on('#revertRules', 'click', ( ) => { revertFirewallRules(); });
14351504
dom.on('a[href]', 'click', gotoURL);
14361505

14371506
/******************************************************************************/
1438-
1439-
// Toggle emphasis of rows with[out] 3rd-party scripts/frames
1440-
dom.on('#firewall > [data-type="3p-script"] .filter', 'click', ( ) => {
1441-
dom.cl.toggle('#firewall', 'show3pScript');
1442-
});
1443-
1444-
// Toggle visibility of rows with[out] 3rd-party frames
1445-
dom.on('#firewall > [data-type="3p-frame"] .filter', 'click', ( ) => {
1446-
dom.cl.toggle('#firewall', 'show3pFrame');
1447-
});
1448-
1449-
/******************************************************************************/

src/popup-fenix.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,14 @@
7777
</div>
7878
</div>
7979
<div id="firewall" data-more="e">
80-
<div data-des="*" data-type="*"><span data-i18n="popupAnyRulePrompt"></span><span data-src="/" data-i18n-title="popupTipGlobalRules"> </span><span data-src="." data-i18n-title="popupTipLocalRules"> </span></div>
80+
<section><span class="fa-icon">filter</span><div class="filterExpressions"><div><span data-i18n="loggerRowFiltererBuiltinNot" data-expr="not">_</span><span data-i18n="loggerRowFiltererBuiltinBlocked" data-expr="blocked">_</span><span data-i18n="loggerRowFiltererBuiltinAllowed" data-expr="allowed">_</span></div><div><span data-i18n="loggerRowFiltererBuiltinNot" data-expr="not">_</span><span data-expr="script">&lt;script&gt;</span><span data-expr="frame">&lt;iframe&gt;</span></div></div></section>
81+
<div data-des="*" data-type="*"><span data-i18n="popupAnyRulePrompt">_</span><span data-src="/" data-i18n-title="popupTipGlobalRules"> </span><span data-src="." data-i18n-title="popupTipLocalRules"> </span></div>
8182
<div data-des="*" data-type="image"><span data-i18n="popupImageRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
8283
<div data-des="*" data-type="3p"><span data-i18n="popup3pAnyRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
8384
<div data-des="*" data-type="inline-script"><span data-i18n="popupInlineScriptRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
8485
<div data-des="*" data-type="1p-script"><span data-i18n="popup1pScriptRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
85-
<div data-des="*" data-type="3p-script"><span><span class="filter" data-i18n-title="popup3pScriptFilterTip"></span><span data-i18n="popup3pScriptRulePrompt"></span></span><span data-src="/"> </span><span data-src="."> </span></div>
86-
<div data-des="*" data-type="3p-frame"><span><span class="filter" data-i18n-title="popup3pFrameFilterTip"></span><span data-i18n="popup3pFrameRulePrompt"></span></span><span data-src="/"> </span><span data-src="."> </span></div>
86+
<div data-des="*" data-type="3p-script"><span data-i18n="popup3pScriptRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
87+
<div data-des="*" data-type="3p-frame"><span data-i18n="popup3pFrameRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
8788
</div>
8889
<div id="firewall-vspacer"></div>
8990
</div>

0 commit comments

Comments
 (0)