@browserless.io/browserless 2.24.0 → 2.24.2

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 (81) hide show
  1. package/CHANGELOG.md +16 -3
  2. package/build/browsers/index.js +1 -1
  3. package/build/routes/chrome/http/content.post.body.json +8 -8
  4. package/build/routes/chrome/http/pdf.post.body.json +8 -8
  5. package/build/routes/chrome/http/scrape.post.body.json +8 -8
  6. package/build/routes/chrome/http/screenshot.post.body.json +8 -8
  7. package/build/routes/chromium/http/content.post.body.json +8 -8
  8. package/build/routes/chromium/http/pdf.post.body.json +8 -8
  9. package/build/routes/chromium/http/scrape.post.body.json +8 -8
  10. package/build/routes/chromium/http/screenshot.post.body.json +8 -8
  11. package/build/routes/management/http/meta.get.js +3 -1
  12. package/build/shared/utils/performance/main.js +2 -1
  13. package/extensions/ublock/_locales/ar/messages.json +3 -3
  14. package/extensions/ublock/_locales/bg/messages.json +1 -1
  15. package/extensions/ublock/_locales/br_FR/messages.json +2 -2
  16. package/extensions/ublock/_locales/cy/messages.json +11 -11
  17. package/extensions/ublock/_locales/el/messages.json +2 -2
  18. package/extensions/ublock/_locales/hu/messages.json +1 -1
  19. package/extensions/ublock/_locales/id/messages.json +1 -1
  20. package/extensions/ublock/_locales/lv/messages.json +4 -4
  21. package/extensions/ublock/_locales/mk/messages.json +130 -130
  22. package/extensions/ublock/_locales/oc/messages.json +1 -1
  23. package/extensions/ublock/_locales/pt_BR/messages.json +1 -1
  24. package/extensions/ublock/_locales/pt_PT/messages.json +2 -2
  25. package/extensions/ublock/_locales/si/messages.json +100 -100
  26. package/extensions/ublock/_locales/sr/messages.json +4 -4
  27. package/extensions/ublock/_locales/vi/messages.json +19 -19
  28. package/extensions/ublock/_locales/zh_TW/messages.json +28 -28
  29. package/extensions/ublock/assets/assets.json +33 -29
  30. package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +2984 -3287
  31. package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +150 -171
  32. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +37 -27
  33. package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +802 -888
  34. package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +2355 -2071
  35. package/extensions/ublock/assets/ublock/badlists.txt +9 -1
  36. package/extensions/ublock/assets/ublock/badware.min.txt +354 -243
  37. package/extensions/ublock/assets/ublock/filters.min.txt +5837 -5737
  38. package/extensions/ublock/assets/ublock/privacy.min.txt +151 -38
  39. package/extensions/ublock/assets/ublock/quick-fixes.min.txt +83 -127
  40. package/extensions/ublock/assets/ublock/unbreak.min.txt +66 -50
  41. package/extensions/ublock/css/codemirror.css +4 -0
  42. package/extensions/ublock/document-blocked.html +3 -1
  43. package/extensions/ublock/js/arglist-parser.js +116 -0
  44. package/extensions/ublock/js/background.js +1 -1
  45. package/extensions/ublock/js/logger-ui.js +1 -1
  46. package/extensions/ublock/js/messaging.js +9 -2
  47. package/extensions/ublock/js/pagestore.js +3 -1
  48. package/extensions/ublock/js/redirect-engine.js +3 -1
  49. package/extensions/ublock/{assets/resources/set-attr.js → js/resources/attribute.js} +115 -11
  50. package/extensions/ublock/js/resources/base.js +38 -0
  51. package/extensions/ublock/js/resources/cookie.js +419 -0
  52. package/extensions/ublock/js/resources/href-sanitizer.js +188 -0
  53. package/extensions/ublock/js/resources/localstorage.js +235 -0
  54. package/extensions/ublock/js/resources/parse-replace.js +54 -0
  55. package/extensions/ublock/js/resources/prevent-settimeout.js +236 -0
  56. package/extensions/ublock/js/resources/proxy-apply.js +109 -0
  57. package/extensions/ublock/js/resources/replace-argument.js +120 -0
  58. package/extensions/ublock/{assets → js}/resources/run-at.js +20 -4
  59. package/extensions/ublock/{assets → js}/resources/safe-self.js +5 -4
  60. package/extensions/ublock/{assets → js}/resources/scriptlets.js +90 -1589
  61. package/extensions/ublock/js/resources/set-constant.js +287 -0
  62. package/extensions/ublock/js/resources/shared.js +44 -0
  63. package/extensions/ublock/js/resources/spoof-css.js +163 -0
  64. package/extensions/ublock/js/s14e-serializer.js +2 -1
  65. package/extensions/ublock/js/scriptlet-filtering-core.js +1 -1
  66. package/extensions/ublock/js/scriptlet-filtering.js +1 -31
  67. package/extensions/ublock/js/static-dnr-filtering.js +143 -129
  68. package/extensions/ublock/js/static-filtering-parser.js +27 -117
  69. package/extensions/ublock/js/static-net-filtering.js +53 -141
  70. package/extensions/ublock/js/traffic.js +1 -1
  71. package/extensions/ublock/js/urlskip.js +166 -0
  72. package/extensions/ublock/js/vapi-background-ext.js +38 -14
  73. package/extensions/ublock/manifest.json +1 -1
  74. package/package.json +11 -11
  75. package/src/browsers/index.ts +1 -1
  76. package/src/routes/management/http/meta.get.ts +6 -1
  77. package/src/shared/utils/performance/main.ts +2 -8
  78. package/static/docs/swagger.json +10 -10
  79. package/static/docs/swagger.min.json +9 -9
  80. package/static/function/client.js +119 -18
  81. package/static/function/index.html +119 -18
