toward 0.1.4.0

This commit is contained in:
gorhill 2014-07-06 19:14:32 -04:00
parent aa84651a3e
commit ee610b3aad
17 changed files with 311 additions and 175 deletions

View File

@ -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.", "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" "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", "message": "Type",
"description": "English: Type" "description": "English: Type"
}, },
"logBlockedRequestsHeaderDomain" : { "logRequestsHeaderDomain" : {
"message": "Domain", "message": "Domain",
"description": "English: Domain" "description": "English: Domain"
}, },
"logBlockedRequestsHeaderURL" : { "logRequestsHeaderURL" : {
"message": "Blocked URL", "message": "URL",
"description": "English: Blocked URL" "description": "English: URL"
}, },
"logBlockedRequestsHeaderFilter" : { "logRequestsHeaderFilter" : {
"message": "Filter", "message": "Filter",
"description": "English: Filter" "description": "English: Filter"
}, },
@ -133,6 +149,10 @@
"message": "No blocked requests logged for this page", "message": "No blocked requests logged for this page",
"description": "English: 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" : { "aboutChangelog" : {

View File

@ -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.", "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" "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", "message": "Type",
"description": "English: Type" "description": "English: Type"
}, },
"logBlockedRequestsHeaderDomain" : { "logRequestsHeaderDomain" : {
"message": "Domaine", "message": "Domaine",
"description": "English: Domaine" "description": "English: Domain"
}, },
"logBlockedRequestsHeaderURL" : { "logRequestsHeaderURL" : {
"message": "URL bloquée", "message": "URL",
"description": "English: Blocked URL" "description": "English: URL"
}, },
"logBlockedRequestsHeaderFilter" : { "logRequestsHeaderFilter" : {
"message": "Filtre", "message": "Filtre",
"description": "English: Filter" "description": "English: Filter"
}, },
@ -133,6 +149,10 @@
"message": "Il n'y a aucune requête bloquée dans le journal", "message": "Il n'y a aucune requête bloquée dans le journal",
"description": "English: No blocked requests logged for this page" "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" : { "aboutChangelog" : {

View File

@ -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.", "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" "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", "message": "Tipo",
"description": "English: Type" "description": "English: Type"
}, },
"logBlockedRequestsHeaderDomain" : { "logRequestsHeaderDomain" : {
"message": "Dominio", "message": "Dominio",
"description": "English: Domain" "description": "English: Domain"
}, },
"logBlockedRequestsHeaderURL" : { "logRequestsHeaderURL" : {
"message": "Indirizzo bloccato", "message": "Indirizzo",
"description": "English: Blocked URL" "description": "English: URL"
}, },
"logBlockedRequestsHeaderFilter" : { "logRequestsHeaderFilter" : {
"message": "Filtro", "message": "Filtro",
"description": "English: Filter" "description": "English: Filter"
}, },
"logBlockedRequestsEmpty" : { "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" "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" : { "aboutChangelog" : {

View File

@ -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.", "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" "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", "message": "Type",
"description": "English: Type" "description": "English: Type"
}, },
"logBlockedRequestsHeaderDomain" : { "logRequestsHeaderDomain" : {
"message": "Domain", "message": "Domain",
"description": "English: Domain" "description": "English: Domain"
}, },
"logBlockedRequestsHeaderURL" : { "logRequestsHeaderURL" : {
"message": "Blocked URL", "message": "URL",
"description": "English: Blocked URL" "description": "English: URL"
}, },
"logBlockedRequestsHeaderFilter" : { "logRequestsHeaderFilter" : {
"message": "Filter", "message": "Filter",
"description": "English: Filter" "description": "English: Filter"
}, },
@ -133,6 +149,10 @@
"message": "No blocked requests logged for this page", "message": "No blocked requests logged for this page",
"description": "English: 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" : { "aboutChangelog" : {

View File

@ -113,19 +113,35 @@
"message": "如果你想要开启此选项你将可以查看拦截广告的详情。拦截记录会增加µBlock的内存占用。由于很多用户用不到这个功能它默认是禁用的。", "message": "如果你想要开启此选项你将可以查看拦截广告的详情。拦截记录会增加µBlock的内存占用。由于很多用户用不到这个功能它默认是禁用的。",
"description": "English: see _locales/en/messages.log" "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": "类型", "message": "类型",
"description": "English: Type" "description": "English: Type"
}, },
"logBlockedRequestsHeaderDomain" : { "logRequestsHeaderDomain" : {
"message": "域名", "message": "域名",
"description": "English: Domain" "description": "English: Domain"
}, },
"logBlockedRequestsHeaderURL" : { "logRequestsHeaderURL" : {
"message": "屏蔽网站", "message": "网址",
"description": "English: Blocked URL" "description": "English: URL"
}, },
"logBlockedRequestsHeaderFilter" : { "logRequestsHeaderFilter" : {
"message": "过滤", "message": "过滤",
"description": "English: Filter" "description": "English: Filter"
}, },
@ -133,6 +149,10 @@
"message": "该页面没有拦截记录", "message": "该页面没有拦截记录",
"description": "English: 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" : { "aboutChangelog" : {

View File

@ -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. Gratuito.
Open source with public license (GPLv3) Open source with public license (GPLv3)
Fatto dagli utenti per gli utenti. Fatto dagli utenti per gli utenti.

View File

@ -1415,17 +1415,16 @@ FilterContainer.prototype.matchString = function(pageDetails, url, requestType,
var categories = this.categories; var categories = this.categories;
// Test hostname-based block filters // Test hostname-based block filters
var bf = false; var br = this.matchAnyPartyHostname(requestHostname);
bf = this.matchAnyPartyHostname(requestHostname); if ( br === false && party === ThirdParty ) {
if ( bf === false && party === ThirdParty ) { br = this.match3rdPartyHostname(requestHostname);
bf = this.match3rdPartyHostname(requestHostname);
} }
// This will be used by hostname-based filters // This will be used by hostname-based filters
pageHostname = pageDetails.pageHostname || ''; pageHostname = pageDetails.pageHostname || '';
// Test against block filters // Test against block filters
if ( bf === false ) { if ( br === false ) {
this.bucket0 = categories[this.makeCategoryKey(BlockAnyTypeAnyParty)]; this.bucket0 = categories[this.makeCategoryKey(BlockAnyTypeAnyParty)];
this.bucket1 = categories[this.makeCategoryKey(BlockAnyType | party)]; this.bucket1 = categories[this.makeCategoryKey(BlockAnyType | party)];
this.bucket2 = categories[this.makeCategoryKey(BlockAnyTypeOneParty | domainParty)]; 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.bucket6 = categories[this.makeCategoryKey(BlockOneParty | type | domainParty)];
this.bucket7 = categories[this.makeCategoryKey(BlockOtherParties | type)]; 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 there is no block filter, no need to test against allow filters
if ( bf === false ) { if ( br === false ) {
return false; return false;
} }
@ -1453,11 +1452,12 @@ FilterContainer.prototype.matchString = function(pageDetails, url, requestType,
this.bucket6 = categories[this.makeCategoryKey(AllowOneParty | type | domainParty)]; this.bucket6 = categories[this.makeCategoryKey(AllowOneParty | type | domainParty)];
this.bucket7 = categories[this.makeCategoryKey(AllowOtherParties | type | domainParty)]; this.bucket7 = categories[this.makeCategoryKey(AllowOtherParties | type | domainParty)];
if ( this.matchTokens() !== false ) { var ar = this.matchTokens();
return false; if ( ar !== false ) {
return '@@' + ar;
} }
return bf; return br;
}; };
/******************************************************************************/ /******************************************************************************/

View File

@ -133,7 +133,7 @@ return asyncJobManager;
// Update visual of extension icon. // Update visual of extension icon.
// A time out is used to coalesce adjacent requests to update badge. // A time out is used to coalesce adjacent requests to update badge.
µBlock.updateBadge = function(tabId) { µBlock.updateBadgeAsync = function(tabId) {
if ( tabId < 0 ) { if ( tabId < 0 ) {
return; return;
} }

View File

@ -33,6 +33,7 @@ return {
userSettings: { userSettings: {
collapseBlocked: true, collapseBlocked: true,
logBlockedRequests: false, logBlockedRequests: false,
logAllowedRequests: false,
parseAllABPHideFilters: true, parseAllABPHideFilters: true,
netExceptionList: {}, netExceptionList: {},
showIconBadge: true showIconBadge: true

View File

@ -40,7 +40,8 @@ var getStats = function(request) {
pageAllowedRequestCount: 0, pageAllowedRequestCount: 0,
netFilteringSwitch: false, netFilteringSwitch: false,
cosmeticFilteringSwitch: false, cosmeticFilteringSwitch: false,
logBlockedRequests: µb.userSettings.logBlockedRequests logBlockedRequests: µb.userSettings.logBlockedRequests,
logAllowedRequests: µb.userSettings.logAllowedRequests
}; };
var pageStore = µb.pageStoreFromTabId(request.tabId); var pageStore = µb.pageStoreFromTabId(request.tabId);
if ( pageStore ) { if ( pageStore ) {
@ -75,7 +76,7 @@ var onMessage = function(request, sender, callback) {
request.hostname, request.hostname,
request.state request.state
); );
µBlock.updateBadge(request.tabId); µBlock.updateBadgeAsync(request.tabId);
break; break;
default: default:
@ -260,33 +261,43 @@ var onMessage = function(request, sender, callback) {
var getPageDetails = function(µb, tabId) { var getPageDetails = function(µb, tabId) {
var r = { var r = {
requests: [], blockedRequests: [],
allowedRequests: [],
hash: '' hash: ''
}; };
var pageStore = µb.pageStores[tabId]; var pageStore = µb.pageStores[tabId];
if ( !pageStore ) { if ( !pageStore ) {
return r; return r;
} }
var blockedRequests = pageStore.blockedRequests; var prepareRequests = function(requests, hasher) {
var details, pos; 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(); var hasher = new YaMD5();
for ( var requestURL in blockedRequests ) { if ( µb.userSettings.logBlockedRequests ) {
if ( blockedRequests.hasOwnProperty(requestURL) === false ) { r.blockedRequests = prepareRequests(pageStore.blockedRequests, hasher);
continue; }
} if ( µb.userSettings.logAllowedRequests ) {
details = blockedRequests[requestURL]; r.allowedRequests = prepareRequests(pageStore.allowedRequests, hasher);
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)
});
} }
r.hash = hasher.end(); r.hash = hasher.end();
return r; return r;

View File

@ -53,14 +53,6 @@ var pageStoreFactory = function(tabId, pageURL) {
/******************************************************************************/ /******************************************************************************/
function PageStore(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); this.init(tabId, pageURL);
} }
@ -74,6 +66,7 @@ PageStore.prototype.init = function(tabId, pageURL) {
this.perLoadBlockedRequestCount = 0; this.perLoadBlockedRequestCount = 0;
this.perLoadAllowedRequestCount = 0; this.perLoadAllowedRequestCount = 0;
this.blockedRequests = {}; this.blockedRequests = {};
this.allowedRequests = {};
this.disposeTime = 0; this.disposeTime = 0;
return this; return this;
}; };
@ -88,7 +81,7 @@ PageStore.prototype.dispose = function() {
this.pageURL = ''; this.pageURL = '';
this.pageHostname = ''; this.pageHostname = '';
this.pageDomain = ''; this.pageDomain = '';
if ( pageStoreJunkyard.length < 32 ) { if ( pageStoreJunkyard.length < 8 ) {
pageStoreJunkyard.push(this); pageStoreJunkyard.push(this);
} }
}; };
@ -96,17 +89,19 @@ PageStore.prototype.dispose = function() {
/******************************************************************************/ /******************************************************************************/
PageStore.prototype.recordRequest = function(type, url, reason) { PageStore.prototype.recordRequest = function(type, url, reason) {
// rhill 2013-10-26: This needs to be called even if the request is var blocked = reason !== false && reason.slice(0, 2) !== '@@';
// 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);
if ( reason === false ) { if ( !blocked ) {
this.perLoadAllowedRequestCount++; this.perLoadAllowedRequestCount++;
µb.localSettings.allowedRequestCount++; µb.localSettings.allowedRequestCount++;
if ( µb.userSettings.logAllowedRequests ) {
this.allowedRequests[url] = type + '\t' + (reason || '');
}
return; return;
} }
µb.updateBadgeAsync(this.tabId);
this.perLoadBlockedRequestCount++; this.perLoadBlockedRequestCount++;
µb.localSettings.blockedRequestCount++; µb.localSettings.blockedRequestCount++;

View File

@ -70,7 +70,7 @@ var renderStats = function() {
uDom('#gotoLog').toggleClass( uDom('#gotoLog').toggleClass(
'enabled', 'enabled',
stats.netFilteringSwitch && stats.logBlockedRequests stats.logBlockedRequests || stats.logAllowedRequests
); );
var blocked = stats.pageBlockedRequestCount; var blocked = stats.pageBlockedRequestCount;

View File

@ -31,13 +31,27 @@ messaging.start('stats.js');
/******************************************************************************/ /******************************************************************************/
var logSettingChanged = function() { var logBlockedSettingChanged = function() {
messaging.tell({ messaging.tell({
what: 'userSettings', what: 'userSettings',
name: 'logBlockedRequests', name: 'logBlockedRequests',
value: this.checked 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(); renderPageSelector();
}; };
@ -47,9 +61,10 @@ var cachedPageSelectors = {};
var cachedPageHash = ''; var cachedPageHash = '';
var toPrettyTypeNames = { var toPrettyTypeNames = {
'sub_frame': 'frame', 'stylesheet': 'css',
'object': 'plugin', 'sub_frame': 'frame',
'xmlhttprequest': 'XHR' 'object': 'plugin',
'xmlhttprequest': 'XHR'
}; };
/******************************************************************************/ /******************************************************************************/
@ -62,6 +77,9 @@ var renderURL = function(url, filter) {
if ( pos > 0 ) { if ( pos > 0 ) {
reText = reText.slice(0, pos); reText = reText.slice(0, pos);
} }
if ( reText.slice(0, 2) === '@@' ) {
reText = reText.slice(2);
}
reText = reText reText = reText
.replace(/\./g, '\\.') .replace(/\./g, '\\.')
.replace(/\?/g, '\\?') .replace(/\?/g, '\\?')
@ -112,41 +130,40 @@ var renderPageDetails = function(tabId) {
if ( details.hash === cachedPageHash ) { if ( details.hash === cachedPageHash ) {
return; 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(
'<tr>',
'<td>', toPrettyTypeNames[blockedRequest.type] || blockedRequest.type,
'<td>', blockedRequest.domain,
'<td>', renderURL(blockedRequest.url, blockedRequest.reason),
'<td>', blockedRequest.reason
);
}
if ( !html.length ) {
html.push(
'<tr><td colspan="4">',
chrome.i18n.getMessage('logBlockedRequestsEmpty')
);
}
uDom('#tableHeader').insertAfter(html.join(''));
cachedPageHash = details.hash; 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(
'<tr class="header ', className, '">',
'<td colspan="4"><h3>',
chrome.i18n.getMessage(className + (requests.length ? 'RequestsHeader' : 'RequestsEmpty')),
'</h3>'
);
for ( var i = 0; i < requests.length; i++ ) {
request = requests[i];
html.push(
'<tr class="', className, '">',
'<td>', request.domain,
'<td>', toPrettyTypeNames[request.type] || request.type,
'<td>', renderURL(request.url, request.reason),
'<td>', 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); messaging.ask({ what: 'getPageDetails', tabId: tabId }, onDataReceived);
@ -161,11 +178,14 @@ var pageSelectorChanged = function() {
/******************************************************************************/ /******************************************************************************/
var renderPageSelector = function(targetTabId) { var renderPageSelector = function(targetTabId) {
if ( uDom('#logBlockedRequests').prop('checked') !== true ) { if ( !uDom('#logBlockedRequests').prop('checked') && !uDom('#logAllowedRequests').prop('checked') ) {
return; return;
} }
var selectedTabId = targetTabId || parseInt(uDom('#pageSelector').val(), 10); var selectedTabId = targetTabId || parseInt(uDom('#pageSelector').val(), 10);
var onTabReceived = function(tab) { var onTabReceived = function(tab) {
if ( !tab ) {
return;
}
var html = [ var html = [
'<option value="', '<option value="',
tab.id, tab.id,
@ -200,13 +220,17 @@ var renderPageSelector = function(targetTabId) {
var onUserSettingsReceived = function(details) { var onUserSettingsReceived = function(details) {
uDom('#logBlockedRequests').prop('checked', details.logBlockedRequests); uDom('#logBlockedRequests').prop('checked', details.logBlockedRequests);
uDom('#blockedRequests').toggleClass('logEnabled', details.logBlockedRequests); uDom('#logAllowedRequests').prop('checked', details.logAllowedRequests);
uDom('#requests').toggleClass('logEnabled', details.logBlockedRequests || details.logAllowedRequests);
uDom('#requests table').toggleClass('hideBlocked', !details.logBlockedRequests);
uDom('#requests table').toggleClass('hideAllowed', !details.logAllowedRequests);
var matches = window.location.search.slice(1).match(/(?:^|&)which=(\d+)/); var matches = window.location.search.slice(1).match(/(?:^|&)which=(\d+)/);
var tabId = matches && matches.length === 2 ? parseInt(matches[1], 10) : 0; var tabId = matches && matches.length === 2 ? parseInt(matches[1], 10) : 0;
renderPageSelector(tabId); renderPageSelector(tabId);
uDom('#logBlockedRequests').on('change', logSettingChanged); uDom('#logBlockedRequests').on('change', logBlockedSettingChanged);
uDom('#logAllowedRequests').on('change', logAllowedSettingChanged);
uDom('#refresh').on('click', function() { renderPageSelector(); }); uDom('#refresh').on('click', function() { renderPageSelector(); });
uDom('#pageSelector').on('change', pageSelectorChanged); uDom('#pageSelector').on('change', pageSelectorChanged);
}; };

View File

@ -24,43 +24,29 @@
/******************************************************************************/ /******************************************************************************/
(function(){ (function(){
function onTabCreated(tab) { // When the DOM content of root frame is loaded, this means the tab
// Can this happen? // content has changed.
if ( tab.id < 0 || !tab.url || tab.url === '' ) { function onDOMContentLoaded(details) {
if ( details.frameId !== 0 ) {
return; return;
} }
µBlock.bindTabToPageStats(tab.id, tab.url); µBlock.updateBadgeAsync(details.tabId);
} }
chrome.tabs.onCreated.addListener(onTabCreated); chrome.webNavigation.onDOMContentLoaded.addListener(onDOMContentLoaded);
// It may happen the URL in the tab changes, while the page's document
// stays the same (for instance, Google Maps). Without this listener,
// the extension icon won't be properly refreshed.
function onTabUpdated(tabId, changeInfo, tab) { function onTabUpdated(tabId, changeInfo, tab) {
// Can this happen?
if ( !tab.url || tab.url === '' ) { if ( !tab.url || tab.url === '' ) {
return; return;
} }
if ( changeInfo.url ) { if ( changeInfo.url && µBlock.pageStores[tabId] ) {
µBlock.bindTabToPageStats(tabId, tab.url); µBlock.updateBadgeAsync(tabId);
µBlock.updateBadge(tabId);
} }
} }
chrome.tabs.onUpdated.addListener(onTabUpdated); chrome.tabs.onUpdated.addListener(onTabUpdated);
function onTabRemoved(tabId) {
if ( tabId < 0 ) {
return;
}
µBlock.unbindTabFromPageStats(tabId);
}
chrome.tabs.onRemoved.addListener(onTabRemoved);
function onBeforeNavigateCallback(details) {
if ( details.frameId > 0 ) {
return;
}
µBlock.bindTabToPageStats(details.tabId, details.url);
}
chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigateCallback);
// Initialize internal state with maybe already existing tabs // Initialize internal state with maybe already existing tabs
chrome.tabs.query({ url: '<all_urls>' }, function(tabs) { chrome.tabs.query({ url: '<all_urls>' }, function(tabs) {
var i = tabs.length; var i = tabs.length;
@ -96,6 +82,8 @@
// Create an entry for the tab if it doesn't exist. // Create an entry for the tab if it doesn't exist.
µBlock.bindTabToPageStats = function(tabId, pageURL) { µBlock.bindTabToPageStats = function(tabId, pageURL) {
this.updateBadgeAsync(tabId);
// First unbind whatever page store is bound to the tab id. // First unbind whatever page store is bound to the tab id.
this.unbindTabFromPageStats(tabId); this.unbindTabFromPageStats(tabId);
@ -124,6 +112,7 @@
pageStore.perLoadBlockedRequestCount = 0; pageStore.perLoadBlockedRequestCount = 0;
} }
//console.log('µBlock> bindTabToPageStats(%d, "%s")', tabId, pageURL);
this.pageStores[tabId] = pageStore; this.pageStores[tabId] = pageStore;
return pageStore; return pageStore;
@ -134,6 +123,7 @@
if ( pageStore ) { if ( pageStore ) {
//pageStore.disposeTime = Date.now(); //pageStore.disposeTime = Date.now();
//this.pageStoreDump[pageStore.pageURL + ' ' + tabId] = pageStore; //this.pageStoreDump[pageStore.pageURL + ' ' + tabId] = pageStore;
//console.log('µBlock> unbindTabFromPageStats(%d)', tabId);
} }
delete this.pageStores[tabId]; delete this.pageStores[tabId];
}; };

View File

@ -84,7 +84,7 @@ var onBeforeRequestHandler = function(details) {
pageStore.recordRequest(requestType, requestURL, reason); pageStore.recordRequest(requestType, requestURL, reason);
// Not blocked? // Not blocked?
if ( reason === false ) { if ( reason === false || reason.slice(0, 2) === '@@' ) {
return; return;
} }

View File

@ -416,7 +416,7 @@ DOMList.prototype.toggleClass = function(className, targetState) {
for ( var i = 0; i < n; i++ ) { for ( var i = 0; i < n; i++ ) {
node = this.nodes[i]; node = this.nodes[i];
currentState = re.test(node.className); currentState = re.test(node.className);
newState = targetState; newState = !!targetState;
if ( newState === undefined ) { if ( newState === undefined ) {
newState = !currentState; newState = !currentState;
} }
@ -427,7 +427,7 @@ DOMList.prototype.toggleClass = function(className, targetState) {
if ( newState ) { if ( newState ) {
newClassName += ' ' + className; newClassName += ' ' + className;
} else { } else {
newClassName = newClassName.replace(re, ''); newClassName = newClassName.replace(re, ' ');
} }
node.className = newClassName.trim(); node.className = newClassName.trim();
} }

View File

@ -24,6 +24,13 @@ select {
padding: 2px 0; padding: 2px 0;
font-size: 14px; font-size: 14px;
} }
#requests {
margin: 2em 0 0 0;
display: none;
}
#requests.logEnabled {
display: block;
}
table { table {
margin: 1em 0; margin: 1em 0;
border: 1px solid gray; border: 1px solid gray;
@ -36,23 +43,36 @@ td, th {
padding: 6px 6px; padding: 6px 6px;
white-space: pre; white-space: pre;
} }
td:nth-of-type(2) { td:nth-of-type(1), td:nth-of-type(2) {
text-align: right; text-align: right;
} }
tr.header td:nth-of-type(1) {
text-align: left;
}
td:nth-of-type(3) { td:nth-of-type(3) {
color: #444; color: #444;
} }
td:nth-of-type(3) b { table.hideBlocked tr.logBlocked {
padding: 2px 0;
color: #000;
background-color: #ff8;
}
#blockedRequests {
margin: 2em 0 0 0;
display: none; display: none;
} }
#blockedRequests.logEnabled { table.hideAllowed tr.logAllowed {
display: block; display: none;
}
tr.logBlocked {
background-color: #fff8f8;
}
tr.logBlocked ~ tr td:nth-of-type(3) b {
padding: 2px 0;
color: #000;
background-color: rgba(255,0,0,0.1);
}
tr.logAllowed {
background-color: #f8fff8 !important;
}
tr.logAllowed ~ tr td:nth-of-type(3) b {
padding: 2px 0;
color: #000;
background-color: rgba(0,255,0,0.2);
} }
</style> </style>
</head> </head>
@ -63,17 +83,20 @@ td:nth-of-type(3) b {
<li><input id="logBlockedRequests" type="checkbox" data-range="bool" /><span data-i18n="logBlockedRequestsPrompt"></span> <li><input id="logBlockedRequests" type="checkbox" data-range="bool" /><span data-i18n="logBlockedRequestsPrompt"></span>
<button class="whatisthis"></button> <button class="whatisthis"></button>
<div class="whatisthis-expandable para" data-i18n="logBlockedRequestsHelp"></div> <div class="whatisthis-expandable para" data-i18n="logBlockedRequestsHelp"></div>
<li><input id="logAllowedRequests" type="checkbox" data-range="bool" /><span data-i18n="logAllowedRequestsPrompt"></span>
<button class="whatisthis"></button>
<div class="whatisthis-expandable para" data-i18n="logAllowedRequestsHelp"></div>
</ul> </ul>
<div id="blockedRequests"> <div id="requests">
<span id="refresh" class="fa">&#xf021;</span><select id="pageSelector"></select> <span id="refresh" class="fa">&#xf021;</span><select id="pageSelector"></select>
<table id="pageDetails"> <table>
<tr id="tableHeader"> <tr class="tableHeader">
<th data-i18n="logBlockedRequestsHeaderType"> <th data-i18n="logRequestsHeaderDomain">
<th data-i18n="logBlockedRequestsHeaderDomain"> <th data-i18n="logRequestsHeaderType">
<th data-i18n="logBlockedRequestsHeaderURL"> <th data-i18n="logRequestsHeaderURL">
<th data-i18n="logBlockedRequestsHeaderFilter"> <th data-i18n="logRequestsHeaderFilter">
</table> </table>
</div> </div>