@browserless.io/browserless 2.25.0-beta-2 → 2.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/CHANGELOG.md +43 -3
  2. package/README.md +4 -5
  3. package/build/browserless.js +3 -1
  4. package/build/browsers/browsers.cdp.d.ts +3 -0
  5. package/build/browsers/browsers.cdp.js +4 -1
  6. package/build/browsers/browsers.playwright.d.ts +4 -0
  7. package/build/browsers/browsers.playwright.js +11 -2
  8. package/build/browsers/index.js +4 -3
  9. package/build/http.d.ts +9 -0
  10. package/build/http.js +9 -0
  11. package/build/routes/chrome/http/content.post.body.json +8 -8
  12. package/build/routes/chrome/http/pdf.post.body.json +8 -8
  13. package/build/routes/chrome/http/scrape.post.body.json +8 -8
  14. package/build/routes/chrome/http/screenshot.post.body.json +8 -8
  15. package/build/routes/chrome/tests/kill-sessions.spec.js +1 -1
  16. package/build/routes/chromium/http/content.post.body.json +8 -8
  17. package/build/routes/chromium/http/pdf.post.body.json +8 -8
  18. package/build/routes/chromium/http/scrape.post.body.json +8 -8
  19. package/build/routes/chromium/http/screenshot.post.body.json +8 -8
  20. package/build/routes/chromium/tests/kill-sessions.spec.js +1 -1
  21. package/build/routes/edge/http/content.post.body.json +579 -0
  22. package/build/routes/edge/http/content.post.d.ts +8 -0
  23. package/build/routes/edge/http/content.post.js +7 -0
  24. package/build/routes/edge/http/content.post.query.json +183 -0
  25. package/build/routes/edge/http/content.post.response.json +5 -0
  26. package/build/routes/edge/http/download.post.body.json +32 -0
  27. package/build/routes/edge/http/download.post.d.ts +8 -0
  28. package/build/routes/edge/http/download.post.js +7 -0
  29. package/build/routes/edge/http/download.post.query.json +120 -0
  30. package/build/routes/edge/http/download.post.response.json +4 -0
  31. package/build/routes/edge/http/function.post.body.json +32 -0
  32. package/build/routes/edge/http/function.post.d.ts +8 -0
  33. package/build/routes/edge/http/function.post.js +7 -0
  34. package/build/routes/edge/http/function.post.query.json +120 -0
  35. package/build/routes/edge/http/function.post.response.json +4 -0
  36. package/build/routes/edge/http/json-list.get.d.ts +5 -0
  37. package/build/routes/edge/http/json-list.get.js +5 -0
  38. package/build/routes/edge/http/json-list.get.response.json +52 -0
  39. package/build/routes/edge/http/json-new.put.d.ts +5 -0
  40. package/build/routes/edge/http/json-new.put.js +5 -0
  41. package/build/routes/edge/http/json-new.put.response.json +44 -0
  42. package/build/routes/edge/http/json-protocol.get.d.ts +5 -0
  43. package/build/routes/edge/http/json-protocol.get.js +5 -0
  44. package/build/routes/edge/http/json-protocol.get.response.json +6 -0
  45. package/build/routes/edge/http/json-version.get.d.ts +5 -0
  46. package/build/routes/edge/http/json-version.get.js +5 -0
  47. package/build/routes/edge/http/json-version.get.response.json +44 -0
  48. package/build/routes/edge/http/pdf.post.body.json +724 -0
  49. package/build/routes/edge/http/pdf.post.d.ts +8 -0
  50. package/build/routes/edge/http/pdf.post.js +7 -0
  51. package/build/routes/edge/http/pdf.post.query.json +120 -0
  52. package/build/routes/edge/http/pdf.post.response.json +5 -0
  53. package/build/routes/edge/http/performance.post.body.json +26 -0
  54. package/build/routes/edge/http/performance.post.d.ts +8 -0
  55. package/build/routes/edge/http/performance.post.js +7 -0
  56. package/build/routes/edge/http/performance.post.query.json +120 -0
  57. package/build/routes/edge/http/performance.post.response.json +7 -0
  58. package/build/routes/edge/http/scrape.post.body.json +626 -0
  59. package/build/routes/edge/http/scrape.post.d.ts +8 -0
  60. package/build/routes/edge/http/scrape.post.js +7 -0
  61. package/build/routes/edge/http/scrape.post.query.json +183 -0
  62. package/build/routes/edge/http/scrape.post.response.json +334 -0
  63. package/build/routes/edge/http/screenshot.post.body.json +669 -0
  64. package/build/routes/edge/http/screenshot.post.d.ts +8 -0
  65. package/build/routes/edge/http/screenshot.post.js +7 -0
  66. package/build/routes/edge/http/screenshot.post.query.json +120 -0
  67. package/build/routes/edge/http/screenshot.post.response.json +5 -0
  68. package/build/routes/edge/tests/content.spec.d.ts +1 -0
  69. package/build/routes/edge/tests/content.spec.js +312 -0
  70. package/build/routes/edge/tests/download.spec.d.ts +1 -0
  71. package/build/routes/edge/tests/download.spec.js +67 -0
  72. package/build/routes/edge/tests/function.spec.d.ts +1 -0
  73. package/build/routes/edge/tests/function.spec.js +277 -0
  74. package/build/routes/edge/tests/json-version.spec.d.ts +1 -0
  75. package/build/routes/edge/tests/json-version.spec.js +37 -0
  76. package/build/routes/edge/tests/kill-sessions.spec.d.ts +1 -0
  77. package/build/routes/edge/tests/kill-sessions.spec.js +80 -0
  78. package/build/routes/edge/tests/page-websocket.spec.d.ts +1 -0
  79. package/build/routes/edge/tests/page-websocket.spec.js +97 -0
  80. package/build/routes/edge/tests/pdf.spec.d.ts +1 -0
  81. package/build/routes/edge/tests/pdf.spec.js +345 -0
  82. package/build/routes/edge/tests/performance.spec.d.ts +1 -0
  83. package/build/routes/edge/tests/performance.spec.js +124 -0
  84. package/build/routes/edge/tests/scrape.spec.d.ts +1 -0
  85. package/build/routes/edge/tests/scrape.spec.js +354 -0
  86. package/build/routes/edge/tests/screenshot.spec.d.ts +1 -0
  87. package/build/routes/edge/tests/screenshot.spec.js +339 -0
  88. package/build/routes/edge/tests/websocket.spec.d.ts +1 -0
  89. package/build/routes/edge/tests/websocket.spec.js +384 -0
  90. package/build/routes/edge/ws/browser.d.ts +7 -0
  91. package/build/routes/edge/ws/browser.js +6 -0
  92. package/build/routes/edge/ws/browser.query.json +120 -0
  93. package/build/routes/edge/ws/cdp.d.ts +8 -0
  94. package/build/routes/edge/ws/cdp.js +7 -0
  95. package/build/routes/edge/ws/cdp.query.json +120 -0
  96. package/build/routes/edge/ws/page.d.ts +8 -0
  97. package/build/routes/edge/ws/page.js +7 -0
  98. package/build/routes/edge/ws/page.query.json +120 -0
  99. package/build/routes/edge/ws/playwright.d.ts +8 -0
  100. package/build/routes/edge/ws/playwright.js +7 -0
  101. package/build/routes/edge/ws/playwright.query.json +100 -0
  102. package/build/routes/firefox/tests/kill-sessions.spec.js +1 -1
  103. package/build/routes/management/http/meta.get.js +3 -1
  104. package/build/routes/webkit/tests/kill-sessions.spec.js +1 -1
  105. package/build/sdk-utils.js +1 -1
  106. package/build/shared/scrape.http.js +2 -2
  107. package/build/types.d.ts +32 -0
  108. package/build/types.js +18 -0
  109. package/build/utils.d.ts +1 -0
  110. package/build/utils.js +16 -2
  111. package/docker/chrome/Dockerfile +14 -14
  112. package/docker/chromium/Dockerfile +14 -14
  113. package/docker/edge/.dockerignore +16 -0
  114. package/docker/edge/Dockerfile +43 -0
  115. package/docker/firefox/Dockerfile +14 -14
  116. package/docker/multi/Dockerfile +18 -18
  117. package/docker/sdk/Dockerfile +10 -0
  118. package/extensions/ublock/_locales/ar/messages.json +3 -3
  119. package/extensions/ublock/_locales/bg/messages.json +1 -1
  120. package/extensions/ublock/_locales/br_FR/messages.json +2 -2
  121. package/extensions/ublock/_locales/cy/messages.json +11 -11
  122. package/extensions/ublock/_locales/el/messages.json +2 -2
  123. package/extensions/ublock/_locales/hu/messages.json +1 -1
  124. package/extensions/ublock/_locales/id/messages.json +1 -1
  125. package/extensions/ublock/_locales/lv/messages.json +4 -4
  126. package/extensions/ublock/_locales/mk/messages.json +130 -130
  127. package/extensions/ublock/_locales/oc/messages.json +1 -1
  128. package/extensions/ublock/_locales/pt_BR/messages.json +1 -1
  129. package/extensions/ublock/_locales/pt_PT/messages.json +2 -2
  130. package/extensions/ublock/_locales/si/messages.json +100 -100
  131. package/extensions/ublock/_locales/sr/messages.json +4 -4
  132. package/extensions/ublock/_locales/vi/messages.json +19 -19
  133. package/extensions/ublock/_locales/zh_TW/messages.json +28 -28
  134. package/extensions/ublock/assets/assets.json +33 -29
  135. package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +2984 -3287
  136. package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +150 -171
  137. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +37 -27
  138. package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +802 -888
  139. package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +2355 -2071
  140. package/extensions/ublock/assets/ublock/badlists.txt +9 -1
  141. package/extensions/ublock/assets/ublock/badware.min.txt +354 -243
  142. package/extensions/ublock/assets/ublock/filters.min.txt +5837 -5737
  143. package/extensions/ublock/assets/ublock/privacy.min.txt +151 -38
  144. package/extensions/ublock/assets/ublock/quick-fixes.min.txt +83 -127
  145. package/extensions/ublock/assets/ublock/unbreak.min.txt +66 -50
  146. package/extensions/ublock/css/codemirror.css +4 -0
  147. package/extensions/ublock/document-blocked.html +3 -1
  148. package/extensions/ublock/js/arglist-parser.js +116 -0
  149. package/extensions/ublock/js/background.js +1 -1
  150. package/extensions/ublock/js/logger-ui.js +1 -1
  151. package/extensions/ublock/js/messaging.js +9 -2
  152. package/extensions/ublock/js/pagestore.js +3 -1
  153. package/extensions/ublock/js/redirect-engine.js +3 -1
  154. package/extensions/ublock/{assets/resources/set-attr.js → js/resources/attribute.js} +115 -11
  155. package/extensions/ublock/js/resources/base.js +38 -0
  156. package/extensions/ublock/js/resources/cookie.js +419 -0
  157. package/extensions/ublock/js/resources/href-sanitizer.js +188 -0
  158. package/extensions/ublock/js/resources/localstorage.js +235 -0
  159. package/extensions/ublock/js/resources/parse-replace.js +54 -0
  160. package/extensions/ublock/js/resources/prevent-settimeout.js +236 -0
  161. package/extensions/ublock/js/resources/proxy-apply.js +109 -0
  162. package/extensions/ublock/js/resources/replace-argument.js +120 -0
  163. package/extensions/ublock/{assets → js}/resources/run-at.js +20 -4
  164. package/extensions/ublock/{assets → js}/resources/safe-self.js +5 -4
  165. package/extensions/ublock/{assets → js}/resources/scriptlets.js +90 -1589
  166. package/extensions/ublock/js/resources/set-constant.js +287 -0
  167. package/extensions/ublock/js/resources/shared.js +44 -0
  168. package/extensions/ublock/js/resources/spoof-css.js +163 -0
  169. package/extensions/ublock/js/s14e-serializer.js +2 -1
  170. package/extensions/ublock/js/scriptlet-filtering-core.js +1 -1
  171. package/extensions/ublock/js/scriptlet-filtering.js +1 -31
  172. package/extensions/ublock/js/static-dnr-filtering.js +143 -129
  173. package/extensions/ublock/js/static-filtering-parser.js +27 -117
  174. package/extensions/ublock/js/static-net-filtering.js +53 -141
  175. package/extensions/ublock/js/traffic.js +1 -1
  176. package/extensions/ublock/js/urlskip.js +166 -0
  177. package/extensions/ublock/js/vapi-background-ext.js +38 -14
  178. package/extensions/ublock/manifest.json +1 -1
  179. package/package.json +22 -22
  180. package/src/browserless.ts +4 -0
  181. package/src/browsers/browsers.cdp.ts +5 -0
  182. package/src/browsers/browsers.playwright.ts +14 -1
  183. package/src/browsers/index.ts +5 -2
  184. package/src/http.ts +9 -0
  185. package/src/routes/chrome/tests/kill-sessions.spec.ts +1 -1
  186. package/src/routes/chromium/tests/kill-sessions.spec.ts +1 -1
  187. package/src/routes/edge/http/content.post.ts +20 -0
  188. package/src/routes/edge/http/download.post.ts +20 -0
  189. package/src/routes/edge/http/function.post.ts +20 -0
  190. package/src/routes/edge/http/json-list.get.ts +7 -0
  191. package/src/routes/edge/http/json-new.put.ts +7 -0
  192. package/src/routes/edge/http/json-protocol.get.ts +7 -0
  193. package/src/routes/edge/http/json-version.get.ts +7 -0
  194. package/src/routes/edge/http/pdf.post.ts +20 -0
  195. package/src/routes/edge/http/performance.post.ts +20 -0
  196. package/src/routes/edge/http/scrape.post.ts +20 -0
  197. package/src/routes/edge/http/screenshot.post.ts +20 -0
  198. package/src/routes/edge/tests/content.spec.ts +376 -0
  199. package/src/routes/edge/tests/download.spec.ts +77 -0
  200. package/src/routes/edge/tests/function.spec.ts +317 -0
  201. package/src/routes/edge/tests/json-version.spec.ts +52 -0
  202. package/src/routes/edge/tests/kill-sessions.spec.ts +99 -0
  203. package/src/routes/edge/tests/page-websocket.spec.ts +129 -0
  204. package/src/routes/edge/tests/pdf.spec.ts +389 -0
  205. package/src/routes/edge/tests/performance.spec.ts +155 -0
  206. package/src/routes/edge/tests/scrape.spec.ts +417 -0
  207. package/src/routes/edge/tests/screenshot.spec.ts +387 -0
  208. package/src/routes/edge/tests/websocket.spec.ts +510 -0
  209. package/src/routes/edge/ws/browser.ts +10 -0
  210. package/src/routes/edge/ws/cdp.ts +17 -0
  211. package/src/routes/edge/ws/page.ts +10 -0
  212. package/src/routes/edge/ws/playwright.ts +17 -0
  213. package/src/routes/firefox/tests/kill-sessions.spec.ts +1 -1
  214. package/src/routes/management/http/meta.get.ts +6 -1
  215. package/src/routes/management/http/static.get.ts +1 -1
  216. package/src/routes/webkit/tests/kill-sessions.spec.ts +1 -1
  217. package/src/sdk-utils.ts +1 -1
  218. package/src/shared/scrape.http.ts +2 -2
  219. package/src/types.ts +19 -0
  220. package/src/utils.ts +38 -16
  221. package/static/docs/swagger.json +2097 -10
  222. package/static/docs/swagger.min.json +2096 -9
  223. package/static/function/client.js +141 -253
  224. package/static/function/index.html +141 -253
