@browserless.io/browserless 2.32.0-beta-1 → 2.32.0

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 (165) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/build/routes/chrome/http/content.post.body.json +8 -8
  3. package/build/routes/chrome/http/pdf.post.body.json +8 -8
  4. package/build/routes/chrome/http/scrape.post.body.json +8 -8
  5. package/build/routes/chrome/http/screenshot.post.body.json +8 -8
  6. package/build/routes/chromium/http/content.post.body.json +8 -8
  7. package/build/routes/chromium/http/pdf.post.body.json +8 -8
  8. package/build/routes/chromium/http/scrape.post.body.json +8 -8
  9. package/build/routes/chromium/http/screenshot.post.body.json +8 -8
  10. package/build/routes/edge/http/content.post.body.json +8 -8
  11. package/build/routes/edge/http/pdf.post.body.json +8 -8
  12. package/build/routes/edge/http/scrape.post.body.json +8 -8
  13. package/build/routes/edge/http/screenshot.post.body.json +8 -8
  14. package/extensions/ublocklite/_locales/be/messages.json +9 -9
  15. package/extensions/ublocklite/_locales/cs/messages.json +7 -7
  16. package/extensions/ublocklite/_locales/hi/messages.json +1 -1
  17. package/extensions/ublocklite/_locales/ko/messages.json +7 -7
  18. package/extensions/ublocklite/_locales/vi/messages.json +8 -8
  19. package/extensions/ublocklite/_locales/zh_TW/messages.json +7 -7
  20. package/extensions/ublocklite/css/develop.css +1 -2
  21. package/extensions/ublocklite/js/arglist-parser.js +116 -0
  22. package/extensions/ublocklite/js/develop.js +18 -11
  23. package/extensions/ublocklite/js/jsonpath.js +470 -0
  24. package/extensions/ublocklite/js/redirect-resources.js +192 -0
  25. package/extensions/ublocklite/js/rw-dnr-editor.js +17 -3
  26. package/extensions/ublocklite/js/static-filtering-parser.js +4413 -0
  27. package/extensions/ublocklite/js/ubo-parser.js +461 -0
  28. package/extensions/ublocklite/lib/codemirror/cm6.bundle.ubol.min.js +1 -1
  29. package/extensions/ublocklite/lib/csstree/LICENSE +19 -0
  30. package/extensions/ublocklite/lib/csstree/css-tree.js +17 -0
  31. package/extensions/ublocklite/manifest.json +1 -1
  32. package/extensions/ublocklite/rulesets/generic-details.json +3 -8
  33. package/extensions/ublocklite/rulesets/main/annoyances-cookies.json +7 -5
  34. package/extensions/ublocklite/rulesets/main/annoyances-others.json +2 -1
  35. package/extensions/ublocklite/rulesets/main/chn-0.json +11 -7
  36. package/extensions/ublocklite/rulesets/main/deu-0.json +0 -3
  37. package/extensions/ublocklite/rulesets/main/easylist.json +13 -9
  38. package/extensions/ublocklite/rulesets/main/easyprivacy.json +17 -4
  39. package/extensions/ublocklite/rulesets/main/fra-0.json +4 -6
  40. package/extensions/ublocklite/rulesets/main/idn-0.json +1 -1
  41. package/extensions/ublocklite/rulesets/main/ind-0.json +13 -6
  42. package/extensions/ublocklite/rulesets/main/nld-0.json +1 -0
  43. package/extensions/ublocklite/rulesets/main/pgl.json +2 -11
  44. package/extensions/ublocklite/rulesets/main/rus-0.json +7 -4
  45. package/extensions/ublocklite/rulesets/main/stevenblack-hosts.json +2092 -363
  46. package/extensions/ublocklite/rulesets/main/swe-1.json +8 -7
  47. package/extensions/ublocklite/rulesets/main/tur-0.json +3 -0
  48. package/extensions/ublocklite/rulesets/main/ublock-badware.json +48 -49
  49. package/extensions/ublocklite/rulesets/main/ublock-filters.json +21 -17
  50. package/extensions/ublocklite/rulesets/main/urlhaus-full.json +272 -234
  51. package/extensions/ublocklite/rulesets/main/vie-1.json +18 -15
  52. package/extensions/ublocklite/rulesets/modify-headers/chn-0.json +1 -0
  53. package/extensions/ublocklite/rulesets/redirect/nld-0.json +19 -0
  54. package/extensions/ublocklite/rulesets/redirect/swe-1.json +1 -1
  55. package/extensions/ublocklite/rulesets/redirect/ublock-filters.json +5 -6
  56. package/extensions/ublocklite/rulesets/redirect/vie-1.json +2 -2
  57. package/extensions/ublocklite/rulesets/regex/chn-0.json +1 -1
  58. package/extensions/ublocklite/rulesets/regex/ublock-filters.json +5 -4
  59. package/extensions/ublocklite/rulesets/removeparam/adguard-spyware-url.json +1 -1
  60. package/extensions/ublocklite/rulesets/removeparam/rus-1.json +3 -4
  61. package/extensions/ublocklite/rulesets/ruleset-details.json +111 -111
  62. package/extensions/ublocklite/rulesets/scripting/declarative/annoyances-overlays.js +1 -1
  63. package/extensions/ublocklite/rulesets/scripting/declarative/fra-0.js +3 -3
  64. package/extensions/ublocklite/rulesets/scripting/declarative/rus-0.js +1 -1
  65. package/extensions/ublocklite/rulesets/scripting/declarative/rus-1.js +3 -3
  66. package/extensions/ublocklite/rulesets/scripting/declarative/tur-0.js +3 -3
  67. package/extensions/ublocklite/rulesets/scripting/declarative/ublock-filters.js +3 -3
  68. package/extensions/ublocklite/rulesets/scripting/generic/annoyances-cookies.js +1 -1
  69. package/extensions/ublocklite/rulesets/scripting/generic/annoyances-social.js +1 -1
  70. package/extensions/ublocklite/rulesets/scripting/generic/rus-0.js +1 -1
  71. package/extensions/ublocklite/rulesets/scripting/generic/ublock-badware.js +1 -1
  72. package/extensions/ublocklite/rulesets/scripting/generic/ublock-filters.js +1 -1
  73. package/extensions/ublocklite/rulesets/scripting/generichigh/chn-0.css +1 -0
  74. package/extensions/ublocklite/rulesets/scripting/generichigh/idn-0.css +1 -0
  75. package/extensions/ublocklite/rulesets/scripting/generichigh/ublock-filters.css +0 -4
  76. package/extensions/ublocklite/rulesets/scripting/procedural/chn-0.js +3 -3
  77. package/extensions/ublocklite/rulesets/scripting/procedural/easylist.js +3 -3
  78. package/extensions/ublocklite/rulesets/scripting/procedural/rus-0.js +1 -1
  79. package/extensions/ublocklite/rulesets/scripting/procedural/swe-1.js +3 -3
  80. package/extensions/ublocklite/rulesets/scripting/procedural/ublock-filters.js +3 -3
  81. package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.set-cookie.js +2 -2
  82. package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.set-local-storage-item.js +1 -1
  83. package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.trusted-click-element.js +2 -2
  84. package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.trusted-set-cookie.js +2 -2
  85. package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.trusted-set-local-storage-item.js +2 -2
  86. package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-others.remove-cookie.js +2 -2
  87. package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-overlays.addEventListener-defuser.js +1 -1
  88. package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-overlays.prevent-fetch.js +2 -2
  89. package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-overlays.set-cookie.js +2 -2
  90. package/extensions/ublocklite/rulesets/scripting/scriptlet/fra-0.prevent-fetch.js +2 -2
  91. package/extensions/ublocklite/rulesets/scripting/scriptlet/hun-0.prevent-fetch.js +2 -2
  92. package/extensions/ublocklite/rulesets/scripting/scriptlet/jpn-1.addEventListener-defuser.js +2 -2
  93. package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.abort-on-property-read.js +1 -1
  94. package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.set-attr.js +1 -1
  95. package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.set-constant.js +1 -1
  96. package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.set-cookie.js +2 -2
  97. package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-1.addEventListener-defuser.js +1 -1
  98. package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-1.remove-cookie.js +2 -2
  99. package/extensions/ublocklite/rulesets/scripting/scriptlet/spa-1.prevent-window-open.js +1 -1
  100. package/extensions/ublocklite/rulesets/scripting/scriptlet/swe-1.addEventListener-defuser.js +2 -2
  101. package/extensions/ublocklite/rulesets/scripting/scriptlet/tur-0.prevent-window-open.js +1 -1
  102. package/extensions/ublocklite/rulesets/scripting/scriptlet/tur-0.remove-node-text.js +2 -2
  103. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.abort-current-script.js +3 -3
  104. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.abort-on-property-read.js +1 -1
  105. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.abort-on-stack-trace.js +2 -2
  106. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.addEventListener-defuser.js +3 -3
  107. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.adjust-setInterval.js +2 -2
  108. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.adjust-setTimeout.js +2 -2
  109. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.alert-buster.js +1 -1
  110. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.href-sanitizer.js +1 -1
  111. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.noeval-if.js +1 -1
  112. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-fetch.js +2 -2
  113. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-setTimeout.js +2 -2
  114. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-window-open.js +1 -1
  115. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-xhr.js +1 -1
  116. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.remove-cookie.js +2 -2
  117. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.remove-node-text.js +3 -3
  118. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.set-constant.js +3 -3
  119. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.set-local-storage-item.js +2 -2
  120. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.set-session-storage-item.js +2 -2
  121. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-replace-argument.js +1 -1
  122. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-replace-node-text.js +2 -2
  123. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-replace-outbound-text.js +1 -1
  124. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-set-constant.js +2 -2
  125. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-set-local-storage-item.js +1 -1
  126. package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-suppress-native-method.js +1 -1
  127. package/extensions/ublocklite/rulesets/scripting/scriptlet/vie-1.abort-current-script.js +1 -1
  128. package/extensions/ublocklite/rulesets/scripting/scriptlet/vie-1.abort-on-property-read.js +1 -1
  129. package/extensions/ublocklite/rulesets/scripting/scriptlet/vie-1.set-constant.js +2 -2
  130. package/extensions/ublocklite/rulesets/scripting/specific/adguard-mobile.js +3 -3
  131. package/extensions/ublocklite/rulesets/scripting/specific/annoyances-cookies.js +3 -3
  132. package/extensions/ublocklite/rulesets/scripting/specific/annoyances-others.js +2 -2
  133. package/extensions/ublocklite/rulesets/scripting/specific/annoyances-overlays.js +3 -3
  134. package/extensions/ublocklite/rulesets/scripting/specific/annoyances-social.js +3 -3
  135. package/extensions/ublocklite/rulesets/scripting/specific/chn-0.js +3 -3
  136. package/extensions/ublocklite/rulesets/scripting/specific/deu-0.js +3 -3
  137. package/extensions/ublocklite/rulesets/scripting/specific/easylist.js +3 -3
  138. package/extensions/ublocklite/rulesets/scripting/specific/fin-0.js +3 -3
  139. package/extensions/ublocklite/rulesets/scripting/specific/fra-0.js +3 -3
  140. package/extensions/ublocklite/rulesets/scripting/specific/hun-0.js +3 -3
  141. package/extensions/ublocklite/rulesets/scripting/specific/idn-0.js +3 -3
  142. package/extensions/ublocklite/rulesets/scripting/specific/ind-0.js +3 -3
  143. package/extensions/ublocklite/rulesets/scripting/specific/jpn-1.js +3 -3
  144. package/extensions/ublocklite/rulesets/scripting/specific/rus-0.js +3 -3
  145. package/extensions/ublocklite/rulesets/scripting/specific/spa-0.js +3 -3
  146. package/extensions/ublocklite/rulesets/scripting/specific/spa-1.js +3 -3
  147. package/extensions/ublocklite/rulesets/scripting/specific/swe-1.js +3 -3
  148. package/extensions/ublocklite/rulesets/scripting/specific/tur-0.js +3 -3
  149. package/extensions/ublocklite/rulesets/scripting/specific/ublock-filters.js +3 -3
  150. package/extensions/ublocklite/rulesets/scripting/specific/vie-1.js +3 -3
  151. package/extensions/ublocklite/rulesets/scriptlet-details.json +82 -70
  152. package/extensions/ublocklite/rulesets/strictblock/chn-0.json +64 -0
  153. package/extensions/ublocklite/rulesets/strictblock/easylist.json +1 -1
  154. package/extensions/ublocklite/rulesets/strictblock/easyprivacy.json +7 -1
  155. package/extensions/ublocklite/rulesets/strictblock/idn-0.json +0 -1
  156. package/extensions/ublocklite/rulesets/strictblock/pgl.json +2 -11
  157. package/extensions/ublocklite/rulesets/strictblock/stevenblack-hosts.json +2092 -363
  158. package/extensions/ublocklite/rulesets/strictblock/ublock-badware.json +633 -632
  159. package/extensions/ublocklite/rulesets/strictblock/ublock-filters.json +1 -1
  160. package/extensions/ublocklite/rulesets/strictblock/urlhaus-full.json +272 -234
  161. package/extensions/ublocklite/rulesets/urlskip/ublock-filters.json +6 -0
  162. package/extensions/ublocklite/ublock.zip +0 -0
  163. package/package.json +3 -3
  164. package/static/docs/swagger.json +10 -10
  165. package/static/docs/swagger.min.json +9 -9
