uBlock/js/ublock.js

271 lines
8.2 KiB
JavaScript
Raw Normal View History

2014-06-23 16:42:43 -06:00
/*******************************************************************************
µ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
*/
2014-08-02 09:40:27 -06:00
/* global µBlock */
2014-06-23 16:42:43 -06:00
/******************************************************************************/
2014-08-02 09:40:27 -06:00
µBlock.getNetFilteringSwitch = function(url, domain) {
var keyHostname = this.URI.hostnameFromURI(url);
var pos = url.indexOf('#');
var keyURL = pos !== -1 ? url.slice(0, pos) : url;
// The caller may provide an already known domain -- convenient to reduce
// overhead of extracting a domain from the url
2014-08-27 00:01:10 -06:00
if ( typeof domain !== 'string' ) {
2014-08-02 09:40:27 -06:00
domain = this.URI.domainFromHostname(keyHostname);
}
2014-08-27 00:01:10 -06:00
// https://github.com/gorhill/uBlock/issues/185
// Use hostname if no domain can be extracted
if ( domain === '' ) {
domain = keyHostname;
2014-06-23 16:42:43 -06:00
}
2014-08-02 09:40:27 -06:00
var exceptions = this.netWhitelist[domain];
if ( !exceptions ) {
return true;
}
var i = exceptions.length;
var exception;
while ( i-- ) {
exception = exceptions[i];
if ( exception.indexOf('/') !== -1 ) {
if ( exception.slice(-1) === '*' ) {
exception = exception.slice(0, -1);
if ( keyURL.slice(0, exception.length) === exception ) {
return false;
}
} else if ( keyURL === exception ) {
return false;
}
} else if ( keyHostname.slice(-exception.length) === exception ) {
2014-06-23 16:42:43 -06:00
return false;
}
}
return true;
};
/******************************************************************************/
2014-08-02 09:40:27 -06:00
µBlock.toggleNetFilteringSwitch = function(url, scope, newState) {
var keyHostname = this.URI.hostnameFromURI(url);
var pos = url.indexOf('#');
var keyURL = pos !== -1 ? url.slice(0, pos) : url;
var key = scope === 'page' ? keyURL : keyHostname;
// The caller may provide an already known domain -- convenient to reduce
// overhead of extracting a domain from `key`
var domain = this.URI.domainFromHostname(keyHostname);
2014-08-27 00:01:10 -06:00
// https://github.com/gorhill/uBlock/issues/185
// Use hostname if no domain can be extracted
if ( domain === '' ) {
domain = keyHostname;
2014-08-02 09:40:27 -06:00
}
var currentState = this.getNetFilteringSwitch(url, domain);
2014-06-23 16:42:43 -06:00
if ( newState === undefined ) {
newState = !currentState;
}
if ( newState === currentState ) {
return currentState;
}
2014-08-02 09:40:27 -06:00
var netWhitelist = this.netWhitelist;
var exceptions = netWhitelist[domain];
if ( !exceptions ) {
exceptions = netWhitelist[domain] = [];
}
2014-06-23 16:42:43 -06:00
// Add to exception list
if ( !newState ) {
2014-08-02 09:40:27 -06:00
exceptions.push(key);
this.saveWhitelist();
2014-06-23 16:42:43 -06:00
return true;
}
// Remove from exception list
2014-08-02 09:40:27 -06:00
var i = exceptions.length;
var exception;
while ( i-- ) {
exception = exceptions[i];
if ( exception.indexOf('/') !== -1 ) {
if ( exception.slice(-1) === '*' ) {
exception = exception.slice(0, -1);
if ( keyURL.slice(0, exception.length) === exception ) {
exceptions.splice(i, 1);
}
} else if ( keyURL === exception ) {
exceptions.splice(i, 1);
}
} else if ( keyHostname.slice(-exception.length) === exception ) {
exceptions.splice(i, 1);
2014-06-23 16:42:43 -06:00
}
}
2014-08-02 09:40:27 -06:00
if ( exceptions.length === 0 ) {
delete netWhitelist[domain];
}
this.saveWhitelist();
return true;
2014-06-23 16:42:43 -06:00
};
/******************************************************************************/
2014-06-23 17:23:36 -06:00
// For now we will use the net exception list
2014-08-02 09:40:27 -06:00
µBlock.getCosmeticFilteringSwitch = function(url, domain) {
return this.getNetFilteringSwitch(url, domain);
};
/******************************************************************************/
µBlock.stringFromWhitelist = function(exceptions) {
var r = {};
var i, bucket;
for ( var domain in exceptions ) {
if ( exceptions.hasOwnProperty(domain) === false ) {
continue;
}
bucket = exceptions[domain];
for ( i = 0; i < bucket.length; i++ ) {
r[bucket[i]] = true;
2014-06-23 17:23:36 -06:00
}
}
2014-08-02 09:40:27 -06:00
return Object.keys(r).sort(function(a,b){return a.localeCompare(b);}).join('\n');
2014-06-23 17:23:36 -06:00
};
/******************************************************************************/
2014-08-02 09:40:27 -06:00
µBlock.whitelistFromString = function(s) {
var exceptions = {};
var lines = s.split(/[\n\r]+/);
2014-08-27 00:01:10 -06:00
var line, hostname, domain, bucket;
2014-08-02 09:40:27 -06:00
for ( var i = 0; i < lines.length; i++ ) {
line = lines[i].trim();
2014-08-27 00:01:10 -06:00
hostname = line.indexOf('/') !== -1 ? this.URI.hostnameFromURI(line) : line;
domain = this.URI.domainFromHostname(hostname);
// https://github.com/gorhill/uBlock/issues/185
// Use hostname if no domain can be extracted
if ( domain === '' ) {
domain = hostname;
2014-08-02 09:40:27 -06:00
}
bucket = exceptions[domain];
if ( bucket === undefined ) {
exceptions[domain] = [line];
} else {
bucket.push(line);
}
}
return exceptions;
2014-06-23 16:42:43 -06:00
};
/******************************************************************************/
2014-06-24 16:29:55 -06:00
// Return all settings if none specified.
2014-06-23 16:42:43 -06:00
µBlock.changeUserSettings = function(name, value) {
2014-06-24 16:29:55 -06:00
if ( name === undefined ) {
2014-09-28 10:05:46 -06:00
return this.userSettings;
2014-06-24 16:29:55 -06:00
}
2014-06-23 16:42:43 -06:00
if ( typeof name !== 'string' || name === '' ) {
return;
}
// Do not allow an unknown user setting to be created
2014-09-28 10:05:46 -06:00
if ( this.userSettings[name] === undefined ) {
2014-06-23 16:42:43 -06:00
return;
}
if ( value === undefined ) {
2014-09-28 10:05:46 -06:00
return this.userSettings[name];
2014-06-23 16:42:43 -06:00
}
// Pre-change
switch ( name ) {
default:
break;
2014-06-23 16:42:43 -06:00
}
// Change
2014-09-28 10:05:46 -06:00
this.userSettings[name] = value;
2014-06-23 16:42:43 -06:00
// Post-change
switch ( name ) {
2014-09-28 10:05:46 -06:00
case 'contextMenuEnabled':
this.contextMenu.toggle(value);
break;
case 'experimentalEnabled':
if ( typeof this.mirrors === 'object' ) {
this.mirrors.toggle(value);
}
2014-09-28 10:05:46 -06:00
break;
default:
break;
2014-06-23 16:42:43 -06:00
}
2014-09-28 10:05:46 -06:00
this.saveUserSettings();
2014-06-23 16:42:43 -06:00
};
/******************************************************************************/
µBlock.transposeType = function(type, path) {
2014-09-20 08:44:04 -06:00
if ( type !== 'other' ) {
return type;
}
var pos = path.lastIndexOf('.');
if ( pos === -1 ) {
return type;
}
2014-09-20 08:47:30 -06:00
var ext = path.slice(pos) + '.';
2014-10-06 12:02:44 -06:00
if ( '.css.eot.ttf.otf.svg.woff.woff2.'.indexOf(ext) !== -1 ) {
2014-09-20 08:44:04 -06:00
return 'stylesheet';
}
2014-09-20 08:47:30 -06:00
if ( '.ico.png.gif.jpg.jpeg.'.indexOf(ext) !== -1 ) {
2014-09-20 08:44:04 -06:00
return 'image';
2014-06-23 16:42:43 -06:00
}
return type;
};
/******************************************************************************/
2014-09-28 10:05:46 -06:00
µBlock.elementPickerExec = function(tabId, targetElement) {
this.elementPickerTarget = targetElement || '';
2014-09-28 12:38:17 -06:00
this.XAL.injectScript(tabId, { file: 'js/element-picker.js' });
2014-09-28 10:05:46 -06:00
};
/******************************************************************************/
2014-10-06 12:02:44 -06:00
µBlock.toggleDynamicFilter = function(details) {
var changed = false;
if ( details.block ) {
changed = this.netFilteringEngine.dynamicFilterBlock(details.hostname, details.requestType, details.firstParty);
} else {
changed = this.netFilteringEngine.dynamicFilterUnblock(details.hostname, details.requestType, details.firstParty);
}
if ( changed ) {
this.userSettings.dynamicFilteringSelfie = this.netFilteringEngine.selfieFromDynamicFilters();
2014-10-07 06:59:35 -06:00
this.XAL.keyvalSetOne('dynamicFilteringSelfie', this.userSettings.dynamicFilteringSelfie);
2014-10-06 12:02:44 -06:00
}
};