mirror of https://github.com/gorhill/uBlock.git
This commit is contained in:
parent
0d6a18207a
commit
e7d4aff2a2
|
@ -40,19 +40,28 @@
|
||||||
|
|
||||||
µBlock.cacheStorage = (function() {
|
µBlock.cacheStorage = (function() {
|
||||||
|
|
||||||
// Firefox-specific: we use indexedDB because chrome.storage.local() has
|
const STORAGE_NAME = 'uBlock0CacheStorage';
|
||||||
// poor performance in Firefox. See:
|
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1371255
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1371255
|
||||||
if ( vAPI.webextFlavor.soup.has('firefox') === false ) {
|
// Firefox-specific: we use indexedDB because chrome.storage.local() has
|
||||||
|
// poor performance in Firefox.
|
||||||
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/328
|
||||||
|
// Use IndexedDB for Chromium as well, to take advantage of LZ4
|
||||||
|
// compression.
|
||||||
|
if (
|
||||||
|
vAPI.webextFlavor.soup.has('firefox') === false &&
|
||||||
|
vAPI.webextFlavor.soup.has('chromium') === false
|
||||||
|
) {
|
||||||
|
// In case IndexedDB was used as cache storage, remove it.
|
||||||
|
indexedDB.deleteDatabase(STORAGE_NAME);
|
||||||
return vAPI.cacheStorage;
|
return vAPI.cacheStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
const STORAGE_NAME = 'uBlock0CacheStorage';
|
|
||||||
let db;
|
let db;
|
||||||
let pendingInitialization;
|
let pendingInitialization;
|
||||||
let dbByteLength;
|
let dbByteLength;
|
||||||
|
|
||||||
let get = function get(input, callback) {
|
const get = function get(input, callback) {
|
||||||
if ( typeof callback !== 'function' ) { return; }
|
if ( typeof callback !== 'function' ) { return; }
|
||||||
if ( input === null ) {
|
if ( input === null ) {
|
||||||
return getAllFromDb(callback);
|
return getAllFromDb(callback);
|
||||||
|
@ -69,23 +78,23 @@
|
||||||
return getFromDb(toRead, output, callback);
|
return getFromDb(toRead, output, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
let set = function set(input, callback) {
|
const set = function set(input, callback) {
|
||||||
putToDb(input, callback);
|
putToDb(input, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
let remove = function remove(key, callback) {
|
const remove = function remove(key, callback) {
|
||||||
deleteFromDb(key, callback);
|
deleteFromDb(key, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
let clear = function clear(callback) {
|
const clear = function clear(callback) {
|
||||||
clearDb(callback);
|
clearDb(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
let getBytesInUse = function getBytesInUse(keys, callback) {
|
const getBytesInUse = function getBytesInUse(keys, callback) {
|
||||||
getDbSize(callback);
|
getDbSize(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
let api = {
|
const api = {
|
||||||
get,
|
get,
|
||||||
set,
|
set,
|
||||||
remove,
|
remove,
|
||||||
|
@ -94,7 +103,7 @@
|
||||||
error: undefined
|
error: undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
let genericErrorHandler = function(ev) {
|
const genericErrorHandler = function(ev) {
|
||||||
let error = ev.target && ev.target.error;
|
let error = ev.target && ev.target.error;
|
||||||
if ( error && error.name === 'QuotaExceededError' ) {
|
if ( error && error.name === 'QuotaExceededError' ) {
|
||||||
api.error = error.name;
|
api.error = error.name;
|
||||||
|
@ -102,10 +111,10 @@
|
||||||
console.error('[%s]', STORAGE_NAME, error && error.name);
|
console.error('[%s]', STORAGE_NAME, error && error.name);
|
||||||
};
|
};
|
||||||
|
|
||||||
function noopfn() {
|
const noopfn = function () {
|
||||||
}
|
};
|
||||||
|
|
||||||
let getDb = function getDb() {
|
const getDb = function getDb() {
|
||||||
if ( db instanceof IDBDatabase ) {
|
if ( db instanceof IDBDatabase ) {
|
||||||
return Promise.resolve(db);
|
return Promise.resolve(db);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +174,7 @@
|
||||||
return pendingInitialization;
|
return pendingInitialization;
|
||||||
};
|
};
|
||||||
|
|
||||||
let getFromDb = function(keys, keyvalStore, callback) {
|
const getFromDb = function(keys, keyvalStore, callback) {
|
||||||
if ( typeof callback !== 'function' ) { return; }
|
if ( typeof callback !== 'function' ) { return; }
|
||||||
if ( keys.length === 0 ) { return callback(keyvalStore); }
|
if ( keys.length === 0 ) { return callback(keyvalStore); }
|
||||||
let promises = [];
|
let promises = [];
|
||||||
|
@ -202,7 +211,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let visitAllFromDb = function(visitFn) {
|
const visitAllFromDb = function(visitFn) {
|
||||||
getDb().then(( ) => {
|
getDb().then(( ) => {
|
||||||
if ( !db ) { return visitFn(); }
|
if ( !db ) { return visitFn(); }
|
||||||
let transaction = db.transaction(STORAGE_NAME);
|
let transaction = db.transaction(STORAGE_NAME);
|
||||||
|
@ -221,7 +230,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let getAllFromDb = function(callback) {
|
const getAllFromDb = function(callback) {
|
||||||
if ( typeof callback !== 'function' ) { return; }
|
if ( typeof callback !== 'function' ) { return; }
|
||||||
let promises = [];
|
let promises = [];
|
||||||
let keyvalStore = {};
|
let keyvalStore = {};
|
||||||
|
@ -245,7 +254,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let getDbSize = function(callback) {
|
const getDbSize = function(callback) {
|
||||||
if ( typeof callback !== 'function' ) { return; }
|
if ( typeof callback !== 'function' ) { return; }
|
||||||
if ( typeof dbByteLength === 'number' ) {
|
if ( typeof dbByteLength === 'number' ) {
|
||||||
return Promise.resolve().then(( ) => {
|
return Promise.resolve().then(( ) => {
|
||||||
|
@ -280,7 +289,7 @@
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/transaction
|
// https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/transaction
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/put
|
// https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/put
|
||||||
|
|
||||||
let putToDb = function(keyvalStore, callback) {
|
const putToDb = function(keyvalStore, callback) {
|
||||||
if ( typeof callback !== 'function' ) {
|
if ( typeof callback !== 'function' ) {
|
||||||
callback = noopfn;
|
callback = noopfn;
|
||||||
}
|
}
|
||||||
|
@ -326,7 +335,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let deleteFromDb = function(input, callback) {
|
const deleteFromDb = function(input, callback) {
|
||||||
if ( typeof callback !== 'function' ) {
|
if ( typeof callback !== 'function' ) {
|
||||||
callback = noopfn;
|
callback = noopfn;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +365,7 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let clearDb = function(callback) {
|
const clearDb = function(callback) {
|
||||||
if ( typeof callback !== 'function' ) {
|
if ( typeof callback !== 'function' ) {
|
||||||
callback = noopfn;
|
callback = noopfn;
|
||||||
}
|
}
|
||||||
|
@ -383,6 +392,57 @@
|
||||||
// prime the db so that it's ready asap for next access.
|
// prime the db so that it's ready asap for next access.
|
||||||
getDb(noopfn);
|
getDb(noopfn);
|
||||||
|
|
||||||
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/328
|
||||||
|
// Detect whether browser.storage.local was used as cache storage,
|
||||||
|
// and if so, move cache-related entries to the new storage.
|
||||||
|
{
|
||||||
|
const srcStorage = vAPI.cacheStorage;
|
||||||
|
const desStorage = api;
|
||||||
|
srcStorage.get(
|
||||||
|
[ 'assetCacheRegistry', 'assetSourceRegistry' ],
|
||||||
|
bin => {
|
||||||
|
if (
|
||||||
|
bin instanceof Object === false ||
|
||||||
|
bin.assetSourceRegistry instanceof Object === false
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
desStorage.set(bin);
|
||||||
|
const toRemove = [
|
||||||
|
'assetCacheRegistry',
|
||||||
|
'assetSourceRegistry',
|
||||||
|
'resourcesSelfie',
|
||||||
|
'selfie'
|
||||||
|
];
|
||||||
|
let toMigrate = 0;
|
||||||
|
const setEntry = function(assetKey, bin) {
|
||||||
|
if (
|
||||||
|
bin instanceof Object &&
|
||||||
|
bin[assetKey] !== undefined
|
||||||
|
) {
|
||||||
|
desStorage.set(bin);
|
||||||
|
}
|
||||||
|
toMigrate -= 1;
|
||||||
|
if ( toMigrate === 0 ) {
|
||||||
|
srcStorage.remove(toRemove);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for ( const key in bin.assetCacheRegistry ) {
|
||||||
|
if ( bin.assetCacheRegistry.hasOwnProperty(key) === false ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const assetKey = 'cache/' + key;
|
||||||
|
srcStorage.get(assetKey, setEntry.bind(null, assetKey));
|
||||||
|
toMigrate += 1;
|
||||||
|
toRemove.push(assetKey);
|
||||||
|
}
|
||||||
|
if ( toMigrate === 0 ) {
|
||||||
|
srcStorage.remove(toRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return api;
|
return api;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,11 @@ return {
|
||||||
data: decodeValue(result.key, result.data) || result.data
|
data: decodeValue(result.key, result.data) || result.data
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
relinquish: function() {
|
||||||
|
ttlDelay = 1;
|
||||||
|
ttlManage(0);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -53,6 +53,13 @@ vAPI.app.onShutdown = function() {
|
||||||
// - Schedule next update operation.
|
// - Schedule next update operation.
|
||||||
|
|
||||||
var onAllReady = function() {
|
var onAllReady = function() {
|
||||||
|
// 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();
|
||||||
|
|
||||||
µb.webRequest.start();
|
µb.webRequest.start();
|
||||||
initializeTabs();
|
initializeTabs();
|
||||||
|
|
||||||
|
|
|
@ -608,15 +608,15 @@
|
||||||
if ( this.loadingFilterLists ) { return; }
|
if ( this.loadingFilterLists ) { return; }
|
||||||
this.loadingFilterLists = true;
|
this.loadingFilterLists = true;
|
||||||
|
|
||||||
var µb = this,
|
const µb = µBlock;
|
||||||
filterlistsCount = 0,
|
const loadedListKeys = [];
|
||||||
loadedListKeys = [];
|
let filterlistsCount = 0;
|
||||||
|
|
||||||
if ( typeof callback !== 'function' ) {
|
if ( typeof callback !== 'function' ) {
|
||||||
callback = this.noopFunc;
|
callback = this.noopFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
var onDone = function() {
|
const onDone = function() {
|
||||||
µb.staticNetFilteringEngine.freeze();
|
µb.staticNetFilteringEngine.freeze();
|
||||||
µb.staticExtFilteringEngine.freeze();
|
µb.staticExtFilteringEngine.freeze();
|
||||||
µb.redirectEngine.freeze();
|
µb.redirectEngine.freeze();
|
||||||
|
@ -632,17 +632,19 @@
|
||||||
callback();
|
callback();
|
||||||
|
|
||||||
µb.selfieManager.destroy();
|
µb.selfieManager.destroy();
|
||||||
|
µb.lz4Codec.relinquish();
|
||||||
|
|
||||||
µb.loadingFilterLists = false;
|
µb.loadingFilterLists = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
var applyCompiledFilters = function(assetKey, compiled) {
|
const applyCompiledFilters = function(assetKey, compiled) {
|
||||||
var snfe = µb.staticNetFilteringEngine,
|
const snfe = µb.staticNetFilteringEngine;
|
||||||
sxfe = µb.staticExtFilteringEngine,
|
const sxfe = µb.staticExtFilteringEngine;
|
||||||
acceptedCount = snfe.acceptedCount + sxfe.acceptedCount,
|
let acceptedCount = snfe.acceptedCount + sxfe.acceptedCount,
|
||||||
discardedCount = snfe.discardedCount + sxfe.discardedCount;
|
discardedCount = snfe.discardedCount + sxfe.discardedCount;
|
||||||
µb.applyCompiledFilters(compiled, assetKey === µb.userFiltersPath);
|
µb.applyCompiledFilters(compiled, assetKey === µb.userFiltersPath);
|
||||||
if ( µb.availableFilterLists.hasOwnProperty(assetKey) ) {
|
if ( µb.availableFilterLists.hasOwnProperty(assetKey) ) {
|
||||||
var entry = µb.availableFilterLists[assetKey];
|
const entry = µb.availableFilterLists[assetKey];
|
||||||
entry.entryCount = snfe.acceptedCount + sxfe.acceptedCount -
|
entry.entryCount = snfe.acceptedCount + sxfe.acceptedCount -
|
||||||
acceptedCount;
|
acceptedCount;
|
||||||
entry.entryUsedCount = entry.entryCount -
|
entry.entryUsedCount = entry.entryCount -
|
||||||
|
@ -651,7 +653,7 @@
|
||||||
loadedListKeys.push(assetKey);
|
loadedListKeys.push(assetKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
var onCompiledListLoaded = function(details) {
|
const onCompiledListLoaded = function(details) {
|
||||||
applyCompiledFilters(details.assetKey, details.content);
|
applyCompiledFilters(details.assetKey, details.content);
|
||||||
filterlistsCount -= 1;
|
filterlistsCount -= 1;
|
||||||
if ( filterlistsCount === 0 ) {
|
if ( filterlistsCount === 0 ) {
|
||||||
|
@ -659,7 +661,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var onFilterListsReady = function(lists) {
|
const onFilterListsReady = function(lists) {
|
||||||
µb.availableFilterLists = lists;
|
µb.availableFilterLists = lists;
|
||||||
|
|
||||||
µb.redirectEngine.reset();
|
µb.redirectEngine.reset();
|
||||||
|
@ -672,8 +674,8 @@
|
||||||
// because it *may* happens that some load operations are synchronous:
|
// because it *may* happens that some load operations are synchronous:
|
||||||
// This happens for assets which do not exist, ot assets with no
|
// This happens for assets which do not exist, ot assets with no
|
||||||
// content.
|
// content.
|
||||||
var toLoad = [];
|
const toLoad = [];
|
||||||
for ( var assetKey in lists ) {
|
for ( const assetKey in lists ) {
|
||||||
if ( lists.hasOwnProperty(assetKey) === false ) { continue; }
|
if ( lists.hasOwnProperty(assetKey) === false ) { continue; }
|
||||||
if ( lists[assetKey].off ) { continue; }
|
if ( lists[assetKey].off ) { continue; }
|
||||||
toLoad.push(assetKey);
|
toLoad.push(assetKey);
|
||||||
|
@ -683,7 +685,7 @@
|
||||||
return onDone();
|
return onDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
var i = toLoad.length;
|
let i = toLoad.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
µb.getCompiledFilterList(toLoad[i], onCompiledListLoaded);
|
µb.getCompiledFilterList(toLoad[i], onCompiledListLoaded);
|
||||||
}
|
}
|
||||||
|
@ -1021,6 +1023,7 @@
|
||||||
staticExtFilteringEngine: µb.staticExtFilteringEngine.toSelfie()
|
staticExtFilteringEngine: µb.staticExtFilteringEngine.toSelfie()
|
||||||
});
|
});
|
||||||
µb.cacheStorage.set({ selfie: selfie });
|
µb.cacheStorage.set({ selfie: selfie });
|
||||||
|
µb.lz4Codec.relinquish();
|
||||||
};
|
};
|
||||||
|
|
||||||
let load = function(callback) {
|
let load = function(callback) {
|
||||||
|
|
Loading…
Reference in New Issue