forked from AdguardTeam/Scriptlets
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprevent-canvas.ts
More file actions
107 lines (101 loc) · 2.74 KB
/
prevent-canvas.ts
File metadata and controls
107 lines (101 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import {
hit,
logMessage,
parseMatchArg,
isValidMatchStr,
toRegExp,
escapeRegExp,
isValidStrPattern,
} from '../helpers';
import { type Source } from './scriptlets';
/**
* @scriptlet prevent-canvas
*
* @description
* Prevents calls to `HTMLCanvasElement.prototype.getContext` and returns `null`.
*
* Related UBO scriptlet:
* https://github.com/gorhill/uBlock/wiki/Resources-Library#prevent-canvasjs-
*
* ### Syntax
*
* ```text
* example.org#%#//scriptlet('prevent-canvas'[, contextType])
* ```
*
* - `contextType` — optional, string matching the context type (e.g., '2d', 'webgl');
* by default it matches all context types.
* It can be a string pattern or a regular expression pattern.
* If the pattern starts with `!`, it will be negated.
*
* ### Examples
*
* 1. Prevent all canvas contexts
*
* ```adblock
* example.org#%#//scriptlet('prevent-canvas')
* ```
*
* 1. Prevent only '2d' canvas contexts
*
* ```adblock
* example.org#%#//scriptlet('prevent-canvas', '2d')
* ```
*
* 1. Prevent all canvas contexts except '2d'
*
* ```adblock
* example.org#%#//scriptlet('prevent-canvas', '!2d')
* ```
*
* @added v2.0.1.
*/
export function preventCanvas(source: Source, contextType?: string) {
const handlerWrapper = (
target: HTMLCanvasElement['getContext'],
thisArg: HTMLCanvasElement,
argumentsList: string[],
) => {
const type = argumentsList[0];
let shouldPrevent = false;
if (!contextType) {
shouldPrevent = true;
} else if (isValidMatchStr(contextType)) {
const { isInvertedMatch, matchRegexp } = parseMatchArg(contextType);
shouldPrevent = matchRegexp.test(type) !== isInvertedMatch;
} else {
logMessage(source, `Invalid contextType parameter: ${contextType}`);
shouldPrevent = false;
}
if (shouldPrevent) {
hit(source);
return null;
}
return Reflect.apply(target, thisArg, argumentsList);
};
const canvasHandler = {
apply: handlerWrapper,
};
window.HTMLCanvasElement.prototype.getContext = new Proxy(
window.HTMLCanvasElement.prototype.getContext,
canvasHandler,
);
}
export const preventCanvasNames = [
'prevent-canvas',
// aliases are needed for matching the related scriptlet converted into our syntax
'prevent-canvas.js',
'ubo-prevent-canvas.js',
'ubo-prevent-canvas',
];
// eslint-disable-next-line prefer-destructuring
preventCanvas.primaryName = preventCanvasNames[0];
preventCanvas.injections = [
hit,
logMessage,
parseMatchArg,
isValidMatchStr,
toRegExp,
escapeRegExp,
isValidStrPattern,
];