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-07-20 19:52:14 +02:00
|
|
|
Copyright (C) 2014-present 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
|
|
|
|
*/
|
|
|
|
|
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
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
(async ( ) => {
|
|
|
|
// >>>>> start of private scope
|
2015-02-13 18:10:10 +01:00
|
|
|
|
2018-11-03 12:58:46 +01:00
|
|
|
const µb = µBlock;
|
2015-02-24 19:48:03 +01:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2015-06-11 18:12:23 +02:00
|
|
|
vAPI.app.onShutdown = function() {
|
2019-09-11 14:00:55 +02:00
|
|
|
const µb = µBlock;
|
2015-06-11 18:12:23 +02:00
|
|
|
µb.staticFilteringReverseLookup.shutdown();
|
2017-01-18 19:17:47 +01:00
|
|
|
µb.assets.updateStop();
|
2015-06-11 18:12:23 +02:00
|
|
|
µb.staticNetFilteringEngine.reset();
|
2017-12-28 19:49:02 +01:00
|
|
|
µb.staticExtFilteringEngine.reset();
|
2015-06-11 18:12:23 +02:00
|
|
|
µb.sessionFirewall.reset();
|
|
|
|
µb.permanentFirewall.reset();
|
|
|
|
µb.sessionURLFiltering.reset();
|
|
|
|
µb.permanentURLFiltering.reset();
|
2018-09-03 20:06:49 +02:00
|
|
|
µb.sessionSwitches.reset();
|
|
|
|
µb.permanentSwitches.reset();
|
2015-06-11 18:12:23 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
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.
|
|
|
|
|
2019-09-11 14:00:55 +02:00
|
|
|
const onAllReady = function() {
|
2018-12-23 23:59:31 +01:00
|
|
|
µb.webRequest.start();
|
|
|
|
|
2018-12-06 01:18:20 +01:00
|
|
|
// Ensure that the resources allocated for decompression purpose (likely
|
|
|
|
// large buffers) are garbage-collectable immediately after launch.
|
|
|
|
// Otherwise I have observed that it may take quite a while before the
|
|
|
|
// garbage collection of these resources kicks in. Relinquishing as soon
|
|
|
|
// as possible ensure minimal memory usage baseline.
|
|
|
|
µb.lz4Codec.relinquish();
|
|
|
|
|
2018-10-28 14:58:25 +01:00
|
|
|
initializeTabs();
|
|
|
|
|
2015-04-07 03:26:05 +02:00
|
|
|
// https://github.com/chrisaljoudi/uBlock/issues/184
|
2019-05-20 00:31:12 +02:00
|
|
|
// Check for updates not too far in the future.
|
2017-01-18 19:17:47 +01:00
|
|
|
µb.assets.addObserver(µb.assetObserver.bind(µb));
|
2019-05-20 00:31:12 +02:00
|
|
|
µb.scheduleAssetUpdater(
|
|
|
|
µb.userSettings.autoUpdate
|
|
|
|
? µb.hiddenSettings.autoUpdateDelayAfterLaunch * 1000
|
|
|
|
: 0
|
|
|
|
);
|
2015-02-13 18:10:10 +01:00
|
|
|
|
2016-10-16 19:04:31 +02:00
|
|
|
// vAPI.cloud is optional.
|
2016-10-19 16:20:26 +02:00
|
|
|
if ( µb.cloudStorageSupported ) {
|
2016-10-16 19:04:31 +02:00
|
|
|
vAPI.cloud.start([
|
|
|
|
'tpFiltersPane',
|
|
|
|
'myFiltersPane',
|
|
|
|
'myRulesPane',
|
|
|
|
'whitelistPane'
|
|
|
|
]);
|
|
|
|
}
|
2015-08-11 21:29:14 +02:00
|
|
|
|
2016-01-17 19:30:43 +01:00
|
|
|
µb.contextMenu.update(null);
|
2016-01-03 19:58:25 +01:00
|
|
|
µb.firstInstall = false;
|
2019-02-14 19:33:55 +01:00
|
|
|
|
2019-09-11 14:00:55 +02:00
|
|
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/717
|
|
|
|
// Prevent the extensions from being restarted mid-session.
|
|
|
|
browser.runtime.onUpdateAvailable.addListener(details => {
|
|
|
|
const toInt = vAPI.app.intFromVersion;
|
|
|
|
if (
|
|
|
|
µBlock.hiddenSettings.extensionUpdateForceReload === true ||
|
|
|
|
toInt(details.version) <= toInt(vAPI.app.version)
|
|
|
|
) {
|
|
|
|
vAPI.app.restart();
|
|
|
|
}
|
|
|
|
});
|
2018-10-28 14:58:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
2016-11-03 16:20:47 +01:00
|
|
|
|
2018-10-28 14:58:25 +01:00
|
|
|
// This is called only once, when everything has been loaded in memory after
|
|
|
|
// the extension was launched. It can be used to inject content scripts
|
|
|
|
// in already opened web pages, to remove whatever nuisance could make it to
|
|
|
|
// the web pages before uBlock was ready.
|
|
|
|
|
2019-09-11 14:00:55 +02:00
|
|
|
const initializeTabs = function() {
|
|
|
|
const handleScriptResponse = function(tabId, results) {
|
2018-10-28 14:58:25 +01:00
|
|
|
if (
|
|
|
|
Array.isArray(results) === false ||
|
|
|
|
results.length === 0 ||
|
|
|
|
results[0] !== true
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Inject dclarative content scripts programmatically.
|
2019-09-11 14:00:55 +02:00
|
|
|
const manifest = chrome.runtime.getManifest();
|
2018-10-28 14:58:25 +01:00
|
|
|
if ( manifest instanceof Object === false ) { return; }
|
2019-09-11 14:00:55 +02:00
|
|
|
for ( const contentScript of manifest.content_scripts ) {
|
|
|
|
for ( const file of contentScript.js ) {
|
2018-10-28 14:58:25 +01:00
|
|
|
vAPI.tabs.injectScript(tabId, {
|
|
|
|
file: file,
|
|
|
|
allFrames: contentScript.all_frames,
|
|
|
|
runAt: contentScript.run_at
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2019-09-11 14:00:55 +02:00
|
|
|
const bindToTabs = function(tabs) {
|
|
|
|
for ( const tab of tabs ) {
|
2018-10-28 14:58:25 +01:00
|
|
|
µb.tabContextManager.commit(tab.id, tab.url);
|
|
|
|
µb.bindTabToPageStats(tab.id);
|
|
|
|
// https://github.com/chrisaljoudi/uBlock/issues/129
|
|
|
|
// Find out whether content scripts need to be injected
|
|
|
|
// programmatically. This may be necessary for web pages which
|
|
|
|
// were loaded before uBO launched.
|
|
|
|
if ( /^https?:\/\//.test(tab.url) === false ) { continue; }
|
|
|
|
vAPI.tabs.injectScript(
|
|
|
|
tab.id,
|
|
|
|
{ file: 'js/scriptlets/should-inject-contentscript.js' },
|
|
|
|
handleScriptResponse.bind(null, tab.id)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
browser.tabs.query({ url: '<all_urls>' }, bindToTabs);
|
2015-02-13 18:10:10 +01:00
|
|
|
};
|
2014-12-20 21:28:16 +01:00
|
|
|
|
2014-08-21 01:39:49 +02:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-02-14 19:33:55 +01:00
|
|
|
const onCommandShortcutsReady = function(commandShortcuts) {
|
2018-07-19 00:00:55 +02:00
|
|
|
if ( Array.isArray(commandShortcuts) === false ) { return; }
|
|
|
|
µb.commandShortcuts = new Map(commandShortcuts);
|
2018-07-20 19:52:14 +02:00
|
|
|
if ( µb.canUpdateShortcuts === false ) { return; }
|
2019-02-14 19:33:55 +01:00
|
|
|
for ( const entry of commandShortcuts ) {
|
2018-07-19 00:00:55 +02:00
|
|
|
vAPI.commands.update({ name: entry[0], shortcut: entry[1] });
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2015-02-24 19:48:03 +01:00
|
|
|
// To bring older versions up to date
|
|
|
|
|
2019-02-14 19:33:55 +01:00
|
|
|
const onVersionReady = function(lastVersion) {
|
2018-03-30 14:55:51 +02:00
|
|
|
if ( lastVersion === vAPI.app.version ) { return; }
|
|
|
|
|
2019-07-03 15:40:12 +02:00
|
|
|
// Since built-in resources may have changed since last version, we
|
|
|
|
// force a reload of all resources.
|
|
|
|
µb.redirectEngine.invalidateResourcesSelfie();
|
2018-04-02 17:03:12 +02:00
|
|
|
|
2019-09-06 19:03:06 +02:00
|
|
|
const lastVersionInt = vAPI.app.intFromVersion(lastVersion);
|
2018-09-11 14:42:02 +02:00
|
|
|
|
2019-05-18 20:20:05 +02:00
|
|
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/494
|
|
|
|
// Remove useless per-site switches.
|
|
|
|
if ( lastVersionInt <= 1019003007 ) {
|
|
|
|
µb.sessionSwitches.toggle('no-scripting', 'behind-the-scene', 0);
|
|
|
|
µb.permanentSwitches.toggle('no-scripting', 'behind-the-scene', 0);
|
2018-09-11 14:37:32 +02:00
|
|
|
µb.saveHostnameSwitches();
|
|
|
|
}
|
|
|
|
|
2018-03-30 14:55:51 +02:00
|
|
|
vAPI.storage.set({ version: vAPI.app.version });
|
2015-02-13 18:10:10 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
2014-09-08 23:46:58 +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
|
|
|
|
|
2019-02-14 19:33:55 +01:00
|
|
|
const onNetWhitelistReady = function(netWhitelistRaw) {
|
2019-06-25 17:57:14 +02:00
|
|
|
if ( typeof netWhitelistRaw === 'string' ) {
|
|
|
|
netWhitelistRaw = netWhitelistRaw.split('\n');
|
|
|
|
}
|
|
|
|
µb.netWhitelist = µb.whitelistFromArray(netWhitelistRaw);
|
2015-02-24 19:48:03 +01:00
|
|
|
µb.netWhitelistModifyTime = Date.now();
|
2015-02-13 18:10:10 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
// User settings are in memory
|
|
|
|
|
2019-02-14 19:33:55 +01:00
|
|
|
const onUserSettingsReady = function(fetched) {
|
|
|
|
const userSettings = µb.userSettings;
|
2015-02-24 19:48:03 +01:00
|
|
|
|
|
|
|
fromFetch(userSettings, fetched);
|
2014-08-21 16:56:36 +02:00
|
|
|
|
2016-10-19 16:20:26 +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);
|
2018-09-03 20:06:49 +02:00
|
|
|
µb.permanentSwitches.fromString(fetched.hostnameSwitchesString);
|
|
|
|
µb.sessionSwitches.assign(µb.permanentSwitches);
|
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
|
|
|
|
|
2019-02-14 19:33:55 +01:00
|
|
|
const onSystemSettingsReady = function(fetched) {
|
2019-09-11 14:00:55 +02:00
|
|
|
let mustSaveSystemSettings = false;
|
2015-02-24 19:48:03 +01:00
|
|
|
if ( fetched.compiledMagic !== µb.systemSettings.compiledMagic ) {
|
2017-01-18 19:17:47 +01:00
|
|
|
µ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 ) {
|
2015-03-01 23:25:48 +01:00
|
|
|
fetched.selfie = null;
|
2015-11-29 23:06:58 +01:00
|
|
|
µb.selfieManager.destroy();
|
2018-04-06 22:02:35 +02:00
|
|
|
vAPI.storage.set(µb.systemSettings);
|
2015-02-24 00:31:29 +01:00
|
|
|
}
|
2015-02-24 19:48:03 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-02-14 19:33:55 +01:00
|
|
|
const onFirstFetchReady = function(fetched) {
|
2019-04-03 18:18:47 +02:00
|
|
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/507
|
|
|
|
// Firefox-specific: somehow `fetched` is undefined under certain
|
|
|
|
// circumstances even though we asked to load with default values.
|
|
|
|
if ( fetched instanceof Object === false ) {
|
|
|
|
fetched = createDefaultProps();
|
|
|
|
}
|
|
|
|
|
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);
|
2018-07-19 00:00:55 +02:00
|
|
|
onCommandShortcutsReady(fetched.commandShortcuts);
|
2015-02-24 19:48:03 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-02-14 19:33:55 +01:00
|
|
|
const toFetch = function(from, fetched) {
|
|
|
|
for ( const k in from ) {
|
|
|
|
if ( from.hasOwnProperty(k) === false ) { continue; }
|
2015-02-24 19:48:03 +01:00
|
|
|
fetched[k] = from[k];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-02-14 19:33:55 +01:00
|
|
|
const fromFetch = function(to, fetched) {
|
|
|
|
for ( const k in to ) {
|
|
|
|
if ( to.hasOwnProperty(k) === false ) { continue; }
|
|
|
|
if ( fetched.hasOwnProperty(k) === false ) { continue; }
|
2015-02-24 19:48:03 +01:00
|
|
|
to[k] = fetched[k];
|
|
|
|
}
|
2015-02-24 00:31:29 +01:00
|
|
|
};
|
|
|
|
|
2019-04-03 18:18:47 +02:00
|
|
|
const createDefaultProps = function() {
|
2019-02-14 19:33:55 +01:00
|
|
|
const fetchableProps = {
|
2018-07-19 00:00:55 +02:00
|
|
|
'commandShortcuts': [],
|
2018-09-11 14:37:32 +02:00
|
|
|
'compiledMagic': 0,
|
2018-03-31 16:21:11 +02:00
|
|
|
'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': '',
|
2018-03-31 16:21:11 +02:00
|
|
|
'hostnameSwitchesString': [
|
2018-09-03 20:06:49 +02:00
|
|
|
'no-large-media: behind-the-scene false',
|
2018-03-31 16:21:11 +02:00
|
|
|
].join('\n'),
|
2016-01-03 19:58:25 +01:00
|
|
|
'lastRestoreFile': '',
|
|
|
|
'lastRestoreTime': 0,
|
|
|
|
'lastBackupFile': '',
|
|
|
|
'lastBackupTime': 0,
|
2019-06-25 17:57:14 +02:00
|
|
|
'netWhitelist': µb.netWhitelistDefault,
|
2018-09-11 14:37:32 +02:00
|
|
|
'selfieMagic': 0,
|
2016-01-03 19:58:25 +01:00
|
|
|
'version': '0.0.0.0'
|
2015-10-21 17:53:03 +02:00
|
|
|
};
|
2016-01-03 19:58:25 +01:00
|
|
|
toFetch(µb.localSettings, fetchableProps);
|
|
|
|
toFetch(µb.userSettings, fetchableProps);
|
|
|
|
toFetch(µb.restoreBackupSettings, fetchableProps);
|
2019-04-03 18:18:47 +02:00
|
|
|
return fetchableProps;
|
2016-01-03 19:58:25 +01:00
|
|
|
};
|
2017-01-26 16:17:38 +01:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
try {
|
|
|
|
// https://github.com/gorhill/uBlock/issues/531
|
|
|
|
await µb.restoreAdminSettings();
|
2019-02-14 19:33:55 +01:00
|
|
|
log.info(`Admin settings ready ${Date.now()-vAPI.T0} ms after launch`);
|
2019-02-17 21:40:09 +01:00
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
await µb.loadHiddenSettings();
|
|
|
|
log.info(`Hidden settings ready ${Date.now()-vAPI.T0} ms after launch`);
|
2016-01-03 19:58:25 +01:00
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
const cacheBackend = await µb.cacheStorage.select(
|
|
|
|
µb.hiddenSettings.cacheStorageAPI
|
|
|
|
);
|
|
|
|
log.info(`Backend storage for cache will be ${cacheBackend}`);
|
|
|
|
|
|
|
|
await Promise.all([
|
|
|
|
µb.loadSelectedFilterLists().then(( ) => {
|
|
|
|
log.info(`List selection ready ${Date.now()-vAPI.T0} ms after launch`);
|
|
|
|
}),
|
|
|
|
vAPI.storage.get(createDefaultProps()).then(fetched => {
|
|
|
|
log.info(`First fetch ready ${Date.now()-vAPI.T0} ms after launch`);
|
|
|
|
onFirstFetchReady(fetched);
|
|
|
|
}),
|
|
|
|
µb.loadPublicSuffixList().then(( ) => {
|
|
|
|
log.info(`PSL ready ${Date.now()-vAPI.T0} ms after launch`);
|
|
|
|
}),
|
|
|
|
]);
|
|
|
|
|
|
|
|
const selfieIsValid = await µb.selfieManager.load();
|
|
|
|
if ( selfieIsValid === true ) {
|
|
|
|
log.info(`Selfie ready ${Date.now()-vAPI.T0} ms after launch`);
|
|
|
|
} else {
|
|
|
|
await µb.loadFilterLists();
|
|
|
|
log.info(`Filter lists ready ${Date.now()-vAPI.T0} ms after launch`);
|
|
|
|
}
|
|
|
|
} catch (ex) {
|
|
|
|
console.trace(ex);
|
|
|
|
}
|
2016-01-03 19:58:25 +01:00
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
onAllReady();
|
|
|
|
log.info(`All ready ${Date.now()-vAPI.T0} ms after launch`);
|
2015-03-11 23:26:00 +01:00
|
|
|
|
2019-09-15 13:58:28 +02:00
|
|
|
// <<<<< end of private scope
|
|
|
|
})();
|