Skip to content

Commit

Permalink
Add trusted-override-element-method scriptlet
Browse files Browse the repository at this point in the history
@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])
  • Loading branch information
gorhill committed Oct 5, 2024
1 parent a0a33eb commit 95b0ce5
Showing 1 changed file with 64 additions and 0 deletions.
64 changes: 64 additions & 0 deletions assets/resources/scriptlets.js
Original file line number Diff line number Diff line change
Expand Up @@ -5218,4 +5218,68 @@ function trustedPreventDomBypass(
});
}

/**
*
* @trustedScriptlet trusted-override-element-method
*
* @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])
*
* */

builtinScriptlets.push({
name: 'trusted-override-element-method.js',
requiresTrust: true,
fn: trustedOverrideElementMethod,
dependencies: [
'proxy-apply.fn',
'safe-self.fn',
'validate-constant.fn',
],
});
function trustedOverrideElementMethod(
methodPath = '',
selector = '',
disposition = ''
) {
if ( methodPath === '' ) { return; }
const safe = safeSelf();
const logPrefix = safe.makeLogPrefix('trusted-override-element-method', methodPath, selector, disposition);
proxyApplyFn(methodPath, function(context) {
let override = selector === '';
if ( override === false ) {
const { thisArg } = context;
try {
override = thisArg.closest(selector) === thisArg;
} catch(_) {
}
}
if ( override === false ) {
return context.reflect();
}
safe.uboLog(logPrefix, 'Overridden');
if ( disposition === '' ) { return; }
if ( disposition === 'throw' ) {
throw new ReferenceError();
}
return validateConstantFn(false, disposition);
});
}

/******************************************************************************/

0 comments on commit 95b0ce5

Please sign in to comment.