diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 57ef7e5f7..0dd67de0f 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -113,19 +113,35 @@ "message": "You can inspect the details of blocked requests if you wish by enabling this option. The logging of blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.", "description": "English: see _locales/en/messages.log" }, - "logBlockedRequestsHeaderType" : { + "logAllowedRequestsPrompt" : { + "message": "Enable the logging of non-blocked requests", + "description": "English: Enable the logging of non-blocked requests" + }, + "logAllowedRequestsHelp" : { + "message": "You can inspect the details of non-blocked requests if you wish by enabling this option. The logging of non-blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.", + "description": "English: see _locales/en/messages.log" + }, + "logBlockedRequestsHeader" : { + "message": "Blocked requests", + "description": "English: Blocked requests" + }, + "logAllowedRequestsHeader" : { + "message": "Allowed requests", + "description": "English: Allowed requests" + }, + "logRequestsHeaderType" : { "message": "Type", "description": "English: Type" }, - "logBlockedRequestsHeaderDomain" : { + "logRequestsHeaderDomain" : { "message": "Domain", "description": "English: Domain" }, - "logBlockedRequestsHeaderURL" : { - "message": "Blocked URL", - "description": "English: Blocked URL" + "logRequestsHeaderURL" : { + "message": "URL", + "description": "English: URL" }, - "logBlockedRequestsHeaderFilter" : { + "logRequestsHeaderFilter" : { "message": "Filter", "description": "English: Filter" }, @@ -133,6 +149,10 @@ "message": "No blocked requests logged for this page", "description": "English: No blocked requests logged for this page" }, + "logAllowedRequestsEmpty" : { + "message": "No non-blocked requests logged for this page", + "description": "English: No non-blocked requests logged for this page" + }, "aboutChangelog" : { diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index a918fc1fc..0f91250f3 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -113,19 +113,35 @@ "message": "Vous pouvez inspecter les détails des requêtes bloquées en activant cette option. La journalisation des requêtes bloquées augmente l'empreinte mémoire utilisée par µBlock. Puisque que bon nombre d'utilisateurs n'utiliseront jamais cette fonctionnalité, elle est désactivée par défaut.", "description": "English: see _locales/en/messages.log" }, - "logBlockedRequestsHeaderType" : { + "logAllowedRequestsPrompt" : { + "message": "Activer la journalisation des requêtes permises", + "description": "English: Enable the logging of non-blocked requests" + }, + "logAllowedRequestsHelp" : { + "message": "Vous pouvez inspecter les détails des requêtes permises en activant cette option. La journalisation des requêtes permises augmente l'empreinte mémoire utilisée par µBlock. Puisque que bon nombre d'utilisateurs n'utiliseront jamais cette fonctionnalité, elle est désactivée par défaut.", + "description": "English: see _locales/en/messages.log" + }, + "logBlockedRequestsHeader" : { + "message": "Requêtes bloquées", + "description": "English: Blocked requests" + }, + "logAllowedRequestsHeader" : { + "message": "Requêtes permises", + "description": "English: Allowed requests" + }, + "logRequestsHeaderType" : { "message": "Type", "description": "English: Type" }, - "logBlockedRequestsHeaderDomain" : { + "logRequestsHeaderDomain" : { "message": "Domaine", - "description": "English: Domaine" + "description": "English: Domain" }, - "logBlockedRequestsHeaderURL" : { - "message": "URL bloquée", - "description": "English: Blocked URL" + "logRequestsHeaderURL" : { + "message": "URL", + "description": "English: URL" }, - "logBlockedRequestsHeaderFilter" : { + "logRequestsHeaderFilter" : { "message": "Filtre", "description": "English: Filter" }, @@ -133,6 +149,10 @@ "message": "Il n'y a aucune requête bloquée dans le journal", "description": "English: No blocked requests logged for this page" }, + "logAllowedRequestsEmpty" : { + "message": "Il n'y a aucune requête non-bloquée dans le journal", + "description": "English: No non-blocked requests logged for this page" + }, "aboutChangelog" : { diff --git a/_locales/it/messages.json b/_locales/it/messages.json index cb04d3ac2..b603cd81d 100644 --- a/_locales/it/messages.json +++ b/_locales/it/messages.json @@ -113,26 +113,46 @@ "message": "Puoi controllare i dettagli delle richieste bloccate se abiliti questa opzione. La registrazione delle richieste bloccate aumenta l'uso della memoria da parte di µBlock. Di default è disabilitata, poiché la maggior parte degli utenti non ha bisogno di questa funzione.", "description": "English: see _locales/en/messages.log" }, - "logBlockedRequestsHeaderType" : { + "logAllowedRequestsPrompt" : { + "message": "Enable the logging of non-blocked requests", + "description": "English: Enable the logging of non-blocked requests" + }, + "logAllowedRequestsHelp" : { + "message": "You can inspect the details of non-blocked requests if you wish by enabling this option. The logging of non-blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.", + "description": "English: see _locales/en/messages.log" + }, + "logBlockedRequestsHeader" : { + "message": "Richieste bloccate", + "description": "English: Blocked requests" + }, + "logAllowedRequestsHeader" : { + "message": "Allowed requests", + "description": "English: Allowed requests" + }, + "logRequestsHeaderType" : { "message": "Tipo", "description": "English: Type" }, - "logBlockedRequestsHeaderDomain" : { + "logRequestsHeaderDomain" : { "message": "Dominio", "description": "English: Domain" }, - "logBlockedRequestsHeaderURL" : { - "message": "Indirizzo bloccato", - "description": "English: Blocked URL" + "logRequestsHeaderURL" : { + "message": "Indirizzo", + "description": "English: URL" }, - "logBlockedRequestsHeaderFilter" : { + "logRequestsHeaderFilter" : { "message": "Filtro", "description": "English: Filter" }, "logBlockedRequestsEmpty" : { - "message": "Nel registro, non ci sono richieste bloccate per questa pagina.", + "message": "Nel registro, non ci sono richieste bloccate per questa pagina", "description": "English: No blocked requests logged for this page" }, + "logAllowedRequestsEmpty" : { + "message": "No non-blocked requests logged for this page", + "description": "English: No non-blocked requests logged for this page" + }, "aboutChangelog" : { diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json index b7fa549cc..b4603a84b 100644 --- a/_locales/ru/messages.json +++ b/_locales/ru/messages.json @@ -113,19 +113,35 @@ "message": "You can inspect the details of blocked requests if you wish by enabling this option. The logging of blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.", "description": "English: see _locales/en/messages.log" }, - "logBlockedRequestsHeaderType" : { + "logAllowedRequestsPrompt" : { + "message": "Enable the logging of non-blocked requests", + "description": "English: Enable the logging of non-blocked requests" + }, + "logAllowedRequestsHelp" : { + "message": "You can inspect the details of non-blocked requests if you wish by enabling this option. The logging of non-blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.", + "description": "English: see _locales/en/messages.log" + }, + "logBlockedRequestsHeader" : { + "message": "Blocked requests", + "description": "English: Blocked requests" + }, + "logAllowedRequestsHeader" : { + "message": "Allowed requests", + "description": "English: Allowed requests" + }, + "logRequestsHeaderType" : { "message": "Type", "description": "English: Type" }, - "logBlockedRequestsHeaderDomain" : { + "logRequestsHeaderDomain" : { "message": "Domain", "description": "English: Domain" }, - "logBlockedRequestsHeaderURL" : { - "message": "Blocked URL", - "description": "English: Blocked URL" + "logRequestsHeaderURL" : { + "message": "URL", + "description": "English: URL" }, - "logBlockedRequestsHeaderFilter" : { + "logRequestsHeaderFilter" : { "message": "Filter", "description": "English: Filter" }, @@ -133,6 +149,10 @@ "message": "No blocked requests logged for this page", "description": "English: No blocked requests logged for this page" }, + "logAllowedRequestsEmpty" : { + "message": "No non-blocked requests logged for this page", + "description": "English: No non-blocked requests logged for this page" + }, "aboutChangelog" : { diff --git a/_locales/zh_CN/messages.json b/_locales/zh_CN/messages.json index 1d6294628..a362338d9 100644 --- a/_locales/zh_CN/messages.json +++ b/_locales/zh_CN/messages.json @@ -113,19 +113,35 @@ "message": "如果你想要开启此选项,你将可以查看拦截广告的详情。拦截记录会增加µBlock的内存占用。由于很多用户用不到这个功能,它默认是禁用的。", "description": "English: see _locales/en/messages.log" }, - "logBlockedRequestsHeaderType" : { + "logAllowedRequestsPrompt" : { + "message": "Enable the logging of non-blocked requests", + "description": "English: Enable the logging of non-blocked requests" + }, + "logAllowedRequestsHelp" : { + "message": "You can inspect the details of non-blocked requests if you wish by enabling this option. The logging of non-blocked requests increases the memory footprint of µBlock. Since many users will never use this feature, it is disabled by default.", + "description": "English: see _locales/en/messages.log" + }, + "logBlockedRequestsHeader" : { + "message": "Blocked requests", + "description": "English: Blocked requests" + }, + "logAllowedRequestsHeader" : { + "message": "Allowed requests", + "description": "English: Allowed requests" + }, + "logRequestsHeaderType" : { "message": "类型", "description": "English: Type" }, - "logBlockedRequestsHeaderDomain" : { + "logRequestsHeaderDomain" : { "message": "域名", "description": "English: Domain" }, - "logBlockedRequestsHeaderURL" : { - "message": "屏蔽网站", - "description": "English: Blocked URL" + "logRequestsHeaderURL" : { + "message": "网址", + "description": "English: URL" }, - "logBlockedRequestsHeaderFilter" : { + "logRequestsHeaderFilter" : { "message": "过滤", "description": "English: Filter" }, @@ -133,6 +149,10 @@ "message": "该页面没有拦截记录", "description": "English: No blocked requests logged for this page" }, + "logAllowedRequestsEmpty" : { + "message": "No non-blocked requests logged for this page", + "description": "English: No non-blocked requests logged for this page" + }, "aboutChangelog" : { diff --git a/dist/it/description.txt b/dist/it/description.txt index 1660960ca..7075ab8d6 100644 --- a/dist/it/description.txt +++ b/dist/it/description.txt @@ -36,14 +36,6 @@ Senza queste liste di filtri, questa estensione non è niente. Così se vuoi con *** -Poichè le recensioni non consentono all'autore di rispondere, ho deciso di rispondere attraverso il sito principale del progetto. - -https://github.com/gorhill/uBlock/wiki/My-answer-to-web-store-reviews-where-appropriate - -*** - -Dall'autore di HTTP Switchboard. - Gratuito. Open source with public license (GPLv3) Fatto dagli utenti per gli utenti. diff --git a/js/abp-filters.js b/js/abp-filters.js index f990bc92a..7a64a9b96 100644 --- a/js/abp-filters.js +++ b/js/abp-filters.js @@ -1415,17 +1415,16 @@ FilterContainer.prototype.matchString = function(pageDetails, url, requestType, var categories = this.categories; // Test hostname-based block filters - var bf = false; - bf = this.matchAnyPartyHostname(requestHostname); - if ( bf === false && party === ThirdParty ) { - bf = this.match3rdPartyHostname(requestHostname); + var br = this.matchAnyPartyHostname(requestHostname); + if ( br === false && party === ThirdParty ) { + br = this.match3rdPartyHostname(requestHostname); } // This will be used by hostname-based filters pageHostname = pageDetails.pageHostname || ''; // Test against block filters - if ( bf === false ) { + if ( br === false ) { this.bucket0 = categories[this.makeCategoryKey(BlockAnyTypeAnyParty)]; this.bucket1 = categories[this.makeCategoryKey(BlockAnyType | party)]; this.bucket2 = categories[this.makeCategoryKey(BlockAnyTypeOneParty | domainParty)]; @@ -1435,11 +1434,11 @@ FilterContainer.prototype.matchString = function(pageDetails, url, requestType, this.bucket6 = categories[this.makeCategoryKey(BlockOneParty | type | domainParty)]; this.bucket7 = categories[this.makeCategoryKey(BlockOtherParties | type)]; - bf = this.matchTokens(); + br = this.matchTokens(); } // If there is no block filter, no need to test against allow filters - if ( bf === false ) { + if ( br === false ) { return false; } @@ -1453,11 +1452,12 @@ FilterContainer.prototype.matchString = function(pageDetails, url, requestType, this.bucket6 = categories[this.makeCategoryKey(AllowOneParty | type | domainParty)]; this.bucket7 = categories[this.makeCategoryKey(AllowOtherParties | type | domainParty)]; - if ( this.matchTokens() !== false ) { - return false; + var ar = this.matchTokens(); + if ( ar !== false ) { + return '@@' + ar; } - return bf; + return br; }; /******************************************************************************/ diff --git a/js/async.js b/js/async.js index fa0d680ec..c232829a2 100644 --- a/js/async.js +++ b/js/async.js @@ -133,7 +133,7 @@ return asyncJobManager; // Update visual of extension icon. // A time out is used to coalesce adjacent requests to update badge. -µBlock.updateBadge = function(tabId) { +µBlock.updateBadgeAsync = function(tabId) { if ( tabId < 0 ) { return; } diff --git a/js/background.js b/js/background.js index 1cb5278d3..b1d883cb9 100644 --- a/js/background.js +++ b/js/background.js @@ -33,6 +33,7 @@ return { userSettings: { collapseBlocked: true, logBlockedRequests: false, + logAllowedRequests: false, parseAllABPHideFilters: true, netExceptionList: {}, showIconBadge: true diff --git a/js/messaging-handlers.js b/js/messaging-handlers.js index 597e6cbcb..e5ce663b7 100644 --- a/js/messaging-handlers.js +++ b/js/messaging-handlers.js @@ -40,7 +40,8 @@ var getStats = function(request) { pageAllowedRequestCount: 0, netFilteringSwitch: false, cosmeticFilteringSwitch: false, - logBlockedRequests: µb.userSettings.logBlockedRequests + logBlockedRequests: µb.userSettings.logBlockedRequests, + logAllowedRequests: µb.userSettings.logAllowedRequests }; var pageStore = µb.pageStoreFromTabId(request.tabId); if ( pageStore ) { @@ -75,7 +76,7 @@ var onMessage = function(request, sender, callback) { request.hostname, request.state ); - µBlock.updateBadge(request.tabId); + µBlock.updateBadgeAsync(request.tabId); break; default: @@ -260,33 +261,43 @@ var onMessage = function(request, sender, callback) { var getPageDetails = function(µb, tabId) { var r = { - requests: [], + blockedRequests: [], + allowedRequests: [], hash: '' }; var pageStore = µb.pageStores[tabId]; if ( !pageStore ) { return r; } - var blockedRequests = pageStore.blockedRequests; - var details, pos; + var prepareRequests = function(requests, hasher) { + var r = []; + var details, pos; + for ( var requestURL in requests ) { + if ( requests.hasOwnProperty(requestURL) === false ) { + continue; + } + details = requests[requestURL]; + if ( typeof details !== 'string' ) { + continue; + } + hasher.appendStr(requestURL); + hasher.appendStr(details); + pos = details.indexOf('\t'); + r.push({ + type: details.slice(0, pos), + domain: µb.URI.domainFromURI(requestURL), + url: requestURL, + reason: details.slice(pos + 1) + }); + } + return r; + } var hasher = new YaMD5(); - for ( var requestURL in blockedRequests ) { - if ( blockedRequests.hasOwnProperty(requestURL) === false ) { - continue; - } - details = blockedRequests[requestURL]; - if ( typeof details !== 'string' ) { - continue; - } - hasher.appendStr(requestURL); - hasher.appendStr(details); - pos = details.indexOf('\t'); - r.requests.push({ - type: details.slice(0, pos), - domain: µb.URI.domainFromURI(requestURL), - url: requestURL, - reason: details.slice(pos + 1) - }); + if ( µb.userSettings.logBlockedRequests ) { + r.blockedRequests = prepareRequests(pageStore.blockedRequests, hasher); + } + if ( µb.userSettings.logAllowedRequests ) { + r.allowedRequests = prepareRequests(pageStore.allowedRequests, hasher); } r.hash = hasher.end(); return r; diff --git a/js/pagestore.js b/js/pagestore.js index fd94d9f16..d28459f08 100644 --- a/js/pagestore.js +++ b/js/pagestore.js @@ -53,14 +53,6 @@ var pageStoreFactory = function(tabId, pageURL) { /******************************************************************************/ function PageStore(tabId, pageURL) { - this.tabId = -1; - this.pageURL = ''; - this.pageHostname = ''; - this.pageDomain = ''; - this.perLoadBlockedRequestCount = 0; - this.perLoadAllowedRequestCount = 0; - this.blockedRequests = {}; - this.disposeTime = 0; this.init(tabId, pageURL); } @@ -74,6 +66,7 @@ PageStore.prototype.init = function(tabId, pageURL) { this.perLoadBlockedRequestCount = 0; this.perLoadAllowedRequestCount = 0; this.blockedRequests = {}; + this.allowedRequests = {}; this.disposeTime = 0; return this; }; @@ -88,7 +81,7 @@ PageStore.prototype.dispose = function() { this.pageURL = ''; this.pageHostname = ''; this.pageDomain = ''; - if ( pageStoreJunkyard.length < 32 ) { + if ( pageStoreJunkyard.length < 8 ) { pageStoreJunkyard.push(this); } }; @@ -96,17 +89,19 @@ PageStore.prototype.dispose = function() { /******************************************************************************/ PageStore.prototype.recordRequest = function(type, url, reason) { - // rhill 2013-10-26: This needs to be called even if the request is - // already logged, since the request stats are cached for a while after - // the page is no longer visible in a browser tab. - µb.updateBadge(this.tabId); + var blocked = reason !== false && reason.slice(0, 2) !== '@@'; - if ( reason === false ) { + if ( !blocked ) { this.perLoadAllowedRequestCount++; µb.localSettings.allowedRequestCount++; + if ( µb.userSettings.logAllowedRequests ) { + this.allowedRequests[url] = type + '\t' + (reason || ''); + } return; } + µb.updateBadgeAsync(this.tabId); + this.perLoadBlockedRequestCount++; µb.localSettings.blockedRequestCount++; diff --git a/js/popup.js b/js/popup.js index adde7b02e..7e6c94c5e 100644 --- a/js/popup.js +++ b/js/popup.js @@ -70,7 +70,7 @@ var renderStats = function() { uDom('#gotoLog').toggleClass( 'enabled', - stats.netFilteringSwitch && stats.logBlockedRequests + stats.logBlockedRequests || stats.logAllowedRequests ); var blocked = stats.pageBlockedRequestCount; diff --git a/js/stats.js b/js/stats.js index 6ea6d3f4f..5f6a430bf 100644 --- a/js/stats.js +++ b/js/stats.js @@ -31,13 +31,27 @@ messaging.start('stats.js'); /******************************************************************************/ -var logSettingChanged = function() { +var logBlockedSettingChanged = function() { messaging.tell({ what: 'userSettings', name: 'logBlockedRequests', value: this.checked }); - uDom('#blockedRequests').toggleClass('logEnabled', this.checked); + uDom('#requests table').toggleClass('hideBlocked', !this.checked); + uDom('#requests').toggleClass('logEnabled', this.checked || uDom('#logAllowedRequests').prop('checked')); + renderPageSelector(); +}; + +/******************************************************************************/ + +var logAllowedSettingChanged = function() { + messaging.tell({ + what: 'userSettings', + name: 'logAllowedRequests', + value: this.checked + }); + uDom('#requests table').toggleClass('hideAllowed', !this.checked); + uDom('#requests').toggleClass('logEnabled', this.checked || uDom('#logBlockedRequests').prop('checked')); renderPageSelector(); }; @@ -47,9 +61,10 @@ var cachedPageSelectors = {}; var cachedPageHash = ''; var toPrettyTypeNames = { - 'sub_frame': 'frame', - 'object': 'plugin', - 'xmlhttprequest': 'XHR' + 'stylesheet': 'css', + 'sub_frame': 'frame', + 'object': 'plugin', + 'xmlhttprequest': 'XHR' }; /******************************************************************************/ @@ -62,6 +77,9 @@ var renderURL = function(url, filter) { if ( pos > 0 ) { reText = reText.slice(0, pos); } + if ( reText.slice(0, 2) === '@@' ) { + reText = reText.slice(2); + } reText = reText .replace(/\./g, '\\.') .replace(/\?/g, '\\?') @@ -112,41 +130,40 @@ var renderPageDetails = function(tabId) { if ( details.hash === cachedPageHash ) { return; } - var blockedRequests = details.requests || []; - blockedRequests.sort(function(a, b) { - var r = a.domain.localeCompare(b.domain); - if ( r === 0 ) { - r = a.reason.localeCompare(b.reason); - if ( r === 0 ) { - r = a.type.localeCompare(b.type); - } - } - return r; - }); - - uDom('#tableHeader ~ tr').remove(); - - var blockedRequest, requestURL; - var html = []; - - for ( var i = 0; i < blockedRequests.length; i++ ) { - blockedRequest = blockedRequests[i]; - html.push( - '', - '', toPrettyTypeNames[blockedRequest.type] || blockedRequest.type, - '', blockedRequest.domain, - '', renderURL(blockedRequest.url, blockedRequest.reason), - '', blockedRequest.reason - ); - } - if ( !html.length ) { - html.push( - '', - chrome.i18n.getMessage('logBlockedRequestsEmpty') - ); - } - uDom('#tableHeader').insertAfter(html.join('')); cachedPageHash = details.hash; + var renderRequests = function(requests, className) { + requests.sort(function(a, b) { + var r = a.domain.localeCompare(b.domain); + if ( r ) { return r; } + r = a.reason.localeCompare(b.reason); + if ( r ) { return r; } + r = a.type.localeCompare(b.type); + if ( r ) { return r; } + return a.url.localeCompare(b.url); + }); + var html = [], request; + html.push( + '', + '

', + chrome.i18n.getMessage(className + (requests.length ? 'RequestsHeader' : 'RequestsEmpty')), + '

' + ); + for ( var i = 0; i < requests.length; i++ ) { + request = requests[i]; + html.push( + '', + '', request.domain, + '', toPrettyTypeNames[request.type] || request.type, + '', renderURL(request.url, request.reason), + '', request.reason || '' + ); + } + return html; + }; + uDom('#requests .tableHeader ~ tr').remove(); + var htmlBlocked = renderRequests(details.blockedRequests || [], 'logBlocked'); + var htmlAllowed = renderRequests(details.allowedRequests || [], 'logAllowed'); + uDom('#requests .tableHeader').insertAfter(htmlBlocked.concat(htmlAllowed).join('')); }; messaging.ask({ what: 'getPageDetails', tabId: tabId }, onDataReceived); @@ -161,11 +178,14 @@ var pageSelectorChanged = function() { /******************************************************************************/ var renderPageSelector = function(targetTabId) { - if ( uDom('#logBlockedRequests').prop('checked') !== true ) { + if ( !uDom('#logBlockedRequests').prop('checked') && !uDom('#logAllowedRequests').prop('checked') ) { return; } var selectedTabId = targetTabId || parseInt(uDom('#pageSelector').val(), 10); var onTabReceived = function(tab) { + if ( !tab ) { + return; + } var html = [ '