diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 31547b90f..94edc24f4 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -180,8 +180,8 @@ "description":"" }, "popupHitDomainCountPrompt":{ - "message":"Connected to {{count}} distinct domain(s) out of {{total}}", - "description":"appear in dynamic filtering pane" + "message":"{{count}} out of {{total}}", + "description":"appears in popup" }, "pickerCreate":{ "message":"Create", diff --git a/src/css/popup.css b/src/css/popup.css index 1af20e3b4..6ead129be 100644 --- a/src/css/popup.css +++ b/src/css/popup.css @@ -8,15 +8,19 @@ body { white-space: nowrap; overflow: hidden; } -h1,h2,h3,h4 { - background-color: #444; +h2 { + background-color: #eee; border: 0; - color: white; - cursor: pointer; - margin: 0; - padding: 4px; + color: #666; + font-size: 14px; + font-weight: normal; + margin: 1em 0 0.5em 0; + padding: 2px 0; text-align: center; } +h2:nth-of-type(1) { + margin-top: 0; + } a { color: inherit; text-decoration: none; @@ -75,17 +79,19 @@ body[dir="rtl"] #panes > div:nth-of-type(2) { #panes > div:nth-of-type(1) { min-width: 150px; - padding: 4px 5px 0 5px; + padding: 4px 1px; } p { - margin: 16px 0; text-align: center; white-space: nowrap; } +#switch { + margin: 8px 0; + } #switch .fa { color: green; cursor: pointer; - font-size: 108px; + font-size: 96px; margin: 0; } #switch .fa:hover { @@ -98,20 +104,17 @@ p { color: #888; font-size: 11px; } -[data-i18n="popupBlockedRequestPrompt"] { - font-size: 16px; - } #page-blocked { font-size: 20px; - margin-top: 4px; } -#total-blocked { +.statName { + color: #666; + margin: 1em 0 0.2em 0; + text-align: center; + } +.statValue { font-size: 14px; - margin-bottom: 8px; - margin-top: 4px; - } -.stats { - margin-bottom: 4px; + margin: 0; text-align: center; } .tool { @@ -128,16 +131,14 @@ p { color: #444; } -body.advancedUser #dfToggler { +body.advancedUser h2 { cursor: pointer; } -body.advancedUser #dfToggler:before { - color: gray; +body.advancedUser h2:before { + color: #aaa; content: '+\202F'; - font-size: 14px; - line-height: 14px; } -body.advancedUser #panes.dfEnabled #dfToggler:before { +body.advancedUser #panes.dfEnabled h2:before { content: '\2212\202F'; } diff --git a/src/js/popup.js b/src/js/popup.js index 5e814d430..75ce568fe 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -45,9 +45,12 @@ var dfHotspots = null; var hostnameToSortableTokenMap = {}; var allDomains = {}; var allDomainCount = 0; +var allDomainRows = []; var touchedDomainCount = 0; var rowsToRecycle = uDom(); var cachedPopupHash = ''; +var orStr = vAPI.i18n('popupOr'); +var domainsHitStr = vAPI.i18n('popupHitDomainCountPrompt'); /******************************************************************************/ @@ -152,19 +155,6 @@ var addDynamicFilterRow = function(des) { row.toggleClass('isDomain', des === hnDetails.domain); row.toggleClass('allowed', hnDetails.allowCount !== 0); row.toggleClass('blocked', hnDetails.blockCount !== 0); - - if ( allDomains.hasOwnProperty(hnDetails.domain) === false ) { - allDomains[hnDetails.domain] = false; - allDomainCount += 1; - } - - if ( hnDetails.allowCount !== 0 ) { - if ( allDomains[hnDetails.domain] === false ) { - allDomains[hnDetails.domain] = true; - touchedDomainCount += 1; - } - } - row.appendTo('#dynamicFilteringContainer'); // Hacky? I couldn't figure a CSS recipe for this problem. @@ -257,33 +247,13 @@ var buildAllDynamicFilters = function() { // Remove and reuse all rows: the order may have changed, we can't just // reuse them in-place. - rowsToRecycle = uDom('#privacyInfo ~ div').detach(); + rowsToRecycle = uDom('#dynamicFilteringContainer > div:nth-of-type(7) ~ div').detach(); - allDomains = {}; - allDomainCount = touchedDomainCount = 0; - - // Sort hostnames. First-party hostnames must always appear at the top - // of the list. - var desHostnameDone = {}; - var keys = Object.keys(popupData.dynamicFilterRules) - .sort(rulekeyCompare); - var key, des; - for ( var i = 0; i < keys.length; i++ ) { - key = keys[i]; - des = key.slice(2, key.indexOf(' ', 2)); - // Specific-type rules -- these are built-in - if ( des === '*' || desHostnameDone.hasOwnProperty(des) ) { - continue; - } - addDynamicFilterRow(des); - desHostnameDone[des] = true; + var n = allDomainRows.length; + for ( var i = 0; i < n; i++ ) { + addDynamicFilterRow(allDomainRows[i]); } - var summary = vAPI.i18n('popupHitDomainCountPrompt') - .replace('{{count}}', touchedDomainCount.toLocaleString()) - .replace('{{total}}', allDomainCount.toLocaleString()); - uDom('#privacyInfo').text(summary); - if ( dfPaneBuilt !== true ) { uDom('#dynamicFilteringContainer') .on('click', 'span[data-src]', unsetDynamicFilterHandler) @@ -297,6 +267,46 @@ var buildAllDynamicFilters = function() { /******************************************************************************/ +var renderPrivacyExposure = function() { + allDomains = {}; + allDomainCount = touchedDomainCount = 0; + allDomainRows = []; + + // Sort hostnames. First-party hostnames must always appear at the top + // of the list. + var desHostnameDone = {}; + var keys = Object.keys(popupData.dynamicFilterRules) + .sort(rulekeyCompare); + var key, des, hnDetails; + for ( var i = 0; i < keys.length; i++ ) { + key = keys[i]; + des = key.slice(2, key.indexOf(' ', 2)); + // Specific-type rules -- these are built-in + if ( des === '*' || desHostnameDone.hasOwnProperty(des) ) { + continue; + } + hnDetails = popupData.hostnameDict[des] || {}; + if ( allDomains.hasOwnProperty(hnDetails.domain) === false ) { + allDomains[hnDetails.domain] = false; + allDomainCount += 1; + } + if ( hnDetails.allowCount !== 0 ) { + if ( allDomains[hnDetails.domain] === false ) { + allDomains[hnDetails.domain] = true; + touchedDomainCount += 1; + } + } + allDomainRows.push(des); + desHostnameDone[des] = true; + } + + var summary = domainsHitStr.replace('{{count}}', touchedDomainCount.toLocaleString()) + .replace('{{total}}', allDomainCount.toLocaleString()); + uDom('#privacyExposure').text(summary); +}; + +/******************************************************************************/ + // Assume everything has to be done incrementally. var renderPopup = function() { @@ -316,40 +326,36 @@ var renderPopup = function() { .attr('href', 'devtools.html?tabId=' + popupData.tabId); uDom('#gotoPick').toggleClass('enabled', popupData.canElementPicker === true); - var or = vAPI.i18n('popupOr'); var blocked = popupData.pageBlockedRequestCount; var total = popupData.pageAllowedRequestCount + blocked; - var html = []; + var text = []; if ( total === 0 ) { - html.push('0'); + text.push('0'); } else { - html.push( + text.push( formatNumber(blocked), - ' ', - or, - ' ', - formatNumber(Math.floor(blocked * 100 / total)), - '%' + '\u00a0', orStr, '\u00a0', + formatNumber(Math.floor(blocked * 100 / total)), '%' ); } - uDom('#page-blocked').html(html.join('')); + uDom('#page-blocked').text(text.join('')); blocked = popupData.globalBlockedRequestCount; total = popupData.globalAllowedRequestCount + blocked; - html = []; + text = []; if ( total === 0 ) { - html.push('0'); + text.push('0'); } else { - html.push( + text.push( formatNumber(blocked), - ' ', - or, - ' ', - formatNumber(Math.floor(blocked * 100 / total)), - '%' + '\u00a0', orStr, '\u00a0', + formatNumber(Math.floor(blocked * 100 / total)), '%' ); } - uDom('#total-blocked').html(html.join('')); + uDom('#total-blocked').text(text.join('')); + + // This will collate all domains, touched or not + renderPrivacyExposure(); // https://github.com/gorhill/uBlock/issues/470 // This must be done here, to be sure the popup is resized properly @@ -592,7 +598,7 @@ uDom.onLoad(function() { uDom('#switch').on('click', toggleNetFilteringSwitch); uDom('#gotoPick').on('click', gotoPick); uDom('a[href]').on('click', gotoURL); - uDom('#dfToggler').on('click', toggleDynamicFiltering); + uDom('h2').on('click', toggleDynamicFiltering); uDom('#refresh').on('click', reloadTab); }); diff --git a/src/popup.html b/src/popup.html index f134cd0ee..3d08a00f4 100644 --- a/src/popup.html +++ b/src/popup.html @@ -14,15 +14,17 @@