-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathadjust-setTimeout.js
134 lines (126 loc) · 4.03 KB
/
adjust-setTimeout.js
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
132
133
134
import {
hit,
isValidCallback,
toRegExp,
getBoostMultiplier,
isDelayMatched,
logMessage,
nativeIsNaN,
nativeIsFinite,
getMatchDelay,
shouldMatchAnyDelay,
} from '../helpers';
/* eslint-disable max-len */
/**
* @scriptlet adjust-setTimeout
*
* @description
* Adjusts delay for specified setTimeout() callbacks.
*
* Related UBO scriptlet:
* https://github.com/gorhill/uBlock/wiki/Resources-Library#nano-settimeout-boosterjs-
*
* ### Syntax
*
* ```text
* example.org#%#//scriptlet('adjust-setTimeout'[, matchCallback [, matchDelay[, boost]]])
* ```
*
* - `matchCallback` — optional, string or regular expression for stringified callback matching;
* defaults to match all callbacks; invalid regular expression will cause exit and rule will not work
* - `matchDelay` — optional, defaults to 1000, matching setTimeout delay; decimal integer OR '*' for any delay
* - `boost` — optional, default to 0.05, float,
* capped at 1000 times for up and 50 for down (0.001...50), setTimeout delay multiplier
*
* ### Examples
*
* 1. Adjust all setTimeout() x20 times where timeout equal 1000ms
*
* ```adblock
* example.org#%#//scriptlet('adjust-setTimeout')
* ```
*
* 1. Adjust all setTimeout() x20 times where callback matched with `example` and timeout equal 1000ms
*
* ```adblock
* example.org#%#//scriptlet('adjust-setTimeout', 'example')
* ```
*
* 1. Adjust all setTimeout() x20 times where callback matched with `example` and timeout equal 400ms
*
* ```adblock
* example.org#%#//scriptlet('adjust-setTimeout', 'example', '400')
* ```
*
* 1. Slow down setTimeout() x2 times where callback matched with `example` and timeout equal 1000ms
*
* ```adblock
* example.org#%#//scriptlet('adjust-setTimeout', 'example', '', '2')
* ```
*
* 1. Adjust all setTimeout() x50 times where timeout equal 2000ms
*
* ```adblock
* example.org#%#//scriptlet('adjust-setTimeout', '', '2000', '0.02')
* ```
*
* 1. Adjust all setTimeout() x1000 times where timeout equal 2000ms
*
* ```adblock
* example.org#%#//scriptlet('adjust-setTimeout', '', '2000', '0.001')
* ```
*
* 1. Adjust all setTimeout() x20 times where callback matched with `test` and timeout is randomized
*
* ```adblock
* example.org#%#//scriptlet('adjust-setTimeout', 'test', '*')
* ```
*
* @added v1.0.4.
*/
/* eslint-enable max-len */
export function adjustSetTimeout(source, matchCallback, matchDelay, boost) {
const nativeSetTimeout = window.setTimeout;
const matchRegexp = toRegExp(matchCallback);
const timeoutWrapper = (callback, delay, ...args) => {
// https://github.com/AdguardTeam/Scriptlets/issues/221
if (!isValidCallback(callback)) {
// eslint-disable-next-line max-len
const message = `Scriptlet can't be applied because of invalid callback: '${String(callback)}'`;
logMessage(source, message);
} else if (matchRegexp.test(callback.toString()) && isDelayMatched(matchDelay, delay)) {
delay *= getBoostMultiplier(boost);
hit(source);
}
return nativeSetTimeout.apply(window, [callback, delay, ...args]);
};
window.setTimeout = timeoutWrapper;
}
export const adjustSetTimeoutNames = [
'adjust-setTimeout',
// aliases are needed for matching the related scriptlet converted into our syntax
'adjust-setTimeout.js',
'ubo-adjust-setTimeout.js',
'nano-setTimeout-booster.js',
'ubo-nano-setTimeout-booster.js',
'nano-stb.js',
'ubo-nano-stb.js',
'ubo-adjust-setTimeout',
'ubo-nano-setTimeout-booster',
'ubo-nano-stb',
];
// eslint-disable-next-line prefer-destructuring
adjustSetTimeout.primaryName = adjustSetTimeoutNames[0];
adjustSetTimeout.injections = [
hit,
isValidCallback,
toRegExp,
getBoostMultiplier,
isDelayMatched,
logMessage,
// following helpers should be injected as helpers above use them
nativeIsNaN,
nativeIsFinite,
getMatchDelay,
shouldMatchAnyDelay,
];