@@ -0,0 +1,236 @@
1
+ /*******************************************************************************
2
+
3
+ uBlock Origin - a comprehensive, efficient content blocker
4
+ Copyright (C) 2019-present Raymond Hill
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program. If not, see {http://www.gnu.org/licenses/}.
18
+
19
+ Home: https://github.com/gorhill/uBlock
20
+
21
+ */
22
+
23
+ import { proxyApplyFn } from './proxy-apply.js';
24
+ import { registerScriptlet } from './base.js';
25
+ import { safeSelf } from './safe-self.js';
26
+
27
+ /******************************************************************************/
28
+
29
+ class RangeParser {
30
+ constructor(s) {
31
+ this.not = s.charAt(0) === '!';
32
+ if ( this.not ) { s = s.slice(1); }
33
+ if ( s === '' ) { return; }
34
+ const pos = s.indexOf('-');
35
+ if ( pos !== 0 ) {
36
+ this.min = this.max = parseInt(s, 10) || 0;
37
+ }
38
+ if ( pos !== -1 ) {
39
+ this.max = parseInt(s.slice(1), 10) || Number.MAX_SAFE_INTEGER;
40
+ }
41
+ }
42
+ unbound() {
43
+ return this.min === undefined && this.max === undefined;
44
+ }
45
+ test(v) {
46
+ const n = Math.min(Math.max(Number(v) || 0, 0), Number.MAX_SAFE_INTEGER);
47
+ if ( this.min === this.max ) {
48
+ return (this.min === undefined || n === this.min) !== this.not;
49
+ }
50
+ if ( this.min === undefined ) {
51
+ return (n <= this.max) !== this.not;
52
+ }
53
+ if ( this.max === undefined ) {
54
+ return (n >= this.min) !== this.not;
55
+ }
56
+ return (n >= this.min && n <= this.max) !== this.not;
57
+ }
58
+ }
59
+ registerScriptlet(RangeParser, {
60
+ name: 'range-parser.fn',
61
+ });
62
+
63
+ /**
64
+ * @scriptlet prevent-setTimeout
65
+ *
66
+ * @description
67
+ * Conditionally prevent execution of the callback function passed to native
68
+ * setTimeout method. With no parameters, all calls to setTimeout will be
69
+ * shown in the logger.
70
+ *
71
+ * @param [needle]
72
+ * A pattern to match against the stringified callback. The pattern can be a
73
+ * plain string, or a regex. Prepend with `!` to reverse the match condition.
74
+ *
75
+ * @param [delay]
76
+ * A value to match against the delay. Can be a single value for exact match,
77
+ * or a range:
78
+ * - `min-max`: matches if delay >= min and delay <= max
79
+ * - `min-`: matches if delay >= min
80
+ * - `-max`: matches if delay <= max
81
+ * No delay means to match any delay value.
82
+ * Prepend with `!` to reverse the match condition.
83
+ *
84
+ * */
85
+
86
+ export function preventSetTimeout(
87
+ needleRaw = '',
88
+ delayRaw = ''
89
+ ) {
90
+ const safe = safeSelf();
91
+ const logPrefix = safe.makeLogPrefix('prevent-setTimeout', needleRaw, delayRaw);
92
+ const needleNot = needleRaw.charAt(0) === '!';
93
+ const reNeedle = safe.patternToRegex(needleNot ? needleRaw.slice(1) : needleRaw);
94
+ const range = new RangeParser(delayRaw);
95
+ proxyApplyFn('setTimeout', function(context) {
96
+ const { callArgs } = context;
97
+ const a = callArgs[0] instanceof Function
98
+ ? String(safe.Function_toString(callArgs[0]))
99
+ : String(callArgs[0]);
100
+ const b = callArgs[1];
101
+ if ( needleRaw === '' && range.unbound() ) {
102
+ safe.uboLog(logPrefix, `Called:\n${a}\n${b}`);
103
+ return context.reflect();
104
+ }
105
+ if ( reNeedle.test(a) !== needleNot && range.test(b) ) {
106
+ callArgs[0] = function(){};
107
+ safe.uboLog(logPrefix, `Prevented:\n${a}\n${b}`);
108
+ }
109
+ return context.reflect();
110
+ });
111
+ }
112
+ registerScriptlet(preventSetTimeout, {
113
+ name: 'prevent-setTimeout.js',
114
+ aliases: [
115
+ 'no-setTimeout-if.js',
116
+ 'nostif.js',
117
+ 'setTimeout-defuser.js',
118
+ ],
119
+ dependencies: [
120
+ proxyApplyFn,
121
+ RangeParser,
122
+ safeSelf,
123
+ ],
124
+ });
125
+
126
+ /**
127
+ * @scriptlet prevent-setInterval
128
+ *
129
+ * @description
130
+ * Conditionally prevent execution of the callback function passed to native
131
+ * setInterval method. With no parameters, all calls to setInterval will be
132
+ * shown in the logger.
133
+ *
134
+ * @param [needle]
135
+ * A pattern to match against the stringified callback. The pattern can be a
136
+ * plain string, or a regex. Prepend with `!` to reverse the match condition.
137
+ * No pattern means to match anything.
138
+ *
139
+ * @param [delay]
140
+ * A value to match against the delay. Can be a single value for exact match,
141
+ * or a range:
142
+ * - `min-max`: matches if delay >= min and delay <= max
143
+ * - `min-`: matches if delay >= min
144
+ * - `-max`: matches if delay <= max
145
+ * No delay means to match any delay value.
146
+ * Prepend with `!` to reverse the match condition.
147
+ *
148
+ * */
149
+
150
+ export function preventSetInterval(
151
+ needleRaw = '',
152
+ delayRaw = ''
153
+ ) {
154
+ const safe = safeSelf();
155
+ const logPrefix = safe.makeLogPrefix('prevent-setInterval', needleRaw, delayRaw);
156
+ const needleNot = needleRaw.charAt(0) === '!';
157
+ const reNeedle = safe.patternToRegex(needleNot ? needleRaw.slice(1) : needleRaw);
158
+ const range = new RangeParser(delayRaw);
159
+ proxyApplyFn('setInterval', function(context) {
160
+ const { callArgs } = context;
161
+ const a = callArgs[0] instanceof Function
162
+ ? String(safe.Function_toString(callArgs[0]))
163
+ : String(callArgs[0]);
164
+ const b = callArgs[1];
165
+ if ( needleRaw === '' && range.unbound() ) {
166
+ safe.uboLog(logPrefix, `Called:\n${a}\n${b}`);
167
+ return context.reflect();
168
+ }
169
+ if ( reNeedle.test(a) !== needleNot && range.test(b) ) {
170
+ callArgs[0] = function(){};
171
+ safe.uboLog(logPrefix, `Prevented:\n${a}\n${b}`);
172
+ }
173
+ return context.reflect();
174
+ });
175
+ }
176
+ registerScriptlet(preventSetInterval, {
177
+ name: 'prevent-setInterval.js',
178
+ aliases: [
179
+ 'no-setInterval-if.js',
180
+ 'nosiif.js',
181
+ 'setInterval-defuser.js',
182
+ ],
183
+ dependencies: [
184
+ proxyApplyFn,
185
+ RangeParser,
186
+ safeSelf,
187
+ ],
188
+ });
189
+
190
+ /**
191
+ * @scriptlet prevent-requestAnimationFrame
192
+ *
193
+ * @description
194
+ * Conditionally prevent execution of the callback function passed to native
195
+ * requestAnimationFrame method. With no parameters, all calls to
196
+ * requestAnimationFrame will be shown in the logger.
197
+ *
198
+ * @param [needle]
199
+ * A pattern to match against the stringified callback. The pattern can be a
200
+ * plain string, or a regex.
201
+ * Prepend with `!` to reverse the match condition.
202
+ *
203
+ * */
204
+
205
+ export function preventRequestAnimationFrame(
206
+ needleRaw = ''
207
+ ) {
208
+ const safe = safeSelf();
209
+ const logPrefix = safe.makeLogPrefix('prevent-requestAnimationFrame', needleRaw);
210
+ const needleNot = needleRaw.charAt(0) === '!';
211
+ const reNeedle = safe.patternToRegex(needleNot ? needleRaw.slice(1) : needleRaw);
212
+ proxyApplyFn('requestAnimationFrame', function(context) {
213
+ const { callArgs } = context;
214
+ const a = callArgs[0] instanceof Function
215
+ ? String(safe.Function_toString(callArgs[0]))
216
+ : String(callArgs[0]);
217
+ if ( needleRaw === '' ) {
218
+ safe.uboLog(logPrefix, `Called:\n${a}`);
219
+ } else if ( reNeedle.test(a) !== needleNot ) {
220
+ callArgs[0] = function(){};
221
+ safe.uboLog(logPrefix, `Prevented:\n${a}`);
222
+ }
223
+ return context.reflect();
224
+ });
225
+ }
226
+ registerScriptlet(preventRequestAnimationFrame, {
227
+ name: 'prevent-requestAnimationFrame.js',
228
+ aliases: [
229
+ 'no-requestAnimationFrame-if.js',
230
+ 'norafif.js',
231
+ ],
232
+ dependencies: [
233
+ proxyApplyFn,
234
+ safeSelf,
235
+ ],
236
+ });
@@ -0,0 +1,109 @@
1
+ /*******************************************************************************
2
+
3
+ uBlock Origin - a comprehensive, efficient content blocker
4
+ Copyright (C) 2019-present Raymond Hill
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program. If not, see {http://www.gnu.org/licenses/}.
18
+
19
+ Home: https://github.com/gorhill/uBlock
20
+
21
+ */
22
+
23
+ import { registerScriptlet } from './base.js';
24
+
25
+ /******************************************************************************/
26
+
27
+ export function proxyApplyFn(
28
+ target = '',
29
+ handler = ''
30
+ ) {
31
+ let context = globalThis;
32
+ let prop = target;
33
+ for (;;) {
34
+ const pos = prop.indexOf('.');
35
+ if ( pos === -1 ) { break; }
36
+ context = context[prop.slice(0, pos)];
37
+ if ( context instanceof Object === false ) { return; }
38
+ prop = prop.slice(pos+1);
39
+ }
40
+ const fn = context[prop];
41
+ if ( typeof fn !== 'function' ) { return; }
42
+ if ( proxyApplyFn.CtorContext === undefined ) {
43
+ proxyApplyFn.ctorContexts = [];
44
+ proxyApplyFn.CtorContext = class {
45
+ constructor(...args) {
46
+ this.init(...args);
47
+ }
48
+ init(callFn, callArgs) {
49
+ this.callFn = callFn;
50
+ this.callArgs = callArgs;
51
+ return this;
52
+ }
53
+ reflect() {
54
+ const r = Reflect.construct(this.callFn, this.callArgs);
55
+ this.callFn = this.callArgs = this.private = undefined;
56
+ proxyApplyFn.ctorContexts.push(this);
57
+ return r;
58
+ }
59
+ static factory(...args) {
60
+ return proxyApplyFn.ctorContexts.length !== 0
61
+ ? proxyApplyFn.ctorContexts.pop().init(...args)
62
+ : new proxyApplyFn.CtorContext(...args);
63
+ }
64
+ };
65
+ proxyApplyFn.applyContexts = [];
66
+ proxyApplyFn.ApplyContext = class {
67
+ constructor(...args) {
68
+ this.init(...args);
69
+ }
70
+ init(callFn, thisArg, callArgs) {
71
+ this.callFn = callFn;
72
+ this.thisArg = thisArg;
73
+ this.callArgs = callArgs;
74
+ return this;
75
+ }
76
+ reflect() {
77
+ const r = Reflect.apply(this.callFn, this.thisArg, this.callArgs);
78
+ this.callFn = this.thisArg = this.callArgs = this.private = undefined;
79
+ proxyApplyFn.applyContexts.push(this);
80
+ return r;
81
+ }
82
+ static factory(...args) {
83
+ return proxyApplyFn.applyContexts.length !== 0
84
+ ? proxyApplyFn.applyContexts.pop().init(...args)
85
+ : new proxyApplyFn.ApplyContext(...args);
86
+ }
87
+ };
88
+ }
89
+ const fnStr = fn.toString();
90
+ const toString = (function toString() { return fnStr; }).bind(null);
91
+ const proxyDetails = {
92
+ apply(target, thisArg, args) {
93
+ return handler(proxyApplyFn.ApplyContext.factory(target, thisArg, args));
94
+ },
95
+ get(target, prop) {
96
+ if ( prop === 'toString' ) { return toString; }
97
+ return Reflect.get(target, prop);
98
+ },
99
+ };
100
+ if ( fn.prototype?.constructor === fn ) {
101
+ proxyDetails.construct = function(target, args) {
102
+ return handler(proxyApplyFn.CtorContext.factory(target, args));
103
+ };
104
+ }
105
+ context[prop] = new Proxy(fn, proxyDetails);
106
+ }
107
+ registerScriptlet(proxyApplyFn, {
108
+ name: 'proxy-apply.fn',
109
+ });
@@ -0,0 +1,120 @@
1
+ /*******************************************************************************
2
+
3
+ uBlock Origin - a comprehensive, efficient content blocker
4
+ Copyright (C) 2019-present Raymond Hill
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program. If not, see {http://www.gnu.org/licenses/}.
18
+
19
+ Home: https://github.com/gorhill/uBlock
20
+
21
+ */
22
+
23
+ import { parseReplaceFn } from './parse-replace.js';
24
+ import { proxyApplyFn } from './proxy-apply.js';
25
+ import { registerScriptlet } from './base.js';
26
+ import { safeSelf } from './safe-self.js';
27
+ import { validateConstantFn } from './set-constant.js';
28
+
29
+ /**
30
+ * @scriptlet trusted-replace-argument.js
31
+ *
32
+ * @description
33
+ * Replace an argument passed to a method. Requires a trusted source.
34
+ *
35
+ * @param propChain
36
+ * The property chain to the function which argument must be replaced when
37
+ * called.
38
+ *
39
+ * @param argposRaw
40
+ * The zero-based position of the argument in the argument list. Use a negative
41
+ * number for a position relative to the last argument. Use literal `this` to
42
+ * replace the value used in `prototype`-based methods.
43
+ *
44
+ * @param argraw
45
+ * The replacement value, validated using the same heuristic as with the
46
+ * `set-constant.js` scriptlet.
47
+ * If the replacement value matches `json:...`, the value will be the
48
+ * json-parsed string after `json:`.
49
+ * If the replacement value matches `repl:/.../.../`, the target argument will
50
+ * be replaced according the regex-replacement directive following `repl:`
51
+ *
52
+ * @param [, condition, pattern]
53
+ * Optional. The replacement will occur only when pattern matches the target
54
+ * argument.
55
+ *
56
+ * */
57
+
58
+ export function trustedReplaceArgument(
59
+ propChain = '',
60
+ argposRaw = '',
61
+ argraw = ''
62
+ ) {
63
+ if ( propChain === '' ) { return; }
64
+ const safe = safeSelf();
65
+ const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argposRaw, argraw);
66
+ const argoffset = parseInt(argposRaw, 10) || 0;
67
+ const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
68
+ const replacer = argraw.startsWith('repl:/') &&
69
+ parseReplaceFn(argraw.slice(5)) || undefined;
70
+ const value = replacer === undefined &&
71
+ validateConstantFn(true, argraw, extraArgs) || undefined;
72
+ const reCondition = extraArgs.condition
73
+ ? safe.patternToRegex(extraArgs.condition)
74
+ : /^/;
75
+ const getArg = context => {
76
+ if ( argposRaw === 'this' ) { return context.thisArg; }
77
+ const { callArgs } = context;
78
+ const argpos = argoffset >= 0 ? argoffset : callArgs.length - argoffset;
79
+ if ( argpos < 0 || argpos >= callArgs.length ) { return; }
80
+ context.private = { argpos };
81
+ return callArgs[argpos];
82
+ };
83
+ const setArg = (context, value) => {
84
+ if ( argposRaw === 'this' ) {
85
+ if ( value !== context.thisArg ) {
86
+ context.thisArg = value;
87
+ }
88
+ } else if ( context.private ) {
89
+ context.callArgs[context.private.argpos] = value;
90
+ }
91
+ };
92
+ proxyApplyFn(propChain, function(context) {
93
+ if ( argposRaw === '' ) {
94
+ safe.uboLog(logPrefix, `Arguments:\n${context.callArgs.join('\n')}`);
95
+ return context.reflect();
96
+ }
97
+ const argBefore = getArg(context);
98
+ if ( safe.RegExp_test.call(reCondition, argBefore) === false ) {
99
+ return context.reflect();
100
+ }
101
+ const argAfter = replacer && typeof argBefore === 'string'
102
+ ? argBefore.replace(replacer.re, replacer.replacement)
103
+ : value;
104
+ if ( argAfter !== argBefore ) {
105
+ setArg(context, argAfter);
106
+ safe.uboLog(logPrefix, `Replaced argument:\nBefore: ${JSON.stringify(argBefore)}\nAfter: ${argAfter}`);
107
+ }
108
+ return context.reflect();
109
+ });
110
+ }
111
+ registerScriptlet(trustedReplaceArgument, {
112
+ name: 'trusted-replace-argument.js',
113
+ requiresTrust: true,
114
+ dependencies: [
115
+ parseReplaceFn,
116
+ proxyApplyFn,
117
+ safeSelf,
118
+ validateConstantFn,
119
+ ],
120
+ });
@@ -18,10 +18,9 @@
18
18
 