@@ -0,0 +1,470 @@
1
+ /*******************************************************************************
2
+
3
+ uBlock Origin - a comprehensive, efficient content blocker
4
+ Copyright (C) 2025-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
+ /**
24
+ * Implement the parsing of uBO-flavored JSON path queries.
25
+ *
26
+ * Reference to original JSON path syntax:
27
+ * https://goessner.net/articles/JsonPath/index.html
28
+ *
29
+ * uBO-flavored JSON path implementation differs as follow:
30
+ *
31
+ * - Both $ and @ are implicit. Though you can use them, you do not have to.
32
+ * Use $ only when the implicit context is not that of root. Example:
33
+ * - Official: $..book[?(@.isbn)]
34
+ * - uBO-flavored: ..book[?(.isbn)]
35
+ *
36
+ * - uBO-flavor syntax does not (yet) support:
37
+ * - Array slice operator
38
+ *
39
+ * - Regarding filter expressions, uBO-flavored JSON path supports a limited
40
+ * set of expressions since unlike the official implementation, uBO can't use
41
+ * JS eval() to evaluate arbitrary JS expressions. The operand MUST be valid
42
+ * JSON. The currently supported expressions are:
43
+ * - ==: strict equality
44
+ * - !=: strict inequality
45
+ * - <: less than
46
+ * - <=: less than or equal to
47
+ * - >: greater than
48
+ * - >=: greater than or equal to
49
+ * - ^=: stringified value starts with
50
+ * - $=: stringified value ends with
51
+ * - *=: stringified value includes
52
+ *
53
+ * - Examples (from "JSONPath examples" at reference link)
54
+ * - .store.book[*].author
55
+ * - ..author
56
+ * - .store.*
57
+ * - .store..price
58
+ * - ..book[2]
59
+ * - ..book[?(.isbn)]
60
+ * - ..book[?(.price<10)]
61
+ * - ..*
62
+ *
63
+ * uBO-flavored syntax supports assigning a value to a resolved JSON path by
64
+ * appending `=[value]` to the JSON path query. The assigned value MUST be
65
+ * valid JSON. Examples:
66
+ * - .store..price=0
67
+ * - .store.book[*].author="redacted"
68
+ *
69
+ * A JSONPath instance can be use to compile a JSON path query, and the result
70
+ * of the compilation can be applied to different objects. When a JSON path
71
+ * query does not assign a value, the resolved property will be removed.
72
+ *
73
+ * More capabilities can be added in the future as needed.
74
+ *
75
+ * */
76
+
77
+ export class JSONPath {
78
+ static create(query) {
79
+ const jsonp = new JSONPath();
80
+ jsonp.compile(query);
81
+ return jsonp;
82
+ }
83
+ static toJSON(obj, stringifier, ...args) {
84
+ return (stringifier || JSON.stringify)(obj, ...args)
85
+ .replace(/\//g, '\\/');
86
+ }
87
+ get value() {
88
+ return this.#compiled && this.#compiled.rval;
89
+ }
90
+ set value(v) {
91
+ if ( this.#compiled === undefined ) { return; }
92
+ this.#compiled.rval = v;
93
+ }
94
+ get valid() {
95
+ return this.#compiled !== undefined;
96
+ }
97
+ compile(query) {
98
+ this.#compiled = undefined;
99
+ const r = this.#compile(query, 0);
100
+ if ( r === undefined ) { return; }
101
+ if ( r.i !== query.length ) {
102
+ if ( query.startsWith('+=', r.i) ) {
103
+ r.modify = '+';
104
+ r.i += 1;
105
+ }
106
+ if ( query.startsWith('=', r.i) === false ) { return; }
107
+ try { r.rval = JSON.parse(query.slice(r.i+1)); }
108
+ catch { return; }
109
+ }
110
+ this.#compiled = r;
111
+ }
112
+ evaluate(root) {
113
+ if ( this.valid === false ) { return []; }
114
+ this.#root = root;
115
+ const paths = this.#evaluate(this.#compiled.steps, []);
116
+ this.#root = null;
117
+ return paths;
118
+ }
119
+ apply(root) {
120
+ if ( this.valid === false ) { return 0; }
121
+ const { modify, rval } = this.#compiled;
122
+ this.#root = root;
123
+ const paths = this.#evaluate(this.#compiled.steps, []);
124
+ const n = paths.length;
125
+ let i = n;
126
+ while ( i-- ) {
127
+ const { obj, key } = this.#resolvePath(paths[i]);
128
+ if ( rval !== undefined ) {
129
+ if ( modify === '+' ) {
130
+ this.#modifyVal(obj, key, rval);
131
+ } else {
132
+ obj[key] = rval;
133
+ }
134
+ } else if ( Array.isArray(obj) && typeof key === 'number' ) {
135
+ obj.splice(key, 1);
136
+ } else {
137
+ delete obj[key];
138
+ }
139
+ }
140
+ this.#root = null;
141
+ return n;
142
+ }
143
+ dump() {
144
+ return JSON.stringify(this.#compiled);
145
+ }
146
+ toJSON(obj, ...args) {
147
+ return JSONPath.toJSON(obj, null, ...args)
148
+ }
149
+ get [Symbol.toStringTag]() {
150
+ return 'JSONPath';
151
+ }
152
+ #UNDEFINED = 0;
153
+ #ROOT = 1;
154
+ #CURRENT = 2;
155
+ #CHILDREN = 3;
156
+ #DESCENDANTS = 4;
157
+ #reUnquotedIdentifier = /^[A-Za-z_][\w]*|^\*/;
158
+ #reExpr = /^([!=^$*]=|[<>]=?)(.+?)\]/;
159
+ #reIndice = /^-?\d+/;
160
+ #root;
161
+ #compiled;
162
+ #compile(query, i) {
163
+ if ( query.length === 0 ) { return; }
164
+ const steps = [];
165
+ let c = query.charCodeAt(i);
166
+ steps.push({ mv: c === 0x24 /* $ */ ? this.#ROOT : this.#CURRENT });
167
+ if ( c === 0x24 /* $ */ || c === 0x40 /* @ */ ) { i += 1; }
168
+ let mv = this.#UNDEFINED;
169
+ for (;;) {
170
+ if ( i === query.length ) { break; }
171
+ c = query.charCodeAt(i);
172
+ if ( c === 0x20 /* whitespace */ ) {
173
+ i += 1;
174
+ continue;
175
+ }
176
+ // Dot accessor syntax
177
+ if ( c === 0x2E /* . */ ) {
178
+ if ( mv !== this.#UNDEFINED ) { return; }
179
+ if ( query.startsWith('..', i) ) {
180
+ mv = this.#DESCENDANTS;
181
+ i += 2;
182
+ } else {
183
+ mv = this.#CHILDREN;
184
+ i += 1;
185
+ }
186
+ continue;
187
+ }
188
+ if ( c !== 0x5B /* [ */ ) {
189
+ if ( mv === this.#UNDEFINED ) {
190
+ const step = steps.at(-1);
191
+ if ( step === undefined ) { return; }
192
+ i = this.#compileExpr(query, step, i);
193
+ break;
194
+ }
195
+ const s = this.#consumeUnquotedIdentifier(query, i);
196
+ if ( s === undefined ) { return; }
197
+ steps.push({ mv, k: s });
198
+ i += s.length;
199
+ mv = this.#UNDEFINED;
200
+ continue;
201
+ }
202
+ // Bracket accessor syntax
203
+ if ( query.startsWith('[?', i) ) {
204
+ const not = query.charCodeAt(i+2) === 0x21 /* ! */;
205
+ const j = i + 2 + (not ? 1 : 0);
206
+ const r = this.#compile(query, j);
207
+ if ( r === undefined ) { return; }
208
+ if ( query.startsWith(']', r.i) === false ) { return; }
209
+ if ( not ) { r.steps.at(-1).not = true; }
210
+ steps.push({ mv: mv || this.#CHILDREN, steps: r.steps });
211
+ i = r.i + 1;
212
+ mv = this.#UNDEFINED;
213
+ continue;
214
+ }
215
+ if ( query.startsWith('[*]', i) ) {
216
+ mv ||= this.#CHILDREN;
217
+ steps.push({ mv, k: '*' });
218
+ i += 3;
219
+ mv = this.#UNDEFINED;
220
+ continue;
221
+ }
222
+ const r = this.#consumeIdentifier(query, i+1);
223
+ if ( r === undefined ) { return; }
224
+ mv ||= this.#CHILDREN;
225
+ steps.push({ mv, k: r.s });
226
+ i = r.i + 1;
227
+ mv = this.#UNDEFINED;
228
+ }
229
+ if ( steps.length <= 1 ) { return; }
230
+ return { steps, i };
231
+ }
232
+ #evaluate(steps, pathin) {
233
+ let resultset = [];
234
+ if ( Array.isArray(steps) === false ) { return resultset; }
235
+ for ( const step of steps ) {
236
+ switch ( step.mv ) {
237
+ case this.#ROOT:
238
+ resultset = [ [] ];
239
+ break;
240
+ case this.#CURRENT:
241
+ resultset = [ pathin ];
242
+ break;
243
+ case this.#CHILDREN:
244
+ case this.#DESCENDANTS:
245
+ resultset = this.#getMatches(resultset, step);
246
+ break;
247
+ default:
248
+ break;
249
+ }
250
+ }
251
+ return resultset;
252
+ }
253
+ #getMatches(listin, step) {
254
+ const listout = [];
255
+ for ( const pathin of listin ) {
256
+ const { value: owner } = this.#resolvePath(pathin);
257
+ if ( step.k === '*' ) {
258
+ this.#getMatchesFromAll(pathin, step, owner, listout);
259
+ } else if ( step.k !== undefined ) {
260
+ this.#getMatchesFromKeys(pathin, step, owner, listout);
261
+ } else if ( step.steps ) {
262
+ this.#getMatchesFromExpr(pathin, step, owner, listout);
263
+ }
264
+ }
265
+ return listout;
266
+ }
267
+ #getMatchesFromAll(pathin, step, owner, out) {
268
+ const recursive = step.mv === this.#DESCENDANTS;
269
+ for ( const { path } of this.#getDescendants(owner, recursive) ) {
270
+ out.push([ ...pathin, ...path ]);
271
+ }
272
+ }
273
+ #getMatchesFromKeys(pathin, step, owner, out) {
274
+ const kk = Array.isArray(step.k) ? step.k : [ step.k ];
275
+ for ( const k of kk ) {
276
+ const normalized = this.#evaluateExpr(step, owner, k);
277
+ if ( normalized === undefined ) { continue; }
278
+ out.push([ ...pathin, normalized ]);
279
+ }
280
+ if ( step.mv !== this.#DESCENDANTS ) { return; }
281
+ for ( const { obj, key, path } of this.#getDescendants(owner, true) ) {
282
+ for ( const k of kk ) {
283
+ const normalized = this.#evaluateExpr(step, obj[key], k);
284
+ if ( normalized === undefined ) { continue; }
285
+ out.push([ ...pathin, ...path, normalized ]);
286
+ }
287
+ }
288
+ }
289
+ #getMatchesFromExpr(pathin, step, owner, out) {
290
+ const recursive = step.mv === this.#DESCENDANTS;
291
+ if ( Array.isArray(owner) === false ) {
292
+ const r = this.#evaluate(step.steps, pathin);
293
+ if ( r.length !== 0 ) { out.push(pathin); }
294
+ if ( recursive !== true ) { return; }
295
+ }
296
+ for ( const { obj, key, path } of this.#getDescendants(owner, recursive) ) {
297
+ if ( Array.isArray(obj[key]) ) { continue; }
298
+ const q = [ ...pathin, ...path ];
299
+ const r = this.#evaluate(step.steps, q);
300
+ if ( r.length === 0 ) { continue; }
301
+ out.push(q);
302
+ }
303
+ }
304
+ #normalizeKey(owner, key) {
305
+ if ( typeof key === 'number' ) {
306
+ if ( Array.isArray(owner) ) {
307
+ return key >= 0 ? key : owner.length + key;
308
+ }
309
+ }
310
+ return key;
311
+ }
312
+ #getDescendants(v, recursive) {
313
+ const iterator = {
314
+ next() {
315
+ const n = this.stack.length;
316
+ if ( n === 0 ) {
317
+ this.value = undefined;
318
+ this.done = true;
319
+ return this;
320
+ }
321
+ const details = this.stack[n-1];
322
+ const entry = details.keys.next();
323
+ if ( entry.done ) {
324
+ this.stack.pop();
325
+ this.path.pop();
326
+ return this.next();
327
+ }
328
+ this.path[n-1] = entry.value;
329
+ this.value = {
330
+ obj: details.obj,
331
+ key: entry.value,
332
+ path: this.path.slice(),
333
+ };
334
+ const v = this.value.obj[this.value.key];
335
+ if ( recursive ) {
336
+ if ( Array.isArray(v) ) {
337
+ this.stack.push({ obj: v, keys: v.keys() });
338
+ } else if ( typeof v === 'object' && v !== null ) {
339
+ this.stack.push({ obj: v, keys: Object.keys(v).values() });
340
+ }
341
+ }
342
+ return this;
343
+ },
344
+ path: [],
345
+ value: undefined,
346
+ done: false,
347
+ stack: [],
348
+ [Symbol.iterator]() { return this; },
349
+ };
350
+ if ( Array.isArray(v) ) {
351
+ iterator.stack.push({ obj: v, keys: v.keys() });
352
+ } else if ( typeof v === 'object' && v !== null ) {
353
+ iterator.stack.push({ obj: v, keys: Object.keys(v).values() });
354
+ }
355
+ return iterator;
356
+ }
357
+ #consumeIdentifier(query, i) {
358
+ const keys = [];
359
+ for (;;) {
360
+ const c0 = query.charCodeAt(i);
361
+ if ( c0 === 0x5D /* ] */ ) { break; }
362
+ if ( c0 === 0x2C /* , */ ) {
363
+ i += 1;
364
+ continue;
365
+ }
366
+ if ( c0 === 0x27 /* ' */ ) {
367
+ const r = this.#consumeQuotedIdentifier(query, i+1);
368
+ if ( r === undefined ) { return; }
369
+ keys.push(r.s);
370
+ i = r.i;
371
+ continue;
372
+ }
373
+ if ( c0 === 0x2D /* - */ || c0 >= 0x30 && c0 <= 0x39 ) {
374
+ const match = this.#reIndice.exec(query.slice(i));
375
+ if ( match === null ) { return; }
376
+ const indice = parseInt(query.slice(i), 10);
377
+ keys.push(indice);
378
+ i += match[0].length;
379
+ continue;
380
+ }
381
+ const s = this.#consumeUnquotedIdentifier(query, i);
382
+ if ( s === undefined ) { return; }
383
+ keys.push(s);
384
+ i += s.length;
385
+ }
386
+ return { s: keys.length === 1 ? keys[0] : keys, i };
387
+ }
388
+ #consumeQuotedIdentifier(query, i) {
389
+ const len = query.length;
390
+ const parts = [];
391
+ let beg = i, end = i;
392
+ for (;;) {
393
+ if ( end === len ) { return; }
394
+ const c = query.charCodeAt(end);
395
+ if ( c === 0x27 /* ' */ ) {
396
+ parts.push(query.slice(beg, end));
397
+ end += 1;
398
+ break;
399
+ }
400
+ if ( c === 0x5C /* \ */ && (end+1) < len ) {
401
+ parts.push(query.slice(beg, end));
402
+ const d = query.chatCodeAt(end+1);
403
+ if ( d === 0x27 || d === 0x5C ) {
404
+ end += 1;
405
+ beg = end;
406
+ }
407
+ }
408
+ end += 1;
409
+ }
410
+ return { s: parts.join(''), i: end };
411
+ }
412
+ #consumeUnquotedIdentifier(query, i) {
413
+ const match = this.#reUnquotedIdentifier.exec(query.slice(i));
414
+ if ( match === null ) { return; }
415
+ return match[0];
416
+ }
417
+ #compileExpr(query, step, i) {
418
+ const match = this.#reExpr.exec(query.slice(i));
419
+ if ( match === null ) { return i; }
420
+ try {
421
+ step.rval = JSON.parse(match[2]);
422
+ step.op = match[1];
423
+ } catch {
424
+ }
425
+ return i + match[1].length + match[2].length;
426
+ }
427
+ #resolvePath(path) {
428
+ if ( path.length === 0 ) { return { value: this.#root }; }
429
+ const key = path.at(-1);
430
+ let obj = this.#root
431
+ for ( let i = 0, n = path.length-1; i < n; i++ ) {
432
+ obj = obj[path[i]];
433
+ }
434
+ return { obj, key, value: obj[key] };
435
+ }
436
+ #evaluateExpr(step, owner, key) {
437
+ if ( owner === undefined || owner === null ) { return; }
438
+ if ( typeof key === 'number' ) {
439
+ if ( Array.isArray(owner) === false ) { return; }
440
+ }
441
+ const k = this.#normalizeKey(owner, key);
442
+ const hasOwn = Object.hasOwn(owner, k);
443
+ if ( step.op !== undefined && hasOwn === false ) { return; }
444
+ const target = step.not !== true;
445
+ const v = owner[k];
446
+ let outcome = false;
447
+ switch ( step.op ) {
448
+ case '==': outcome = (v === step.rval) === target; break;
449
+ case '!=': outcome = (v !== step.rval) === target; break;
450
+ case '<': outcome = (v < step.rval) === target; break;
451
+ case '<=': outcome = (v <= step.rval) === target; break;
452
+ case '>': outcome = (v > step.rval) === target; break;
453
+ case '>=': outcome = (v >= step.rval) === target; break;
454
+ case '^=': outcome = `${v}`.startsWith(step.rval) === target; break;
455
+ case '$=': outcome = `${v}`.endsWith(step.rval) === target; break;
456
+ case '*=': outcome = `${v}`.includes(step.rval) === target; break;
457
+ default: outcome = hasOwn === target; break;
458
+ }
459
+ if ( outcome ) { return k; }
460
+ }
461
+ #modifyVal(obj, key, rval) {
462
+ const lval = obj[key];
463
+ if ( rval instanceof Object === false ) { return; }
464
+ if ( lval instanceof Object === false ) { return; }
465
+ if ( Array.isArray(lval) ) { return; }
466
+ for ( const [ k, v ] of Object.entries(rval) ) {
467
+ lval[k] = v;
468
+ }
469
+ }
470
+ }
@@ -0,0 +1,192 @@
1
+ /*******************************************************************************
2
+
3
+ uBlock Origin - a comprehensive, efficient content blocker
4
+ Copyright (C) 2015-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
+
24
+ // The resources referenced below are found in ./web_accessible_resources/
25
+ //
26
+ // The content of the resources which declare a `data` property will be loaded
27
+ // in memory, and converted to a suitable internal format depending on the
28
+ // type of the loaded data. The `data` property allows for manual injection
29
+ // through `+js(...)`, or for redirection to a data: URI when a redirection
30
+ // to a web accessible resource is not desirable.
31
+
32
+ export default new Map([
33
+ [ '1x1.gif', {
34
+ alias: '1x1-transparent.gif',
35
+ data: 'blob',
36
+ } ],
37
+ [ '2x2.png', {
38
+ alias: '2x2-transparent.png',
39
+ data: 'blob',
40
+ } ],
41
+ [ '3x2.png', {
42
+ alias: '3x2-transparent.png',
43
+ data: 'blob',
44
+ } ],
45
+ [ '32x32.png', {
46
+ alias: '32x32-transparent.png',
47
+ data: 'blob',
48
+ } ],
49
+ [ 'amazon_ads.js', {
50
+ alias: 'amazon-adsystem.com/aax2/amzn_ads.js',
51
+ data: 'text',
52
+ } ],
53
+ [ 'amazon_apstag.js', {
54
+ } ],
55
+ [ 'ampproject_v0.js', {
56
+ alias: 'ampproject.org/v0.js',
57
+ } ],
58
+ [ 'chartbeat.js', {
59
+ alias: 'static.chartbeat.com/chartbeat.js',
60
+ } ],
61
+ [ 'click2load.html', {
62
+ params: [ 'aliasURL', 'url' ],
63
+ } ],
64
+ [ 'doubleclick_instream_ad_status.js', {
65
+ alias: 'doubleclick.net/instream/ad_status.js',
66
+ data: 'text',
67
+ } ],
68
+ [ 'empty', {
69
+ data: 'text', // Important!
70
+ } ],
71
+ [ 'fingerprint2.js', {
72
+ data: 'text',
73
+ } ],
74
+ [ 'fingerprint3.js', {
75
+ data: 'text',
76
+ } ],
77
+ [ 'google-analytics_analytics.js', {
78
+ alias: [
79
+ 'google-analytics.com/analytics.js',
80
+ 'googletagmanager_gtm.js',
81
+ 'googletagmanager.com/gtm.js'
82
+ ],
83
+ data: 'text',
84
+ } ],
85
+ [ 'google-analytics_cx_api.js', {
86
+ alias: 'google-analytics.com/cx/api.js',
87
+ } ],
88
+ [ 'google-analytics_ga.js', {
89
+ alias: 'google-analytics.com/ga.js',
90
+ data: 'text',
91
+ } ],
92
+ [ 'google-analytics_inpage_linkid.js', {
93
+ alias: 'google-analytics.com/inpage_linkid.js',
94
+ } ],
95
+ [ 'google-ima.js', {
96
+ alias: 'google-ima3', /* adguard compatibility */
97
+ } ],
98
+ [ 'googlesyndication_adsbygoogle.js', {
99
+ alias: [
100
+ 'googlesyndication.com/adsbygoogle.js',
101
+ 'googlesyndication-adsbygoogle', /* adguard compatibility */
102
+ ],
103
+ data: 'text',
104
+ } ],
105
+ [ 'googletagservices_gpt.js', {
106
+ alias: [
107
+ 'googletagservices.com/gpt.js',
108
+ 'googletagservices-gpt', /* adguard compatibility */
109
+ ],
110
+ data: 'text',
111
+ } ],
112
+ [ 'hd-main.js', {
113
+ } ],
114
+ [ 'nobab.js', {
115
+ alias: [ 'bab-defuser.js', 'prevent-bab.js' ],
116
+ data: 'text',
117
+ } ],
118
+ [ 'nobab2.js', {
119
+ data: 'text',
120
+ } ],
121
+ [ 'noeval.js', {
122
+ data: 'text',
123
+ } ],
124
+ [ 'noeval-silent.js', {
125
+ alias: 'silent-noeval.js',
126
+ data: 'text',
127
+ } ],
128
+ [ 'nofab.js', {
129
+ alias: 'fuckadblock.js-3.2.0',
130
+ data: 'text',
131
+ } ],
132
+ [ 'noop-0.1s.mp3', {
133
+ alias: [ 'noopmp3-0.1s', 'abp-resource:blank-mp3' ],
134
+ data: 'blob',
135
+ } ],
136
+ [ 'noop-0.5s.mp3', {
137
+ } ],
138
+ [ 'noop-1s.mp4', {
139
+ alias: [ 'noopmp4-1s', 'abp-resource:blank-mp4' ],
140
+ data: 'blob',
141
+ } ],
142
+ [ 'noop.css', {
143
+ data: 'text',
144
+ } ],
145
+ [ 'noop.html', {
146
+ alias: 'noopframe',
147
+ } ],
148
+ [ 'noop.js', {
149
+ alias: [ 'noopjs', 'abp-resource:blank-js' ],
150
+ data: 'text',
151
+ } ],
152
+ [ 'noop.json', {
153
+ alias: [ 'noopjson' ],
154
+ data: 'text',
155
+ } ],
156
+ [ 'noop.txt', {
157
+ alias: 'nooptext',
158
+ data: 'text',
159
+ } ],
160
+ [ 'noop-vast2.xml', {
161
+ alias: 'noopvast-2.0',
162
+ data: 'text',
163
+ } ],
164
+ [ 'noop-vast3.xml', {
165
+ alias: 'noopvast-3.0',
166
+ data: 'text',
167
+ } ],
168
+ [ 'noop-vast4.xml', {
169
+ alias: 'noopvast-4.0',
170
+ data: 'text',
171
+ } ],
172
+ [ 'noop-vmap1.xml', {
173
+ alias: [ 'noop-vmap1.0.xml', 'noopvmap-1.0' ],
174
+ data: 'text',
175
+ } ],
176
+ [ 'outbrain-widget.js', {
177
+ alias: 'widgets.outbrain.com/outbrain.js',
178
+ } ],
179
+ [ 'popads.js', {
180
+ alias: [ 'popads.net.js', 'prevent-popads-net.js' ],
181
+ data: 'text',
182
+ } ],
183
+ [ 'popads-dummy.js', {
184
+ data: 'text',
185
+ } ],
186
+ [ 'prebid-ads.js', {
187
+ data: 'text',
188
+ } ],
189
+ [ 'scorecardresearch_beacon.js', {
190
+ alias: 'scorecardresearch.com/beacon.js',
191
+ } ],
192
+ ]);
@@ -29,6 +29,7 @@ import {
29
29
  import { dom, qs$ } from './dom.js';
30
30
  import { i18n, i18n$ } from './i18n.js';
31
31
  import { DNREditor } from './dnr-editor.js';
32
+ import { parseFilters } from './ubo-parser.js';
32
33
  import { textFromRules } from './dnr-parser.js';
33
34
 
34
35
  /******************************************************************************/
@@ -368,15 +369,28 @@ export class ReadWriteDNREditor extends DNREditor {
368
369
  const lineFrom = newDoc.lineAt(from);
369
370
  if ( lineFrom.from !== from ) { return; }
370
371
  // Paste position must match a rule boundary
372
+ let separatorBefore = false;
371
373
  if ( lineFrom.number !== 1 ) {
372
374
  const lineBefore = newDoc.line(lineFrom.number-1);
373
375
  if ( /^---\s*$/.test(lineBefore.text) === false ) { return; }
376
+ separatorBefore = true;
374
377
  }
375
378
  const pastedText = newDoc.sliceString(from, to);
376
- const rules = this.rulesFromJSON(pastedText);
377
- if ( rules === undefined ) { return; }
378
- const yamlText = textFromRules(rules);
379
+ let prepend;
380
+ let rules = this.rulesFromJSON(pastedText);
381
+ if ( Boolean(rules?.length) === false ) {
382
+ rules = parseFilters(pastedText);
383
+ if ( Boolean(rules?.length) === false ) { return; }
384
+ prepend = pastedText.trim().split(/\n/).map(a => `# ${a}`).join('\n');
385
+ }
386
+ let yamlText = textFromRules(rules);
379
387
  if ( yamlText === undefined ) { return; }
388
+ if ( prepend ) {
389
+ yamlText = yamlText.replace('---\n', `---\n${prepend}\n`);
390
+ }
391
+ if ( separatorBefore && yamlText.startsWith('---\n') ) {
392
+ yamlText = yamlText.slice(4);
393
+ }
380
394
  editor.view.dispatch({ changes: { from, to, insert: yamlText } });
381
395
  self.cm6.foldAll(editor.view);
382
396
  return true;