/******************************************************************************* µBlock - a Chromium browser extension to block requests. Copyright (C) 2014 Raymond Hill This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see {http://www.gnu.org/licenses/}. Home: https://github.com/gorhill/uBlock */ /* global chrome, uDom, messaging */ /******************************************************************************/ (function() { /******************************************************************************/ messaging.start('stats.js'); /******************************************************************************/ var logBlockedSettingChanged = function() { messaging.tell({ what: 'userSettings', name: 'logBlockedRequests', value: 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(); }; /******************************************************************************/ var cachedPageSelectors = {}; var cachedPageHash = ''; var toPrettyTypeNames = { 'stylesheet': 'css', 'sub_frame': 'frame', 'object': 'plugin', 'xmlhttprequest': 'XHR' }; /******************************************************************************/ var renderURL = function(url, filter) { var chunkSize = 50; // make a regex out of the filter var reText = filter; var pos = reText.indexOf('$'); if ( pos > 0 ) { reText = reText.slice(0, pos); } if ( reText.slice(0, 2) === '@@' ) { reText = reText.slice(2); } reText = reText .replace(/\./g, '\\.') .replace(/\?/g, '\\?') .replace('||', '') .replace(/\^/g, '.') .replace(/\*/g, '.*') ; var re = new RegExp(reText, 'gi'); var matches = re.exec(url); var renderedURL = []; while ( url.length ) { renderedURL.push(url.slice(0, chunkSize)); url = url.slice(chunkSize); } if ( matches && matches[0].length ) { var index = (re.lastIndex / chunkSize) | 0; var offset = re.lastIndex % chunkSize; if ( index > 0 && offset === 0 ) { offset = chunkSize; index -= 1; } var segment = renderedURL[index]; renderedURL[index] = segment.slice(0, offset) + '' + segment.slice(offset); index = (matches.index / chunkSize) | 0; offset = matches.index % chunkSize; if ( index > 0 && offset === 0 ) { offset = chunkSize; index -= 1; } segment = renderedURL[index]; renderedURL[index] = segment.slice(0, offset) + '' + segment.slice(offset); } return renderedURL.join('\n'); }; /******************************************************************************/ var renderPageDetails = function(tabId) { if ( !cachedPageSelectors[tabId] ) { return; } var onDataReceived = function(details) { if ( details.hash === cachedPageHash ) { return; } 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')), '

' ); var currentDomain = ''; for ( var i = 0; i < requests.length; i++ ) { request = requests[i]; if ( request.domain !== currentDomain ) { currentDomain = request.domain; html.push( '', '', currentDomain ); } html.push( '', '', '', 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); }; /******************************************************************************/ var pageSelectorChanged = function() { renderPageDetails(this.value); }; /******************************************************************************/ var renderPageSelector = function(targetTabId) { 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 = [ '