19
19
  Home: https://github.com/gorhill/uBlock
20
20
 
21
- The scriptlets below are meant to be injected only into a
22
- web page context.
23
21
  */
24
22
 
23
+ import { registerScriptlet } from './base.js';
25
24
  import { safeSelf } from './safe-self.js';
26
25
 
27
26
  /* eslint no-prototype-builtins: 0 */
@@ -72,9 +71,26 @@ export function runAt(fn, when) {
72
71
  const args = [ 'readystatechange', onStateChange, { capture: true } ];
73
72
  safe.addEventListener.apply(document, args);
74
73
  }
75
- runAt.details = {
74
+ registerScriptlet(runAt, {
76
75
  name: 'run-at.fn',
77
76
  dependencies: [
78
77
  safeSelf,
79
78
  ],
80
- };
79
+ });
80
+
81
+ /******************************************************************************/
82
+
83
+ export function runAtHtmlElementFn(fn) {
84
+ if ( document.documentElement ) {
85
+ fn();
86
+ return;
87
+ }
88
+ const observer = new MutationObserver(( ) => {
89
+ observer.disconnect();
90
+ fn();
91
+ });
92
+ observer.observe(document, { childList: true });
93
+ }
94
+ registerScriptlet(runAtHtmlElementFn, {
95
+ name: 'run-at-html-element.fn',
96
+ });
@@ -18,10 +18,10 @@
18
18
 
19
19
  Home: https://github.com/gorhill/uBlock
20
20
 
21
- The scriptlets below are meant to be injected only into a
22
- web page context.
23
21
  */
24
22
 
23
+ import { registerScriptlet } from './base.js';
24
+
25
25
  /******************************************************************************/
26
26
 
27
27
  // Externally added to the private namespace in which scriptlets execute.
@@ -51,6 +51,7 @@ export function safeSelf() {
51
51
  'RegExp_exec': self.RegExp.prototype.exec,
52
52
  'Request_clone': self.Request.prototype.clone,
53
53
  'String_fromCharCode': String.fromCharCode,
54
+ 'String_split': String.prototype.split,
54
55
  'XMLHttpRequest': self.XMLHttpRequest,
55
56
  'addEventListener': self.EventTarget.prototype.addEventListener,
56
57
  'removeEventListener': self.EventTarget.prototype.removeEventListener,
@@ -213,6 +214,6 @@ export function safeSelf() {
213
214
  }
214
215
  return safe;
215
216
  }
216
- safeSelf.details = {
217
+ registerScriptlet(safeSelf, {
217
218
  name: 'safe-self.fn',
218
- };
219
+ });