Skip to content

Commit 95b0ce5

Browse files
committed
Add trusted-override-element-method scriptlet
@description Override the behavior of a method on matching elements. @param methodPath The method which calls must be intercepted. @param [selector] A CSS selector which the target element must match. If not specified, the override will occur for all elements. @param [disposition] How the override should be handled. If not specified, the overridden call will be equivalent to an empty function. If set to `throw`, an exception will be thrown. Any other value will be validated and returned as a supported safe constant. @example ..##+js(trusted-override-element-method, HTMLAnchorElement.prototype.click, a[target="_blank"][style])
1 parent a0a33eb commit 95b0ce5

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

assets/resources/scriptlets.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5218,4 +5218,68 @@ function trustedPreventDomBypass(
52185218
});
52195219
}
52205220

5221+
/**
5222+
*
5223+
* @trustedScriptlet trusted-override-element-method
5224+
*
5225+
* @description
5226+
* Override the behavior of a method on matching elements.
5227+
*
5228+
* @param methodPath
5229+
* The method which calls must be intercepted.
5230+
*
5231+
* @param [selector]
5232+
* A CSS selector which the target element must match. If not specified,
5233+
* the override will occur for all elements.
5234+
*
5235+
* @param [disposition]
5236+
* How the override should be handled. If not specified, the overridden call
5237+
* will be equivalent to an empty function. If set to `throw`, an exception
5238+
* will be thrown. Any other value will be validated and returned as a
5239+
* supported safe constant.
5240+
*
5241+
* @example
5242+
* ##+js(trusted-override-element-method, HTMLAnchorElement.prototype.click, a[target="_blank"][style])
5243+
*
5244+
* */
5245+
5246+
builtinScriptlets.push({
5247+
name: 'trusted-override-element-method.js',
5248+
requiresTrust: true,
5249+
fn: trustedOverrideElementMethod,
5250+
dependencies: [
5251+
'proxy-apply.fn',
5252+
'safe-self.fn',
5253+
'validate-constant.fn',
5254+
],
5255+
});
5256+
function trustedOverrideElementMethod(
5257+
methodPath = '',
5258+
selector = '',
5259+
disposition = ''
5260+
) {
5261+
if ( methodPath === '' ) { return; }
5262+
const safe = safeSelf();
5263+
const logPrefix = safe.makeLogPrefix('trusted-override-element-method', methodPath, selector, disposition);
5264+
proxyApplyFn(methodPath, function(context) {
5265+
let override = selector === '';
5266+
if ( override === false ) {
5267+
const { thisArg } = context;
5268+
try {
5269+
override = thisArg.closest(selector) === thisArg;
5270+
} catch(_) {
5271+
}
5272+
}
5273+
if ( override === false ) {
5274+
return context.reflect();
5275+
}
5276+
safe.uboLog(logPrefix, 'Overridden');
5277+
if ( disposition === '' ) { return; }
5278+
if ( disposition === 'throw' ) {
5279+
throw new ReferenceError();
5280+
}
5281+
return validateConstantFn(false, disposition);
5282+
});
5283+
}
5284+
52215285
/******************************************************************************/

0 commit comments

Comments
 (0)