1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-07-08 12:57:57 +02:00

Add ability to defer set-constant execution

A new optional parameter has been added to `set-constant`
scriptlet: `runAt`, default to `0`.

 ..##+js(set, document.body.oncontextmenu, null, 2)

When the `runAt` parameter is present, uBO will take it into
account to possibly defer execution of `set-constant`:

- `runAt` not present: execute immediately
- `runAt` = 1: execute immediately
- `runAt` = 2: execute when document state is "interactive"
- `runAt` = 3: execute when document state is `"complete"
This commit is contained in:
Raymond Hill 2023-04-11 21:45:40 -04:00
parent 8083e06b30
commit e1500ee88d
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2

View File

@ -982,11 +982,17 @@ builtinScriptlets.push({
fn: setConstant,
});
function setConstant(
chain = '',
cValue = ''
arg1 = '',
arg2 = '',
arg3 = 0
) {
const details = typeof arg1 !== 'object'
? { prop: arg1, value: arg2, runAt: parseInt(arg3, 10) || 0 }
: arg1;
const { prop: chain = '', value: cValue = '' } = details;
if ( typeof chain !== 'string' ) { return; }
if ( chain === '' ) { return; }
function setConstant(chain, cValue) {
const trappedProp = (( ) => {
const pos = chain.lastIndexOf('.');
if ( pos === -1 ) { return chain; }
@ -1060,7 +1066,7 @@ function setConstant(
// https://github.com/uBlockOrigin/uBlock-issues/issues/156
// Support multiple trappers for the same property.
const trapProp = function(owner, prop, configurable, handler) {
if ( handler.init(owner[prop]) === false ) { return; }
if ( handler.init(configurable ? owner[prop] : cValue) === false ) { return; }
const odesc = Object.getOwnPropertyDescriptor(owner, prop);
let prevGetter, prevSetter;
if ( odesc instanceof Object ) {
@ -1139,6 +1145,23 @@ function setConstant(
};
trapChain(window, chain);
}
const runAt = details.runAt;
if ( runAt === 0 ) {
setConstant(chain, cValue); return;
}
const docReadyState = ( ) => {
return ({ loading: 1, interactive: 2, complete: 3, })[document.readyState] || 0;
};
if ( docReadyState() >= runAt ) {
setConstant(chain, cValue); return;
}
const onReadyStateChange = ( ) => {
if ( docReadyState() < runAt ) { return; }
setConstant(chain, cValue);
document.removeEventListener('readystatechange', onReadyStateChange);
};
document.addEventListener('readystatechange', onReadyStateChange);
}
/******************************************************************************/