forked from AdguardTeam/Scriptlets
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprevent-requestAnimationFrame.js
More file actions
131 lines (121 loc) · 4.11 KB
/
prevent-requestAnimationFrame.js
File metadata and controls
131 lines (121 loc) · 4.11 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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import {
hit,
noopFunc,
parseMatchArg,
isValidStrPattern,
isValidCallback,
// following helpers are needed for helpers above
toRegExp,
startsWith,
} from '../helpers/index';
/* eslint-disable max-len */
/**
* @scriptlet prevent-requestAnimationFrame
*
* @description
* Prevents a `requestAnimationFrame` call
* if the text of the callback is matching the specified search string which does not start with `!`;
* otherwise mismatched calls should be defused.
*
* Related UBO scriptlet:
* https://github.com/gorhill/uBlock/wiki/Resources-Library#no-requestanimationframe-ifjs-
*
* **Syntax**
* ```
* example.org#%#//scriptlet('prevent-requestAnimationFrame'[, search])
* ```
*
* - `search` - optional, string or regular expression; invalid regular expression will be skipped and all callbacks will be matched.
* If starts with `!`, scriptlet will not match the stringified callback but all other will be defused.
* If do not start with `!`, the stringified callback will be matched.
*
* Call with no argument will log all requestAnimationFrame calls while debugging.
* So do not use the scriptlet without any parameter in production filter lists.
*
* **Examples**
* 1. Prevents `requestAnimationFrame` calls if the callback matches `/\.test/`.
* ```bash
* example.org#%#//scriptlet('prevent-requestAnimationFrame', '/\.test/')
* ```
*
* For instance, the following call will be prevented:
* ```javascript
* var times = 0;
* requestAnimationFrame(function change() {
* window.test = 'new value';
* if (times < 2) {
* times += 1;
* requestAnimationFrame(change);
* }
* });
* ```
* 2. Prevents `requestAnimationFrame` calls if **does not match** 'check'.
* ```bash
* example.org#%#//scriptlet('prevent-requestAnimationFrame', '!check')
* ```
*
* For instance, only the first call will be prevented:
*
* ```javascript
* var timesFirst = 0;
* requestAnimationFrame(function changeFirst() {
* window.check = 'should not be prevented';
* if (timesFirst < 2) {
* timesFirst += 1;
* requestAnimationFrame(changeFirst);
* }
* });
*
* var timesSecond = 0;
* requestAnimationFrame(function changeSecond() {
* window.second = 'should be prevented';
* if (timesSecond < 2) {
* timesSecond += 1;
* requestAnimationFrame(changeSecond);
* }
* });
* ```
*/
/* eslint-enable max-len */
export function preventRequestAnimationFrame(source, match) {
const nativeRequestAnimationFrame = window.requestAnimationFrame;
const log = console.log.bind(console); // eslint-disable-line no-console
// logs requestAnimationFrame to console if no arguments have been specified
const shouldLog = typeof match === 'undefined';
const { isInvertedMatch, matchRegexp } = parseMatchArg(match);
const rafWrapper = (callback, ...args) => {
let shouldPrevent = false;
if (shouldLog) {
hit(source);
log(`requestAnimationFrame(${String(callback)})`);
} else if (isValidCallback(callback) && isValidStrPattern(match)) {
shouldPrevent = matchRegexp.test(callback.toString()) !== isInvertedMatch;
}
if (shouldPrevent) {
hit(source);
return nativeRequestAnimationFrame(noopFunc);
}
return nativeRequestAnimationFrame.apply(window, [callback, ...args]);
};
window.requestAnimationFrame = rafWrapper;
}
preventRequestAnimationFrame.names = [
'prevent-requestAnimationFrame',
// aliases are needed for matching the related scriptlet converted into our syntax
'no-requestAnimationFrame-if.js',
'ubo-no-requestAnimationFrame-if.js',
'norafif.js',
'ubo-norafif.js',
'ubo-no-requestAnimationFrame-if',
'ubo-norafif',
];
preventRequestAnimationFrame.injections = [
hit,
noopFunc,
parseMatchArg,
isValidStrPattern,
isValidCallback,
// following helpers should be injected as helpers above use them
toRegExp,
startsWith,
];