@@ -0,0 +1,287 @@
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
+ import { runAt } from './run-at.js';
25
+ import { safeSelf } from './safe-self.js';
26
+
27
+ /******************************************************************************/
28
+
29
+ export function validateConstantFn(trusted, raw, extraArgs = {}) {
30
+ const safe = safeSelf();
31
+ let value;
32
+ if ( raw === 'undefined' ) {
33
+ value = undefined;
34
+ } else if ( raw === 'false' ) {
35
+ value = false;
36
+ } else if ( raw === 'true' ) {
37
+ value = true;
38
+ } else if ( raw === 'null' ) {
39
+ value = null;
40
+ } else if ( raw === "''" || raw === '' ) {
41
+ value = '';
42
+ } else if ( raw === '[]' || raw === 'emptyArr' ) {
43
+ value = [];
44
+ } else if ( raw === '{}' || raw === 'emptyObj' ) {
45
+ value = {};
46
+ } else if ( raw === 'noopFunc' ) {
47
+ value = function(){};
48
+ } else if ( raw === 'trueFunc' ) {
49
+ value = function(){ return true; };
50
+ } else if ( raw === 'falseFunc' ) {
51
+ value = function(){ return false; };
52
+ } else if ( raw === 'throwFunc' ) {
53
+ value = function(){ throw ''; };
54
+ } else if ( /^-?\d+$/.test(raw) ) {
55
+ value = parseInt(raw);
56
+ if ( isNaN(raw) ) { return; }
57
+ if ( Math.abs(raw) > 0x7FFF ) { return; }
58
+ } else if ( trusted ) {
59
+ if ( raw.startsWith('json:') ) {
60
+ try { value = safe.JSON_parse(raw.slice(5)); } catch(ex) { return; }
61
+ } else if ( raw.startsWith('{') && raw.endsWith('}') ) {
62
+ try { value = safe.JSON_parse(raw).value; } catch(ex) { return; }
63
+ }
64
+ } else {
65
+ return;
66
+ }
67
+ if ( extraArgs.as !== undefined ) {
68
+ if ( extraArgs.as === 'function' ) {
69
+ return ( ) => value;
70
+ } else if ( extraArgs.as === 'callback' ) {
71
+ return ( ) => (( ) => value);
72
+ } else if ( extraArgs.as === 'resolved' ) {
73
+ return Promise.resolve(value);
74
+ } else if ( extraArgs.as === 'rejected' ) {
75
+ return Promise.reject(value);
76
+ }
77
+ }
78
+ return value;
79
+ }
80
+ registerScriptlet(validateConstantFn, {
81
+ name: 'validate-constant.fn',
82
+ dependencies: [
83
+ safeSelf,
84
+ ],
85
+ });
86
+
87
+ /******************************************************************************/
88
+
89
+ export function setConstantFn(
90
+ trusted = false,
91
+ chain = '',
92
+ rawValue = ''
93
+ ) {
94
+ if ( chain === '' ) { return; }
95
+ const safe = safeSelf();
96
+ const logPrefix = safe.makeLogPrefix('set-constant', chain, rawValue);
97
+ const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
98
+ function setConstant(chain, rawValue) {
99
+ const trappedProp = (( ) => {
100
+ const pos = chain.lastIndexOf('.');
101
+ if ( pos === -1 ) { return chain; }
102
+ return chain.slice(pos+1);
103
+ })();
104
+ const cloakFunc = fn => {
105
+ safe.Object_defineProperty(fn, 'name', { value: trappedProp });
106
+ return new Proxy(fn, {
107
+ defineProperty(target, prop) {
108
+ if ( prop !== 'toString' ) {
109
+ return Reflect.defineProperty(...arguments);
110
+ }
111
+ return true;
112
+ },
113
+ deleteProperty(target, prop) {
114
+ if ( prop !== 'toString' ) {
115
+ return Reflect.deleteProperty(...arguments);
116
+ }
117
+ return true;
118
+ },
119
+ get(target, prop) {
120
+ if ( prop === 'toString' ) {
121
+ return function() {
122
+ return `function ${trappedProp}() { [native code] }`;
123
+ }.bind(null);
124
+ }
125
+ return Reflect.get(...arguments);
126
+ },
127
+ });
128
+ };
129
+ if ( trappedProp === '' ) { return; }
130
+ const thisScript = document.currentScript;
131
+ let normalValue = validateConstantFn(trusted, rawValue, extraArgs);
132
+ if ( rawValue === 'noopFunc' || rawValue === 'trueFunc' || rawValue === 'falseFunc' ) {
133
+ normalValue = cloakFunc(normalValue);
134
+ }
135
+ let aborted = false;
136
+ const mustAbort = function(v) {
137
+ if ( trusted ) { return false; }
138
+ if ( aborted ) { return true; }
139
+ aborted =
140
+ (v !== undefined && v !== null) &&
141
+ (normalValue !== undefined && normalValue !== null) &&
142
+ (typeof v !== typeof normalValue);
143
+ if ( aborted ) {
144
+ safe.uboLog(logPrefix, `Aborted because value set to ${v}`);
145
+ }
146
+ return aborted;
147
+ };
148
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/156
149
+ // Support multiple trappers for the same property.
150
+ const trapProp = function(owner, prop, configurable, handler) {
151
+ if ( handler.init(configurable ? owner[prop] : normalValue) === false ) { return; }
152
+ const odesc = safe.Object_getOwnPropertyDescriptor(owner, prop);
153
+ let prevGetter, prevSetter;
154
+ if ( odesc instanceof safe.Object ) {
155
+ owner[prop] = normalValue;
156
+ if ( odesc.get instanceof Function ) {
157
+ prevGetter = odesc.get;
158
+ }
159
+ if ( odesc.set instanceof Function ) {
160
+ prevSetter = odesc.set;
161
+ }
162
+ }
163
+ try {
164
+ safe.Object_defineProperty(owner, prop, {
165
+ configurable,
166
+ get() {
167
+ if ( prevGetter !== undefined ) {
168
+ prevGetter();
169
+ }
170
+ return handler.getter();
171
+ },
172
+ set(a) {
173
+ if ( prevSetter !== undefined ) {
174
+ prevSetter(a);
175
+ }
176
+ handler.setter(a);
177
+ }
178
+ });
179
+ safe.uboLog(logPrefix, 'Trap installed');
180
+ } catch(ex) {
181
+ safe.uboErr(logPrefix, ex);
182
+ }
183
+ };
184
+ const trapChain = function(owner, chain) {
185
+ const pos = chain.indexOf('.');
186
+ if ( pos === -1 ) {
187
+ trapProp(owner, chain, false, {
188
+ v: undefined,
189
+ init: function(v) {
190
+ if ( mustAbort(v) ) { return false; }
191
+ this.v = v;
192
+ return true;
193
+ },
194
+ getter: function() {
195
+ if ( document.currentScript === thisScript ) {
196
+ return this.v;
197
+ }
198
+ safe.uboLog(logPrefix, 'Property read');
199
+ return normalValue;
200
+ },
201
+ setter: function(a) {
202
+ if ( mustAbort(a) === false ) { return; }
203
+ normalValue = a;
204
+ }
205
+ });
206
+ return;
207
+ }
208
+ const prop = chain.slice(0, pos);
209
+ const v = owner[prop];
210
+ chain = chain.slice(pos + 1);
211
+ if ( v instanceof safe.Object || typeof v === 'object' && v !== null ) {
212
+ trapChain(v, chain);
213
+ return;
214
+ }
215
+ trapProp(owner, prop, true, {
216
+ v: undefined,
217
+ init: function(v) {
218
+ this.v = v;
219
+ return true;
220
+ },
221
+ getter: function() {
222
+ return this.v;
223
+ },
224
+ setter: function(a) {
225
+ this.v = a;
226
+ if ( a instanceof safe.Object ) {
227
+ trapChain(a, chain);
228
+ }
229
+ }
230
+ });
231
+ };
232
+ trapChain(window, chain);
233
+ }
234
+ runAt(( ) => {
235
+ setConstant(chain, rawValue);
236
+ }, extraArgs.runAt);
237
+ }
238
+ registerScriptlet(setConstantFn, {
239
+ name: 'set-constant.fn',
240
+ dependencies: [
241
+ runAt,
242
+ safeSelf,
243
+ validateConstantFn,
244
+ ],
245
+ });
246
+
247
+ /******************************************************************************/
248
+
249
+ export function setConstant(
250
+ ...args
251
+ ) {
252
+ setConstantFn(false, ...args);
253
+ }
254
+ registerScriptlet(setConstant, {
255
+ name: 'set-constant.js',
256
+ aliases: [
257
+ 'set.js',
258
+ ],
259
+ dependencies: [
260
+ setConstantFn,
261
+ ],
262
+ });
263
+
264
+ /*******************************************************************************
265
+ *
266
+ * trusted-set-constant.js
267
+ *
268
+ * Set specified property to any value. This is essentially the same as
269
+ * set-constant.js, but with no restriction as to which values can be used.
270
+ *
271
+ **/
272
+
273
+ export function trustedSetConstant(
274
+ ...args
275
+ ) {
276
+ setConstantFn(true, ...args);
277
+ }
278
+ registerScriptlet(trustedSetConstant, {
279
+ name: 'trusted-set-constant.js',
280
+ requiresTrust: true,
281
+ aliases: [
282
+ 'trusted-set.js',
283
+ ],
284
+ dependencies: [
285
+ setConstantFn,
286
+ ],
287
+ });
@@ -0,0 +1,44 @@
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
+ // Code imported from main code base and exposed as injectable scriptlets
24
+ import { ArglistParser } from '../arglist-parser.js';
25
+
26
+ import { registerScriptlet } from './base.js';
27
+
28
+ /******************************************************************************/
29
+
30
+ registerScriptlet(ArglistParser, {
31
+ name: 'arglist-parser.fn',
32
+ });
33
+
34
+ /******************************************************************************/
35
+
36
+ export function createArglistParser(...args) {
37
+ return new ArglistParser(...args);
38
+ }
39
+ registerScriptlet(createArglistParser, {
40
+ name: 'create-arglist-parser.fn',
41
+ dependencies: [
42
+ ArglistParser,
43
+ ],
44
+ });
@@ -0,0 +1,163 @@
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
+ import { safeSelf } from './safe-self.js';
25
+
26
+ /**
27
+ * @scriptlet spoof-css.js
28
+ *
29
+ * @description
30
+ * Spoof the value of CSS properties.
31
+ *
32
+ * @param selector
33
+ * A CSS selector for the element(s) to target.
34
+ *
35
+ * @param [property, value, ...]
36
+ * A list of property-value pairs of the style properties to spoof to the
37
+ * specified values.
38
+ *
39
+ * */
40
+
41
+ export function spoofCSS(
42
+ selector,
43
+ ...args
44
+ ) {
45
+ if ( typeof selector !== 'string' ) { return; }
46
+ if ( selector === '' ) { return; }
47
+ const toCamelCase = s => s.replace(/-[a-z]/g, s => s.charAt(1).toUpperCase());
48
+ const propToValueMap = new Map();
49
+ const privatePropToValueMap = new Map();
50
+ for ( let i = 0; i < args.length; i += 2 ) {
51
+ const prop = toCamelCase(args[i+0]);
52
+ if ( prop === '' ) { break; }
53
+ const value = args[i+1];
54
+ if ( typeof value !== 'string' ) { break; }
55
+ if ( prop.charCodeAt(0) === 0x5F /* _ */ ) {
56
+ privatePropToValueMap.set(prop, value);
57
+ } else {
58
+ propToValueMap.set(prop, value);
59
+ }
60
+ }
61
+ const safe = safeSelf();
62
+ const logPrefix = safe.makeLogPrefix('spoof-css', selector, ...args);
63
+ const instanceProperties = [ 'cssText', 'length', 'parentRule' ];
64
+ const spoofStyle = (prop, real) => {
65
+ const normalProp = toCamelCase(prop);
66
+ const shouldSpoof = propToValueMap.has(normalProp);
67
+ const value = shouldSpoof ? propToValueMap.get(normalProp) : real;
68
+ if ( shouldSpoof ) {
69
+ safe.uboLog(logPrefix, `Spoofing ${prop} to ${value}`);
70
+ }
71
+ return value;
72
+ };
73
+ const cloackFunc = (fn, thisArg, name) => {
74
+ const trap = fn.bind(thisArg);
75
+ Object.defineProperty(trap, 'name', { value: name });
76
+ Object.defineProperty(trap, 'toString', {
77
+ value: ( ) => `function ${name}() { [native code] }`
78
+ });
79
+ return trap;
80
+ };
81
+ self.getComputedStyle = new Proxy(self.getComputedStyle, {
82
+ apply: function(target, thisArg, args) {
83
+ // eslint-disable-next-line no-debugger
84
+ if ( privatePropToValueMap.has('_debug') ) { debugger; }
85
+ const style = Reflect.apply(target, thisArg, args);
86
+ const targetElements = new WeakSet(document.querySelectorAll(selector));
87
+ if ( targetElements.has(args[0]) === false ) { return style; }
88
+ const proxiedStyle = new Proxy(style, {
89
+ get(target, prop) {
90
+ if ( typeof target[prop] === 'function' ) {
91
+ if ( prop === 'getPropertyValue' ) {
92
+ return cloackFunc(function getPropertyValue(prop) {
93
+ return spoofStyle(prop, target[prop]);
94
+ }, target, 'getPropertyValue');
95
+ }
96
+ return cloackFunc(target[prop], target, prop);
97
+ }
98
+ if ( instanceProperties.includes(prop) ) {
99
+ return Reflect.get(target, prop);
100
+ }
101
+ return spoofStyle(prop, Reflect.get(target, prop));
102
+ },
103
+ getOwnPropertyDescriptor(target, prop) {
104
+ if ( propToValueMap.has(prop) ) {
105
+ return {
106
+ configurable: true,
107
+ enumerable: true,
108
+ value: propToValueMap.get(prop),
109
+ writable: true,
110
+ };
111
+ }
112
+ return Reflect.getOwnPropertyDescriptor(target, prop);
113
+ },
114
+ });
115
+ return proxiedStyle;
116
+ },
117
+ get(target, prop) {
118
+ if ( prop === 'toString' ) {
119
+ return target.toString.bind(target);
120
+ }
121
+ return Reflect.get(target, prop);
122
+ },
123
+ });
124
+ Element.prototype.getBoundingClientRect = new Proxy(Element.prototype.getBoundingClientRect, {
125
+ apply: function(target, thisArg, args) {
126
+ // eslint-disable-next-line no-debugger
127
+ if ( privatePropToValueMap.has('_debug') ) { debugger; }
128
+ const rect = Reflect.apply(target, thisArg, args);
129
+ const targetElements = new WeakSet(document.querySelectorAll(selector));
130
+ if ( targetElements.has(thisArg) === false ) { return rect; }
131
+ let { x, y, height, width } = rect;
132
+ if ( privatePropToValueMap.has('_rectx') ) {
133
+ x = parseFloat(privatePropToValueMap.get('_rectx'));
134
+ }
135
+ if ( privatePropToValueMap.has('_recty') ) {
136
+ y = parseFloat(privatePropToValueMap.get('_recty'));
137
+ }
138
+ if ( privatePropToValueMap.has('_rectw') ) {
139
+ width = parseFloat(privatePropToValueMap.get('_rectw'));
140
+ } else if ( propToValueMap.has('width') ) {
141
+ width = parseFloat(propToValueMap.get('width'));
142
+ }
143
+ if ( privatePropToValueMap.has('_recth') ) {
144
+ height = parseFloat(privatePropToValueMap.get('_recth'));
145
+ } else if ( propToValueMap.has('height') ) {
146
+ height = parseFloat(propToValueMap.get('height'));
147
+ }
148
+ return new self.DOMRect(x, y, width, height);
149
+ },
150
+ get(target, prop) {
151
+ if ( prop === 'toString' ) {
152
+ return target.toString.bind(target);
153
+ }
154
+ return Reflect.get(target, prop);
155
+ },
156
+ });
157
+ }
158
+ registerScriptlet(spoofCSS, {
159
+ name: 'spoof-css.js',
160
+ dependencies: [
161
+ safeSelf,
162
+ ],
163
+ });
@@ -851,10 +851,11 @@ const _deserialize = ( ) => {
851
851
  case I_DATAVIEW: {
852
852
  const byteOffset = deserializeLargeUint();
853
853
  const length = deserializeLargeUint();
854
+ const ref = refCounter++;
854
855
  const arrayBuffer = _deserialize();
855
856
  const ctor = toArrayBufferViewConstructor[`${type}`];
856
857
  const out = new ctor(arrayBuffer, byteOffset, length);
857
- readRefs.set(refCounter++, out);
858
+ readRefs.set(ref, out);
858
859
  return out;
859
860
  }
860
861
  default:
@@ -99,7 +99,7 @@ const patchScriptlet = (content, arglist) => {
99
99
  };
100
100
 
101
101
  const requote = s => {
102
- if ( /^(["'`]).+\1$|,/.test(s) === false ) { return s; }
102
+ if ( /^(["'`]).*\1$|,|^$/.test(s) === false ) { return s; }
103
103
  if ( s.includes("'") === false ) { return `'${s}'`; }
104
104
  if ( s.includes('"') === false ) { return `"${s}"`; }
105
105
  if ( s.includes('`') === false ) { return `\`${s}\``; }
@@ -106,36 +106,6 @@ const contentScriptRegisterer = new (class {
106
106
 
107
107
  /******************************************************************************/
108
108
 
109
- const mainWorldInjector = (( ) => {
110
- const parts = [
111
- '(',
112
- function(injector, details) {
113
- if ( typeof self.uBO_scriptletsInjected === 'string' ) { return; }
114
- const doc = document;
115
- if ( doc.location === null ) { return; }
116
- const hostname = doc.location.hostname;
117
- if ( hostname !== '' && details.hostname !== hostname ) { return; }
118
- injector(doc, details);
119
- return 0;
120
- }.toString(),
121
- ')(',
122
- vAPI.scriptletsInjector, ', ',
123
- 'json-slot',
124
- ');',
125
- ];
126
- const jsonSlot = parts.indexOf('json-slot');
127
- return {
128
- assemble: function(hostname, details) {
129
- parts[jsonSlot] = JSON.stringify({
130
- hostname,
131
- scriptlets: details.mainWorld,
132
- filters: details.filters,
133
- });
134
- return parts.join('');
135
- },
136
- };
137
- })();
138
-
139
109
  const isolatedWorldInjector = (( ) => {
140
110
  const parts = [
141
111
  '(',
@@ -334,7 +304,7 @@ export class ScriptletFilteringEngineEx extends ScriptletFilteringEngine {
334
304
 
335
305
  const contentScript = [];
336
306
  if ( scriptletDetails.mainWorld ) {
337
- contentScript.push(mainWorldInjector.assemble(hostname, scriptletDetails));
307
+ contentScript.push(vAPI.scriptletsInjector(hostname, scriptletDetails));
338
308
  }
339
309
  if ( scriptletDetails.isolatedWorld ) {
340
310
  contentScript.push(isolatedWorldInjector.assemble(hostname, scriptletDetails));