mirror of
https://github.com/gorhill/uBlock.git
synced 2024-10-06 09:37:12 +02:00
Wrap usage of setTimeout in helper for background + auxiliary pages
This commit centralizes usage of setTimeout()/clearTimeout() in the source code at one single location.
This commit is contained in:
parent
b4984ed85b
commit
91f9795023
@ -35,6 +35,116 @@ vAPI.T0 = Date.now();
|
|||||||
|
|
||||||
vAPI.setTimeout = vAPI.setTimeout || self.setTimeout.bind(self);
|
vAPI.setTimeout = vAPI.setTimeout || self.setTimeout.bind(self);
|
||||||
|
|
||||||
|
vAPI.defer = {
|
||||||
|
create(callback) {
|
||||||
|
return new this.Client(callback);
|
||||||
|
},
|
||||||
|
once(delay, ...args) {
|
||||||
|
const delayInMs = vAPI.defer.normalizeDelay(delay);
|
||||||
|
return new Promise(resolve => {
|
||||||
|
vAPI.setTimeout(
|
||||||
|
(...args) => { resolve(...args); },
|
||||||
|
delayInMs,
|
||||||
|
...args
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
Client: class {
|
||||||
|
constructor(callback) {
|
||||||
|
this.timer = null;
|
||||||
|
this.type = 0;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
on(delay, ...args) {
|
||||||
|
if ( this.timer !== null ) { return; }
|
||||||
|
const delayInMs = vAPI.defer.normalizeDelay(delay);
|
||||||
|
this.type = 0;
|
||||||
|
this.timer = vAPI.setTimeout(( ) => {
|
||||||
|
this.timer = null;
|
||||||
|
this.callback(...args);
|
||||||
|
}, delayInMs || 1);
|
||||||
|
}
|
||||||
|
offon(delay, ...args) {
|
||||||
|
this.off();
|
||||||
|
this.on(delay, ...args);
|
||||||
|
}
|
||||||
|
onvsync(delay, ...args) {
|
||||||
|
if ( this.timer !== null ) { return; }
|
||||||
|
const delayInMs = vAPI.defer.normalizeDelay(delay);
|
||||||
|
if ( delayInMs !== 0 ) {
|
||||||
|
this.type = 0;
|
||||||
|
this.timer = vAPI.setTimeout(( ) => {
|
||||||
|
this.timer = null;
|
||||||
|
this.onraf(...args);
|
||||||
|
}, delayInMs);
|
||||||
|
} else {
|
||||||
|
this.onraf(...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onidle(delay, ...args) {
|
||||||
|
if ( this.timer !== null ) { return; }
|
||||||
|
const delayInMs = vAPI.defer.normalizeDelay(delay);
|
||||||
|
if ( delayInMs !== 0 ) {
|
||||||
|
this.type = 0;
|
||||||
|
this.timer = vAPI.setTimeout(( ) => {
|
||||||
|
this.timer = null;
|
||||||
|
this.onric(...args);
|
||||||
|
}, delayInMs);
|
||||||
|
} else {
|
||||||
|
this.onric(...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
off() {
|
||||||
|
if ( this.timer === null ) { return; }
|
||||||
|
switch ( this.type ) {
|
||||||
|
case 0:
|
||||||
|
self.clearTimeout(this.timer);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
self.cancelAnimationFrame(this.timer);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
self.cancelIdleCallback(this.timer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.timer = null;
|
||||||
|
}
|
||||||
|
onraf(...args) {
|
||||||
|
if ( this.timer !== null ) { return; }
|
||||||
|
this.type = 1;
|
||||||
|
this.timer = requestAnimationFrame(( ) => {
|
||||||
|
this.timer = null;
|
||||||
|
this.callback(...args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onric(...args) {
|
||||||
|
if ( this.timer !== null ) { return; }
|
||||||
|
this.type = 2;
|
||||||
|
this.timer = self.requestIdleCallback(deadline => {
|
||||||
|
this.timer = null;
|
||||||
|
this.callback(deadline, ...args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ongoing() {
|
||||||
|
return this.timer !== null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
normalizeDelay(delay = 0) {
|
||||||
|
if ( typeof delay === 'object' ) {
|
||||||
|
if ( delay.sec !== undefined ) {
|
||||||
|
return delay.sec * 1000;
|
||||||
|
} else if ( delay.min !== undefined ) {
|
||||||
|
return delay.min * 60000;
|
||||||
|
} else if ( delay.hr !== undefined ) {
|
||||||
|
return delay.hr * 3600000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.webextFlavor = {
|
vAPI.webextFlavor = {
|
||||||
|
@ -56,12 +56,17 @@ let cachedUserFilters = '';
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// Add auto-complete ability to the editor.
|
// Add auto-complete ability to the editor. Polling is used as the suggested
|
||||||
|
// hints also depend on the tabs currently opened.
|
||||||
|
|
||||||
{
|
{
|
||||||
let hintUpdateToken = 0;
|
let hintUpdateToken = 0;
|
||||||
|
|
||||||
const responseHandler = function(response) {
|
const getHints = async function() {
|
||||||
|
const response = await vAPI.messaging.send('dashboard', {
|
||||||
|
what: 'getAutoCompleteDetails',
|
||||||
|
hintUpdateToken
|
||||||
|
});
|
||||||
if ( response instanceof Object === false ) { return; }
|
if ( response instanceof Object === false ) { return; }
|
||||||
if ( response.hintUpdateToken !== undefined ) {
|
if ( response.hintUpdateToken !== undefined ) {
|
||||||
const mode = cmEditor.getMode();
|
const mode = cmEditor.getMode();
|
||||||
@ -73,15 +78,12 @@ let cachedUserFilters = '';
|
|||||||
}
|
}
|
||||||
hintUpdateToken = response.hintUpdateToken;
|
hintUpdateToken = response.hintUpdateToken;
|
||||||
}
|
}
|
||||||
vAPI.setTimeout(getHints, 2503);
|
timer.on(2503);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getHints = function() {
|
const timer = vAPI.defer.create(( ) => {
|
||||||
vAPI.messaging.send('dashboard', {
|
getHints();
|
||||||
what: 'getAutoCompleteDetails',
|
});
|
||||||
hintUpdateToken
|
|
||||||
}).then(responseHandler);
|
|
||||||
};
|
|
||||||
|
|
||||||
getHints();
|
getHints();
|
||||||
}
|
}
|
||||||
@ -306,8 +308,7 @@ dom.on('#userFiltersRevert', 'click', revertChanges);
|
|||||||
// https://github.com/gorhill/uBlock/issues/3706
|
// https://github.com/gorhill/uBlock/issues/3706
|
||||||
// Save/restore cursor position
|
// Save/restore cursor position
|
||||||
{
|
{
|
||||||
const line =
|
const line = await vAPI.localStorage.getItemAsync('myFiltersCursorPosition');
|
||||||
await vAPI.localStorage.getItemAsync('myFiltersCursorPosition');
|
|
||||||
if ( typeof line === 'number' ) {
|
if ( typeof line === 'number' ) {
|
||||||
cmEditor.setCursor(line, 0);
|
cmEditor.setCursor(line, 0);
|
||||||
}
|
}
|
||||||
@ -317,15 +318,14 @@ dom.on('#userFiltersRevert', 'click', revertChanges);
|
|||||||
// Save/restore cursor position
|
// Save/restore cursor position
|
||||||
{
|
{
|
||||||
let curline = 0;
|
let curline = 0;
|
||||||
let timer;
|
|
||||||
cmEditor.on('cursorActivity', ( ) => {
|
cmEditor.on('cursorActivity', ( ) => {
|
||||||
if ( timer !== undefined ) { return; }
|
if ( timer.ongoing() ) { return; }
|
||||||
if ( cmEditor.getCursor().line === curline ) { return; }
|
if ( cmEditor.getCursor().line === curline ) { return; }
|
||||||
timer = vAPI.setTimeout(( ) => {
|
timer.on(701);
|
||||||
timer = undefined;
|
});
|
||||||
|
const timer = vAPI.defer.create(( ) => {
|
||||||
curline = cmEditor.getCursor().line;
|
curline = cmEditor.getCursor().line;
|
||||||
vAPI.localStorage.setItem('myFiltersCursorPosition', curline);
|
vAPI.localStorage.setItem('myFiltersCursorPosition', curline);
|
||||||
}, 701);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,19 +118,16 @@ const arrayFromString = function(s) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const advancedSettingsChanged = (( ) => {
|
const advancedSettingsChanged = (( ) => {
|
||||||
let timer;
|
|
||||||
|
|
||||||
const handler = ( ) => {
|
const handler = ( ) => {
|
||||||
timer = undefined;
|
const changed = hashFromAdvancedSettings(cmEditor.getValue()) !== beforeHash;
|
||||||
const changed =
|
|
||||||
hashFromAdvancedSettings(cmEditor.getValue()) !== beforeHash;
|
|
||||||
qs$('#advancedSettingsApply').disabled = !changed;
|
qs$('#advancedSettingsApply').disabled = !changed;
|
||||||
CodeMirror.commands.save = changed ? applyChanges : function(){};
|
CodeMirror.commands.save = changed ? applyChanges : function(){};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const timer = vAPI.defer.create(handler);
|
||||||
|
|
||||||
return function() {
|
return function() {
|
||||||
if ( timer !== undefined ) { clearTimeout(timer); }
|
timer.offon(200);
|
||||||
timer = vAPI.setTimeout(handler, 100);
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -73,20 +73,16 @@ assets.fetch = function(url, options = {}) {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// Start of executor
|
// Start of executor
|
||||||
|
|
||||||
const timeoutAfter = µb.hiddenSettings.assetFetchTimeout * 1000 || 30000;
|
const timeoutAfter = µb.hiddenSettings.assetFetchTimeout || 30;
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
let contentLoaded = 0;
|
let contentLoaded = 0;
|
||||||
let timeoutTimer;
|
|
||||||
|
|
||||||
const cleanup = function() {
|
const cleanup = function() {
|
||||||
xhr.removeEventListener('load', onLoadEvent);
|
xhr.removeEventListener('load', onLoadEvent);
|
||||||
xhr.removeEventListener('error', onErrorEvent);
|
xhr.removeEventListener('error', onErrorEvent);
|
||||||
xhr.removeEventListener('abort', onErrorEvent);
|
xhr.removeEventListener('abort', onErrorEvent);
|
||||||
xhr.removeEventListener('progress', onProgressEvent);
|
xhr.removeEventListener('progress', onProgressEvent);
|
||||||
if ( timeoutTimer !== undefined ) {
|
timeoutTimer.off();
|
||||||
clearTimeout(timeoutTimer);
|
|
||||||
timeoutTimer = undefined;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const fail = function(details, msg) {
|
const fail = function(details, msg) {
|
||||||
@ -130,12 +126,11 @@ assets.fetch = function(url, options = {}) {
|
|||||||
const onProgressEvent = function(ev) {
|
const onProgressEvent = function(ev) {
|
||||||
if ( ev.loaded === contentLoaded ) { return; }
|
if ( ev.loaded === contentLoaded ) { return; }
|
||||||
contentLoaded = ev.loaded;
|
contentLoaded = ev.loaded;
|
||||||
if ( timeoutTimer !== undefined ) {
|
timeoutTimer.offon({ sec: timeoutAfter });
|
||||||
clearTimeout(timeoutTimer);
|
|
||||||
}
|
|
||||||
timeoutTimer = vAPI.setTimeout(onTimeout, timeoutAfter);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const timeoutTimer = vAPI.defer.create(onTimeout);
|
||||||
|
|
||||||
// Be ready for thrown exceptions:
|
// Be ready for thrown exceptions:
|
||||||
// I am pretty sure it used to work, but now using a URL such as
|
// I am pretty sure it used to work, but now using a URL such as
|
||||||
// `file:///` on Chromium 40 results in an exception being thrown.
|
// `file:///` on Chromium 40 results in an exception being thrown.
|
||||||
@ -147,7 +142,7 @@ assets.fetch = function(url, options = {}) {
|
|||||||
xhr.addEventListener('progress', onProgressEvent);
|
xhr.addEventListener('progress', onProgressEvent);
|
||||||
xhr.responseType = options.responseType || 'text';
|
xhr.responseType = options.responseType || 'text';
|
||||||
xhr.send();
|
xhr.send();
|
||||||
timeoutTimer = vAPI.setTimeout(onTimeout, timeoutAfter);
|
timeoutTimer.on({ sec: timeoutAfter });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
onErrorEvent.call(xhr);
|
onErrorEvent.call(xhr);
|
||||||
}
|
}
|
||||||
@ -422,17 +417,14 @@ const unregisterAssetSource = function(assetKey) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const saveAssetSourceRegistry = (( ) => {
|
const saveAssetSourceRegistry = (( ) => {
|
||||||
let timer;
|
const save = ( ) => {
|
||||||
const save = function() {
|
timer.off();
|
||||||
timer = undefined;
|
|
||||||
cacheStorage.set({ assetSourceRegistry });
|
cacheStorage.set({ assetSourceRegistry });
|
||||||
};
|
};
|
||||||
|
const timer = vAPI.defer.create(save);
|
||||||
return function(lazily) {
|
return function(lazily) {
|
||||||
if ( timer !== undefined ) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
}
|
|
||||||
if ( lazily ) {
|
if ( lazily ) {
|
||||||
timer = vAPI.setTimeout(save, 500);
|
timer.offon(500);
|
||||||
} else {
|
} else {
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
@ -533,15 +525,14 @@ const getAssetCacheRegistry = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const saveAssetCacheRegistry = (( ) => {
|
const saveAssetCacheRegistry = (( ) => {
|
||||||
let timer;
|
|
||||||
const save = function() {
|
const save = function() {
|
||||||
timer = undefined;
|
timer.off();
|
||||||
cacheStorage.set({ assetCacheRegistry });
|
cacheStorage.set({ assetCacheRegistry });
|
||||||
};
|
};
|
||||||
|
const timer = vAPI.defer.create(save);
|
||||||
return function(lazily) {
|
return function(lazily) {
|
||||||
if ( timer !== undefined ) { clearTimeout(timer); }
|
|
||||||
if ( lazily ) {
|
if ( lazily ) {
|
||||||
timer = vAPI.setTimeout(save, 30000);
|
timer.offon({ sec: 30 });
|
||||||
} else {
|
} else {
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
@ -961,7 +952,6 @@ const updaterUpdated = [];
|
|||||||
const updaterFetched = new Set();
|
const updaterFetched = new Set();
|
||||||
|
|
||||||
let updaterStatus;
|
let updaterStatus;
|
||||||
let updaterTimer;
|
|
||||||
let updaterAssetDelay = updaterAssetDelayDefault;
|
let updaterAssetDelay = updaterAssetDelayDefault;
|
||||||
let updaterAuto = false;
|
let updaterAuto = false;
|
||||||
|
|
||||||
@ -1043,9 +1033,11 @@ const updateNext = async function() {
|
|||||||
fireNotification('asset-update-failed', { assetKey: result.assetKey });
|
fireNotification('asset-update-failed', { assetKey: result.assetKey });
|
||||||
}
|
}
|
||||||
|
|
||||||
vAPI.setTimeout(updateNext, updaterAssetDelay);
|
updaterTimer.on(updaterAssetDelay);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updaterTimer = vAPI.defer.create(updateNext);
|
||||||
|
|
||||||
const updateDone = function() {
|
const updateDone = function() {
|
||||||
const assetKeys = updaterUpdated.slice(0);
|
const assetKeys = updaterUpdated.slice(0);
|
||||||
updaterFetched.clear();
|
updaterFetched.clear();
|
||||||
@ -1064,8 +1056,7 @@ assets.updateStart = function(details) {
|
|||||||
updaterAuto = details.auto === true;
|
updaterAuto = details.auto === true;
|
||||||
if ( updaterStatus !== undefined ) {
|
if ( updaterStatus !== undefined ) {
|
||||||
if ( newUpdateDelay < oldUpdateDelay ) {
|
if ( newUpdateDelay < oldUpdateDelay ) {
|
||||||
clearTimeout(updaterTimer);
|
updaterTimer.offon(updaterAssetDelay);
|
||||||
updaterTimer = vAPI.setTimeout(updateNext, updaterAssetDelay);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1073,10 +1064,7 @@ assets.updateStart = function(details) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assets.updateStop = function() {
|
assets.updateStop = function() {
|
||||||
if ( updaterTimer ) {
|
updaterTimer.off();
|
||||||
clearTimeout(updaterTimer);
|
|
||||||
updaterTimer = undefined;
|
|
||||||
}
|
|
||||||
if ( updaterStatus !== undefined ) {
|
if ( updaterStatus !== undefined ) {
|
||||||
updateDone();
|
updateDone();
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,6 @@ const µBlock = { // jshint ignore:line
|
|||||||
allowedRequestCount: 0,
|
allowedRequestCount: 0,
|
||||||
},
|
},
|
||||||
localSettingsLastModified: 0,
|
localSettingsLastModified: 0,
|
||||||
localSettingsLastSaved: 0,
|
|
||||||
|
|
||||||
// Read-only
|
// Read-only
|
||||||
systemSettings: {
|
systemSettings: {
|
||||||
|
@ -69,18 +69,13 @@ import {
|
|||||||
|
|
||||||
const loadBenchmarkDataset = (( ) => {
|
const loadBenchmarkDataset = (( ) => {
|
||||||
let datasetPromise;
|
let datasetPromise;
|
||||||
let ttlTimer;
|
|
||||||
|
const ttlTimer = vAPI.defer.create(( ) => {
|
||||||
|
datasetPromise = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
return function() {
|
return function() {
|
||||||
if ( ttlTimer !== undefined ) {
|
ttlTimer.offon({ min: 5 });
|
||||||
clearTimeout(ttlTimer);
|
|
||||||
ttlTimer = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(( ) => {
|
|
||||||
ttlTimer = undefined;
|
|
||||||
datasetPromise = undefined;
|
|
||||||
}, 5 * 60 * 1000);
|
|
||||||
|
|
||||||
if ( datasetPromise !== undefined ) {
|
if ( datasetPromise !== undefined ) {
|
||||||
return datasetPromise;
|
return datasetPromise;
|
||||||
|
@ -101,36 +101,27 @@ const cacheStorage = {
|
|||||||
const selectIDB = async function() {
|
const selectIDB = async function() {
|
||||||
let db;
|
let db;
|
||||||
let dbPromise;
|
let dbPromise;
|
||||||
let dbTimer;
|
|
||||||
|
|
||||||
const noopfn = function () {
|
const noopfn = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
const disconnect = function() {
|
const disconnect = function() {
|
||||||
if ( dbTimer !== undefined ) {
|
dbTimer.off();
|
||||||
clearTimeout(dbTimer);
|
|
||||||
dbTimer = undefined;
|
|
||||||
}
|
|
||||||
if ( db instanceof IDBDatabase ) {
|
if ( db instanceof IDBDatabase ) {
|
||||||
db.close();
|
db.close();
|
||||||
db = undefined;
|
db = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const keepAlive = function() {
|
const dbTimer = vAPI.defer.create(( ) => {
|
||||||
if ( dbTimer !== undefined ) {
|
|
||||||
clearTimeout(dbTimer);
|
|
||||||
}
|
|
||||||
dbTimer = vAPI.setTimeout(
|
|
||||||
( ) => {
|
|
||||||
dbTimer = undefined;
|
|
||||||
disconnect();
|
disconnect();
|
||||||
},
|
});
|
||||||
Math.max(
|
|
||||||
|
const keepAlive = function() {
|
||||||
|
dbTimer.offon(Math.max(
|
||||||
µb.hiddenSettings.autoUpdateAssetFetchPeriod * 2 * 1000,
|
µb.hiddenSettings.autoUpdateAssetFetchPeriod * 2 * 1000,
|
||||||
180000
|
180000
|
||||||
)
|
));
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/3156
|
// https://github.com/gorhill/uBlock/issues/3156
|
||||||
@ -192,13 +183,13 @@ const selectIDB = async function() {
|
|||||||
resolve(null);
|
resolve(null);
|
||||||
resolve = undefined;
|
resolve = undefined;
|
||||||
};
|
};
|
||||||
setTimeout(( ) => {
|
vAPI.defer.once(5000).then(( ) => {
|
||||||
if ( resolve === undefined ) { return; }
|
if ( resolve === undefined ) { return; }
|
||||||
db = null;
|
db = null;
|
||||||
dbPromise = undefined;
|
dbPromise = undefined;
|
||||||
resolve(null);
|
resolve(null);
|
||||||
resolve = undefined;
|
resolve = undefined;
|
||||||
}, 5000);
|
});
|
||||||
});
|
});
|
||||||
return dbPromise;
|
return dbPromise;
|
||||||
};
|
};
|
||||||
|
@ -211,7 +211,7 @@ async function setURL(resourceURL) {
|
|||||||
dom.attr(a, 'title', afterURL);
|
dom.attr(a, 'title', afterURL);
|
||||||
addPastURLs(afterURL);
|
addPastURLs(afterURL);
|
||||||
// For unknown reasons, calling focus() synchronously does not work...
|
// For unknown reasons, calling focus() synchronously does not work...
|
||||||
vAPI.setTimeout(( ) => { cmEditor.focus(); }, 1);
|
vAPI.defer.once(1).then(( ) => { cmEditor.focus(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -86,16 +86,7 @@ import { i18n$ } from '../i18n.js';
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( queryTextFromSearchWidget(cm) === state.queryText ) { return; }
|
if ( queryTextFromSearchWidget(cm) === state.queryText ) { return; }
|
||||||
if ( state.queryTimer !== null ) {
|
state.queryTimer.offon(350);
|
||||||
clearTimeout(state.queryTimer);
|
|
||||||
}
|
|
||||||
state.queryTimer = setTimeout(
|
|
||||||
() => {
|
|
||||||
state.queryTimer = null;
|
|
||||||
findCommit(cm, 0);
|
|
||||||
},
|
|
||||||
350
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchWidgetClickHandler = function(cm, ev) {
|
const searchWidgetClickHandler = function(cm, ev) {
|
||||||
@ -141,7 +132,6 @@ import { i18n$ } from '../i18n.js';
|
|||||||
this.panel = cm.addPanel(this.widget);
|
this.panel = cm.addPanel(this.widget);
|
||||||
}
|
}
|
||||||
this.queryText = '';
|
this.queryText = '';
|
||||||
this.queryTimer = null;
|
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
this.lines = [];
|
this.lines = [];
|
||||||
cm.on('changes', (cm, changes) => {
|
cm.on('changes', (cm, changes) => {
|
||||||
@ -155,6 +145,9 @@ import { i18n$ } from '../i18n.js';
|
|||||||
cm.on('cursorActivity', cm => {
|
cm.on('cursorActivity', cm => {
|
||||||
updateCount(cm);
|
updateCount(cm);
|
||||||
});
|
});
|
||||||
|
this.queryTimer = vAPI.defer.create(( ) => {
|
||||||
|
findCommit(cm, 0);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// We want the search widget to behave as if the focus was on the
|
// We want the search widget to behave as if the focus was on the
|
||||||
@ -426,10 +419,7 @@ import { i18n$ } from '../i18n.js';
|
|||||||
|
|
||||||
const findCommit = function(cm, dir) {
|
const findCommit = function(cm, dir) {
|
||||||
const state = getSearchState(cm);
|
const state = getSearchState(cm);
|
||||||
if ( state.queryTimer !== null ) {
|
state.queryTimer.off();
|
||||||
clearTimeout(state.queryTimer);
|
|
||||||
state.queryTimer = null;
|
|
||||||
}
|
|
||||||
const queryText = queryTextFromSearchWidget(cm);
|
const queryText = queryTextFromSearchWidget(cm);
|
||||||
if ( queryText === state.queryText ) { return; }
|
if ( queryText === state.queryText ) { return; }
|
||||||
state.queryText = queryText;
|
state.queryText = queryText;
|
||||||
|
@ -111,19 +111,15 @@ const relaxBlockingMode = (( ) => {
|
|||||||
if ( noReload ) { return; }
|
if ( noReload ) { return; }
|
||||||
|
|
||||||
// Reload: use a timer to coalesce bursts of reload commands.
|
// Reload: use a timer to coalesce bursts of reload commands.
|
||||||
let timer = reloadTimers.get(tab.id);
|
const timer = reloadTimers.get(tab.id) || (( ) => {
|
||||||
if ( timer !== undefined ) {
|
const t = vAPI.defer.create(tabId => {
|
||||||
clearTimeout(timer);
|
|
||||||
}
|
|
||||||
timer = vAPI.setTimeout(
|
|
||||||
tabId => {
|
|
||||||
reloadTimers.delete(tabId);
|
reloadTimers.delete(tabId);
|
||||||
vAPI.tabs.reload(tabId);
|
vAPI.tabs.reload(tabId);
|
||||||
},
|
});
|
||||||
547,
|
reloadTimers.set(tab.id, t);
|
||||||
tab.id
|
return t;
|
||||||
);
|
})();
|
||||||
reloadTimers.set(tab.id, timer);
|
timer.offon(547, tab.id);
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -225,10 +225,12 @@ const FilterContainer = function() {
|
|||||||
this.reSimpleHighGeneric = /^(?:[a-z]*\[[^\]]+\]|\S+)$/;
|
this.reSimpleHighGeneric = /^(?:[a-z]*\[[^\]]+\]|\S+)$/;
|
||||||
|
|
||||||
this.selectorCache = new Map();
|
this.selectorCache = new Map();
|
||||||
this.selectorCachePruneDelay = 10 * 60 * 1000; // 10 minutes
|
this.selectorCachePruneDelay = 10; // 10 minutes
|
||||||
this.selectorCacheCountMin = 40;
|
this.selectorCacheCountMin = 40;
|
||||||
this.selectorCacheCountMax = 50;
|
this.selectorCacheCountMax = 50;
|
||||||
this.selectorCacheTimer = null;
|
this.selectorCacheTimer = vAPI.defer.create(( ) => {
|
||||||
|
this.pruneSelectorCacheAsync();
|
||||||
|
});
|
||||||
|
|
||||||
// specific filters
|
// specific filters
|
||||||
this.specificFilters = new StaticExtFilteringHostnameDB(2);
|
this.specificFilters = new StaticExtFilteringHostnameDB(2);
|
||||||
@ -274,10 +276,7 @@ FilterContainer.prototype.reset = function() {
|
|||||||
this.duplicateBuster = new Set();
|
this.duplicateBuster = new Set();
|
||||||
|
|
||||||
this.selectorCache.clear();
|
this.selectorCache.clear();
|
||||||
if ( this.selectorCacheTimer !== null ) {
|
this.selectorCacheTimer.off();
|
||||||
clearTimeout(this.selectorCacheTimer);
|
|
||||||
this.selectorCacheTimer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// hostname, entity-based filters
|
// hostname, entity-based filters
|
||||||
this.specificFilters.clear();
|
this.specificFilters.clear();
|
||||||
@ -604,18 +603,6 @@ FilterContainer.prototype.fromSelfie = function(selfie) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.triggerSelectorCachePruner = function() {
|
|
||||||
// Of interest: http://fitzgeraldnick.com/weblog/40/
|
|
||||||
// http://googlecode.blogspot.ca/2009/07/gmail-for-mobile-html5-series-using.html
|
|
||||||
if ( this.selectorCacheTimer !== null ) { return; }
|
|
||||||
this.selectorCacheTimer = vAPI.setTimeout(
|
|
||||||
( ) => { this.pruneSelectorCacheAsync(); },
|
|
||||||
this.selectorCachePruneDelay
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
FilterContainer.prototype.addToSelectorCache = function(details) {
|
FilterContainer.prototype.addToSelectorCache = function(details) {
|
||||||
const hostname = details.hostname;
|
const hostname = details.hostname;
|
||||||
if ( typeof hostname !== 'string' || hostname === '' ) { return; }
|
if ( typeof hostname !== 'string' || hostname === '' ) { return; }
|
||||||
@ -626,7 +613,7 @@ FilterContainer.prototype.addToSelectorCache = function(details) {
|
|||||||
entry = SelectorCacheEntry.factory();
|
entry = SelectorCacheEntry.factory();
|
||||||
this.selectorCache.set(hostname, entry);
|
this.selectorCache.set(hostname, entry);
|
||||||
if ( this.selectorCache.size > this.selectorCacheCountMax ) {
|
if ( this.selectorCache.size > this.selectorCacheCountMax ) {
|
||||||
this.triggerSelectorCachePruner();
|
this.selectorCacheTimer.on({ min: this.selectorCachePruneDelay });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entry.add(details);
|
entry.add(details);
|
||||||
@ -658,7 +645,6 @@ FilterContainer.prototype.removeFromSelectorCache = function(
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
FilterContainer.prototype.pruneSelectorCacheAsync = function() {
|
FilterContainer.prototype.pruneSelectorCacheAsync = function() {
|
||||||
this.selectorCacheTimer = null;
|
|
||||||
if ( this.selectorCache.size <= this.selectorCacheCountMax ) { return; }
|
if ( this.selectorCache.size <= this.selectorCacheCountMax ) { return; }
|
||||||
const cache = this.selectorCache;
|
const cache = this.selectorCache;
|
||||||
const hostnames = Array.from(cache.keys())
|
const hostnames = Array.from(cache.keys())
|
||||||
|
@ -113,18 +113,18 @@ self.uBlockDashboard.dateNowToSensibleString = function() {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
self.uBlockDashboard.patchCodeMirrorEditor = (function() {
|
self.uBlockDashboard.patchCodeMirrorEditor = (function() {
|
||||||
let grabFocusTimer;
|
|
||||||
let grabFocusTarget;
|
let grabFocusTarget;
|
||||||
|
|
||||||
const grabFocus = function() {
|
const grabFocus = function() {
|
||||||
grabFocusTarget.focus();
|
grabFocusTarget.focus();
|
||||||
grabFocusTimer = grabFocusTarget = undefined;
|
grabFocusTarget = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const grabFocusTimer = vAPI.defer.create(grabFocus);
|
||||||
|
|
||||||
const grabFocusAsync = function(cm) {
|
const grabFocusAsync = function(cm) {
|
||||||
grabFocusTarget = cm;
|
grabFocusTarget = cm;
|
||||||
if ( grabFocusTimer === undefined ) {
|
grabFocusTimer.on(1);
|
||||||
grabFocusTimer = vAPI.setTimeout(grabFocus, 1);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/3646
|
// https://github.com/gorhill/uBlock/issues/3646
|
||||||
|
@ -104,19 +104,19 @@ if ( self.location.hash.slice(1) === 'no-dashboard.html' ) {
|
|||||||
(async ( ) => {
|
(async ( ) => {
|
||||||
// Wait for uBO's main process to be ready
|
// Wait for uBO's main process to be ready
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
const check = ( ) => {
|
const check = async ( ) => {
|
||||||
vAPI.messaging.send('dashboard', {
|
try {
|
||||||
|
const response = await vAPI.messaging.send('dashboard', {
|
||||||
what: 'readyToFilter'
|
what: 'readyToFilter'
|
||||||
}).then(response => {
|
});
|
||||||
if ( response ) { return resolve(true); }
|
if ( response ) { return resolve(true); }
|
||||||
const iframe = qs$('#iframe');
|
const iframe = qs$('#iframe');
|
||||||
if ( iframe.src !== '' ) {
|
if ( iframe.src !== '' ) {
|
||||||
iframe.src = '';
|
iframe.src = '';
|
||||||
}
|
}
|
||||||
vAPI.setTimeout(check, 250);
|
} catch(ex) {
|
||||||
}).catch(( ) => {
|
}
|
||||||
vAPI.setTimeout(check, 250);
|
vAPI.defer.once(250).then(( ) => check());
|
||||||
});
|
|
||||||
};
|
};
|
||||||
check();
|
check();
|
||||||
});
|
});
|
||||||
|
@ -336,11 +336,8 @@ const startDialog = (function() {
|
|||||||
let textarea;
|
let textarea;
|
||||||
let hideSelectors = [];
|
let hideSelectors = [];
|
||||||
let unhideSelectors = [];
|
let unhideSelectors = [];
|
||||||
let inputTimer;
|
|
||||||
|
|
||||||
const onInputChanged = (function() {
|
|
||||||
const parse = function() {
|
const parse = function() {
|
||||||
inputTimer = undefined;
|
|
||||||
hideSelectors = [];
|
hideSelectors = [];
|
||||||
unhideSelectors = [];
|
unhideSelectors = [];
|
||||||
|
|
||||||
@ -363,12 +360,11 @@ const startDialog = (function() {
|
|||||||
showCommitted();
|
showCommitted();
|
||||||
};
|
};
|
||||||
|
|
||||||
return function parseAsync() {
|
const inputTimer = vAPI.defer.create(parse);
|
||||||
if ( inputTimer === undefined ) {
|
|
||||||
inputTimer = vAPI.setTimeout(parse, 743);
|
const onInputChanged = ( ) => {
|
||||||
}
|
inputTimer.on(743);
|
||||||
};
|
};
|
||||||
})();
|
|
||||||
|
|
||||||
const onClicked = function(ev) {
|
const onClicked = function(ev) {
|
||||||
var target = ev.target;
|
var target = ev.target;
|
||||||
@ -433,10 +429,7 @@ const startDialog = (function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const stop = function() {
|
const stop = function() {
|
||||||
if ( inputTimer !== undefined ) {
|
inputTimer.off();
|
||||||
clearTimeout(inputTimer);
|
|
||||||
inputTimer = undefined;
|
|
||||||
}
|
|
||||||
showInteractive();
|
showInteractive();
|
||||||
textarea.removeEventListener('input', onInputChanged);
|
textarea.removeEventListener('input', onInputChanged);
|
||||||
dialog.removeEventListener('click', onClicked, true);
|
dialog.removeEventListener('click', onClicked, true);
|
||||||
@ -513,11 +506,9 @@ const onClicked = function(ev) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const onMouseOver = (function() {
|
const onMouseOver = (function() {
|
||||||
var mouseoverTarget = null;
|
let mouseoverTarget = null;
|
||||||
var mouseoverTimer = null;
|
|
||||||
|
|
||||||
var timerHandler = function() {
|
const timerHandler = ( ) => {
|
||||||
mouseoverTimer = null;
|
|
||||||
vAPI.MessagingConnection.sendTo(inspectorConnectionId, {
|
vAPI.MessagingConnection.sendTo(inspectorConnectionId, {
|
||||||
what: 'highlightOne',
|
what: 'highlightOne',
|
||||||
selector: selectorFromNode(mouseoverTarget),
|
selector: selectorFromNode(mouseoverTarget),
|
||||||
@ -526,21 +517,17 @@ const onMouseOver = (function() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mouseoverTimer = vAPI.defer.create(timerHandler);
|
||||||
|
|
||||||
return function(ev) {
|
return function(ev) {
|
||||||
if ( inspectedTabId === 0 ) { return; }
|
if ( inspectedTabId === 0 ) { return; }
|
||||||
// Convenience: skip real-time highlighting if shift key is pressed.
|
// Convenience: skip real-time highlighting if shift key is pressed.
|
||||||
if ( ev.shiftKey ) { return; }
|
if ( ev.shiftKey ) { return; }
|
||||||
// Find closest `li`
|
// Find closest `li`
|
||||||
var target = ev.target;
|
const target = ev.target.closest('li');
|
||||||
while ( target !== null ) {
|
|
||||||
if ( target.localName === 'li' ) { break; }
|
|
||||||
target = target.parentElement;
|
|
||||||
}
|
|
||||||
if ( target === mouseoverTarget ) { return; }
|
if ( target === mouseoverTarget ) { return; }
|
||||||
mouseoverTarget = target;
|
mouseoverTarget = target;
|
||||||
if ( mouseoverTimer === null ) {
|
mouseoverTimer.on(50);
|
||||||
mouseoverTimer = vAPI.setTimeout(timerHandler, 50);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -567,8 +567,6 @@ const viewPort = (( ) => {
|
|||||||
let wholeHeight = 0;
|
let wholeHeight = 0;
|
||||||
let lastTopPix = 0;
|
let lastTopPix = 0;
|
||||||
let lastTopRow = 0;
|
let lastTopRow = 0;
|
||||||
let scrollTimer;
|
|
||||||
let resizeTimer;
|
|
||||||
|
|
||||||
const ViewEntry = function() {
|
const ViewEntry = function() {
|
||||||
this.div = document.createElement('div');
|
this.div = document.createElement('div');
|
||||||
@ -602,19 +600,10 @@ const viewPort = (( ) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Coalesce scroll events
|
// Coalesce scroll events
|
||||||
const onScroll = function() {
|
const scrollTimer = vAPI.defer.create(onScrollChanged);
|
||||||
if ( scrollTimer !== undefined ) { return; }
|
const onScroll = ( ) => {
|
||||||
scrollTimer = setTimeout(
|
scrollTimer.onvsync(1000/32);
|
||||||
( ) => {
|
|
||||||
scrollTimer = requestAnimationFrame(( ) => {
|
|
||||||
scrollTimer = undefined;
|
|
||||||
onScrollChanged();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
1000/32
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
dom.on(vwScroller, 'scroll', onScroll, { passive: true });
|
dom.on(vwScroller, 'scroll', onScroll, { passive: true });
|
||||||
|
|
||||||
const onLayoutChanged = function() {
|
const onLayoutChanged = function() {
|
||||||
@ -721,19 +710,10 @@ const viewPort = (( ) => {
|
|||||||
updateContent(0);
|
updateContent(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resizeTimer = vAPI.defer.create(onLayoutChanged);
|
||||||
const updateLayout = function() {
|
const updateLayout = function() {
|
||||||
if ( resizeTimer !== undefined ) { return; }
|
resizeTimer.onvsync(1000/8);
|
||||||
resizeTimer = setTimeout(
|
|
||||||
( ) => {
|
|
||||||
resizeTimer = requestAnimationFrame(( ) => {
|
|
||||||
resizeTimer = undefined;
|
|
||||||
onLayoutChanged();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
1000/8
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
dom.on(window, 'resize', updateLayout, { passive: true });
|
dom.on(window, 'resize', updateLayout, { passive: true });
|
||||||
|
|
||||||
updateLayout();
|
updateLayout();
|
||||||
@ -1128,10 +1108,13 @@ const onLogBufferRead = function(response) {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const readLogBuffer = (( ) => {
|
const readLogBuffer = (( ) => {
|
||||||
let timer;
|
let reading = false;
|
||||||
|
|
||||||
const readLogBufferNow = async function() {
|
const readLogBufferNow = async function() {
|
||||||
if ( logger.ownerId === undefined ) { return; }
|
if ( logger.ownerId === undefined ) { return; }
|
||||||
|
if ( reading ) { return; }
|
||||||
|
|
||||||
|
reading = true;
|
||||||
|
|
||||||
const msg = {
|
const msg = {
|
||||||
what: 'readAll',
|
what: 'readAll',
|
||||||
@ -1159,20 +1142,20 @@ const readLogBuffer = (( ) => {
|
|||||||
|
|
||||||
const response = await vAPI.messaging.send('loggerUI', msg);
|
const response = await vAPI.messaging.send('loggerUI', msg);
|
||||||
|
|
||||||
timer = undefined;
|
|
||||||
onLogBufferRead(response);
|
onLogBufferRead(response);
|
||||||
readLogBufferLater();
|
|
||||||
|
reading = false;
|
||||||
|
|
||||||
|
timer.on(1200);
|
||||||
};
|
};
|
||||||
|
|
||||||
const readLogBufferLater = function() {
|
const timer = vAPI.defer.create(readLogBufferNow);
|
||||||
if ( timer !== undefined ) { return; }
|
|
||||||
if ( logger.ownerId === undefined ) { return; }
|
|
||||||
timer = vAPI.setTimeout(readLogBufferNow, 1200);
|
|
||||||
};
|
|
||||||
|
|
||||||
readLogBufferNow();
|
readLogBufferNow();
|
||||||
|
|
||||||
return readLogBufferLater;
|
return ( ) => {
|
||||||
|
timer.on(1200);
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -2203,17 +2186,13 @@ const rowFilterer = (( ) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onFilterChangedAsync = (( ) => {
|
const onFilterChangedAsync = (( ) => {
|
||||||
let timer;
|
|
||||||
const commit = ( ) => {
|
const commit = ( ) => {
|
||||||
timer = undefined;
|
|
||||||
parseInput();
|
parseInput();
|
||||||
filterAll();
|
filterAll();
|
||||||
};
|
};
|
||||||
|
const timer = vAPI.defer.create(commit);
|
||||||
return ( ) => {
|
return ( ) => {
|
||||||
if ( timer !== undefined ) {
|
timer.offon(750);
|
||||||
clearTimeout(timer);
|
|
||||||
}
|
|
||||||
timer = vAPI.setTimeout(commit, 750);
|
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@ -2290,7 +2269,7 @@ const rowJanitor = (( ) => {
|
|||||||
|
|
||||||
let rowIndex = 0;
|
let rowIndex = 0;
|
||||||
|
|
||||||
const discard = function(timeRemaining) {
|
const discard = function(deadline) {
|
||||||
const opts = loggerSettings.discard;
|
const opts = loggerSettings.discard;
|
||||||
const maxLoadCount = typeof opts.maxLoadCount === 'number'
|
const maxLoadCount = typeof opts.maxLoadCount === 'number'
|
||||||
? opts.maxLoadCount
|
? opts.maxLoadCount
|
||||||
@ -2301,7 +2280,6 @@ const rowJanitor = (( ) => {
|
|||||||
const obsolete = typeof opts.maxAge === 'number'
|
const obsolete = typeof opts.maxAge === 'number'
|
||||||
? Date.now() - opts.maxAge * 60000
|
? Date.now() - opts.maxAge * 60000
|
||||||
: 0;
|
: 0;
|
||||||
const deadline = Date.now() + Math.ceil(timeRemaining);
|
|
||||||
|
|
||||||
let i = rowIndex;
|
let i = rowIndex;
|
||||||
// TODO: below should not happen -- remove when confirmed.
|
// TODO: below should not happen -- remove when confirmed.
|
||||||
@ -2322,7 +2300,7 @@ const rowJanitor = (( ) => {
|
|||||||
|
|
||||||
while ( i < loggerEntries.length ) {
|
while ( i < loggerEntries.length ) {
|
||||||
|
|
||||||
if ( i % 64 === 0 && Date.now() >= deadline ) { break; }
|
if ( i % 64 === 0 && deadline.timeRemaining() === 0 ) { break; }
|
||||||
|
|
||||||
const entry = loggerEntries[i];
|
const entry = loggerEntries[i];
|
||||||
const tabId = entry.tabId || 0;
|
const tabId = entry.tabId || 0;
|
||||||
@ -2391,18 +2369,15 @@ const rowJanitor = (( ) => {
|
|||||||
rowFilterer.filterAll();
|
rowFilterer.filterAll();
|
||||||
};
|
};
|
||||||
|
|
||||||
const discardAsync = function() {
|
const discardAsync = function(deadline) {
|
||||||
setTimeout(
|
if ( deadline ) {
|
||||||
( ) => {
|
discard(deadline);
|
||||||
self.requestIdleCallback(deadline => {
|
}
|
||||||
discard(deadline.timeRemaining());
|
janitorTimer.onidle(1889);
|
||||||
discardAsync();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
1889
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const janitorTimer = vAPI.defer.create(discardAsync);
|
||||||
|
|
||||||
// Clear voided entries from the logger's visible content.
|
// Clear voided entries from the logger's visible content.
|
||||||
//
|
//
|
||||||
// Voided entries should be visible only from the "All" option of the
|
// Voided entries should be visible only from the "All" option of the
|
||||||
@ -3030,15 +3005,14 @@ dom.on(window, 'hashchange', pageSelectorFromURLHash);
|
|||||||
// to the window geometry pontentially not settling fast enough.
|
// to the window geometry pontentially not settling fast enough.
|
||||||
if ( self.location.search.includes('popup=1') ) {
|
if ( self.location.search.includes('popup=1') ) {
|
||||||
dom.on(window, 'load', ( ) => {
|
dom.on(window, 'load', ( ) => {
|
||||||
setTimeout(
|
vAPI.defer.once(2000).then(( ) => {
|
||||||
( ) => {
|
|
||||||
popupLoggerBox = {
|
popupLoggerBox = {
|
||||||
x: self.screenX,
|
x: self.screenX,
|
||||||
y: self.screenY,
|
y: self.screenY,
|
||||||
w: self.outerWidth,
|
w: self.outerWidth,
|
||||||
h: self.outerHeight,
|
h: self.outerHeight,
|
||||||
};
|
};
|
||||||
}, 2000);
|
});
|
||||||
}, { once: true });
|
}, { once: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,21 +27,21 @@ let buffer = null;
|
|||||||
let lastReadTime = 0;
|
let lastReadTime = 0;
|
||||||
let writePtr = 0;
|
let writePtr = 0;
|
||||||
|
|
||||||
// After 30 seconds without being read, a buffer will be considered
|
// After 30 seconds without being read, the logger buffer will be considered
|
||||||
// unused, and thus removed from memory.
|
// unused, and thus disabled.
|
||||||
const logBufferObsoleteAfter = 30 * 1000;
|
const logBufferObsoleteAfter = 30 * 1000;
|
||||||
|
|
||||||
const janitor = ( ) => {
|
const janitorTimer = vAPI.defer.create(( ) => {
|
||||||
if ( buffer === null ) { return; }
|
if ( buffer === null ) { return; }
|
||||||
if ( lastReadTime >= (Date.now() - logBufferObsoleteAfter) ) {
|
if ( lastReadTime >= (Date.now() - logBufferObsoleteAfter) ) {
|
||||||
return vAPI.setTimeout(janitor, logBufferObsoleteAfter);
|
return janitorTimer.on(logBufferObsoleteAfter);
|
||||||
}
|
}
|
||||||
logger.enabled = false;
|
logger.enabled = false;
|
||||||
buffer = null;
|
buffer = null;
|
||||||
writePtr = 0;
|
writePtr = 0;
|
||||||
logger.ownerId = undefined;
|
logger.ownerId = undefined;
|
||||||
vAPI.messaging.broadcast({ what: 'loggerDisabled' });
|
vAPI.messaging.broadcast({ what: 'loggerDisabled' });
|
||||||
};
|
});
|
||||||
|
|
||||||
const boxEntry = function(details) {
|
const boxEntry = function(details) {
|
||||||
if ( details.tstamp === undefined ) {
|
if ( details.tstamp === undefined ) {
|
||||||
@ -68,7 +68,7 @@ const logger = {
|
|||||||
if ( buffer === null ) {
|
if ( buffer === null ) {
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
buffer = [];
|
buffer = [];
|
||||||
vAPI.setTimeout(janitor, logBufferObsoleteAfter);
|
janitorTimer.on(logBufferObsoleteAfter);
|
||||||
}
|
}
|
||||||
const out = buffer.slice(0, writePtr);
|
const out = buffer.slice(0, writePtr);
|
||||||
writePtr = 0;
|
writePtr = 0;
|
||||||
|
@ -42,7 +42,6 @@ let lz4CodecInstance;
|
|||||||
let pendingInitialization;
|
let pendingInitialization;
|
||||||
let textEncoder, textDecoder;
|
let textEncoder, textDecoder;
|
||||||
let ttlCount = 0;
|
let ttlCount = 0;
|
||||||
let ttlTimer;
|
|
||||||
let ttlDelay = 60000;
|
let ttlDelay = 60000;
|
||||||
|
|
||||||
const init = function() {
|
const init = function() {
|
||||||
@ -84,18 +83,16 @@ const destroy = function() {
|
|||||||
lz4CodecInstance = undefined;
|
lz4CodecInstance = undefined;
|
||||||
textEncoder = textDecoder = undefined;
|
textEncoder = textDecoder = undefined;
|
||||||
ttlCount = 0;
|
ttlCount = 0;
|
||||||
ttlTimer = undefined;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ttlTimer = vAPI.defer.create(destroy);
|
||||||
|
|
||||||
const ttlManage = function(count) {
|
const ttlManage = function(count) {
|
||||||
if ( ttlTimer !== undefined ) {
|
ttlTimer.off();
|
||||||
clearTimeout(ttlTimer);
|
|
||||||
ttlTimer = undefined;
|
|
||||||
}
|
|
||||||
ttlCount += count;
|
ttlCount += count;
|
||||||
if ( ttlCount > 0 ) { return; }
|
if ( ttlCount > 0 ) { return; }
|
||||||
if ( lz4CodecInstance === null ) { return; }
|
if ( lz4CodecInstance === null ) { return; }
|
||||||
ttlTimer = vAPI.setTimeout(destroy, ttlDelay);
|
ttlTimer.on(ttlDelay);
|
||||||
};
|
};
|
||||||
|
|
||||||
const encodeValue = function(dataIn) {
|
const encodeValue = function(dataIn) {
|
||||||
|
@ -56,6 +56,9 @@ To create a log of net requests
|
|||||||
|
|
||||||
const NetFilteringResultCache = class {
|
const NetFilteringResultCache = class {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.pruneTimer = vAPI.defer.create(( ) => {
|
||||||
|
this.prune();
|
||||||
|
});
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +66,6 @@ const NetFilteringResultCache = class {
|
|||||||
this.blocked = new Map();
|
this.blocked = new Map();
|
||||||
this.results = new Map();
|
this.results = new Map();
|
||||||
this.hash = 0;
|
this.hash = 0;
|
||||||
this.timer = undefined;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,10 +113,7 @@ const NetFilteringResultCache = class {
|
|||||||
this.blocked.clear();
|
this.blocked.clear();
|
||||||
this.results.clear();
|
this.results.clear();
|
||||||
this.hash = 0;
|
this.hash = 0;
|
||||||
if ( this.timer !== undefined ) {
|
this.pruneTimer.off();
|
||||||
clearTimeout(this.timer);
|
|
||||||
this.timer = undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prune() {
|
prune() {
|
||||||
@ -136,14 +135,7 @@ const NetFilteringResultCache = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pruneAsync() {
|
pruneAsync() {
|
||||||
if ( this.timer !== undefined ) { return; }
|
this.pruneTimer.on(this.shelfLife);
|
||||||
this.timer = vAPI.setTimeout(
|
|
||||||
( ) => {
|
|
||||||
this.timer = undefined;
|
|
||||||
this.prune();
|
|
||||||
},
|
|
||||||
this.shelfLife
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lookupResult(fctxt) {
|
lookupResult(fctxt) {
|
||||||
@ -353,12 +345,17 @@ const PageStore = class {
|
|||||||
constructor(tabId, details) {
|
constructor(tabId, details) {
|
||||||
this.extraData = new Map();
|
this.extraData = new Map();
|
||||||
this.journal = [];
|
this.journal = [];
|
||||||
this.journalTimer = undefined;
|
|
||||||
this.journalLastCommitted = this.journalLastUncommitted = -1;
|
this.journalLastCommitted = this.journalLastUncommitted = -1;
|
||||||
this.journalLastUncommittedOrigin = undefined;
|
this.journalLastUncommittedOrigin = undefined;
|
||||||
this.netFilteringCache = NetFilteringResultCache.factory();
|
this.netFilteringCache = NetFilteringResultCache.factory();
|
||||||
this.hostnameDetailsMap = new HostnameDetailsMap();
|
this.hostnameDetailsMap = new HostnameDetailsMap();
|
||||||
this.counts = new CountDetails();
|
this.counts = new CountDetails();
|
||||||
|
this.journalTimer = vAPI.defer.create(( ) => {
|
||||||
|
this.journalProcess();
|
||||||
|
});
|
||||||
|
this.largeMediaTimer = vAPI.defer.create(( ) => {
|
||||||
|
this.injectLargeMediaElementScriptlet();
|
||||||
|
});
|
||||||
this.init(tabId, details);
|
this.init(tabId, details);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,7 +395,6 @@ const PageStore = class {
|
|||||||
this.remoteFontCount = 0;
|
this.remoteFontCount = 0;
|
||||||
this.popupBlockedCount = 0;
|
this.popupBlockedCount = 0;
|
||||||
this.largeMediaCount = 0;
|
this.largeMediaCount = 0;
|
||||||
this.largeMediaTimer = null;
|
|
||||||
this.allowLargeMediaElementsRegex = undefined;
|
this.allowLargeMediaElementsRegex = undefined;
|
||||||
this.extraData.clear();
|
this.extraData.clear();
|
||||||
|
|
||||||
@ -441,10 +437,7 @@ const PageStore = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A new page is completely reloaded from scratch, reset all.
|
// A new page is completely reloaded from scratch, reset all.
|
||||||
if ( this.largeMediaTimer !== null ) {
|
this.largeMediaTimer.off();
|
||||||
clearTimeout(this.largeMediaTimer);
|
|
||||||
this.largeMediaTimer = null;
|
|
||||||
}
|
|
||||||
this.disposeFrameStores();
|
this.disposeFrameStores();
|
||||||
this.init(this.tabId, details);
|
this.init(this.tabId, details);
|
||||||
return this;
|
return this;
|
||||||
@ -458,15 +451,9 @@ const PageStore = class {
|
|||||||
this.netFilteringCache.empty();
|
this.netFilteringCache.empty();
|
||||||
this.allowLargeMediaElementsUntil = Date.now();
|
this.allowLargeMediaElementsUntil = Date.now();
|
||||||
this.allowLargeMediaElementsRegex = undefined;
|
this.allowLargeMediaElementsRegex = undefined;
|
||||||
if ( this.largeMediaTimer !== null ) {
|
this.largeMediaTimer.off();
|
||||||
clearTimeout(this.largeMediaTimer);
|
|
||||||
this.largeMediaTimer = null;
|
|
||||||
}
|
|
||||||
this.disposeFrameStores();
|
this.disposeFrameStores();
|
||||||
if ( this.journalTimer !== undefined ) {
|
this.journalTimer.off();
|
||||||
clearTimeout(this.journalTimer);
|
|
||||||
this.journalTimer = undefined;
|
|
||||||
}
|
|
||||||
this.journal = [];
|
this.journal = [];
|
||||||
this.journalLastUncommittedOrigin = undefined;
|
this.journalLastUncommittedOrigin = undefined;
|
||||||
this.journalLastCommitted = this.journalLastUncommitted = -1;
|
this.journalLastCommitted = this.journalLastUncommitted = -1;
|
||||||
@ -668,11 +655,7 @@ const PageStore = class {
|
|||||||
const hostname = fctxt.getHostname();
|
const hostname = fctxt.getHostname();
|
||||||
if ( hostname === '' ) { return; }
|
if ( hostname === '' ) { return; }
|
||||||
this.journal.push(hostname, result, fctxt.itype);
|
this.journal.push(hostname, result, fctxt.itype);
|
||||||
if ( this.journalTimer !== undefined ) { return; }
|
this.journalTimer.on(µb.hiddenSettings.requestJournalProcessPeriod);
|
||||||
this.journalTimer = vAPI.setTimeout(
|
|
||||||
( ) => { this.journalProcess(true); },
|
|
||||||
µb.hiddenSettings.requestJournalProcessPeriod
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
journalAddRootFrame(type, url) {
|
journalAddRootFrame(type, url) {
|
||||||
@ -695,18 +678,11 @@ const PageStore = class {
|
|||||||
this.journalLastUncommittedOrigin = newOrigin;
|
this.journalLastUncommittedOrigin = newOrigin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( this.journalTimer !== undefined ) {
|
this.journalTimer.offon(µb.hiddenSettings.requestJournalProcessPeriod);
|
||||||
clearTimeout(this.journalTimer);
|
|
||||||
}
|
|
||||||
this.journalTimer = vAPI.setTimeout(
|
|
||||||
( ) => { this.journalProcess(true); },
|
|
||||||
µb.hiddenSettings.requestJournalProcessPeriod
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
journalProcess(fromTimer = false) {
|
journalProcess() {
|
||||||
if ( fromTimer === false ) { clearTimeout(this.journalTimer); }
|
this.journalTimer.off();
|
||||||
this.journalTimer = undefined;
|
|
||||||
|
|
||||||
const journal = this.journal;
|
const journal = this.journal;
|
||||||
const pivot = Math.max(0, this.journalLastCommitted);
|
const pivot = Math.max(0, this.journalLastCommitted);
|
||||||
@ -1058,12 +1034,7 @@ const PageStore = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.largeMediaCount += 1;
|
this.largeMediaCount += 1;
|
||||||
if ( this.largeMediaTimer === null ) {
|
this.largeMediaTimer.on(500);
|
||||||
this.largeMediaTimer = vAPI.setTimeout(( ) => {
|
|
||||||
this.largeMediaTimer = null;
|
|
||||||
this.injectLargeMediaElementScriptlet();
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( logger.enabled ) {
|
if ( logger.enabled ) {
|
||||||
fctxt.filter = sessionSwitches.toLogData();
|
fctxt.filter = sessionSwitches.toLogData();
|
||||||
|
@ -1376,29 +1376,23 @@ const toggleHostnameSwitch = async function(ev) {
|
|||||||
// it and thus having to push it all the time unconditionally.
|
// it and thus having to push it all the time unconditionally.
|
||||||
|
|
||||||
const pollForContentChange = (( ) => {
|
const pollForContentChange = (( ) => {
|
||||||
let pollTimer;
|
|
||||||
|
|
||||||
const pollCallback = async function() {
|
const pollCallback = async function() {
|
||||||
pollTimer = undefined;
|
|
||||||
const response = await messaging.send('popupPanel', {
|
const response = await messaging.send('popupPanel', {
|
||||||
what: 'hasPopupContentChanged',
|
what: 'hasPopupContentChanged',
|
||||||
tabId: popupData.tabId,
|
tabId: popupData.tabId,
|
||||||
contentLastModified: popupData.contentLastModified,
|
contentLastModified: popupData.contentLastModified,
|
||||||
});
|
});
|
||||||
queryCallback(response);
|
|
||||||
};
|
|
||||||
|
|
||||||
const queryCallback = function(response) {
|
|
||||||
if ( response ) {
|
if ( response ) {
|
||||||
getPopupData(popupData.tabId);
|
await getPopupData(popupData.tabId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
poll();
|
poll();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const pollTimer = vAPI.defer.create(pollCallback);
|
||||||
|
|
||||||
const poll = function() {
|
const poll = function() {
|
||||||
if ( pollTimer !== undefined ) { return; }
|
pollTimer.on(1500);
|
||||||
pollTimer = vAPI.setTimeout(pollCallback, 1500);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return poll;
|
return poll;
|
||||||
|
@ -36,11 +36,9 @@ import {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const workerTTL = 5 * 60 * 1000;
|
|
||||||
const pendingResponses = new Map();
|
const pendingResponses = new Map();
|
||||||
|
|
||||||
let worker = null;
|
let worker = null;
|
||||||
let workerTTLTimer;
|
|
||||||
let needLists = true;
|
let needLists = true;
|
||||||
let messageId = 1;
|
let messageId = 1;
|
||||||
|
|
||||||
@ -52,10 +50,7 @@ const onWorkerMessage = function(e) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const stopWorker = function() {
|
const stopWorker = function() {
|
||||||
if ( workerTTLTimer !== undefined ) {
|
stopWorker.off();
|
||||||
clearTimeout(workerTTLTimer);
|
|
||||||
workerTTLTimer = undefined;
|
|
||||||
}
|
|
||||||
if ( worker === null ) { return; }
|
if ( worker === null ) { return; }
|
||||||
worker.terminate();
|
worker.terminate();
|
||||||
worker = null;
|
worker = null;
|
||||||
@ -66,6 +61,9 @@ const stopWorker = function() {
|
|||||||
pendingResponses.clear();
|
pendingResponses.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const workerTTLTimer = vAPI.defer.create(stopWorker);
|
||||||
|
const workerTTL = { min: 5 };
|
||||||
|
|
||||||
const initWorker = function() {
|
const initWorker = function() {
|
||||||
if ( worker === null ) {
|
if ( worker === null ) {
|
||||||
worker = new Worker('js/reverselookup-worker.js');
|
worker = new Worker('js/reverselookup-worker.js');
|
||||||
@ -73,10 +71,7 @@ const initWorker = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The worker will be shutdown after n minutes without being used.
|
// The worker will be shutdown after n minutes without being used.
|
||||||
if ( workerTTLTimer !== undefined ) {
|
workerTTLTimer.offon(workerTTL);
|
||||||
clearTimeout(workerTTLTimer);
|
|
||||||
}
|
|
||||||
workerTTLTimer = vAPI.setTimeout(stopWorker, workerTTL);
|
|
||||||
|
|
||||||
if ( needLists === false ) {
|
if ( needLists === false ) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
@ -98,23 +98,26 @@ import {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
µb.saveLocalSettings = (( ) => {
|
{
|
||||||
const saveAfter = 4 * 60 * 1000;
|
let localSettingsLastSaved = Date.now();
|
||||||
|
|
||||||
const onTimeout = ( ) => {
|
const shouldSave = ( ) => {
|
||||||
if ( µb.localSettingsLastModified > µb.localSettingsLastSaved ) {
|
if ( µb.localSettingsLastModified > localSettingsLastSaved ) {
|
||||||
µb.saveLocalSettings();
|
µb.saveLocalSettings();
|
||||||
}
|
}
|
||||||
vAPI.setTimeout(onTimeout, saveAfter);
|
saveTimer.on(saveDelay);
|
||||||
};
|
};
|
||||||
|
|
||||||
vAPI.setTimeout(onTimeout, saveAfter);
|
const saveTimer = vAPI.defer.create(shouldSave);
|
||||||
|
const saveDelay = { min: 4 };
|
||||||
|
|
||||||
return function() {
|
saveTimer.on(saveDelay);
|
||||||
this.localSettingsLastSaved = Date.now();
|
|
||||||
|
µb.saveLocalSettings = function() {
|
||||||
|
localSettingsLastSaved = Date.now();
|
||||||
return vAPI.storage.set(this.localSettings);
|
return vAPI.storage.set(this.localSettings);
|
||||||
};
|
};
|
||||||
})();
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -1445,15 +1448,17 @@ self.addEventListener('hiddenSettingsChanged', ( ) => {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
{
|
{
|
||||||
let timer, next = 0;
|
let next = 0;
|
||||||
let lastEmergencyUpdate = 0;
|
let lastEmergencyUpdate = 0;
|
||||||
|
|
||||||
µb.scheduleAssetUpdater = async function(updateDelay) {
|
const launchTimer = vAPI.defer.create(fetchDelay => {
|
||||||
|
next = 0;
|
||||||
|
io.updateStart({ delay: fetchDelay, auto: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
µb.scheduleAssetUpdater = async function(updateDelay) {
|
||||||
|
launchTimer.off();
|
||||||
|
|
||||||
if ( timer ) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
timer = undefined;
|
|
||||||
}
|
|
||||||
if ( updateDelay === 0 ) {
|
if ( updateDelay === 0 ) {
|
||||||
next = 0;
|
next = 0;
|
||||||
return;
|
return;
|
||||||
@ -1499,11 +1504,7 @@ self.addEventListener('hiddenSettingsChanged', ( ) => {
|
|||||||
? 2000
|
? 2000
|
||||||
: this.hiddenSettings.autoUpdateAssetFetchPeriod * 1000 || 60000;
|
: this.hiddenSettings.autoUpdateAssetFetchPeriod * 1000 || 60000;
|
||||||
|
|
||||||
timer = vAPI.setTimeout(( ) => {
|
launchTimer.on(updateDelay, fetchDelay);
|
||||||
timer = undefined;
|
|
||||||
next = 0;
|
|
||||||
io.updateStart({ delay: fetchDelay, auto: true });
|
|
||||||
}, updateDelay);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,25 +515,19 @@ housekeep itself.
|
|||||||
? µb.maybeGoodPopup.url
|
? µb.maybeGoodPopup.url
|
||||||
: ''
|
: ''
|
||||||
};
|
};
|
||||||
this.selfDestructionTimer = null;
|
this.selfDestructionTimer = vAPI.defer.create(( ) => {
|
||||||
|
this.destroy();
|
||||||
|
});
|
||||||
this.launchSelfDestruction();
|
this.launchSelfDestruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
if ( this.selfDestructionTimer !== null ) {
|
this.selfDestructionTimer.off();
|
||||||
clearTimeout(this.selfDestructionTimer);
|
|
||||||
}
|
|
||||||
popupCandidates.delete(this.targetTabId);
|
popupCandidates.delete(this.targetTabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
launchSelfDestruction() {
|
launchSelfDestruction() {
|
||||||
if ( this.selfDestructionTimer !== null ) {
|
this.selfDestructionTimer.offon(10000);
|
||||||
clearTimeout(this.selfDestructionTimer);
|
|
||||||
}
|
|
||||||
this.selfDestructionTimer = vAPI.setTimeout(
|
|
||||||
( ) => this.destroy(),
|
|
||||||
10000
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -618,8 +612,12 @@ housekeep itself.
|
|||||||
this.origin =
|
this.origin =
|
||||||
this.rootHostname =
|
this.rootHostname =
|
||||||
this.rootDomain = '';
|
this.rootDomain = '';
|
||||||
this.commitTimer = null;
|
this.commitTimer = vAPI.defer.create(( ) => {
|
||||||
this.gcTimer = null;
|
this.onCommit();
|
||||||
|
});
|
||||||
|
this.gcTimer = vAPI.defer.create(( ) => {
|
||||||
|
this.onGC();
|
||||||
|
});
|
||||||
this.onGCBarrier = false;
|
this.onGCBarrier = false;
|
||||||
this.netFiltering = true;
|
this.netFiltering = true;
|
||||||
this.netFilteringReadTime = 0;
|
this.netFilteringReadTime = 0;
|
||||||
@ -629,28 +627,20 @@ housekeep itself.
|
|||||||
|
|
||||||
TabContext.prototype.destroy = function() {
|
TabContext.prototype.destroy = function() {
|
||||||
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) { return; }
|
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) { return; }
|
||||||
if ( this.gcTimer !== null ) {
|
this.gcTimer.off();
|
||||||
clearTimeout(this.gcTimer);
|
|
||||||
this.gcTimer = null;
|
|
||||||
}
|
|
||||||
tabContexts.delete(this.tabId);
|
tabContexts.delete(this.tabId);
|
||||||
};
|
};
|
||||||
|
|
||||||
TabContext.prototype.onGC = async function() {
|
TabContext.prototype.onGC = async function() {
|
||||||
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) { return; }
|
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) { return; }
|
||||||
// https://github.com/gorhill/uBlock/issues/1713
|
|
||||||
// For unknown reasons, Firefox's setTimeout() will sometimes
|
|
||||||
// causes the callback function to be called immediately, bypassing
|
|
||||||
// the main event loop. For now this should prevent uBO from
|
|
||||||
// crashing as a result of the bad setTimeout() behavior.
|
|
||||||
if ( this.onGCBarrier ) { return; }
|
if ( this.onGCBarrier ) { return; }
|
||||||
this.onGCBarrier = true;
|
this.onGCBarrier = true;
|
||||||
this.gcTimer = null;
|
this.gcTimer.off();
|
||||||
const tab = await vAPI.tabs.get(this.tabId);
|
const tab = await vAPI.tabs.get(this.tabId);
|
||||||
if ( tab instanceof Object === false || tab.discarded === true ) {
|
if ( tab instanceof Object === false || tab.discarded === true ) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
} else {
|
} else {
|
||||||
this.gcTimer = vAPI.setTimeout(( ) => this.onGC(), gcPeriod);
|
this.gcTimer.on(gcPeriod);
|
||||||
}
|
}
|
||||||
this.onGCBarrier = false;
|
this.onGCBarrier = false;
|
||||||
};
|
};
|
||||||
@ -659,10 +649,8 @@ housekeep itself.
|
|||||||
// Stack entries have to be committed to stick. Non-committed stack
|
// Stack entries have to be committed to stick. Non-committed stack
|
||||||
// entries are removed after a set delay.
|
// entries are removed after a set delay.
|
||||||
TabContext.prototype.onCommit = function() {
|
TabContext.prototype.onCommit = function() {
|
||||||
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) {
|
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) { return; }
|
||||||
return;
|
this.commitTimer.off();
|
||||||
}
|
|
||||||
this.commitTimer = null;
|
|
||||||
// Remove uncommitted entries at the top of the stack.
|
// Remove uncommitted entries at the top of the stack.
|
||||||
let i = this.stack.length;
|
let i = this.stack.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
@ -687,7 +675,7 @@ housekeep itself.
|
|||||||
// want to flush it.
|
// want to flush it.
|
||||||
TabContext.prototype.autodestroy = function() {
|
TabContext.prototype.autodestroy = function() {
|
||||||
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) { return; }
|
if ( vAPI.isBehindTheSceneTabId(this.tabId) ) { return; }
|
||||||
this.gcTimer = vAPI.setTimeout(( ) => this.onGC(), gcPeriod);
|
this.gcTimer.on(gcPeriod);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update just force all properties to be updated to match the most recent
|
// Update just force all properties to be updated to match the most recent
|
||||||
@ -727,10 +715,7 @@ housekeep itself.
|
|||||||
this.stack.push(new StackEntry(url));
|
this.stack.push(new StackEntry(url));
|
||||||
this.update();
|
this.update();
|
||||||
popupCandidateTest(this.tabId);
|
popupCandidateTest(this.tabId);
|
||||||
if ( this.commitTimer !== null ) {
|
this.commitTimer.offon(500);
|
||||||
clearTimeout(this.commitTimer);
|
|
||||||
}
|
|
||||||
this.commitTimer = vAPI.setTimeout(( ) => this.onCommit(), 500);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This tells that the url is definitely the one to be associated with the
|
// This tells that the url is definitely the one to be associated with the
|
||||||
@ -1156,7 +1141,6 @@ vAPI.tabs = new vAPI.Tabs();
|
|||||||
// Stale page store entries janitor
|
// Stale page store entries janitor
|
||||||
|
|
||||||
{
|
{
|
||||||
const pageStoreJanitorPeriod = 15 * 60 * 1000;
|
|
||||||
let pageStoreJanitorSampleAt = 0;
|
let pageStoreJanitorSampleAt = 0;
|
||||||
let pageStoreJanitorSampleSize = 10;
|
let pageStoreJanitorSampleSize = 10;
|
||||||
|
|
||||||
@ -1182,10 +1166,13 @@ vAPI.tabs = new vAPI.Tabs();
|
|||||||
}
|
}
|
||||||
pageStoreJanitorSampleAt = n;
|
pageStoreJanitorSampleAt = n;
|
||||||
|
|
||||||
vAPI.setTimeout(pageStoreJanitor, pageStoreJanitorPeriod);
|
pageStoreJanitorTimer.on(pageStoreJanitorPeriod);
|
||||||
};
|
};
|
||||||
|
|
||||||
vAPI.setTimeout(pageStoreJanitor, pageStoreJanitorPeriod);
|
const pageStoreJanitorTimer = vAPI.defer.create(pageStoreJanitor);
|
||||||
|
const pageStoreJanitorPeriod = { min: 15 };
|
||||||
|
|
||||||
|
pageStoreJanitorTimer.on(pageStoreJanitorPeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -439,23 +439,23 @@ const onBeforeBehindTheSceneRequest = function(fctxt) {
|
|||||||
// request.
|
// request.
|
||||||
|
|
||||||
{
|
{
|
||||||
|
const pageStores = new Set();
|
||||||
let hostname = '';
|
let hostname = '';
|
||||||
let pageStores = new Set();
|
|
||||||
let pageStoresToken = 0;
|
let pageStoresToken = 0;
|
||||||
let gcTimer;
|
|
||||||
|
|
||||||
const reset = function() {
|
const reset = function() {
|
||||||
hostname = '';
|
hostname = '';
|
||||||
pageStores = new Set();
|
pageStores.clear();
|
||||||
pageStoresToken = 0;
|
pageStoresToken = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const gc = ( ) => {
|
const gc = ( ) => {
|
||||||
gcTimer = undefined;
|
|
||||||
if ( pageStoresToken !== µb.pageStoresToken ) { return reset(); }
|
if ( pageStoresToken !== µb.pageStoresToken ) { return reset(); }
|
||||||
gcTimer = vAPI.setTimeout(gc, 30011);
|
gcTimer.on(30011);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const gcTimer = vAPI.defer.create(gc);
|
||||||
|
|
||||||
onBeforeBehindTheSceneRequest.journalAddRequest = (fctxt, result) => {
|
onBeforeBehindTheSceneRequest.journalAddRequest = (fctxt, result) => {
|
||||||
const docHostname = fctxt.getDocHostname();
|
const docHostname = fctxt.getDocHostname();
|
||||||
if (
|
if (
|
||||||
@ -463,16 +463,13 @@ const onBeforeBehindTheSceneRequest = function(fctxt) {
|
|||||||
pageStoresToken !== µb.pageStoresToken
|
pageStoresToken !== µb.pageStoresToken
|
||||||
) {
|
) {
|
||||||
hostname = docHostname;
|
hostname = docHostname;
|
||||||
pageStores = new Set();
|
pageStores.clear();
|
||||||
for ( const pageStore of µb.pageStores.values() ) {
|
for ( const pageStore of µb.pageStores.values() ) {
|
||||||
if ( pageStore.tabHostname !== docHostname ) { continue; }
|
if ( pageStore.tabHostname !== docHostname ) { continue; }
|
||||||
pageStores.add(pageStore);
|
pageStores.add(pageStore);
|
||||||
}
|
}
|
||||||
pageStoresToken = µb.pageStoresToken;
|
pageStoresToken = µb.pageStoresToken;
|
||||||
if ( gcTimer !== undefined ) {
|
gcTimer.offon(30011);
|
||||||
clearTimeout(gcTimer);
|
|
||||||
}
|
|
||||||
gcTimer = vAPI.setTimeout(gc, 30011);
|
|
||||||
}
|
}
|
||||||
for ( const pageStore of pageStores ) {
|
for ( const pageStore of pageStores ) {
|
||||||
pageStore.journalAddRequest(fctxt, result);
|
pageStore.journalAddRequest(fctxt, result);
|
||||||
@ -1057,7 +1054,9 @@ const headerValueFromName = function(headerName, headers) {
|
|||||||
|
|
||||||
const strictBlockBypasser = {
|
const strictBlockBypasser = {
|
||||||
hostnameToDeadlineMap: new Map(),
|
hostnameToDeadlineMap: new Map(),
|
||||||
cleanupTimer: undefined,
|
cleanupTimer: vAPI.defer.create(( ) => {
|
||||||
|
strictBlockBypasser.cleanup();
|
||||||
|
}),
|
||||||
|
|
||||||
cleanup: function() {
|
cleanup: function() {
|
||||||
for ( const [ hostname, deadline ] of this.hostnameToDeadlineMap ) {
|
for ( const [ hostname, deadline ] of this.hostnameToDeadlineMap ) {
|
||||||
@ -1067,35 +1066,23 @@ const strictBlockBypasser = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
revokeTime: function() {
|
||||||
|
return Date.now() + µb.hiddenSettings.strictBlockingBypassDuration * 1000;
|
||||||
|
},
|
||||||
|
|
||||||
bypass: function(hostname) {
|
bypass: function(hostname) {
|
||||||
if ( typeof hostname !== 'string' || hostname === '' ) { return; }
|
if ( typeof hostname !== 'string' || hostname === '' ) { return; }
|
||||||
this.hostnameToDeadlineMap.set(
|
this.hostnameToDeadlineMap.set(hostname, this.revokeTime());
|
||||||
hostname,
|
|
||||||
Date.now() + µb.hiddenSettings.strictBlockingBypassDuration * 1000
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
isBypassed: function(hostname) {
|
isBypassed: function(hostname) {
|
||||||
if ( this.hostnameToDeadlineMap.size === 0 ) { return false; }
|
if ( this.hostnameToDeadlineMap.size === 0 ) { return false; }
|
||||||
let bypassDuration =
|
this.cleanupTimer.on({ sec: µb.hiddenSettings.strictBlockingBypassDuration + 10 });
|
||||||
µb.hiddenSettings.strictBlockingBypassDuration * 1000;
|
|
||||||
if ( this.cleanupTimer === undefined ) {
|
|
||||||
this.cleanupTimer = vAPI.setTimeout(
|
|
||||||
( ) => {
|
|
||||||
this.cleanupTimer = undefined;
|
|
||||||
this.cleanup();
|
|
||||||
},
|
|
||||||
bypassDuration + 10000
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const deadline = this.hostnameToDeadlineMap.get(hostname);
|
const deadline = this.hostnameToDeadlineMap.get(hostname);
|
||||||
if ( deadline !== undefined ) {
|
if ( deadline !== undefined ) {
|
||||||
if ( deadline > Date.now() ) {
|
if ( deadline > Date.now() ) {
|
||||||
this.hostnameToDeadlineMap.set(
|
this.hostnameToDeadlineMap.set(hostname, this.revokeTime());
|
||||||
hostname,
|
|
||||||
Date.now() + bypassDuration
|
|
||||||
);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this.hostnameToDeadlineMap.delete(hostname);
|
this.hostnameToDeadlineMap.delete(hostname);
|
||||||
|
Loading…
Reference in New Issue
Block a user