Skip to content

Commit

Permalink
Add prevent-canvas scriptlet
Browse files Browse the repository at this point in the history
Prevent usage of specific or all (default) canvas APIs.

Syntax

```text
example.com##+js(prevent-canvas [, contextType])
```

- `contextType`: A specific type of canvas API to prevent (default to all
  APIs). Can be a string or regex which will be matched against the type
  used in getContext() call. Prepend with `!` to test for no-match.

Examples

1. Prevent `example.com` from accessing all canvas APIs

```adblock
example.com##+js(prevent-canvas)
```

2. Prevent access to any flavor of WebGL API, everywhere

```adblock
*##+js(prevent-canvas, /webgl/)
```

3. Prevent `example.com` from accessing any flavor of canvas API except `2d`

```adblock
example.com##+js(prevent-canvas, !2d)
```

References

https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext
  • Loading branch information
gorhill committed Sep 28, 2023
1 parent c20cfd4 commit 1ff3878
Showing 1 changed file with 65 additions and 1 deletion.
66 changes: 65 additions & 1 deletion assets/resources/scriptlets.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function safeSelf() {
if ( pattern === '' ) {
return { matchAll: true };
}
const expect = (options.canNegate === true && pattern.startsWith('!') === false);
const expect = (options.canNegate !== true || pattern.startsWith('!') === false);
if ( expect === false ) {
pattern = pattern.slice(1);
}
Expand Down Expand Up @@ -3388,6 +3388,70 @@ function setAttr(
runAt(( ) => { start(); }, 'idle');
}

/*******************************************************************************
*
* @scriptlet prevent-canvas
*
* @description
* Prevent usage of specific or all (default) canvas APIs.
*
* ### Syntax
*
* ```text
* example.com##+js(prevent-canvas [, contextType])
* ```
*
* - `contextType`: A specific type of canvas API to prevent (default to all
* APIs). Can be a string or regex which will be matched against the type
* used in getContext() call. Prepend with `!` to test for no-match.
*
* ### Examples
*
* 1. Prevent `example.com` from accessing all canvas APIs
*
* ```adblock
* example.com##+js(prevent-canvas)
* ```
*
* 2. Prevent access to any flavor of WebGL API, everywhere
*
* ```adblock
* *##+js(prevent-canvas, /webgl/)
* ```
*
* 3. Prevent `example.com` from accessing any flavor of canvas API except `2d`
*
* ```adblock
* example.com##+js(prevent-canvas, !2d)
* ```
*
* ### References
*
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext
*
* */

builtinScriptlets.push({
name: 'prevent-canvas.js',
fn: preventCanvas,
dependencies: [
'safe-self.fn',
],
});
function preventCanvas(
contextType = ''
) {
const safe = safeSelf();
const pattern = safe.initPattern(contextType, { canNegate: true });
const proto = globalThis.HTMLCanvasElement.prototype;
proto.getContext = new Proxy(proto.getContext, {
apply(target, thisArg, args) {
if ( safe.testPattern(pattern, args[0]) ) { return null; }
return Reflect.apply(target, thisArg, args);
}
});
}


/*******************************************************************************
*
Expand Down

0 comments on commit 1ff3878

Please sign in to comment.