mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 01:02:08 +01:00
Expand/harden some scriptlets
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/2615 Expand `set-constant`: 3rd parameter and beyond are tokens which modify the behavior of `set-contant`. Valid tokens: - `interactive`, `end`, `2`: set the constant when the event `DOMContentInteractive` is fired. - `complete`, `idle`, `3`: set the constant when the event `load` is fired. - `asFunction`: the constant will be a function returning the specified value. - `asCallback`: the constant will be a function returning a function returning the specified value. - `asResolved`: the constant will be a promise resolving to the specified value. - `asRejected`: the constant will be a promise failing with the specified value. Harden `no-setimeout-if` and `no-setinterval-if` as per feedback from filter list maintainers.
This commit is contained in:
parent
0442718efd
commit
2ef2888805
1 changed files with 48 additions and 14 deletions
|
@ -130,13 +130,18 @@ builtinScriptlets.push({
|
|||
});
|
||||
function runAt(fn, when) {
|
||||
const intFromReadyState = state => {
|
||||
return ({
|
||||
loading: 1,
|
||||
interactive: 2,
|
||||
end: 2,
|
||||
complete: 3,
|
||||
idle: 3,
|
||||
})[`${state}`] || 0;
|
||||
const targets = {
|
||||
'loading': 1,
|
||||
'interactive': 2, 'end': 2, '2': 2,
|
||||
'complete': 3, 'idle': 3, '3': 3,
|
||||
};
|
||||
const tokens = Array.isArray(state) ? state : [ state ];
|
||||
for ( const token of tokens ) {
|
||||
const prop = `${token}`;
|
||||
if ( targets.hasOwnProperty(prop) === false ) { continue; }
|
||||
return targets[prop];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
const runAt = intFromReadyState(when);
|
||||
if ( intFromReadyState(document.readyState) >= runAt ) {
|
||||
|
@ -1030,14 +1035,22 @@ builtinScriptlets.push({
|
|||
function setConstant(
|
||||
arg1 = '',
|
||||
arg2 = '',
|
||||
arg3 = 0
|
||||
arg3 = ''
|
||||
) {
|
||||
const details = typeof arg1 !== 'object'
|
||||
? { prop: arg1, value: arg2, runAt: parseInt(arg3, 10) || 0 }
|
||||
? { prop: arg1, value: arg2 }
|
||||
: arg1;
|
||||
if ( arg3 !== '' ) {
|
||||
if ( /^\d$/.test(arg3) ) {
|
||||
details.options = [ arg3 ];
|
||||
} else {
|
||||
details.options = Array.from(arguments).slice(2);
|
||||
}
|
||||
}
|
||||
const { prop: chain = '', value: cValue = '' } = details;
|
||||
if ( typeof chain !== 'string' ) { return; }
|
||||
if ( chain === '' ) { return; }
|
||||
const options = details.options || [];
|
||||
function setConstant(chain, cValue) {
|
||||
const trappedProp = (( ) => {
|
||||
const pos = chain.lastIndexOf('.');
|
||||
|
@ -1093,13 +1106,22 @@ function setConstant(
|
|||
cValue = cloakFunc(function(){ return true; });
|
||||
} else if ( cValue === 'falseFunc' ) {
|
||||
cValue = cloakFunc(function(){ return false; });
|
||||
} else if ( /^\d+$/.test(cValue) ) {
|
||||
cValue = parseFloat(cValue);
|
||||
} else if ( /^-?\d+$/.test(cValue) ) {
|
||||
cValue = parseInt(cValue);
|
||||
if ( isNaN(cValue) ) { return; }
|
||||
if ( Math.abs(cValue) > 0x7FFF ) { return; }
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if ( options.includes('asFunction') ) {
|
||||
cValue = ( ) => cValue;
|
||||
} else if ( options.includes('asCallback') ) {
|
||||
cValue = ( ) => (( ) => cValue);
|
||||
} else if ( options.includes('asResolved') ) {
|
||||
cValue = Promise.resolve(cValue);
|
||||
} else if ( options.includes('asRejected') ) {
|
||||
cValue = Promise.reject(cValue);
|
||||
}
|
||||
let aborted = false;
|
||||
const mustAbort = function(v) {
|
||||
if ( aborted ) { return true; }
|
||||
|
@ -1193,7 +1215,7 @@ function setConstant(
|
|||
}
|
||||
runAt(( ) => {
|
||||
setConstant(chain, cValue);
|
||||
}, details.runAt);
|
||||
}, options);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -1243,7 +1265,13 @@ function noSetIntervalIf(
|
|||
}
|
||||
}
|
||||
return target.apply(thisArg, args);
|
||||
}
|
||||
},
|
||||
get(target, prop, receiver) {
|
||||
if ( prop === 'toString' ) {
|
||||
return target.toString.bind(target);
|
||||
}
|
||||
return Reflect.get(target, prop, receiver);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1294,7 +1322,13 @@ function noSetTimeoutIf(
|
|||
}
|
||||
}
|
||||
return target.apply(thisArg, args);
|
||||
}
|
||||
},
|
||||
get(target, prop, receiver) {
|
||||
if ( prop === 'toString' ) {
|
||||
return target.toString.bind(target);
|
||||
}
|
||||
return Reflect.get(target, prop, receiver);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue