diff --git a/src/css/3p-filters.css b/src/css/3p-filters.css index 96b95b810..785a5115d 100644 --- a/src/css/3p-filters.css +++ b/src/css/3p-filters.css @@ -182,22 +182,25 @@ body.updating .listEntry.checked.obsolete .updating { visibility: visible; } -@media (pointer: coarse) { - .listEntries { - margin-inline-start: 0; - -webkit-margin-start: 0; - } - .li.listEntry { - background-color: var(--bg-1); - overflow-x: auto; - } - .li.listEntry label > span { - flex-grow: 1; - padding-inline-start: 0.3em; - } - .li.listEntry .listname, - .li.listEntry .iconbar, - .li.listEntry.checked .counts { - display: block; - } -} +/* touch-screen devices */ +:root.mobile .listEntry .fa-icon { + font-size: 120%; + margin: 0 0.5em 0 0; + } +:root.mobile .listEntries { + margin-inline-start: 0; + -webkit-margin-start: 0; + } +:root.mobile .li.listEntry { + background-color: var(--bg-1); + overflow-x: auto; + } +:root.mobile .li.listEntry label > span { + flex-grow: 1; + padding-inline-start: 0.3em; + } +:root.mobile .li.listEntry .listname, +:root.mobile .li.listEntry .iconbar, +:root.mobile .li.listEntry.checked .counts { + display: block; + } diff --git a/src/css/common.css b/src/css/common.css index 5809757fa..8d6977c1e 100644 --- a/src/css/common.css +++ b/src/css/common.css @@ -1,17 +1,10 @@ -body { - font: 14px/1.5 sans-serif; - } -@media (pointer: coarse) { - body { - font: 16px/1.5 sans-serif; - } -} body { background-color: var(--bg-0); border: 0; box-sizing: border-box; color: var(--fg-0); fill: var(--fg-0); + font: 14px/1.5 sans-serif; margin: 0; padding: 0; } @@ -94,11 +87,6 @@ label { align-items: center; display: inline-flex; } -@media (pointer: coarse) { - label { - flex-grow: 1 - } -} input[type="checkbox"] { margin: 0; margin-inline-start: 0.4em; @@ -156,3 +144,11 @@ input[type="checkbox"] { height: 1em; width: 1em; } + +/* touch-screen devices */ +:root.mobile body { + font: 16px/1.5 sans-serif; + } +:root.mobile label { + flex-grow: 1 + } diff --git a/src/css/dashboard-common.css b/src/css/dashboard-common.css index 546b5104b..0d95de9cc 100644 --- a/src/css/dashboard-common.css +++ b/src/css/dashboard-common.css @@ -23,7 +23,7 @@ a { .fa-icon.info { color: var(--fg-icon-info-lvl-0-dimmed); fill: var(--fg-icon-info-lvl-0-dimmed); - font-size: 120%; + font-size: 115%; } .fa.info:hover, .fa-icon.info:hover { diff --git a/src/css/dashboard.css b/src/css/dashboard.css index b32b9763b..dc7c5d4e5 100644 --- a/src/css/dashboard.css +++ b/src/css/dashboard.css @@ -76,12 +76,11 @@ body:not(.canUpdateShortcuts) .tabButton[data-pane="shortcuts.html"] { display: none; } -@media (pointer: coarse) { - #dashboard-nav { - flex-wrap: nowrap; - overflow-x: auto; +/* touch-screen devices */ +:root.mobile #dashboard-nav { + flex-wrap: nowrap; + overflow-x: auto; } - #dashboard-nav .logo { - display: none; +:root.mobile #dashboard-nav .logo { + display: none; } -} diff --git a/src/css/popup-fenix.css b/src/css/popup-fenix.css index 16b390c8b..b74128d46 100644 --- a/src/css/popup-fenix.css +++ b/src/css/popup-fenix.css @@ -10,15 +10,8 @@ /* Internal CSS values */ body { font: 14px/20px sans-serif; - min-width: 360px; - white-space: nowrap; + width: 100%; } -@media (pointer: coarse) { - body { - min-width: unset; - width: 100%; - } -} a { color: inherit; text-decoration: none; @@ -27,7 +20,7 @@ a { outline: 0; } -#main { +#panes { align-items: stretch; display: flex; flex-direction: column; @@ -109,20 +102,20 @@ body.needSave #revertRules { .itemRibbon { display: grid; + gap: 0.8em 1em; grid-template: auto / auto auto; padding: 1em 1em; } .itemRibbon > [data-i18n] + span { justify-self: end; + text-align: end; + white-space: nowrap; } .itemRibbon > .h-gutter { display: inline-block; height: 1em; } -#basicStats { - } - .toolRibbon { align-items: start; display: grid; @@ -173,7 +166,7 @@ body.needSave #revertRules { visibility: visible; } -#main:not(.dfEnabled) #moreButton .fa-icon { +body:not(.dfEnabled) #moreButton .fa-icon { transform: rotate(180deg); } @@ -210,7 +203,7 @@ body[dir="rtl"] #tooltip { opacity: 1; } -#firewallContainer { +#firewall { border: 0; flex-shrink: 0; font-family: "Noto Sans", sans-serif; @@ -220,10 +213,10 @@ body[dir="rtl"] #tooltip { overflow: hidden; text-align: right; } -#main:not(.dfEnabled) #firewallContainer { +body:not(.dfEnabled) #firewall { display: none; } -#firewallContainer > div { +#firewall > div { border: 0; direction: ltr; display: flex; @@ -232,17 +225,17 @@ body[dir="rtl"] #tooltip { margin-top: 1px; padding: 0; } -#firewallContainer > div:first-child { +#firewall > div:first-child { margin-top: 0; } -#firewallContainer > div:first-child ~ div[data-des="*"] { +#firewall > div:first-child ~ div[data-des="*"] { display: none; } -#firewallContainer:not(.expanded) > div.isSubDomain:not(.expandException):not(.isRootContext), -#firewallContainer.expanded > div.isSubDomain.expandException:not(.isRootContext) { +#firewall:not(.expanded) > div.isSubDomain:not(.expandException):not(.isRootContext), +#firewall.expanded > div.isSubDomain.expandException:not(.isRootContext) { display: none; } -#firewallContainer > div > span { +#firewall > div > span { background-color: var(--bg-popup-cell-2); border: none; box-sizing: border-box; @@ -251,11 +244,11 @@ body[dir="rtl"] #tooltip { padding: 0.4em 0; position: relative; } -#firewallContainer > div:first-of-type > span:first-of-type { +#firewall > div:first-of-type > span:first-of-type { cursor: pointer; flex-direction: unset; } -#firewallContainer > div > span:first-of-type { +#firewall > div > span:first-of-type { align-items: flex-end; flex-direction: column; flex-grow: 1; @@ -265,116 +258,116 @@ body[dir="rtl"] #tooltip { width: calc(100% - 5em); word-break: break-word; } -#firewallContainer > div.isCname > span:first-of-type { +#firewall > div.isCname > span:first-of-type { color: var(--fg-popup-cell-cname); } -#firewallContainer > div > span:first-of-type > sub { +#firewall > div > span:first-of-type > sub { display: inline-block; font-size: 85%; font-weight: normal; padding: 0.25em 0 0 0; } -#firewallContainer > div > span:first-of-type > sub:empty { +#firewall > div > span:first-of-type > sub:empty { display: none; } -#firewallContainer > div > span:first-of-type ~ span { +#firewall > div > span:first-of-type ~ span { flex-shrink: 0; margin-left: 1px; width: 5em; } -#firewallContainer > div > span:nth-of-type(2) { +#firewall > div > span:nth-of-type(2) { display: none; } -#firewallContainer > div > span:nth-of-type(3), -#firewallContainer > div > span:nth-of-type(4) { +#firewall > div > span:nth-of-type(3), +#firewall > div > span:nth-of-type(4) { color: var(--fg-0-70); display: none; font-family: monospace; text-align: center; } -#firewallContainer > div.isDomain > span:first-of-type { +#firewall > div.isDomain > span:first-of-type { font-weight: bold; } -#firewallContainer > div:first-of-type > span:first-of-type::before { +#firewall > div:first-of-type > span:first-of-type::before { color: var(--fg-0-50); content: '+'; padding-right: 0.25em; } -#firewallContainer.expanded > div:first-of-type > span:first-of-type::before { +#firewall.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) { +#firewall > div[data-des="*"] > span:nth-of-type(3), +#firewall > div.isSubDomain > span:nth-of-type(3), +#firewall > div.isSubDomain.isRootContext > span:nth-of-type(3), +#firewall.expanded > div:not(.expandException) > span:nth-of-type(3), +#firewall:not(.expanded) > div.expandException > span:nth-of-type(3), +#firewall:not(.expanded) > div.isDomain:not(.expandException) > span:nth-of-type(4), +#firewall.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, -#firewallContainer > div > span[data-acount] > #actionSelector > #dynaCounts::before, -#firewallContainer > div > span[data-acount] > #actionSelector > #dynaCounts::after { +#firewall > div > span[data-acount]::before, +#firewall > div > span[data-bcount]::after, +#firewall > div > span[data-acount] > #actionSelector > #dynaCounts::before, +#firewall > div > span[data-acount] > #actionSelector > #dynaCounts::after { content: ' '; } -#firewallContainer > div > span[data-acount]::before, -#firewallContainer > div > span[data-acount] > #actionSelector > #dynaCounts::before { +#firewall > div > span[data-acount]::before, +#firewall > div > span[data-acount] > #actionSelector > #dynaCounts::before { padding-left: 0.1em; } -#firewallContainer > div > span[data-acount="1"]::before, -#firewallContainer > div > span[data-acount="1"] > #actionSelector > #dynaCounts::before { +#firewall > div > span[data-acount="1"]::before, +#firewall > div > span[data-acount="1"] > #actionSelector > #dynaCounts::before { content: '+'; } -#firewallContainer > div > span[data-acount="2"]::before, -#firewallContainer > div > span[data-acount="2"] > #actionSelector > #dynaCounts::before { +#firewall > div > span[data-acount="2"]::before, +#firewall > div > span[data-acount="2"] > #actionSelector > #dynaCounts::before { content: '++'; } -#firewallContainer > div > span[data-acount="3"]::before, -#firewallContainer > div > span[data-acount="3"] > #actionSelector > #dynaCounts::before { +#firewall > div > span[data-acount="3"]::before, +#firewall > div > span[data-acount="3"] > #actionSelector > #dynaCounts::before { content: '+++'; } -#firewallContainer > div > span[data-bcount]::after, -#firewallContainer > div > span[data-bcount] > #actionSelector > #dynaCounts::after { +#firewall > div > span[data-bcount]::after, +#firewall > div > span[data-bcount] > #actionSelector > #dynaCounts::after { padding-right: 0.1em; } -#firewallContainer > div > span[data-bcount="1"]::after, -#firewallContainer > div > span[data-bcount="1"] > #actionSelector > #dynaCounts::after { +#firewall > div > span[data-bcount="1"]::after, +#firewall > div > span[data-bcount="1"] > #actionSelector > #dynaCounts::after { content: '\2212'; } -#firewallContainer > div > span[data-bcount="2"]::after, -#firewallContainer > div > span[data-bcount="2"] > #actionSelector > #dynaCounts::after { +#firewall > div > span[data-bcount="2"]::after, +#firewall > div > span[data-bcount="2"] > #actionSelector > #dynaCounts::after { content: '\2212\2212'; } -#firewallContainer > div > span[data-bcount="3"]::after, -#firewallContainer > div > span[data-bcount="3"] > #actionSelector > #dynaCounts::after { +#firewall > div > span[data-bcount="3"]::after, +#firewall > div > span[data-bcount="3"] > #actionSelector > #dynaCounts::after { content: '\2212\2212\2212'; } -body.advancedUser #firewallContainer > div > span:first-of-type { +body.advancedUser #firewall > div > span:first-of-type { width: calc(100% - 10em); } -body.advancedUser #firewallContainer > div > span:nth-of-type(2) { +body.advancedUser #firewall > div > span:nth-of-type(2) { display: inline-flex; } -body.advancedUser #firewallContainer > div:first-child ~ div[data-des="*"] { +body.advancedUser #firewall > div:first-child ~ div[data-des="*"] { display: flex; } -body.advancedUser #firewallContainer > div > span:first-of-type ~ span { +body.advancedUser #firewall > 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 { +#firewall > div.isRootContext > span:first-of-type::before, +#firewall > div.allowed > span:first-of-type::before, +#firewall > div.blocked > span:first-of-type::before, +#firewall:not(.expanded) > div.isDomain.totalAllowed:not(.expandException) > span:first-of-type::before, +#firewall:not(.expanded) > div.isDomain.totalBlocked:not(.expandException) > span:first-of-type::before, +#firewall.expanded > div.isDomain.totalAllowed.expandException > span:first-of-type::before, +#firewall.expanded > div.isDomain.totalBlocked.expandException > span:first-of-type::before { box-sizing: border-box; content: ''; display: inline-block; @@ -385,48 +378,48 @@ body.advancedUser #firewallContainer > div > span:first-of-type ~ span { top: 0; width: 7px; } -#firewallContainer > div.isRootContext > span:first-of-type::before { +#firewall > div.isRootContext > span:first-of-type::before { background-color: var(--fg-0-50); width: 14px !important; } -#firewallContainer > div.allowed > span:first-of-type::before, -#firewallContainer > div.isDomain.totalAllowed > span:first-of-type::before { +#firewall > div.allowed > span:first-of-type::before, +#firewall > div.isDomain.totalAllowed > span:first-of-type::before { background-color: var(--bg-popup-cell-allow-own); } -#firewallContainer > div.blocked > span:first-of-type::before, -#firewallContainer > div.isDomain.totalBlocked > span:first-of-type::before { +#firewall > div.blocked > span:first-of-type::before, +#firewall > div.isDomain.totalBlocked > span:first-of-type::before { background-color: var(--bg-popup-cell-block-own); } -#firewallContainer > div.allowed.blocked > span:first-of-type::before, -#firewallContainer > div.isDomain.totalAllowed.totalBlocked > span:first-of-type::before { +#firewall > div.allowed.blocked > span:first-of-type::before, +#firewall > div.isDomain.totalAllowed.totalBlocked > span:first-of-type::before { background-color: var(--bg-popup-cell-label-mixed); } /* Rule cells */ -body.advancedUser #firewallContainer > div > span.allowRule, +body.advancedUser #firewall > div > span.allowRule, #actionSelector > #dynaAllow { background-color: var(--bg-popup-cell-allow); } -body.advancedUser #firewallContainer > div > span.blockRule, +body.advancedUser #firewall > div > span.blockRule, #actionSelector > #dynaBlock { background-color: var(--bg-popup-cell-block); } -body.advancedUser #firewallContainer > div > span.noopRule, +body.advancedUser #firewall > div > span.noopRule, #actionSelector > #dynaNoop { background-color: var(--bg-popup-cell-noop); } -body.advancedUser #firewallContainer > div > span.ownRule, -#firewallContainer > div > span.ownRule { +body.advancedUser #firewall > div > span.ownRule, +#firewall > div > span.ownRule { color: var(--bg-0); } -body.advancedUser #firewallContainer > div > span.allowRule.ownRule, +body.advancedUser #firewall > div > span.allowRule.ownRule, #actionSelector > #dynaAllow:hover { background-color: var(--bg-popup-cell-allow-own); } -body.advancedUser #firewallContainer > div > span.blockRule.ownRule, +body.advancedUser #firewall > div > span.blockRule.ownRule, #actionSelector > #dynaBlock:hover { background-color: var(--bg-popup-cell-block-own); } -body.advancedUser #firewallContainer > div > span.noopRule.ownRule, +body.advancedUser #firewall > div > span.noopRule.ownRule, #actionSelector > #dynaNoop:hover { background-color: var(--bg-popup-cell-noop-own); } @@ -465,3 +458,37 @@ body.advancedUser #firewallContainer > div > span.noopRule.ownRule, top: 0; width: 100%; } + +/* mouse-driven devices */ +:root.desktop body { + overflow: hidden; + } +:root.desktop #panes { + flex-direction: row-reverse; + width: unset; + } +:root.desktop #main { + max-width: 300px; + width: max-content; + } +:root.desktop #firewall { + direction: rtl; + flex-grow: 1; + line-height: 1.4; + max-height: 540px; + min-height: 100vh; + max-width: 400px; + min-width: 360px; + overflow-y: auto; + width: max-content; + } +:root.desktop .tool { + padding: 0.5em; + } +:root.desktop .tool:hover { + background-color: var(--bg-button); + } +:root.desktop .tool [data-i18n] { + /* display: none; */ + width: min-content; + } diff --git a/src/css/themes/default.css b/src/css/themes/default.css index 337c61c02..a91cf3fe1 100644 --- a/src/css/themes/default.css +++ b/src/css/themes/default.css @@ -92,12 +92,8 @@ /* Default dark theme starts here */ -@media (prefers-color-scheme: dark) { - - :root { - } - - :root.colorBlind { - } - +:root.darkTheme { +} + +:root.darkTheme.colorBlind { } diff --git a/src/js/popup-fenix.js b/src/js/popup-fenix.js index 86eb9786f..b57c01078 100644 --- a/src/js/popup-fenix.js +++ b/src/js/popup-fenix.js @@ -44,12 +44,22 @@ let dfPaneVisibleStored; vAPI.localStorage.getItemAsync('popupFirewallPane').then(value => { dfPaneVisibleStored = value === true || value === 'true'; if ( dfPaneVisibleStored ) { - document.getElementById('main').classList.add('dfEnabled'); + document.body.classList.add('dfEnabled'); } }); /******************************************************************************/ +if ( uDom.root.classList.contains('desktop') ) { + const sticky = document.getElementById('sticky'); + const main = document.getElementById('main'); + if ( sticky.parentElement !== main ) { + document.getElementById('main').prepend(sticky); + } +} + +/******************************************************************************/ + const messaging = vAPI.messaging; const reIP = /^\d+(?:\.\d+){1,3}$/; const scopeToSrcHostnameMap = { @@ -178,7 +188,7 @@ const rulekeyCompare = function(a, b) { const updateFirewallCell = function(scope, des, type, rule) { const row = document.querySelector( - `#firewallContainer div[data-des="${des}"][data-type="${type}"]` + `#firewall div[data-des="${des}"][data-type="${type}"]` ); if ( row === null ) { return; } @@ -271,7 +281,7 @@ const buildAllFirewallRows = function() { dfHotspots.remove(); // Update incrementally: reuse existing rows if possible. - const rowContainer = document.getElementById('firewallContainer'); + const rowContainer = document.getElementById('firewall'); const toAppend = document.createDocumentFragment(); const rowTemplate = document.querySelector('#templates > div:nth-of-type(1)'); let row = rowContainer.querySelector('div:nth-of-type(7) + div'); @@ -332,7 +342,7 @@ const buildAllFirewallRows = function() { } if ( dfPaneBuilt !== true && popupData.advancedUserEnabled ) { - uDom('#firewallContainer') + uDom('#firewall') .on('click', 'span[data-src]', unsetFirewallRuleHandler) .on('mouseenter', '[data-src]', mouseenterCellHandler) .on('mouseleave', '[data-src]', mouseleaveCellHandler); @@ -473,7 +483,7 @@ const renderPopup = function() { vAPI.localStorage.setItem('popupFirewallPane', dfPaneVisibleStored); } - uDom.nodeFromId('main').classList.toggle( + document.body.classList.toggle( 'dfEnabled', dfPaneVisible === true ); @@ -578,7 +588,7 @@ let renderOnce = function() { // https://github.com/uBlockOrigin/uBlock-issues/issues/22 if ( popupData.advancedUserEnabled !== true ) { - uDom('#firewallContainer [data-i18n-tip][data-src]').removeAttr('data-tip'); + uDom('#firewall [data-i18n-tip][data-src]').removeAttr('data-tip'); } }; @@ -718,7 +728,7 @@ const toggleFirewallPane = function() { vAPI.localStorage.setItem('popupFirewallPane', dfPaneVisibleStored); // Dynamic filtering pane may not have been built yet - uDom.nodeFromId('main').classList.toggle('dfEnabled', popupData.dfEnabled); + document.body.classList.toggle('dfEnabled', popupData.dfEnabled); if ( popupData.dfEnabled && dfPaneBuilt === false ) { buildAllFirewallRows(); } @@ -868,9 +878,9 @@ const saveExpandExceptions = function() { const setGlobalExpand = function(state, internal = false) { uDom('.expandException').removeClass('expandException'); if ( state ) { - uDom('#firewallContainer').addClass('expanded'); + uDom('#firewall').addClass('expanded'); } else { - uDom('#firewallContainer').removeClass('expanded'); + uDom('#firewall').removeClass('expanded'); } if ( internal ) { return; } popupData.firewallPaneMinimized = !state; @@ -917,11 +927,11 @@ uDom('[data-i18n="popupAnyRulePrompt"]').on('click', ev => { } setGlobalExpand( - uDom('#firewallContainer').hasClass('expanded') === false + uDom('#firewall').hasClass('expanded') === false ); }); -uDom('#firewallContainer').on( +uDom('#firewall').on( 'click', '.isDomain[data-type="*"] > span:first-of-type', ev => { const div = ev.target.closest('[data-des]'); diff --git a/src/js/udom.js b/src/js/udom.js index d681b9dcc..92b5ab65a 100644 --- a/src/js/udom.js +++ b/src/js/udom.js @@ -32,7 +32,7 @@ // the code here does *only* what I need, and nothing more, and with a lot // of assumption on passed parameters, etc. I grow it on a per-need-basis only. -const uDom = (function() { +const uDom = (( ) => { /******************************************************************************/ @@ -92,6 +92,27 @@ DOMListFactory.nodeFromSelector = function(selector) { /******************************************************************************/ +{ + const root = DOMListFactory.root = document.querySelector(':root'); + if ( + window.matchMedia('(pointer: coarse)').matches || + window.matchMedia('(hover: none)').matches + ) { + root.classList.add('mobile'); + } + if ( + window.matchMedia('(pointer: fine)').matches && + window.matchMedia('(hover: hover)').matches + ) { + root.classList.add('desktop'); + } + if ( window.matchMedia('(prefers-color-scheme: dark)').matches ) { + root.classList.add('darkTheme'); + } +} + +/******************************************************************************/ + const addNodeToList = function(list, node) { if ( node ) { list.nodes.push(node); diff --git a/src/popup-fenix.html b/src/popup-fenix.html index edebc5c22..3cda7ecf9 100644 --- a/src/popup-fenix.html +++ b/src/popup-fenix.html @@ -12,7 +12,7 @@ -
+
@@ -28,32 +28,32 @@

-
- bolt - eye-dropper - list-alt - sliders +
+
+ bolt + eye-dropper + list-alt + sliders +
+
+
+ + + +
+
+
+ film + eye-slash + font + code +
+
+
+ angle-up +
-
-
- - - - - -
-
-
- film - eye-slash - font - code -
-
-
- angle-up -
-
+