uBlock/src/js/start.js

358 lines
12 KiB
JavaScript
Raw Normal View History

2014-06-24 00:42:43 +02:00
/*******************************************************************************
2016-08-13 22:42:58 +02:00
uBlock Origin - a browser extension to block requests.
2018-02-15 23:25:38 +01:00
Copyright (C) 2014-2018 Raymond Hill
2014-06-24 00:42:43 +02:00
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 publicSuffixList */
2016-08-13 22:42:58 +02:00
'use strict';
2014-06-24 00:42:43 +02:00
/******************************************************************************/
2015-02-13 18:10:10 +01:00
// Load all: executed once.
2014-06-24 00:42:43 +02:00
2015-03-11 23:26:00 +01:00
µBlock.restart = (function() {
2014-08-21 01:39:49 +02:00
2015-02-13 18:10:10 +01:00
/******************************************************************************/
2015-02-24 19:48:03 +01:00
var µb = µBlock;
/******************************************************************************/
vAPI.app.onShutdown = function() {
µb.staticFilteringReverseLookup.shutdown();
µb.assets.updateStop();
µb.staticNetFilteringEngine.reset();
µb.staticExtFilteringEngine.reset();
µb.sessionFirewall.reset();
µb.permanentFirewall.reset();
µb.sessionURLFiltering.reset();
µb.permanentURLFiltering.reset();
2018-03-17 15:25:03 +01:00
µb.hnSwitches.reset();
};
/******************************************************************************/
var processCallbackQueue = function(queue, callback) {
var processOne = function() {
var fn = queue.pop();
if ( fn ) {
fn(processOne);
} else if ( typeof callback === 'function' ) {
callback();
}
};
processOne();
};
/******************************************************************************/
2015-02-13 18:10:10 +01:00
// Final initialization steps after all needed assets are in memory.
// - Initialize internal state with maybe already existing tabs.
// - Schedule next update operation.
var onAllReady = function() {
2015-04-07 03:26:05 +02:00
// https://github.com/chrisaljoudi/uBlock/issues/184
2015-02-13 18:10:10 +01:00
// Check for updates not too far in the future.
µb.assets.addObserver(µb.assetObserver.bind(µb));
µb.scheduleAssetUpdater(µb.userSettings.autoUpdate ? 7 * 60 * 1000 : 0);
2015-02-13 18:10:10 +01:00
// vAPI.cloud is optional.
if ( µb.cloudStorageSupported ) {
vAPI.cloud.start([
'tpFiltersPane',
'myFiltersPane',
'myRulesPane',
'whitelistPane'
]);
}
2015-08-11 21:29:14 +02:00
µb.contextMenu.update(null);
2016-01-03 19:58:25 +01:00
µb.firstInstall = false;
processCallbackQueue(µb.onStartCompletedQueue);
2015-02-13 18:10:10 +01:00
};
2014-12-20 21:28:16 +01:00
2014-08-21 01:39:49 +02:00
/******************************************************************************/
2015-02-24 19:48:03 +01:00
// Filtering engines dependencies:
// - PSL
2014-08-21 01:39:49 +02:00
2015-02-24 19:48:03 +01:00
var onPSLReady = function() {
µb.loadFilterLists(onAllReady);
};
2014-09-08 23:46:58 +02:00
2015-02-24 19:48:03 +01:00
/******************************************************************************/
// To bring older versions up to date
var onVersionReady = function(lastVersion) {
if ( lastVersion === vAPI.app.version ) { return; }
// Since AMO does not allow updating resources.txt, force a reload when a
// new version is detected, as resources.txt may have changed since last
// release. This will be done only for release versions of Firefox.
if (
/^Mozilla-Firefox-/.test(vAPI.webextFlavor) &&
/(b|rc)\d+$/.test(vAPI.app.version) === false
) {
µb.redirectEngine.invalidateResourcesSelfie();
}
// From 1.15.19b9 and above, the `behind-the-scene` scope is no longer
// whitelisted by default, and network requests from that scope will be
// subject to filtering by default.
//
// Following code is to remove the `behind-the-scene` scope when updating
// from a version older than 1.15.19b9.
// This will apply only to webext versions of uBO, as the following would
// certainly cause too much breakage in Firefox legacy given that uBO can
// see ALL network requests.
// Remove when everybody is beyond 1.15.19b8.
(function patch1015019008(s) {
if ( vAPI.firefox !== undefined ) { return; }
var match = /^(\d+)\.(\d+)\.(\d+)(?:\D+(\d+))?/.exec(s);
if ( match === null ) { return; }
var v =
parseInt(match[1], 10) * 1000 * 1000 * 1000 +
parseInt(match[2], 10) * 1000 * 1000 +
parseInt(match[3], 10) * 1000 +
(match[4] ? parseInt(match[4], 10) : 0);
if ( /rc\d+$/.test(s) ) { v += 100; }
if ( v > 1015019008 ) { return; }
2018-03-31 18:12:31 +02:00
if ( µb.getNetFilteringSwitch('http://behind-the-scene/') ) { return; }
var fwRules = [
'behind-the-scene * * noop',
'behind-the-scene * image noop',
'behind-the-scene * 3p noop',
'behind-the-scene * inline-script noop',
'behind-the-scene * 1p-script noop',
'behind-the-scene * 3p-script noop',
'behind-the-scene * 3p-frame noop'
].join('\n');
µb.sessionFirewall.fromString(fwRules, true);
µb.permanentFirewall.fromString(fwRules, true);
µb.savePermanentFirewallRules();
µb.hnSwitches.fromString([
2018-03-31 18:12:31 +02:00
'no-large-media: behind-the-scene false'
].join('\n'), true);
µb.saveHostnameSwitches();
µb.toggleNetFilteringSwitch('http://behind-the-scene/', '', true);
})(lastVersion);
vAPI.storage.set({ version: vAPI.app.version });
2015-02-13 18:10:10 +01:00
};
/******************************************************************************/
2014-09-08 23:46:58 +02:00
2015-02-24 19:48:03 +01:00
var onSelfieReady = function(selfie) {
2017-08-30 00:32:00 +02:00
if (
selfie instanceof Object === false ||
selfie.magic !== µb.systemSettings.selfieMagic
) {
2015-02-24 19:48:03 +01:00
return false;
}
if ( publicSuffixList.fromSelfie(selfie.publicSuffixList) !== true ) {
return false;
}
2015-11-29 23:06:58 +01:00
if ( selfie.redirectEngine === undefined ) {
return false;
}
µb.availableFilterLists = selfie.availableFilterLists;
2015-02-24 19:48:03 +01:00
µb.staticNetFilteringEngine.fromSelfie(selfie.staticNetFilteringEngine);
µb.redirectEngine.fromSelfie(selfie.redirectEngine);
µb.staticExtFilteringEngine.fromSelfie(selfie.staticExtFilteringEngine);
2018-02-15 23:25:38 +01:00
µb.loadRedirectResources();
2015-02-24 19:48:03 +01:00
return true;
2014-08-21 01:39:49 +02:00
};
/******************************************************************************/
2015-04-07 03:26:05 +02:00
// https://github.com/chrisaljoudi/uBlock/issues/226
2015-02-13 18:10:10 +01:00
// Whitelist in memory.
// Whitelist parser needs PSL to be ready.
// gorhill 2014-12-15: not anymore
2015-02-24 19:48:03 +01:00
var onNetWhitelistReady = function(netWhitelistRaw) {
µb.netWhitelist = µb.whitelistFromString(netWhitelistRaw);
µb.netWhitelistModifyTime = Date.now();
2015-02-13 18:10:10 +01:00
};
/******************************************************************************/
// User settings are in memory
2015-02-24 19:48:03 +01:00
var onUserSettingsReady = function(fetched) {
var userSettings = µb.userSettings;
fromFetch(userSettings, fetched);
2014-08-21 16:56:36 +02:00
if ( µb.privacySettingsSupported ) {
vAPI.browserSettings.set({
'hyperlinkAuditing': !userSettings.hyperlinkAuditingDisabled,
'prefetching': !userSettings.prefetchingDisabled,
'webrtcIPAddress': !userSettings.webrtcIPAddressHidden
});
}
2015-06-01 21:03:22 +02:00
2015-03-27 18:00:55 +01:00
µb.permanentFirewall.fromString(fetched.dynamicFilteringString);
2015-02-13 18:10:10 +01:00
µb.sessionFirewall.assign(µb.permanentFirewall);
2015-05-21 20:15:17 +02:00
µb.permanentURLFiltering.fromString(fetched.urlFilteringString);
µb.sessionURLFiltering.assign(µb.permanentURLFiltering);
2015-03-27 18:00:55 +01:00
µb.hnSwitches.fromString(fetched.hostnameSwitchesString);
2015-02-13 18:10:10 +01:00
2016-08-13 22:42:58 +02:00
// https://github.com/gorhill/uBlock/issues/1892
// For first installation on a battery-powered device, disable generic
// cosmetic filtering.
if ( µb.firstInstall && vAPI.battery ) {
userSettings.ignoreGenericCosmeticFilters = true;
}
2015-02-13 18:10:10 +01:00
};
2015-02-24 00:31:29 +01:00
/******************************************************************************/
2015-02-24 19:48:03 +01:00
// Housekeeping, as per system setting changes
var onSystemSettingsReady = function(fetched) {
2015-02-24 00:31:29 +01:00
var mustSaveSystemSettings = false;
2015-02-24 19:48:03 +01:00
if ( fetched.compiledMagic !== µb.systemSettings.compiledMagic ) {
µb.assets.remove(/^compiled\//);
2015-02-24 00:31:29 +01:00
mustSaveSystemSettings = true;
}
2015-02-24 19:48:03 +01:00
if ( fetched.selfieMagic !== µb.systemSettings.selfieMagic ) {
2015-02-24 00:31:29 +01:00
mustSaveSystemSettings = true;
}
if ( mustSaveSystemSettings ) {
fetched.selfie = null;
2015-11-29 23:06:58 +01:00
µb.selfieManager.destroy();
2015-02-24 19:48:03 +01:00
vAPI.storage.set(µb.systemSettings, µb.noopFunc);
2015-02-24 00:31:29 +01:00
}
2015-02-24 19:48:03 +01:00
};
/******************************************************************************/
var onFirstFetchReady = function(fetched) {
2016-01-03 19:58:25 +01:00
// https://github.com/gorhill/uBlock/issues/747
µb.firstInstall = fetched.version === '0.0.0.0';
2015-02-24 19:48:03 +01:00
// Order is important -- do not change:
onSystemSettingsReady(fetched);
2015-03-07 05:36:09 +01:00
fromFetch(µb.localSettings, fetched);
2015-02-24 19:48:03 +01:00
onUserSettingsReady(fetched);
2015-03-07 05:36:09 +01:00
fromFetch(µb.restoreBackupSettings, fetched);
2015-02-24 19:48:03 +01:00
onNetWhitelistReady(fetched.netWhitelist);
onVersionReady(fetched.version);
2015-02-24 00:31:29 +01:00
2017-08-30 00:32:00 +02:00
// If we have a selfie, skip loading PSL, filter lists
vAPI.cacheStorage.get('selfie', function(bin) {
if ( bin instanceof Object && onSelfieReady(bin.selfie) ) {
return onAllReady();
}
µb.loadPublicSuffixList(onPSLReady);
});
2015-02-24 19:48:03 +01:00
};
/******************************************************************************/
var toFetch = function(from, fetched) {
for ( var k in from ) {
if ( from.hasOwnProperty(k) === false ) {
continue;
}
fetched[k] = from[k];
}
};
var fromFetch = function(to, fetched) {
for ( var k in to ) {
if ( to.hasOwnProperty(k) === false ) {
continue;
}
if ( fetched.hasOwnProperty(k) === false ) {
continue;
}
to[k] = fetched[k];
}
2015-02-24 00:31:29 +01:00
};
/******************************************************************************/
2017-01-26 16:17:38 +01:00
var onSelectedFilterListsLoaded = function() {
2016-01-03 19:58:25 +01:00
var fetchableProps = {
'compiledMagic': '',
'dynamicFilteringString': [
'behind-the-scene * * noop',
'behind-the-scene * image noop',
'behind-the-scene * 3p noop',
'behind-the-scene * inline-script noop',
'behind-the-scene * 1p-script noop',
'behind-the-scene * 3p-script noop',
'behind-the-scene * 3p-frame noop'
].join('\n'),
2016-01-03 19:58:25 +01:00
'urlFilteringString': '',
'hostnameSwitchesString': [
2018-03-31 18:12:31 +02:00
'no-large-media: behind-the-scene false'
].join('\n'),
2016-01-03 19:58:25 +01:00
'lastRestoreFile': '',
'lastRestoreTime': 0,
'lastBackupFile': '',
'lastBackupTime': 0,
2016-11-02 05:27:16 +01:00
'netWhitelist': µb.netWhitelistDefault,
2016-01-03 19:58:25 +01:00
'selfieMagic': '',
'version': '0.0.0.0'
2015-10-21 17:53:03 +02:00
};
2015-03-11 23:26:00 +01:00
2016-01-03 19:58:25 +01:00
toFetch(µb.localSettings, fetchableProps);
toFetch(µb.userSettings, fetchableProps);
toFetch(µb.restoreBackupSettings, fetchableProps);
vAPI.storage.get(fetchableProps, onFirstFetchReady);
};
2017-01-26 16:17:38 +01:00
/******************************************************************************/
// TODO(seamless migration):
// Eventually selected filter list keys will be loaded as a fetchable
// property. Until then we need to handle backward and forward
// compatibility, this means a special asynchronous call to load selected
// filter lists.
var onAdminSettingsRestored = function() {
µb.loadSelectedFilterLists(onSelectedFilterListsLoaded);
};
2016-01-03 19:58:25 +01:00
/******************************************************************************/
return function() {
processCallbackQueue(µb.onBeforeStartQueue, function() {
// https://github.com/gorhill/uBlock/issues/531
µb.restoreAdminSettings(onAdminSettingsRestored);
});
2015-03-11 23:26:00 +01:00
};
2015-02-13 18:10:10 +01:00
/******************************************************************************/
})();
2014-08-21 16:56:36 +02:00
/******************************************************************************/
2015-03-11 23:26:00 +01:00
µBlock.restart();