@browserless.io/browserless 2.0.0-beta-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 (875) hide show
  1. package/CHANGELOG.md +674 -0
  2. package/LICENSE +6 -0
  3. package/README.md +132 -0
  4. package/assets/logo.png +0 -0
  5. package/bin/browserless.js +227 -0
  6. package/browser.json +7 -0
  7. package/build/browserless.d.ts +33 -0
  8. package/build/browserless.js +146 -0
  9. package/build/browsers/cdp-chromium.d.ts +41 -0
  10. package/build/browsers/cdp-chromium.js +287 -0
  11. package/build/browsers/index.d.ts +26 -0
  12. package/build/browsers/index.js +183 -0
  13. package/build/browsers/playwright-chromium.d.ts +34 -0
  14. package/build/browsers/playwright-chromium.js +106 -0
  15. package/build/browsers/playwright-firefox.d.ts +34 -0
  16. package/build/browsers/playwright-firefox.js +101 -0
  17. package/build/browsers/playwright-webkit.d.ts +34 -0
  18. package/build/browsers/playwright-webkit.js +101 -0
  19. package/build/config.d.ts +138 -0
  20. package/build/config.js +349 -0
  21. package/build/constants.d.ts +4 -0
  22. package/build/constants.js +4 -0
  23. package/build/data/classes.json +1 -0
  24. package/build/data/selectors.json +1 -0
  25. package/build/exports.d.ts +20 -0
  26. package/build/exports.js +22 -0
  27. package/build/file-system.d.ts +24 -0
  28. package/build/file-system.js +46 -0
  29. package/build/hooks.d.ts +5 -0
  30. package/build/hooks.js +20 -0
  31. package/build/http.d.ts +175 -0
  32. package/build/http.js +104 -0
  33. package/build/index.d.ts +1 -0
  34. package/build/index.js +39 -0
  35. package/build/limiter.d.ts +24 -0
  36. package/build/limiter.js +147 -0
  37. package/build/limiter.spec.d.ts +1 -0
  38. package/build/limiter.spec.js +241 -0
  39. package/build/metrics.d.ts +24 -0
  40. package/build/metrics.js +86 -0
  41. package/build/metrics.spec.d.ts +1 -0
  42. package/build/metrics.spec.js +35 -0
  43. package/build/mime-types.d.ts +1 -0
  44. package/build/mime-types.js +328 -0
  45. package/build/monitoring.d.ts +13 -0
  46. package/build/monitoring.js +38 -0
  47. package/build/routes/chromium/http/content-post.body.json +514 -0
  48. package/build/routes/chromium/http/content-post.d.ts +34 -0
  49. package/build/routes/chromium/http/content-post.js +109 -0
  50. package/build/routes/chromium/http/content-post.query.json +183 -0
  51. package/build/routes/chromium/http/content-post.response.json +5 -0
  52. package/build/routes/chromium/http/download-post.body.json +32 -0
  53. package/build/routes/chromium/http/download-post.d.ts +16 -0
  54. package/build/routes/chromium/http/download-post.js +92 -0
  55. package/build/routes/chromium/http/download-post.query.json +120 -0
  56. package/build/routes/chromium/http/download-post.response.json +4 -0
  57. package/build/routes/chromium/http/function-post.body.json +32 -0
  58. package/build/routes/chromium/http/function-post.d.ts +18 -0
  59. package/build/routes/chromium/http/function-post.js +53 -0
  60. package/build/routes/chromium/http/function-post.query.json +120 -0
  61. package/build/routes/chromium/http/function-post.response.json +4 -0
  62. package/build/routes/chromium/http/pdf-post.body.json +654 -0
  63. package/build/routes/chromium/http/pdf-post.d.ts +35 -0
  64. package/build/routes/chromium/http/pdf-post.js +107 -0
  65. package/build/routes/chromium/http/pdf-post.query.json +120 -0
  66. package/build/routes/chromium/http/pdf-post.response.json +5 -0
  67. package/build/routes/chromium/http/performance.body.json +26 -0
  68. package/build/routes/chromium/http/performance.d.ts +17 -0
  69. package/build/routes/chromium/http/performance.js +30 -0
  70. package/build/routes/chromium/http/performance.query.json +120 -0
  71. package/build/routes/chromium/http/performance.response.json +7 -0
  72. package/build/routes/chromium/http/scrape-post.body.json +561 -0
  73. package/build/routes/chromium/http/scrape-post.d.ts +106 -0
  74. package/build/routes/chromium/http/scrape-post.js +205 -0
  75. package/build/routes/chromium/http/scrape-post.query.json +183 -0
  76. package/build/routes/chromium/http/scrape-post.response.json +325 -0
  77. package/build/routes/chromium/http/screenshot-post.body.json +604 -0
  78. package/build/routes/chromium/http/screenshot-post.d.ts +37 -0
  79. package/build/routes/chromium/http/screenshot-post.js +124 -0
  80. package/build/routes/chromium/http/screenshot-post.query.json +120 -0
  81. package/build/routes/chromium/http/screenshot-post.response.json +5 -0
  82. package/build/routes/chromium/tests/content.spec.d.ts +1 -0
  83. package/build/routes/chromium/tests/content.spec.js +285 -0
  84. package/build/routes/chromium/tests/download.spec.d.ts +1 -0
  85. package/build/routes/chromium/tests/download.spec.js +67 -0
  86. package/build/routes/chromium/tests/function.spec.d.ts +1 -0
  87. package/build/routes/chromium/tests/function.spec.js +245 -0
  88. package/build/routes/chromium/tests/pdf.spec.d.ts +1 -0
  89. package/build/routes/chromium/tests/pdf.spec.js +333 -0
  90. package/build/routes/chromium/tests/performance.spec.d.ts +1 -0
  91. package/build/routes/chromium/tests/performance.spec.js +124 -0
  92. package/build/routes/chromium/tests/scrape.spec.d.ts +1 -0
  93. package/build/routes/chromium/tests/scrape.spec.js +354 -0
  94. package/build/routes/chromium/tests/screenshot.spec.d.ts +1 -0
  95. package/build/routes/chromium/tests/screenshot.spec.js +339 -0
  96. package/build/routes/chromium/tests/websocket.spec.d.ts +1 -0
  97. package/build/routes/chromium/tests/websocket.spec.js +309 -0
  98. package/build/routes/chromium/utils/function/client.d.ts +26 -0
  99. package/build/routes/chromium/utils/function/client.js +66 -0
  100. package/build/routes/chromium/utils/function/handler.d.ts +18 -0
  101. package/build/routes/chromium/utils/function/handler.js +95 -0
  102. package/build/routes/chromium/utils/performance/child.d.ts +1 -0
  103. package/build/routes/chromium/utils/performance/child.js +29 -0
  104. package/build/routes/chromium/utils/performance/main.d.ts +3 -0
  105. package/build/routes/chromium/utils/performance/main.js +65 -0
  106. package/build/routes/chromium/utils/performance/types.d.ts +21 -0
  107. package/build/routes/chromium/utils/performance/types.js +1 -0
  108. package/build/routes/chromium/ws/browser.d.ts +6 -0
  109. package/build/routes/chromium/ws/browser.js +11 -0
  110. package/build/routes/chromium/ws/browser.query.json +120 -0
  111. package/build/routes/chromium/ws/cdp-chromium.d.ts +6 -0
  112. package/build/routes/chromium/ws/cdp-chromium.js +11 -0
  113. package/build/routes/chromium/ws/cdp-chromium.query.json +120 -0
  114. package/build/routes/chromium/ws/page.d.ts +6 -0
  115. package/build/routes/chromium/ws/page.js +11 -0
  116. package/build/routes/chromium/ws/page.query.json +120 -0
  117. package/build/routes/chromium/ws/playwright-chromium.d.ts +6 -0
  118. package/build/routes/chromium/ws/playwright-chromium.js +19 -0
  119. package/build/routes/chromium/ws/playwright-chromium.query.json +100 -0
  120. package/build/routes/firefox/tests/websocket.spec.d.ts +1 -0
  121. package/build/routes/firefox/tests/websocket.spec.js +104 -0
  122. package/build/routes/firefox/ws/playwright-firefox.d.ts +6 -0
  123. package/build/routes/firefox/ws/playwright-firefox.js +19 -0
  124. package/build/routes/firefox/ws/playwright-firefox.query.json +100 -0
  125. package/build/routes/management/http/config-get.d.ts +25 -0
  126. package/build/routes/management/http/config-get.js +43 -0
  127. package/build/routes/management/http/config-get.response.json +107 -0
  128. package/build/routes/management/http/metrics-get.d.ts +4 -0
  129. package/build/routes/management/http/metrics-get.js +24 -0
  130. package/build/routes/management/http/metrics-get.response.json +94 -0
  131. package/build/routes/management/http/metrics-total-get.d.ts +4 -0
  132. package/build/routes/management/http/metrics-total-get.js +60 -0
  133. package/build/routes/management/http/metrics-total-get.response.json +72 -0
  134. package/build/routes/management/http/sessions-get.d.ts +4 -0
  135. package/build/routes/management/http/sessions-get.js +21 -0
  136. package/build/routes/management/http/sessions-get.response.json +221 -0
  137. package/build/routes/management/http/static-get.d.ts +3 -0
  138. package/build/routes/management/http/static-get.js +67 -0
  139. package/build/routes/management/tests/management.spec.d.ts +1 -0
  140. package/build/routes/management/tests/management.spec.js +41 -0
  141. package/build/routes/webkit/tests/websocket.spec.d.ts +1 -0
  142. package/build/routes/webkit/tests/websocket.spec.js +104 -0
  143. package/build/routes/webkit/ws/playwright-webkit.d.ts +6 -0
  144. package/build/routes/webkit/ws/playwright-webkit.js +19 -0
  145. package/build/routes/webkit/ws/playwright-webkit.query.json +100 -0
  146. package/build/server.d.ts +38 -0
  147. package/build/server.js +365 -0
  148. package/build/shim.d.ts +9 -0
  149. package/build/shim.js +54 -0
  150. package/build/shim.spec.d.ts +1 -0
  151. package/build/shim.spec.js +114 -0
  152. package/build/types.d.ts +360 -0
  153. package/build/types.js +6 -0
  154. package/build/utils.d.ts +111 -0
  155. package/build/utils.js +570 -0
  156. package/build/webhooks.d.ts +11 -0
  157. package/build/webhooks.js +43 -0
  158. package/docker/base/.dockerignore +16 -0
  159. package/docker/base/Dockerfile +70 -0
  160. package/docker/chrome/.dockerignore +16 -0
  161. package/docker/chrome/Dockerfile +40 -0
  162. package/docker/firefox/.dockerignore +16 -0
  163. package/docker/firefox/Dockerfile +39 -0
  164. package/docker/multi/.dockerignore +16 -0
  165. package/docker/multi/Dockerfile +37 -0
  166. package/docker/sdk/.dockerignore +16 -0
  167. package/docker/sdk/Dockerfile +34 -0
  168. package/docker/webkit/.dockerignore +16 -0
  169. package/docker/webkit/Dockerfile +40 -0
  170. package/extensions/screencast/background.js +143 -0
  171. package/extensions/screencast/content_script.js +18 -0
  172. package/extensions/screencast/manifest.json +19 -0
  173. package/extensions/ublock/1p-filters.html +69 -0
  174. package/extensions/ublock/3p-filters.html +119 -0
  175. package/extensions/ublock/LICENSE.txt +674 -0
  176. package/extensions/ublock/_locales/ar/messages.json +1290 -0
  177. package/extensions/ublock/_locales/az/messages.json +1290 -0
  178. package/extensions/ublock/_locales/be/messages.json +1290 -0
  179. package/extensions/ublock/_locales/bg/messages.json +1290 -0
  180. package/extensions/ublock/_locales/bn/messages.json +1290 -0
  181. package/extensions/ublock/_locales/br_FR/messages.json +1290 -0
  182. package/extensions/ublock/_locales/bs/messages.json +1290 -0
  183. package/extensions/ublock/_locales/ca/messages.json +1290 -0
  184. package/extensions/ublock/_locales/cs/messages.json +1290 -0
  185. package/extensions/ublock/_locales/cv/messages.json +1290 -0
  186. package/extensions/ublock/_locales/da/messages.json +1290 -0
  187. package/extensions/ublock/_locales/de/messages.json +1290 -0
  188. package/extensions/ublock/_locales/el/messages.json +1290 -0
  189. package/extensions/ublock/_locales/en/messages.json +1292 -0
  190. package/extensions/ublock/_locales/en_GB/messages.json +1290 -0
  191. package/extensions/ublock/_locales/eo/messages.json +1290 -0
  192. package/extensions/ublock/_locales/es/messages.json +1290 -0
  193. package/extensions/ublock/_locales/et/messages.json +1290 -0
  194. package/extensions/ublock/_locales/eu/messages.json +1290 -0
  195. package/extensions/ublock/_locales/fa/messages.json +1290 -0
  196. package/extensions/ublock/_locales/fi/messages.json +1290 -0
  197. package/extensions/ublock/_locales/fil/messages.json +1290 -0
  198. package/extensions/ublock/_locales/fr/messages.json +1290 -0
  199. package/extensions/ublock/_locales/fy/messages.json +1290 -0
  200. package/extensions/ublock/_locales/gl/messages.json +1290 -0
  201. package/extensions/ublock/_locales/gu/messages.json +1290 -0
  202. package/extensions/ublock/_locales/he/messages.json +1290 -0
  203. package/extensions/ublock/_locales/hi/messages.json +1290 -0
  204. package/extensions/ublock/_locales/hr/messages.json +1290 -0
  205. package/extensions/ublock/_locales/hu/messages.json +1290 -0
  206. package/extensions/ublock/_locales/hy/messages.json +1290 -0
  207. package/extensions/ublock/_locales/id/messages.json +1290 -0
  208. package/extensions/ublock/_locales/it/messages.json +1290 -0
  209. package/extensions/ublock/_locales/ja/messages.json +1290 -0
  210. package/extensions/ublock/_locales/ka/messages.json +1290 -0
  211. package/extensions/ublock/_locales/kk/messages.json +1290 -0
  212. package/extensions/ublock/_locales/kn/messages.json +1290 -0
  213. package/extensions/ublock/_locales/ko/messages.json +1290 -0
  214. package/extensions/ublock/_locales/ku/messages.json +1290 -0
  215. package/extensions/ublock/_locales/lt/messages.json +1290 -0
  216. package/extensions/ublock/_locales/lv/messages.json +1290 -0
  217. package/extensions/ublock/_locales/mk/messages.json +1290 -0
  218. package/extensions/ublock/_locales/ml/messages.json +1290 -0
  219. package/extensions/ublock/_locales/mr/messages.json +1290 -0
  220. package/extensions/ublock/_locales/ms/messages.json +1290 -0
  221. package/extensions/ublock/_locales/nb/messages.json +1290 -0
  222. package/extensions/ublock/_locales/nl/messages.json +1290 -0
  223. package/extensions/ublock/_locales/no/messages.json +1290 -0
  224. package/extensions/ublock/_locales/oc/messages.json +1290 -0
  225. package/extensions/ublock/_locales/pa/messages.json +1290 -0
  226. package/extensions/ublock/_locales/pl/messages.json +1290 -0
  227. package/extensions/ublock/_locales/pt_BR/messages.json +1290 -0
  228. package/extensions/ublock/_locales/pt_PT/messages.json +1290 -0
  229. package/extensions/ublock/_locales/ro/messages.json +1290 -0
  230. package/extensions/ublock/_locales/ru/messages.json +1290 -0
  231. package/extensions/ublock/_locales/si/messages.json +1290 -0
  232. package/extensions/ublock/_locales/sk/messages.json +1290 -0
  233. package/extensions/ublock/_locales/sl/messages.json +1290 -0
  234. package/extensions/ublock/_locales/so/messages.json +1290 -0
  235. package/extensions/ublock/_locales/sq/messages.json +1290 -0
  236. package/extensions/ublock/_locales/sr/messages.json +1290 -0
  237. package/extensions/ublock/_locales/sv/messages.json +1290 -0
  238. package/extensions/ublock/_locales/sw/messages.json +1290 -0
  239. package/extensions/ublock/_locales/ta/messages.json +1290 -0
  240. package/extensions/ublock/_locales/te/messages.json +1290 -0
  241. package/extensions/ublock/_locales/th/messages.json +1290 -0
  242. package/extensions/ublock/_locales/tr/messages.json +1290 -0
  243. package/extensions/ublock/_locales/uk/messages.json +1290 -0
  244. package/extensions/ublock/_locales/ur/messages.json +1290 -0
  245. package/extensions/ublock/_locales/vi/messages.json +1290 -0
  246. package/extensions/ublock/_locales/zh_CN/messages.json +1290 -0
  247. package/extensions/ublock/_locales/zh_TW/messages.json +1290 -0
  248. package/extensions/ublock/about.html +63 -0
  249. package/extensions/ublock/advanced-settings.html +42 -0
  250. package/extensions/ublock/asset-viewer.html +50 -0
  251. package/extensions/ublock/assets/assets.json +903 -0
  252. package/extensions/ublock/assets/resources/scriptlets.js +4255 -0
  253. package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +65576 -0
  254. package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +33219 -0
  255. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/README.md +29 -0
  256. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +3732 -0
  257. package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +15431 -0
  258. package/extensions/ublock/assets/thirdparties/urlhaus-filter/LICENSE.md +42 -0
  259. package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +1970 -0
  260. package/extensions/ublock/assets/ublock/badlists.txt +77 -0
  261. package/extensions/ublock/assets/ublock/badware.min.txt +3033 -0
  262. package/extensions/ublock/assets/ublock/filters.min.txt +23419 -0
  263. package/extensions/ublock/assets/ublock/privacy.min.txt +575 -0
  264. package/extensions/ublock/assets/ublock/quick-fixes.min.txt +99 -0
  265. package/extensions/ublock/assets/ublock/unbreak.min.txt +2448 -0
  266. package/extensions/ublock/background.html +12 -0
  267. package/extensions/ublock/cloud-ui.html +23 -0
  268. package/extensions/ublock/code-viewer.html +53 -0
  269. package/extensions/ublock/css/1p-filters.css +26 -0
  270. package/extensions/ublock/css/3p-filters.css +250 -0
  271. package/extensions/ublock/css/about.css +3 -0
  272. package/extensions/ublock/css/advanced-settings.css +26 -0
  273. package/extensions/ublock/css/asset-viewer.css +79 -0
  274. package/extensions/ublock/css/click2load.css +53 -0
  275. package/extensions/ublock/css/cloud-ui.css +104 -0
  276. package/extensions/ublock/css/code-viewer.css +67 -0
  277. package/extensions/ublock/css/codemirror.css +326 -0
  278. package/extensions/ublock/css/common.css +347 -0
  279. package/extensions/ublock/css/dashboard-common.css +55 -0
  280. package/extensions/ublock/css/dashboard.css +115 -0
  281. package/extensions/ublock/css/devtools.css +22 -0
  282. package/extensions/ublock/css/document-blocked.css +146 -0
  283. package/extensions/ublock/css/dyna-rules.css +79 -0
  284. package/extensions/ublock/css/epicker-ui.css +270 -0
  285. package/extensions/ublock/css/fa-icons.css +149 -0
  286. package/extensions/ublock/css/fonts/Inter/Inter-Regular.woff2 +0 -0
  287. package/extensions/ublock/css/fonts/Inter/Inter-SemiBold.woff2 +0 -0
  288. package/extensions/ublock/css/fonts/Inter/LICENSE.txt +93 -0
  289. package/extensions/ublock/css/fonts/Metropolis/Metropolis-Regular.woff2 +0 -0
  290. package/extensions/ublock/css/fonts/Metropolis/Metropolis-SemiBold.woff2 +0 -0
  291. package/extensions/ublock/css/fonts/Metropolis/README.md +25 -0
  292. package/extensions/ublock/css/fonts/Metropolis/UNLICENSE +24 -0
  293. package/extensions/ublock/css/logger-ui-inspector.css +116 -0
  294. package/extensions/ublock/css/logger-ui.css +978 -0
  295. package/extensions/ublock/css/popup-fenix.css +778 -0
  296. package/extensions/ublock/css/settings.css +74 -0
  297. package/extensions/ublock/css/support.css +110 -0
  298. package/extensions/ublock/css/themes/default.css +526 -0
  299. package/extensions/ublock/css/whitelist.css +22 -0
  300. package/extensions/ublock/dashboard.html +47 -0
  301. package/extensions/ublock/devtools.html +58 -0
  302. package/extensions/ublock/document-blocked.html +64 -0
  303. package/extensions/ublock/dyna-rules.html +67 -0
  304. package/extensions/ublock/img/cloud.png +0 -0
  305. package/extensions/ublock/img/flags-of-the-world/README +9 -0
  306. package/extensions/ublock/img/flags-of-the-world/ad.png +0 -0
  307. package/extensions/ublock/img/flags-of-the-world/ae.png +0 -0
  308. package/extensions/ublock/img/flags-of-the-world/af.png +0 -0
  309. package/extensions/ublock/img/flags-of-the-world/ag.png +0 -0
  310. package/extensions/ublock/img/flags-of-the-world/ai.png +0 -0
  311. package/extensions/ublock/img/flags-of-the-world/al.png +0 -0
  312. package/extensions/ublock/img/flags-of-the-world/am.png +0 -0
  313. package/extensions/ublock/img/flags-of-the-world/ao.png +0 -0
  314. package/extensions/ublock/img/flags-of-the-world/aq.png +0 -0
  315. package/extensions/ublock/img/flags-of-the-world/ar.png +0 -0
  316. package/extensions/ublock/img/flags-of-the-world/as.png +0 -0
  317. package/extensions/ublock/img/flags-of-the-world/at.png +0 -0
  318. package/extensions/ublock/img/flags-of-the-world/au.png +0 -0
  319. package/extensions/ublock/img/flags-of-the-world/aw.png +0 -0
  320. package/extensions/ublock/img/flags-of-the-world/ax.png +0 -0
  321. package/extensions/ublock/img/flags-of-the-world/az.png +0 -0
  322. package/extensions/ublock/img/flags-of-the-world/ba.png +0 -0
  323. package/extensions/ublock/img/flags-of-the-world/bb.png +0 -0
  324. package/extensions/ublock/img/flags-of-the-world/bd.png +0 -0
  325. package/extensions/ublock/img/flags-of-the-world/be.png +0 -0
  326. package/extensions/ublock/img/flags-of-the-world/bf.png +0 -0
  327. package/extensions/ublock/img/flags-of-the-world/bg.png +0 -0
  328. package/extensions/ublock/img/flags-of-the-world/bh.png +0 -0
  329. package/extensions/ublock/img/flags-of-the-world/bi.png +0 -0
  330. package/extensions/ublock/img/flags-of-the-world/bj.png +0 -0
  331. package/extensions/ublock/img/flags-of-the-world/bl.png +0 -0
  332. package/extensions/ublock/img/flags-of-the-world/bm.png +0 -0
  333. package/extensions/ublock/img/flags-of-the-world/bn.png +0 -0
  334. package/extensions/ublock/img/flags-of-the-world/bo.png +0 -0
  335. package/extensions/ublock/img/flags-of-the-world/bq.png +0 -0
  336. package/extensions/ublock/img/flags-of-the-world/br.png +0 -0
  337. package/extensions/ublock/img/flags-of-the-world/bs.png +0 -0
  338. package/extensions/ublock/img/flags-of-the-world/bt.png +0 -0
  339. package/extensions/ublock/img/flags-of-the-world/bv.png +0 -0
  340. package/extensions/ublock/img/flags-of-the-world/bw.png +0 -0
  341. package/extensions/ublock/img/flags-of-the-world/by.png +0 -0
  342. package/extensions/ublock/img/flags-of-the-world/bz.png +0 -0
  343. package/extensions/ublock/img/flags-of-the-world/ca.png +0 -0
  344. package/extensions/ublock/img/flags-of-the-world/cc.png +0 -0
  345. package/extensions/ublock/img/flags-of-the-world/cd.png +0 -0
  346. package/extensions/ublock/img/flags-of-the-world/cf.png +0 -0
  347. package/extensions/ublock/img/flags-of-the-world/cg.png +0 -0
  348. package/extensions/ublock/img/flags-of-the-world/ch.png +0 -0
  349. package/extensions/ublock/img/flags-of-the-world/ci.png +0 -0
  350. package/extensions/ublock/img/flags-of-the-world/ck.png +0 -0
  351. package/extensions/ublock/img/flags-of-the-world/cl.png +0 -0
  352. package/extensions/ublock/img/flags-of-the-world/cm.png +0 -0
  353. package/extensions/ublock/img/flags-of-the-world/cn.png +0 -0
  354. package/extensions/ublock/img/flags-of-the-world/co.png +0 -0
  355. package/extensions/ublock/img/flags-of-the-world/cr.png +0 -0
  356. package/extensions/ublock/img/flags-of-the-world/cu.png +0 -0
  357. package/extensions/ublock/img/flags-of-the-world/cv.png +0 -0
  358. package/extensions/ublock/img/flags-of-the-world/cw.png +0 -0
  359. package/extensions/ublock/img/flags-of-the-world/cx.png +0 -0
  360. package/extensions/ublock/img/flags-of-the-world/cy.png +0 -0
  361. package/extensions/ublock/img/flags-of-the-world/cz.png +0 -0
  362. package/extensions/ublock/img/flags-of-the-world/de.png +0 -0
  363. package/extensions/ublock/img/flags-of-the-world/dj.png +0 -0
  364. package/extensions/ublock/img/flags-of-the-world/dk.png +0 -0
  365. package/extensions/ublock/img/flags-of-the-world/dm.png +0 -0
  366. package/extensions/ublock/img/flags-of-the-world/do.png +0 -0
  367. package/extensions/ublock/img/flags-of-the-world/dz.png +0 -0
  368. package/extensions/ublock/img/flags-of-the-world/ec.png +0 -0
  369. package/extensions/ublock/img/flags-of-the-world/ee.png +0 -0
  370. package/extensions/ublock/img/flags-of-the-world/eg.png +0 -0
  371. package/extensions/ublock/img/flags-of-the-world/eh.png +0 -0
  372. package/extensions/ublock/img/flags-of-the-world/er.png +0 -0
  373. package/extensions/ublock/img/flags-of-the-world/es.png +0 -0
  374. package/extensions/ublock/img/flags-of-the-world/et.png +0 -0
  375. package/extensions/ublock/img/flags-of-the-world/fi.png +0 -0
  376. package/extensions/ublock/img/flags-of-the-world/fj.png +0 -0
  377. package/extensions/ublock/img/flags-of-the-world/fk.png +0 -0
  378. package/extensions/ublock/img/flags-of-the-world/fm.png +0 -0
  379. package/extensions/ublock/img/flags-of-the-world/fo.png +0 -0
  380. package/extensions/ublock/img/flags-of-the-world/fr.png +0 -0
  381. package/extensions/ublock/img/flags-of-the-world/ga.png +0 -0
  382. package/extensions/ublock/img/flags-of-the-world/gb-eng.png +0 -0
  383. package/extensions/ublock/img/flags-of-the-world/gb-nir.png +0 -0
  384. package/extensions/ublock/img/flags-of-the-world/gb-sct.png +0 -0
  385. package/extensions/ublock/img/flags-of-the-world/gb-wls.png +0 -0
  386. package/extensions/ublock/img/flags-of-the-world/gb.png +0 -0
  387. package/extensions/ublock/img/flags-of-the-world/gd.png +0 -0
  388. package/extensions/ublock/img/flags-of-the-world/ge.png +0 -0
  389. package/extensions/ublock/img/flags-of-the-world/gf.png +0 -0
  390. package/extensions/ublock/img/flags-of-the-world/gg.png +0 -0
  391. package/extensions/ublock/img/flags-of-the-world/gh.png +0 -0
  392. package/extensions/ublock/img/flags-of-the-world/gi.png +0 -0
  393. package/extensions/ublock/img/flags-of-the-world/gl.png +0 -0
  394. package/extensions/ublock/img/flags-of-the-world/gm.png +0 -0
  395. package/extensions/ublock/img/flags-of-the-world/gn.png +0 -0
  396. package/extensions/ublock/img/flags-of-the-world/gp.png +0 -0
  397. package/extensions/ublock/img/flags-of-the-world/gq.png +0 -0
  398. package/extensions/ublock/img/flags-of-the-world/gr.png +0 -0
  399. package/extensions/ublock/img/flags-of-the-world/gs.png +0 -0
  400. package/extensions/ublock/img/flags-of-the-world/gt.png +0 -0
  401. package/extensions/ublock/img/flags-of-the-world/gu.png +0 -0
  402. package/extensions/ublock/img/flags-of-the-world/gw.png +0 -0
  403. package/extensions/ublock/img/flags-of-the-world/gy.png +0 -0
  404. package/extensions/ublock/img/flags-of-the-world/hk.png +0 -0
  405. package/extensions/ublock/img/flags-of-the-world/hm.png +0 -0
  406. package/extensions/ublock/img/flags-of-the-world/hn.png +0 -0
  407. package/extensions/ublock/img/flags-of-the-world/hr.png +0 -0
  408. package/extensions/ublock/img/flags-of-the-world/ht.png +0 -0
  409. package/extensions/ublock/img/flags-of-the-world/hu.png +0 -0
  410. package/extensions/ublock/img/flags-of-the-world/id.png +0 -0
  411. package/extensions/ublock/img/flags-of-the-world/ie.png +0 -0
  412. package/extensions/ublock/img/flags-of-the-world/il.png +0 -0
  413. package/extensions/ublock/img/flags-of-the-world/im.png +0 -0
  414. package/extensions/ublock/img/flags-of-the-world/in.png +0 -0
  415. package/extensions/ublock/img/flags-of-the-world/io.png +0 -0
  416. package/extensions/ublock/img/flags-of-the-world/iq.png +0 -0
  417. package/extensions/ublock/img/flags-of-the-world/ir.png +0 -0
  418. package/extensions/ublock/img/flags-of-the-world/is.png +0 -0
  419. package/extensions/ublock/img/flags-of-the-world/it.png +0 -0
  420. package/extensions/ublock/img/flags-of-the-world/je.png +0 -0
  421. package/extensions/ublock/img/flags-of-the-world/jm.png +0 -0
  422. package/extensions/ublock/img/flags-of-the-world/jo.png +0 -0
  423. package/extensions/ublock/img/flags-of-the-world/jp.png +0 -0
  424. package/extensions/ublock/img/flags-of-the-world/ke.png +0 -0
  425. package/extensions/ublock/img/flags-of-the-world/kg.png +0 -0
  426. package/extensions/ublock/img/flags-of-the-world/kh.png +0 -0
  427. package/extensions/ublock/img/flags-of-the-world/ki.png +0 -0
  428. package/extensions/ublock/img/flags-of-the-world/km.png +0 -0
  429. package/extensions/ublock/img/flags-of-the-world/kn.png +0 -0
  430. package/extensions/ublock/img/flags-of-the-world/kp.png +0 -0
  431. package/extensions/ublock/img/flags-of-the-world/kr.png +0 -0
  432. package/extensions/ublock/img/flags-of-the-world/kw.png +0 -0
  433. package/extensions/ublock/img/flags-of-the-world/ky.png +0 -0
  434. package/extensions/ublock/img/flags-of-the-world/kz.png +0 -0
  435. package/extensions/ublock/img/flags-of-the-world/la.png +0 -0
  436. package/extensions/ublock/img/flags-of-the-world/lb.png +0 -0
  437. package/extensions/ublock/img/flags-of-the-world/lc.png +0 -0
  438. package/extensions/ublock/img/flags-of-the-world/li.png +0 -0
  439. package/extensions/ublock/img/flags-of-the-world/lk.png +0 -0
  440. package/extensions/ublock/img/flags-of-the-world/lr.png +0 -0
  441. package/extensions/ublock/img/flags-of-the-world/ls.png +0 -0
  442. package/extensions/ublock/img/flags-of-the-world/lt.png +0 -0
  443. package/extensions/ublock/img/flags-of-the-world/lu.png +0 -0
  444. package/extensions/ublock/img/flags-of-the-world/lv.png +0 -0
  445. package/extensions/ublock/img/flags-of-the-world/ly.png +0 -0
  446. package/extensions/ublock/img/flags-of-the-world/ma.png +0 -0
  447. package/extensions/ublock/img/flags-of-the-world/mc.png +0 -0
  448. package/extensions/ublock/img/flags-of-the-world/md.png +0 -0
  449. package/extensions/ublock/img/flags-of-the-world/me.png +0 -0
  450. package/extensions/ublock/img/flags-of-the-world/mf.png +0 -0
  451. package/extensions/ublock/img/flags-of-the-world/mg.png +0 -0
  452. package/extensions/ublock/img/flags-of-the-world/mh.png +0 -0
  453. package/extensions/ublock/img/flags-of-the-world/mk.png +0 -0
  454. package/extensions/ublock/img/flags-of-the-world/ml.png +0 -0
  455. package/extensions/ublock/img/flags-of-the-world/mm.png +0 -0
  456. package/extensions/ublock/img/flags-of-the-world/mn.png +0 -0
  457. package/extensions/ublock/img/flags-of-the-world/mo.png +0 -0
  458. package/extensions/ublock/img/flags-of-the-world/mp.png +0 -0
  459. package/extensions/ublock/img/flags-of-the-world/mq.png +0 -0
  460. package/extensions/ublock/img/flags-of-the-world/mr.png +0 -0
  461. package/extensions/ublock/img/flags-of-the-world/ms.png +0 -0
  462. package/extensions/ublock/img/flags-of-the-world/mt.png +0 -0
  463. package/extensions/ublock/img/flags-of-the-world/mu.png +0 -0
  464. package/extensions/ublock/img/flags-of-the-world/mv.png +0 -0
  465. package/extensions/ublock/img/flags-of-the-world/mw.png +0 -0
  466. package/extensions/ublock/img/flags-of-the-world/mx.png +0 -0
  467. package/extensions/ublock/img/flags-of-the-world/my.png +0 -0
  468. package/extensions/ublock/img/flags-of-the-world/mz.png +0 -0
  469. package/extensions/ublock/img/flags-of-the-world/na.png +0 -0
  470. package/extensions/ublock/img/flags-of-the-world/nc.png +0 -0
  471. package/extensions/ublock/img/flags-of-the-world/ne.png +0 -0
  472. package/extensions/ublock/img/flags-of-the-world/nf.png +0 -0
  473. package/extensions/ublock/img/flags-of-the-world/ng.png +0 -0
  474. package/extensions/ublock/img/flags-of-the-world/ni.png +0 -0
  475. package/extensions/ublock/img/flags-of-the-world/nl.png +0 -0
  476. package/extensions/ublock/img/flags-of-the-world/no.png +0 -0
  477. package/extensions/ublock/img/flags-of-the-world/np.png +0 -0
  478. package/extensions/ublock/img/flags-of-the-world/nr.png +0 -0
  479. package/extensions/ublock/img/flags-of-the-world/nu.png +0 -0
  480. package/extensions/ublock/img/flags-of-the-world/nz.png +0 -0
  481. package/extensions/ublock/img/flags-of-the-world/om.png +0 -0
  482. package/extensions/ublock/img/flags-of-the-world/pa.png +0 -0
  483. package/extensions/ublock/img/flags-of-the-world/pe.png +0 -0
  484. package/extensions/ublock/img/flags-of-the-world/pf.png +0 -0
  485. package/extensions/ublock/img/flags-of-the-world/pg.png +0 -0
  486. package/extensions/ublock/img/flags-of-the-world/ph.png +0 -0
  487. package/extensions/ublock/img/flags-of-the-world/pk.png +0 -0
  488. package/extensions/ublock/img/flags-of-the-world/pl.png +0 -0
  489. package/extensions/ublock/img/flags-of-the-world/pm.png +0 -0
  490. package/extensions/ublock/img/flags-of-the-world/pn.png +0 -0
  491. package/extensions/ublock/img/flags-of-the-world/pr.png +0 -0
  492. package/extensions/ublock/img/flags-of-the-world/ps.png +0 -0
  493. package/extensions/ublock/img/flags-of-the-world/pt.png +0 -0
  494. package/extensions/ublock/img/flags-of-the-world/pw.png +0 -0
  495. package/extensions/ublock/img/flags-of-the-world/py.png +0 -0
  496. package/extensions/ublock/img/flags-of-the-world/qa.png +0 -0
  497. package/extensions/ublock/img/flags-of-the-world/re.png +0 -0
  498. package/extensions/ublock/img/flags-of-the-world/ro.png +0 -0
  499. package/extensions/ublock/img/flags-of-the-world/rs.png +0 -0
  500. package/extensions/ublock/img/flags-of-the-world/ru.png +0 -0
  501. package/extensions/ublock/img/flags-of-the-world/rw.png +0 -0
  502. package/extensions/ublock/img/flags-of-the-world/sa.png +0 -0
  503. package/extensions/ublock/img/flags-of-the-world/sb.png +0 -0
  504. package/extensions/ublock/img/flags-of-the-world/sc.png +0 -0
  505. package/extensions/ublock/img/flags-of-the-world/sd.png +0 -0
  506. package/extensions/ublock/img/flags-of-the-world/se.png +0 -0
  507. package/extensions/ublock/img/flags-of-the-world/sg.png +0 -0
  508. package/extensions/ublock/img/flags-of-the-world/sh.png +0 -0
  509. package/extensions/ublock/img/flags-of-the-world/si.png +0 -0
  510. package/extensions/ublock/img/flags-of-the-world/sj.png +0 -0
  511. package/extensions/ublock/img/flags-of-the-world/sk.png +0 -0
  512. package/extensions/ublock/img/flags-of-the-world/sl.png +0 -0
  513. package/extensions/ublock/img/flags-of-the-world/sm.png +0 -0
  514. package/extensions/ublock/img/flags-of-the-world/sn.png +0 -0
  515. package/extensions/ublock/img/flags-of-the-world/so.png +0 -0
  516. package/extensions/ublock/img/flags-of-the-world/sr.png +0 -0
  517. package/extensions/ublock/img/flags-of-the-world/ss.png +0 -0
  518. package/extensions/ublock/img/flags-of-the-world/st.png +0 -0
  519. package/extensions/ublock/img/flags-of-the-world/sv.png +0 -0
  520. package/extensions/ublock/img/flags-of-the-world/sx.png +0 -0
  521. package/extensions/ublock/img/flags-of-the-world/sy.png +0 -0
  522. package/extensions/ublock/img/flags-of-the-world/sz.png +0 -0
  523. package/extensions/ublock/img/flags-of-the-world/tc.png +0 -0
  524. package/extensions/ublock/img/flags-of-the-world/td.png +0 -0
  525. package/extensions/ublock/img/flags-of-the-world/tf.png +0 -0
  526. package/extensions/ublock/img/flags-of-the-world/tg.png +0 -0
  527. package/extensions/ublock/img/flags-of-the-world/th.png +0 -0
  528. package/extensions/ublock/img/flags-of-the-world/tj.png +0 -0
  529. package/extensions/ublock/img/flags-of-the-world/tk.png +0 -0
  530. package/extensions/ublock/img/flags-of-the-world/tl.png +0 -0
  531. package/extensions/ublock/img/flags-of-the-world/tm.png +0 -0
  532. package/extensions/ublock/img/flags-of-the-world/tn.png +0 -0
  533. package/extensions/ublock/img/flags-of-the-world/to.png +0 -0
  534. package/extensions/ublock/img/flags-of-the-world/tr.png +0 -0
  535. package/extensions/ublock/img/flags-of-the-world/tt.png +0 -0
  536. package/extensions/ublock/img/flags-of-the-world/tv.png +0 -0
  537. package/extensions/ublock/img/flags-of-the-world/tw.png +0 -0
  538. package/extensions/ublock/img/flags-of-the-world/tz.png +0 -0
  539. package/extensions/ublock/img/flags-of-the-world/ua.png +0 -0
  540. package/extensions/ublock/img/flags-of-the-world/ug.png +0 -0
  541. package/extensions/ublock/img/flags-of-the-world/um.png +0 -0
  542. package/extensions/ublock/img/flags-of-the-world/us.png +0 -0
  543. package/extensions/ublock/img/flags-of-the-world/uy.png +0 -0
  544. package/extensions/ublock/img/flags-of-the-world/uz.png +0 -0
  545. package/extensions/ublock/img/flags-of-the-world/va.png +0 -0
  546. package/extensions/ublock/img/flags-of-the-world/vc.png +0 -0
  547. package/extensions/ublock/img/flags-of-the-world/ve.png +0 -0
  548. package/extensions/ublock/img/flags-of-the-world/vg.png +0 -0
  549. package/extensions/ublock/img/flags-of-the-world/vi.png +0 -0
  550. package/extensions/ublock/img/flags-of-the-world/vn.png +0 -0
  551. package/extensions/ublock/img/flags-of-the-world/vu.png +0 -0
  552. package/extensions/ublock/img/flags-of-the-world/wf.png +0 -0
  553. package/extensions/ublock/img/flags-of-the-world/ws.png +0 -0
  554. package/extensions/ublock/img/flags-of-the-world/xk.png +0 -0
  555. package/extensions/ublock/img/flags-of-the-world/ye.png +0 -0
  556. package/extensions/ublock/img/flags-of-the-world/yt.png +0 -0
  557. package/extensions/ublock/img/flags-of-the-world/za.png +0 -0
  558. package/extensions/ublock/img/flags-of-the-world/zm.png +0 -0
  559. package/extensions/ublock/img/flags-of-the-world/zw.png +0 -0
  560. package/extensions/ublock/img/fontawesome/LICENSE.txt +25 -0
  561. package/extensions/ublock/img/fontawesome/fontawesome-defs.svg +79 -0
  562. package/extensions/ublock/img/help16.png +0 -0
  563. package/extensions/ublock/img/icon_128.png +0 -0
  564. package/extensions/ublock/img/icon_16-loading.png +0 -0
  565. package/extensions/ublock/img/icon_16-off.png +0 -0
  566. package/extensions/ublock/img/icon_16.png +0 -0
  567. package/extensions/ublock/img/icon_32-loading.png +0 -0
  568. package/extensions/ublock/img/icon_32-off.png +0 -0
  569. package/extensions/ublock/img/icon_32.png +0 -0
  570. package/extensions/ublock/img/icon_64-loading.png +0 -0
  571. package/extensions/ublock/img/icon_64-off.png +0 -0
  572. package/extensions/ublock/img/icon_64.png +0 -0
  573. package/extensions/ublock/img/material-design.svg +16 -0
  574. package/extensions/ublock/img/photon.svg +16 -0
  575. package/extensions/ublock/img/ublock-defs.svg +27 -0
  576. package/extensions/ublock/img/ublock.svg +44 -0
  577. package/extensions/ublock/is-webrtc-supported.html +9 -0
  578. package/extensions/ublock/js/1p-filters.js +336 -0
  579. package/extensions/ublock/js/3p-filters.js +867 -0
  580. package/extensions/ublock/js/about.js +34 -0
  581. package/extensions/ublock/js/advanced-settings.js +194 -0
  582. package/extensions/ublock/js/asset-viewer.js +112 -0
  583. package/extensions/ublock/js/assets.js +1448 -0
  584. package/extensions/ublock/js/background.js +404 -0
  585. package/extensions/ublock/js/base64-custom.js +246 -0
  586. package/extensions/ublock/js/benchmarks.js +421 -0
  587. package/extensions/ublock/js/biditrie.js +947 -0
  588. package/extensions/ublock/js/cachestorage.js +510 -0
  589. package/extensions/ublock/js/click2load.js +60 -0
  590. package/extensions/ublock/js/cloud-ui.js +238 -0
  591. package/extensions/ublock/js/code-viewer.js +311 -0
  592. package/extensions/ublock/js/codemirror/search-thread.js +199 -0
  593. package/extensions/ublock/js/codemirror/search.js +504 -0
  594. package/extensions/ublock/js/codemirror/ubo-dynamic-filtering.js +239 -0
  595. package/extensions/ublock/js/codemirror/ubo-static-filtering.js +1126 -0
  596. package/extensions/ublock/js/commands.js +181 -0
  597. package/extensions/ublock/js/console.js +59 -0
  598. package/extensions/ublock/js/contentscript-extra.js +662 -0
  599. package/extensions/ublock/js/contentscript.js +1366 -0
  600. package/extensions/ublock/js/contextmenu.js +270 -0
  601. package/extensions/ublock/js/cosmetic-filtering.js +983 -0
  602. package/extensions/ublock/js/dashboard-common.js +215 -0
  603. package/extensions/ublock/js/dashboard.js +166 -0
  604. package/extensions/ublock/js/devtools.js +184 -0
  605. package/extensions/ublock/js/diff-updater.js +288 -0
  606. package/extensions/ublock/js/document-blocked.js +230 -0
  607. package/extensions/ublock/js/dom.js +213 -0
  608. package/extensions/ublock/js/dyna-rules.js +678 -0
  609. package/extensions/ublock/js/dynamic-net-filtering.js +488 -0
  610. package/extensions/ublock/js/epicker-ui.js +924 -0
  611. package/extensions/ublock/js/fa-icons.js +129 -0
  612. package/extensions/ublock/js/filtering-context.js +461 -0
  613. package/extensions/ublock/js/filtering-engines.js +50 -0
  614. package/extensions/ublock/js/hnswitches.js +289 -0
  615. package/extensions/ublock/js/hntrie.js +780 -0
  616. package/extensions/ublock/js/html-filtering.js +465 -0
  617. package/extensions/ublock/js/httpheader-filtering.js +213 -0
  618. package/extensions/ublock/js/i18n.js +346 -0
  619. package/extensions/ublock/js/is-webrtc-supported.js +52 -0
  620. package/extensions/ublock/js/logger-ui-inspector.js +652 -0
  621. package/extensions/ublock/js/logger-ui.js +3028 -0
  622. package/extensions/ublock/js/logger.js +84 -0
  623. package/extensions/ublock/js/lz4.js +190 -0
  624. package/extensions/ublock/js/messaging.js +2095 -0
  625. package/extensions/ublock/js/pagestore.js +1140 -0
  626. package/extensions/ublock/js/popup-fenix.js +1529 -0
  627. package/extensions/ublock/js/redirect-engine.js +494 -0
  628. package/extensions/ublock/js/redirect-resources.js +193 -0
  629. package/extensions/ublock/js/reverselookup-worker.js +287 -0
  630. package/extensions/ublock/js/reverselookup.js +223 -0
  631. package/extensions/ublock/js/scriptlet-filtering.js +556 -0
  632. package/extensions/ublock/js/scriptlets/cosmetic-logger.js +376 -0
  633. package/extensions/ublock/js/scriptlets/cosmetic-off.js +48 -0
  634. package/extensions/ublock/js/scriptlets/cosmetic-on.js +48 -0
  635. package/extensions/ublock/js/scriptlets/cosmetic-report.js +142 -0
  636. package/extensions/ublock/js/scriptlets/dom-inspector.js +906 -0
  637. package/extensions/ublock/js/scriptlets/dom-survey-elements.js +72 -0
  638. package/extensions/ublock/js/scriptlets/dom-survey-scripts.js +126 -0
  639. package/extensions/ublock/js/scriptlets/epicker.js +1365 -0
  640. package/extensions/ublock/js/scriptlets/load-3p-css.js +67 -0
  641. package/extensions/ublock/js/scriptlets/load-large-media-all.js +62 -0
  642. package/extensions/ublock/js/scriptlets/load-large-media-interactive.js +299 -0
  643. package/extensions/ublock/js/scriptlets/noscript-spoof.js +89 -0
  644. package/extensions/ublock/js/scriptlets/should-inject-contentscript.js +40 -0
  645. package/extensions/ublock/js/scriptlets/subscriber.js +113 -0
  646. package/extensions/ublock/js/scriptlets/updater.js +101 -0
  647. package/extensions/ublock/js/settings.js +317 -0
  648. package/extensions/ublock/js/start.js +509 -0
  649. package/extensions/ublock/js/static-dnr-filtering.js +497 -0
  650. package/extensions/ublock/js/static-ext-filtering-db.js +171 -0
  651. package/extensions/ublock/js/static-ext-filtering.js +184 -0
  652. package/extensions/ublock/js/static-filtering-io.js +144 -0
  653. package/extensions/ublock/js/static-filtering-parser.js +4459 -0
  654. package/extensions/ublock/js/static-net-filtering.js +5631 -0
  655. package/extensions/ublock/js/storage.js +1683 -0
  656. package/extensions/ublock/js/support.js +335 -0
  657. package/extensions/ublock/js/tab.js +1178 -0
  658. package/extensions/ublock/js/tasks.js +42 -0
  659. package/extensions/ublock/js/text-encode.js +275 -0
  660. package/extensions/ublock/js/text-utils.js +107 -0
  661. package/extensions/ublock/js/theme.js +151 -0
  662. package/extensions/ublock/js/traffic.js +1260 -0
  663. package/extensions/ublock/js/ublock.js +696 -0
  664. package/extensions/ublock/js/uri-utils.js +175 -0
  665. package/extensions/ublock/js/url-net-filtering.js +336 -0
  666. package/extensions/ublock/js/utils.js +208 -0
  667. package/extensions/ublock/js/vapi-background-ext.js +254 -0
  668. package/extensions/ublock/js/vapi-background.js +1802 -0
  669. package/extensions/ublock/js/vapi-client-extra.js +312 -0
  670. package/extensions/ublock/js/vapi-client.js +280 -0
  671. package/extensions/ublock/js/vapi-common.js +308 -0
  672. package/extensions/ublock/js/vapi.js +89 -0
  673. package/extensions/ublock/js/wasm/README.md +24 -0
  674. package/extensions/ublock/js/wasm/biditrie.wasm +0 -0
  675. package/extensions/ublock/js/wasm/biditrie.wat +728 -0
  676. package/extensions/ublock/js/wasm/hntrie.wasm +0 -0
  677. package/extensions/ublock/js/wasm/hntrie.wat +724 -0
  678. package/extensions/ublock/js/webext.js +164 -0
  679. package/extensions/ublock/js/whitelist.js +258 -0
  680. package/extensions/ublock/lib/codemirror/LICENSE +21 -0
  681. package/extensions/ublock/lib/codemirror/README.md +47 -0
  682. package/extensions/ublock/lib/codemirror/addon/comment/comment.js +211 -0
  683. package/extensions/ublock/lib/codemirror/addon/display/panel.js +133 -0
  684. package/extensions/ublock/lib/codemirror/addon/edit/closebrackets.js +201 -0
  685. package/extensions/ublock/lib/codemirror/addon/edit/matchbrackets.js +160 -0
  686. package/extensions/ublock/lib/codemirror/addon/fold/foldcode.js +157 -0
  687. package/extensions/ublock/lib/codemirror/addon/fold/foldgutter.css +20 -0
  688. package/extensions/ublock/lib/codemirror/addon/fold/foldgutter.js +163 -0
  689. package/extensions/ublock/lib/codemirror/addon/hint/show-hint.css +36 -0
  690. package/extensions/ublock/lib/codemirror/addon/hint/show-hint.js +509 -0
  691. package/extensions/ublock/lib/codemirror/addon/merge/merge.css +119 -0
  692. package/extensions/ublock/lib/codemirror/addon/merge/merge.js +1006 -0
  693. package/extensions/ublock/lib/codemirror/addon/scroll/annotatescrollbar.js +128 -0
  694. package/extensions/ublock/lib/codemirror/addon/search/matchesonscrollbar.css +8 -0
  695. package/extensions/ublock/lib/codemirror/addon/search/searchcursor.js +296 -0
  696. package/extensions/ublock/lib/codemirror/addon/selection/active-line.js +72 -0
  697. package/extensions/ublock/lib/codemirror/lib/codemirror.css +350 -0
  698. package/extensions/ublock/lib/codemirror/lib/codemirror.js +9800 -0
  699. package/extensions/ublock/lib/codemirror/mode/css/css.js +864 -0
  700. package/extensions/ublock/lib/codemirror/mode/htmlmixed/htmlmixed.js +153 -0
  701. package/extensions/ublock/lib/codemirror/mode/javascript/javascript.js +942 -0
  702. package/extensions/ublock/lib/codemirror/mode/xml/xml.js +413 -0
  703. package/extensions/ublock/lib/codemirror/theme/night.css +27 -0
  704. package/extensions/ublock/lib/csstree/LICENSE +19 -0
  705. package/extensions/ublock/lib/csstree/css-tree.js +17 -0
  706. package/extensions/ublock/lib/diff/README.md +34 -0
  707. package/extensions/ublock/lib/diff/swatinem_diff.js +272 -0
  708. package/extensions/ublock/lib/hsluv/LICENSE +20 -0
  709. package/extensions/ublock/lib/hsluv/README +3 -0
  710. package/extensions/ublock/lib/hsluv/hsluv-0.1.0.min.js +8 -0
  711. package/extensions/ublock/lib/js-beautify/LICENSE +9 -0
  712. package/extensions/ublock/lib/js-beautify/README +5 -0
  713. package/extensions/ublock/lib/js-beautify/beautifier.min.js +2 -0
  714. package/extensions/ublock/lib/lz4/README.md +52 -0
  715. package/extensions/ublock/lib/lz4/lz4-block-codec-any.js +151 -0
  716. package/extensions/ublock/lib/lz4/lz4-block-codec-js.js +297 -0
  717. package/extensions/ublock/lib/lz4/lz4-block-codec-wasm.js +195 -0
  718. package/extensions/ublock/lib/lz4/lz4-block-codec.wasm +0 -0
  719. package/extensions/ublock/lib/lz4/lz4-block-codec.wat +745 -0
  720. package/extensions/ublock/lib/publicsuffixlist/publicsuffixlist.js +641 -0
  721. package/extensions/ublock/lib/publicsuffixlist/wasm/README.md +29 -0
  722. package/extensions/ublock/lib/publicsuffixlist/wasm/publicsuffixlist.wasm +0 -0
  723. package/extensions/ublock/lib/publicsuffixlist/wasm/publicsuffixlist.wat +322 -0
  724. package/extensions/ublock/lib/punycode.js +493 -0
  725. package/extensions/ublock/lib/regexanalyzer/CHANGES.md +15 -0
  726. package/extensions/ublock/lib/regexanalyzer/README.md +14 -0
  727. package/extensions/ublock/lib/regexanalyzer/regex.js +2276 -0
  728. package/extensions/ublock/logger-ui.html +232 -0
  729. package/extensions/ublock/managed_storage.json +73 -0
  730. package/extensions/ublock/manifest.json +115 -0
  731. package/extensions/ublock/no-dashboard.html +27 -0
  732. package/extensions/ublock/popup-fenix.html +114 -0
  733. package/extensions/ublock/settings.html +98 -0
  734. package/extensions/ublock/support.html +131 -0
  735. package/extensions/ublock/web_accessible_resources/1x1.gif +0 -0
  736. package/extensions/ublock/web_accessible_resources/2x2.png +0 -0
  737. package/extensions/ublock/web_accessible_resources/32x32.png +0 -0
  738. package/extensions/ublock/web_accessible_resources/3x2.png +0 -0
  739. package/extensions/ublock/web_accessible_resources/README.txt +11 -0
  740. package/extensions/ublock/web_accessible_resources/addthis_widget.js +39 -0
  741. package/extensions/ublock/web_accessible_resources/amazon_ads.js +70 -0
  742. package/extensions/ublock/web_accessible_resources/amazon_apstag.js +62 -0
  743. package/extensions/ublock/web_accessible_resources/ampproject_v0.js +34 -0
  744. package/extensions/ublock/web_accessible_resources/chartbeat.js +30 -0
  745. package/extensions/ublock/web_accessible_resources/click2load.html +28 -0
  746. package/extensions/ublock/web_accessible_resources/doubleclick_instream_ad_status.js +1 -0
  747. package/extensions/ublock/web_accessible_resources/empty +0 -0
  748. package/extensions/ublock/web_accessible_resources/epicker-ui.html +76 -0
  749. package/extensions/ublock/web_accessible_resources/fingerprint2.js +55 -0
  750. package/extensions/ublock/web_accessible_resources/fingerprint3.js +45 -0
  751. package/extensions/ublock/web_accessible_resources/google-analytics_analytics.js +110 -0
  752. package/extensions/ublock/web_accessible_resources/google-analytics_cx_api.js +36 -0
  753. package/extensions/ublock/web_accessible_resources/google-analytics_ga.js +130 -0
  754. package/extensions/ublock/web_accessible_resources/google-analytics_inpage_linkid.js +28 -0
  755. package/extensions/ublock/web_accessible_resources/google-ima.js +855 -0
  756. package/extensions/ublock/web_accessible_resources/googlesyndication_adsbygoogle.js +56 -0
  757. package/extensions/ublock/web_accessible_resources/googletagmanager_gtm.js +43 -0
  758. package/extensions/ublock/web_accessible_resources/googletagservices_gpt.js +153 -0
  759. package/extensions/ublock/web_accessible_resources/hd-main.js +46 -0
  760. package/extensions/ublock/web_accessible_resources/ligatus_angular-tag.js +29 -0
  761. package/extensions/ublock/web_accessible_resources/monkeybroker.js +43 -0
  762. package/extensions/ublock/web_accessible_resources/mxpnl_mixpanel.js +51 -0
  763. package/extensions/ublock/web_accessible_resources/nobab.js +87 -0
  764. package/extensions/ublock/web_accessible_resources/nobab2.js +42 -0
  765. package/extensions/ublock/web_accessible_resources/noeval-silent.js +28 -0
  766. package/extensions/ublock/web_accessible_resources/noeval.js +30 -0
  767. package/extensions/ublock/web_accessible_resources/nofab.js +67 -0
  768. package/extensions/ublock/web_accessible_resources/noop-0.1s.mp3 +0 -0
  769. package/extensions/ublock/web_accessible_resources/noop-0.5s.mp3 +0 -0
  770. package/extensions/ublock/web_accessible_resources/noop-1s.mp4 +0 -0
  771. package/extensions/ublock/web_accessible_resources/noop-vmap1.0.xml +1 -0
  772. package/extensions/ublock/web_accessible_resources/noop.css +1 -0
  773. package/extensions/ublock/web_accessible_resources/noop.html +5 -0
  774. package/extensions/ublock/web_accessible_resources/noop.js +3 -0
  775. package/extensions/ublock/web_accessible_resources/noop.json +1 -0
  776. package/extensions/ublock/web_accessible_resources/noop.txt +1 -0
  777. package/extensions/ublock/web_accessible_resources/outbrain-widget.js +72 -0
  778. package/extensions/ublock/web_accessible_resources/popads-dummy.js +30 -0
  779. package/extensions/ublock/web_accessible_resources/popads.js +40 -0
  780. package/extensions/ublock/web_accessible_resources/prebid-ads.js +26 -0
  781. package/extensions/ublock/web_accessible_resources/scorecardresearch_beacon.js +31 -0
  782. package/extensions/ublock/whitelist.html +63 -0
  783. package/external/.gitkeep +0 -0
  784. package/fonts/Calibri Bold Italic.ttf +0 -0
  785. package/fonts/Calibri Bold.TTF +0 -0
  786. package/fonts/Calibri Italic.ttf +0 -0
  787. package/fonts/Calibri Light Italic.ttf +0 -0
  788. package/fonts/Calibri Light.ttf +0 -0
  789. package/fonts/Calibri Regular.ttf +0 -0
  790. package/fonts/Emoji.ttf +0 -0
  791. package/fonts/SegoeUI-Bold.ttf +0 -0
  792. package/fonts/SegoeUI-Light.ttf +0 -0
  793. package/fonts/SegoeUI-Regular.ttf +0 -0
  794. package/fonts/SegoeUI-Semibold.ttf +0 -0
  795. package/fonts/SegoeUI-Semilight.ttf +0 -0
  796. package/fonts/Tahoma Bold.ttf +0 -0
  797. package/fonts/Tahoma.ttf +0 -0
  798. package/fonts/fonts.conf +21 -0
  799. package/package.json +177 -0
  800. package/scripts/build-function.js +18 -0
  801. package/scripts/build-open-api.js +274 -0
  802. package/scripts/build-schemas.js +86 -0
  803. package/scripts/build-selectors.js +36 -0
  804. package/scripts/clean.js +7 -0
  805. package/scripts/install-adblock.js +45 -0
  806. package/scripts/install-cdp-json.js +37 -0
  807. package/scripts/start.sh +30 -0
  808. package/scripts/test.sh +17 -0
  809. package/src/browserless.ts +253 -0
  810. package/src/browsers/cdp-chromium.ts +422 -0
  811. package/src/browsers/index.ts +296 -0
  812. package/src/browsers/playwright-chromium.ts +168 -0
  813. package/src/browsers/playwright-firefox.ts +161 -0
  814. package/src/browsers/playwright-webkit.ts +161 -0
  815. package/src/config.ts +426 -0
  816. package/src/constants.ts +4 -0
  817. package/src/exports.ts +23 -0
  818. package/src/file-system.ts +54 -0
  819. package/src/hooks.ts +37 -0
  820. package/src/http.ts +157 -0
  821. package/src/index.ts +41 -0
  822. package/src/limiter.spec.ts +365 -0
  823. package/src/limiter.ts +225 -0
  824. package/src/metrics.spec.ts +49 -0
  825. package/src/metrics.ts +108 -0
  826. package/src/mime-types.ts +332 -0
  827. package/src/monitoring.ts +53 -0
  828. package/src/routes/chromium/http/content-post.ts +238 -0
  829. package/src/routes/chromium/http/download-post.ts +162 -0
  830. package/src/routes/chromium/http/function-post.ts +98 -0
  831. package/src/routes/chromium/http/pdf-post.ts +234 -0
  832. package/src/routes/chromium/http/performance.ts +71 -0
  833. package/src/routes/chromium/http/scrape-post.ts +439 -0
  834. package/src/routes/chromium/http/screenshot-post.ts +262 -0
  835. package/src/routes/chromium/tests/content.spec.ts +340 -0
  836. package/src/routes/chromium/tests/download.spec.ts +77 -0
  837. package/src/routes/chromium/tests/function.spec.ts +279 -0
  838. package/src/routes/chromium/tests/pdf.spec.ts +375 -0
  839. package/src/routes/chromium/tests/performance.spec.ts +155 -0
  840. package/src/routes/chromium/tests/scrape.spec.ts +414 -0
  841. package/src/routes/chromium/tests/screenshot.spec.ts +387 -0
  842. package/src/routes/chromium/tests/websocket.spec.ts +407 -0
  843. package/src/routes/chromium/utils/function/client.ts +99 -0
  844. package/src/routes/chromium/utils/function/handler.ts +172 -0
  845. package/src/routes/chromium/utils/performance/child.ts +38 -0
  846. package/src/routes/chromium/utils/performance/main.ts +90 -0
  847. package/src/routes/chromium/utils/performance/types.ts +24 -0
  848. package/src/routes/chromium/ws/browser.ts +31 -0
  849. package/src/routes/chromium/ws/cdp-chromium.ts +31 -0
  850. package/src/routes/chromium/ws/page.ts +31 -0
  851. package/src/routes/chromium/ws/playwright-chromium.ts +44 -0
  852. package/src/routes/firefox/tests/websocket.spec.ts +146 -0
  853. package/src/routes/firefox/ws/playwright-firefox.ts +44 -0
  854. package/src/routes/management/http/config-get.ts +82 -0
  855. package/src/routes/management/http/metrics-get.ts +43 -0
  856. package/src/routes/management/http/metrics-total-get.ts +89 -0
  857. package/src/routes/management/http/sessions-get.ts +39 -0
  858. package/src/routes/management/http/static-get.ts +109 -0
  859. package/src/routes/management/tests/management.spec.ts +71 -0
  860. package/src/routes/webkit/tests/websocket.spec.ts +146 -0
  861. package/src/routes/webkit/ws/playwright-webkit.ts +44 -0
  862. package/src/server.ts +609 -0
  863. package/src/shim.spec.ts +154 -0
  864. package/src/shim.ts +78 -0
  865. package/src/types.ts +470 -0
  866. package/src/utils.ts +787 -0
  867. package/src/webhooks.ts +50 -0
  868. package/static/docs/browserless-logo.png +0 -0
  869. package/static/docs/docs.js +2 -0
  870. package/static/docs/index.html +71 -0
  871. package/static/docs/swagger.json +4232 -0
  872. package/static/favicon-32x32.png +0 -0
  873. package/static/function/client.js +31623 -0
  874. package/static/function/index.html +12 -0
  875. package/tsconfig.json +31 -0
@@ -0,0 +1,1683 @@
1
+ /*******************************************************************************
2
+
3
+ uBlock Origin - a browser extension to block requests.
4
+ Copyright (C) 2014-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
+ /* globals WebAssembly */
23
+
24
+ 'use strict';
25
+
26
+ /******************************************************************************/
27
+
28
+ import publicSuffixList from '../lib/publicsuffixlist/publicsuffixlist.js';
29
+ import punycode from '../lib/punycode.js';
30
+
31
+ import cosmeticFilteringEngine from './cosmetic-filtering.js';
32
+ import io from './assets.js';
33
+ import logger from './logger.js';
34
+ import lz4Codec from './lz4.js';
35
+ import staticExtFilteringEngine from './static-ext-filtering.js';
36
+ import staticFilteringReverseLookup from './reverselookup.js';
37
+ import staticNetFilteringEngine from './static-net-filtering.js';
38
+ import µb from './background.js';
39
+ import { hostnameFromURI } from './uri-utils.js';
40
+ import { i18n, i18n$ } from './i18n.js';
41
+ import { redirectEngine } from './redirect-engine.js';
42
+ import { sparseBase64 } from './base64-custom.js';
43
+ import { ubolog, ubologSet } from './console.js';
44
+ import * as sfp from './static-filtering-parser.js';
45
+
46
+ import {
47
+ permanentFirewall,
48
+ permanentSwitches,
49
+ permanentURLFiltering,
50
+ } from './filtering-engines.js';
51
+
52
+ import {
53
+ CompiledListReader,
54
+ CompiledListWriter,
55
+ } from './static-filtering-io.js';
56
+
57
+ import {
58
+ LineIterator,
59
+ orphanizeString,
60
+ } from './text-utils.js';
61
+
62
+ /******************************************************************************/
63
+
64
+ µb.getBytesInUse = async function() {
65
+ const promises = [];
66
+ let bytesInUse;
67
+
68
+ // Not all platforms implement this method.
69
+ promises.push(
70
+ vAPI.storage.getBytesInUse instanceof Function
71
+ ? vAPI.storage.getBytesInUse(null)
72
+ : undefined
73
+ );
74
+
75
+ if (
76
+ navigator.storage instanceof Object &&
77
+ navigator.storage.estimate instanceof Function
78
+ ) {
79
+ promises.push(navigator.storage.estimate());
80
+ }
81
+
82
+ const results = await Promise.all(promises);
83
+
84
+ const processCount = count => {
85
+ if ( typeof count !== 'number' ) { return; }
86
+ if ( bytesInUse === undefined ) { bytesInUse = 0; }
87
+ bytesInUse += count;
88
+ return bytesInUse;
89
+ };
90
+
91
+ processCount(results[0]);
92
+ if ( results.length > 1 && results[1] instanceof Object ) {
93
+ processCount(results[1].usage);
94
+ }
95
+ µb.storageUsed = bytesInUse;
96
+ return bytesInUse;
97
+ };
98
+
99
+ /******************************************************************************/
100
+
101
+ {
102
+ let localSettingsLastSaved = Date.now();
103
+
104
+ const shouldSave = ( ) => {
105
+ if ( µb.localSettingsLastModified > localSettingsLastSaved ) {
106
+ µb.saveLocalSettings();
107
+ }
108
+ saveTimer.on(saveDelay);
109
+ };
110
+
111
+ const saveTimer = vAPI.defer.create(shouldSave);
112
+ const saveDelay = { min: 4 };
113
+
114
+ saveTimer.on(saveDelay);
115
+
116
+ µb.saveLocalSettings = function() {
117
+ localSettingsLastSaved = Date.now();
118
+ return vAPI.storage.set(this.localSettings);
119
+ };
120
+ }
121
+
122
+ /******************************************************************************/
123
+
124
+ µb.loadUserSettings = async function() {
125
+ const usDefault = this.userSettingsDefault;
126
+
127
+ const results = await Promise.all([
128
+ vAPI.storage.get(Object.assign(usDefault)),
129
+ vAPI.adminStorage.get('userSettings'),
130
+ ]);
131
+
132
+ const usUser = results[0] instanceof Object && results[0] ||
133
+ Object.assign(usDefault);
134
+
135
+ if ( Array.isArray(results[1]) ) {
136
+ const adminSettings = results[1];
137
+ for ( const entry of adminSettings ) {
138
+ if ( entry.length < 1 ) { continue; }
139
+ const name = entry[0];
140
+ if ( usDefault.hasOwnProperty(name) === false ) { continue; }
141
+ const value = entry.length < 2
142
+ ? usDefault[name]
143
+ : this.settingValueFromString(usDefault, name, entry[1]);
144
+ if ( value === undefined ) { continue; }
145
+ usUser[name] = usDefault[name] = value;
146
+ }
147
+ }
148
+
149
+ return usUser;
150
+ };
151
+
152
+ µb.saveUserSettings = function() {
153
+ // `externalLists` will be deprecated in some future, it is kept around
154
+ // for forward compatibility purpose, and should reflect the content of
155
+ // `importedLists`.
156
+ //
157
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/1803
158
+ // Do this before computing modified settings.
159
+ this.userSettings.externalLists =
160
+ this.userSettings.importedLists.join('\n');
161
+
162
+ const toSave = this.getModifiedSettings(
163
+ this.userSettings,
164
+ this.userSettingsDefault
165
+ );
166
+
167
+ const toRemove = [];
168
+ for ( const key in this.userSettings ) {
169
+ if ( this.userSettings.hasOwnProperty(key) === false ) { continue; }
170
+ if ( toSave.hasOwnProperty(key) ) { continue; }
171
+ toRemove.push(key);
172
+ }
173
+ if ( toRemove.length !== 0 ) {
174
+ vAPI.storage.remove(toRemove);
175
+ }
176
+ vAPI.storage.set(toSave);
177
+ };
178
+
179
+ /******************************************************************************/
180
+
181
+ // Admin hidden settings have precedence over user hidden settings.
182
+
183
+ µb.loadHiddenSettings = async function() {
184
+ const hsDefault = this.hiddenSettingsDefault;
185
+ const hsAdmin = this.hiddenSettingsAdmin;
186
+ const hsUser = this.hiddenSettings;
187
+
188
+ const results = await Promise.all([
189
+ vAPI.adminStorage.get([
190
+ 'advancedSettings',
191
+ 'disableDashboard',
192
+ 'disabledPopupPanelParts',
193
+ ]),
194
+ vAPI.storage.get('hiddenSettings'),
195
+ ]);
196
+
197
+ if ( results[0] instanceof Object ) {
198
+ const {
199
+ advancedSettings,
200
+ disableDashboard,
201
+ disabledPopupPanelParts
202
+ } = results[0];
203
+ if ( Array.isArray(advancedSettings) ) {
204
+ for ( const entry of advancedSettings ) {
205
+ if ( entry.length < 1 ) { continue; }
206
+ const name = entry[0];
207
+ if ( hsDefault.hasOwnProperty(name) === false ) { continue; }
208
+ const value = entry.length < 2
209
+ ? hsDefault[name]
210
+ : this.hiddenSettingValueFromString(name, entry[1]);
211
+ if ( value === undefined ) { continue; }
212
+ hsDefault[name] = hsAdmin[name] = hsUser[name] = value;
213
+ }
214
+ }
215
+ µb.noDashboard = disableDashboard === true;
216
+ if ( Array.isArray(disabledPopupPanelParts) ) {
217
+ const partNameToBit = new Map([
218
+ [ 'globalStats', 0b00010 ],
219
+ [ 'basicTools', 0b00100 ],
220
+ [ 'extraTools', 0b01000 ],
221
+ [ 'overviewPane', 0b10000 ],
222
+ ]);
223
+ let bits = hsDefault.popupPanelDisabledSections;
224
+ for ( const part of disabledPopupPanelParts ) {
225
+ const bit = partNameToBit.get(part);
226
+ if ( bit === undefined ) { continue; }
227
+ bits |= bit;
228
+ }
229
+ hsDefault.popupPanelDisabledSections =
230
+ hsAdmin.popupPanelDisabledSections =
231
+ hsUser.popupPanelDisabledSections = bits;
232
+ }
233
+ }
234
+
235
+ const hs = results[1] instanceof Object && results[1].hiddenSettings || {};
236
+ if ( Object.keys(hsAdmin).length === 0 && Object.keys(hs).length === 0 ) {
237
+ return;
238
+ }
239
+
240
+ for ( const key in hsDefault ) {
241
+ if ( hsDefault.hasOwnProperty(key) === false ) { continue; }
242
+ if ( hsAdmin.hasOwnProperty(name) ) { continue; }
243
+ if ( typeof hs[key] !== typeof hsDefault[key] ) { continue; }
244
+ this.hiddenSettings[key] = hs[key];
245
+ }
246
+ this.fireEvent('hiddenSettingsChanged');
247
+ };
248
+
249
+ // Note: Save only the settings which values differ from the default ones.
250
+ // This way the new default values in the future will properly apply for
251
+ // those which were not modified by the user.
252
+
253
+ µb.saveHiddenSettings = function() {
254
+ vAPI.storage.set({
255
+ hiddenSettings: this.getModifiedSettings(
256
+ this.hiddenSettings,
257
+ this.hiddenSettingsDefault
258
+ )
259
+ });
260
+ };
261
+
262
+ µb.onEvent('hiddenSettingsChanged', ( ) => {
263
+ const µbhs = µb.hiddenSettings;
264
+ ubologSet(µbhs.consoleLogLevel === 'info');
265
+ vAPI.net.setOptions({
266
+ cnameIgnoreList: µbhs.cnameIgnoreList,
267
+ cnameIgnore1stParty: µbhs.cnameIgnore1stParty,
268
+ cnameIgnoreExceptions: µbhs.cnameIgnoreExceptions,
269
+ cnameIgnoreRootDocument: µbhs.cnameIgnoreRootDocument,
270
+ cnameMaxTTL: µbhs.cnameMaxTTL,
271
+ cnameReplayFullURL: µbhs.cnameReplayFullURL,
272
+ cnameUncloakProxied: µbhs.cnameUncloakProxied,
273
+ });
274
+ });
275
+
276
+ /******************************************************************************/
277
+
278
+ µb.hiddenSettingsFromString = function(raw) {
279
+ const out = Object.assign({}, this.hiddenSettingsDefault);
280
+ const lineIter = new LineIterator(raw);
281
+ while ( lineIter.eot() === false ) {
282
+ const line = lineIter.next();
283
+ const matches = /^\s*(\S+)\s+(.+)$/.exec(line);
284
+ if ( matches === null || matches.length !== 3 ) { continue; }
285
+ const name = matches[1];
286
+ if ( out.hasOwnProperty(name) === false ) { continue; }
287
+ if ( this.hiddenSettingsAdmin.hasOwnProperty(name) ) { continue; }
288
+ const value = this.hiddenSettingValueFromString(name, matches[2]);
289
+ if ( value !== undefined ) {
290
+ out[name] = value;
291
+ }
292
+ }
293
+ return out;
294
+ };
295
+
296
+ µb.hiddenSettingValueFromString = function(name, value) {
297
+ if ( typeof name !== 'string' || typeof value !== 'string' ) { return; }
298
+ const hsDefault = this.hiddenSettingsDefault;
299
+ if ( hsDefault.hasOwnProperty(name) === false ) { return; }
300
+ let r;
301
+ switch ( typeof hsDefault[name] ) {
302
+ case 'boolean':
303
+ if ( value === 'true' ) {
304
+ r = true;
305
+ } else if ( value === 'false' ) {
306
+ r = false;
307
+ }
308
+ break;
309
+ case 'string':
310
+ r = value.trim();
311
+ break;
312
+ case 'number':
313
+ if ( value.startsWith('0b') ) {
314
+ r = parseInt(value.slice(2), 2);
315
+ } else if ( value.startsWith('0x') ) {
316
+ r = parseInt(value.slice(2), 16);
317
+ } else {
318
+ r = parseInt(value, 10);
319
+ }
320
+ if ( isNaN(r) ) { r = undefined; }
321
+ break;
322
+ default:
323
+ break;
324
+ }
325
+ return r;
326
+ };
327
+
328
+ µb.stringFromHiddenSettings = function() {
329
+ const out = [];
330
+ for ( const key of Object.keys(this.hiddenSettings).sort() ) {
331
+ out.push(key + ' ' + this.hiddenSettings[key]);
332
+ }
333
+ return out.join('\n');
334
+ };
335
+
336
+ /******************************************************************************/
337
+
338
+ µb.savePermanentFirewallRules = function() {
339
+ vAPI.storage.set({
340
+ dynamicFilteringString: permanentFirewall.toString()
341
+ });
342
+ };
343
+
344
+ /******************************************************************************/
345
+
346
+ µb.savePermanentURLFilteringRules = function() {
347
+ vAPI.storage.set({
348
+ urlFilteringString: permanentURLFiltering.toString()
349
+ });
350
+ };
351
+
352
+ /******************************************************************************/
353
+
354
+ µb.saveHostnameSwitches = function() {
355
+ vAPI.storage.set({
356
+ hostnameSwitchesString: permanentSwitches.toString()
357
+ });
358
+ };
359
+
360
+ /******************************************************************************/
361
+
362
+ µb.saveWhitelist = function() {
363
+ vAPI.storage.set({
364
+ netWhitelist: this.arrayFromWhitelist(this.netWhitelist)
365
+ });
366
+ this.netWhitelistModifyTime = Date.now();
367
+ };
368
+
369
+ /******************************************************************************/
370
+
371
+ µb.isTrustedList = function(assetKey) {
372
+ if ( this.parsedTrustedListPrefixes.length === 0 ) {
373
+ this.parsedTrustedListPrefixes =
374
+ µb.hiddenSettings.trustedListPrefixes.split(/ +/).map(prefix => {
375
+ if ( prefix === '' ) { return; }
376
+ if ( prefix.startsWith('http://') ) { return; }
377
+ if ( prefix.startsWith('file:///') ) { return prefix; }
378
+ if ( prefix.startsWith('https://') === false ) {
379
+ return prefix.includes('://') ? undefined : prefix;
380
+ }
381
+ try {
382
+ const url = new URL(prefix);
383
+ if ( url.hostname.length > 0 ) { return url.href; }
384
+ } catch(_) {
385
+ }
386
+ }).filter(prefix => prefix !== undefined);
387
+ }
388
+ for ( const prefix of this.parsedTrustedListPrefixes ) {
389
+ if ( assetKey.startsWith(prefix) ) { return true; }
390
+ }
391
+ return false;
392
+ };
393
+
394
+ µb.onEvent('hiddenSettingsChanged', ( ) => {
395
+ µb.parsedTrustedListPrefixes = [];
396
+ });
397
+
398
+ /******************************************************************************/
399
+
400
+ µb.loadSelectedFilterLists = async function() {
401
+ const bin = await vAPI.storage.get('selectedFilterLists');
402
+ if ( bin instanceof Object && Array.isArray(bin.selectedFilterLists) ) {
403
+ this.selectedFilterLists = bin.selectedFilterLists;
404
+ return;
405
+ }
406
+
407
+ // https://github.com/gorhill/uBlock/issues/747
408
+ // Select default filter lists if first-time launch.
409
+ const lists = await io.metadata();
410
+ this.saveSelectedFilterLists(this.autoSelectRegionalFilterLists(lists));
411
+ };
412
+
413
+ µb.saveSelectedFilterLists = function(newKeys, append = false) {
414
+ const oldKeys = this.selectedFilterLists.slice();
415
+ if ( append ) {
416
+ newKeys = newKeys.concat(oldKeys);
417
+ }
418
+ const newSet = new Set(newKeys);
419
+ // Purge unused filter lists from cache.
420
+ for ( const oldKey of oldKeys ) {
421
+ if ( newSet.has(oldKey) === false ) {
422
+ this.removeFilterList(oldKey);
423
+ }
424
+ }
425
+ newKeys = Array.from(newSet);
426
+ this.selectedFilterLists = newKeys;
427
+ return vAPI.storage.set({ selectedFilterLists: newKeys });
428
+ };
429
+
430
+ /******************************************************************************/
431
+
432
+ µb.applyFilterListSelection = function(details) {
433
+ let selectedListKeySet = new Set(this.selectedFilterLists);
434
+ let importedLists = this.userSettings.importedLists.slice();
435
+
436
+ // Filter lists to select
437
+ if ( Array.isArray(details.toSelect) ) {
438
+ if ( details.merge ) {
439
+ for ( let i = 0, n = details.toSelect.length; i < n; i++ ) {
440
+ selectedListKeySet.add(details.toSelect[i]);
441
+ }
442
+ } else {
443
+ selectedListKeySet = new Set(details.toSelect);
444
+ }
445
+ }
446
+
447
+ // Imported filter lists to remove
448
+ if ( Array.isArray(details.toRemove) ) {
449
+ for ( let i = 0, n = details.toRemove.length; i < n; i++ ) {
450
+ const assetKey = details.toRemove[i];
451
+ selectedListKeySet.delete(assetKey);
452
+ const pos = importedLists.indexOf(assetKey);
453
+ if ( pos !== -1 ) {
454
+ importedLists.splice(pos, 1);
455
+ }
456
+ this.removeFilterList(assetKey);
457
+ }
458
+ }
459
+
460
+ // Filter lists to import
461
+ if ( typeof details.toImport === 'string' ) {
462
+ // https://github.com/gorhill/uBlock/issues/1181
463
+ // Try mapping the URL of an imported filter list to the assetKey
464
+ // of an existing stock list.
465
+ const assetKeyFromURL = url => {
466
+ const needle = url.replace(/^https?:/, '');
467
+ const assets = this.availableFilterLists;
468
+ for ( const assetKey in assets ) {
469
+ const asset = assets[assetKey];
470
+ if ( asset.content !== 'filters' ) { continue; }
471
+ if ( typeof asset.contentURL === 'string' ) {
472
+ if ( asset.contentURL.endsWith(needle) ) { return assetKey; }
473
+ continue;
474
+ }
475
+ if ( Array.isArray(asset.contentURL) === false ) { continue; }
476
+ for ( let i = 0, n = asset.contentURL.length; i < n; i++ ) {
477
+ if ( asset.contentURL[i].endsWith(needle) ) {
478
+ return assetKey;
479
+ }
480
+ }
481
+ }
482
+ return url;
483
+ };
484
+ const importedSet = new Set(this.listKeysFromCustomFilterLists(importedLists));
485
+ const toImportSet = new Set(this.listKeysFromCustomFilterLists(details.toImport));
486
+ for ( const urlKey of toImportSet ) {
487
+ if ( importedSet.has(urlKey) ) {
488
+ selectedListKeySet.add(urlKey);
489
+ continue;
490
+ }
491
+ const assetKey = assetKeyFromURL(urlKey);
492
+ if ( assetKey === urlKey ) {
493
+ importedSet.add(urlKey);
494
+ }
495
+ selectedListKeySet.add(assetKey);
496
+ }
497
+ importedLists = Array.from(importedSet).sort();
498
+ }
499
+
500
+ const result = Array.from(selectedListKeySet);
501
+ if ( importedLists.join() !== this.userSettings.importedLists.join() ) {
502
+ this.userSettings.importedLists = importedLists;
503
+ this.saveUserSettings();
504
+ }
505
+ this.saveSelectedFilterLists(result);
506
+ };
507
+
508
+ /******************************************************************************/
509
+
510
+ µb.listKeysFromCustomFilterLists = function(raw) {
511
+ const urls = typeof raw === 'string'
512
+ ? raw.trim().split(/[\n\r]+/)
513
+ : raw;
514
+ const out = new Set();
515
+ const reIgnore = /^[!#]/;
516
+ const reValid = /^[a-z-]+:\/\/\S+/;
517
+ for ( const url of urls ) {
518
+ if ( reIgnore.test(url) || !reValid.test(url) ) { continue; }
519
+ // Ignore really bad lists.
520
+ if ( this.badLists.get(url) === true ) { continue; }
521
+ out.add(url);
522
+ }
523
+ return Array.from(out);
524
+ };
525
+
526
+ /******************************************************************************/
527
+
528
+ µb.saveUserFilters = function(content) {
529
+ // https://github.com/gorhill/uBlock/issues/1022
530
+ // Be sure to end with an empty line.
531
+ content = content.trim();
532
+ if ( content !== '' ) { content += '\n'; }
533
+ this.removeCompiledFilterList(this.userFiltersPath);
534
+ return io.put(this.userFiltersPath, content);
535
+ };
536
+
537
+ µb.loadUserFilters = function() {
538
+ return io.get(this.userFiltersPath);
539
+ };
540
+
541
+ µb.appendUserFilters = async function(filters, options) {
542
+ filters = filters.trim();
543
+ if ( filters.length === 0 ) { return; }
544
+
545
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/372
546
+ // Auto comment using user-defined template.
547
+ let comment = '';
548
+ if (
549
+ options instanceof Object &&
550
+ options.autoComment === true &&
551
+ this.hiddenSettings.autoCommentFilterTemplate.indexOf('{{') !== -1
552
+ ) {
553
+ const d = new Date();
554
+ // Date in YYYY-MM-DD format - https://stackoverflow.com/a/50130338
555
+ const ISO8601Date = new Date(d.getTime() +
556
+ (d.getTimezoneOffset()*60000)).toISOString().split('T')[0];
557
+ const url = new URL(options.docURL);
558
+ comment =
559
+ '! ' +
560
+ this.hiddenSettings.autoCommentFilterTemplate
561
+ .replace('{{date}}', ISO8601Date)
562
+ .replace('{{time}}', d.toLocaleTimeString())
563
+ .replace('{{hostname}}', url.hostname)
564
+ .replace('{{origin}}', url.origin)
565
+ .replace('{{url}}', url.href);
566
+ }
567
+
568
+ const details = await this.loadUserFilters();
569
+ if ( details.error ) { return; }
570
+
571
+ // The comment, if any, will be applied if and only if it is different
572
+ // from the last comment found in the user filter list.
573
+ if ( comment !== '' ) {
574
+ const beg = details.content.lastIndexOf(comment);
575
+ const end = beg === -1 ? -1 : beg + comment.length;
576
+ if (
577
+ end === -1 ||
578
+ details.content.startsWith('\n', end) === false ||
579
+ details.content.includes('\n!', end)
580
+ ) {
581
+ filters = '\n' + comment + '\n' + filters;
582
+ }
583
+ }
584
+
585
+ // https://github.com/chrisaljoudi/uBlock/issues/976
586
+ // If we reached this point, the filter quite probably needs to be
587
+ // added for sure: do not try to be too smart, trying to avoid
588
+ // duplicates at this point may lead to more issues.
589
+ await this.saveUserFilters(details.content.trim() + '\n' + filters);
590
+
591
+ const compiledFilters = this.compileFilters(filters, {
592
+ assetKey: this.userFiltersPath,
593
+ trustedSource: true,
594
+ });
595
+ const snfe = staticNetFilteringEngine;
596
+ const cfe = cosmeticFilteringEngine;
597
+ const acceptedCount = snfe.acceptedCount + cfe.acceptedCount;
598
+ const discardedCount = snfe.discardedCount + cfe.discardedCount;
599
+ this.applyCompiledFilters(compiledFilters, true);
600
+ const entry = this.availableFilterLists[this.userFiltersPath];
601
+ const deltaEntryCount =
602
+ snfe.acceptedCount +
603
+ cfe.acceptedCount - acceptedCount;
604
+ const deltaEntryUsedCount =
605
+ deltaEntryCount -
606
+ (snfe.discardedCount + cfe.discardedCount - discardedCount);
607
+ entry.entryCount += deltaEntryCount;
608
+ entry.entryUsedCount += deltaEntryUsedCount;
609
+ vAPI.storage.set({ 'availableFilterLists': this.availableFilterLists });
610
+ staticNetFilteringEngine.freeze();
611
+ redirectEngine.freeze();
612
+ staticExtFilteringEngine.freeze();
613
+ this.selfieManager.destroy();
614
+
615
+ // https://www.reddit.com/r/uBlockOrigin/comments/cj7g7m/
616
+ // https://www.reddit.com/r/uBlockOrigin/comments/cnq0bi/
617
+ µb.filteringBehaviorChanged();
618
+
619
+ vAPI.messaging.broadcast({ what: 'userFiltersUpdated' });
620
+ };
621
+
622
+ µb.createUserFilters = function(details) {
623
+ this.appendUserFilters(details.filters, details);
624
+ // https://github.com/gorhill/uBlock/issues/1786
625
+ if ( details.docURL === undefined ) { return; }
626
+ cosmeticFilteringEngine.removeFromSelectorCache(
627
+ hostnameFromURI(details.docURL)
628
+ );
629
+ };
630
+
631
+ /******************************************************************************/
632
+
633
+ µb.autoSelectRegionalFilterLists = function(lists) {
634
+ const selectedListKeys = [ this.userFiltersPath ];
635
+ for ( const key in lists ) {
636
+ if ( lists.hasOwnProperty(key) === false ) { continue; }
637
+ const list = lists[key];
638
+ if ( list.off !== true ) {
639
+ selectedListKeys.push(key);
640
+ continue;
641
+ }
642
+ if ( this.listMatchesEnvironment(list) ) {
643
+ selectedListKeys.push(key);
644
+ list.off = false;
645
+ }
646
+ }
647
+ return selectedListKeys;
648
+ };
649
+
650
+ /******************************************************************************/
651
+
652
+ µb.hasInMemoryFilter = function(raw) {
653
+ return this.inMemoryFilters.includes(raw);
654
+ };
655
+
656
+ µb.addInMemoryFilter = async function(raw) {
657
+ if ( this.inMemoryFilters.includes(raw) ){ return true; }
658
+ this.inMemoryFilters.push(raw);
659
+ this.inMemoryFiltersCompiled = '';
660
+ await this.loadFilterLists();
661
+ return true;
662
+ };
663
+
664
+ µb.removeInMemoryFilter = async function(raw) {
665
+ const pos = this.inMemoryFilters.indexOf(raw);
666
+ if ( pos === -1 ) { return false; }
667
+ this.inMemoryFilters.splice(pos, 1);
668
+ this.inMemoryFiltersCompiled = '';
669
+ await this.loadFilterLists();
670
+ return false;
671
+ };
672
+
673
+ µb.clearInMemoryFilters = async function() {
674
+ if ( this.inMemoryFilters.length === 0 ) { return; }
675
+ this.inMemoryFilters = [];
676
+ this.inMemoryFiltersCompiled = '';
677
+ await this.loadFilterLists();
678
+ };
679
+
680
+ /******************************************************************************/
681
+
682
+ µb.getAvailableLists = async function() {
683
+ const newAvailableLists = {};
684
+
685
+ // User filter list
686
+ newAvailableLists[this.userFiltersPath] = {
687
+ content: 'filters',
688
+ group: 'user',
689
+ title: i18n$('1pPageName'),
690
+ };
691
+
692
+ // Custom filter lists
693
+ const importedListKeys = new Set(
694
+ this.listKeysFromCustomFilterLists(this.userSettings.importedLists)
695
+ );
696
+ for ( const listKey of importedListKeys ) {
697
+ const asset = {
698
+ content: 'filters',
699
+ contentURL: listKey,
700
+ external: true,
701
+ group: 'custom',
702
+ submitter: 'user',
703
+ title: '',
704
+ };
705
+ newAvailableLists[listKey] = asset;
706
+ io.registerAssetSource(listKey, asset);
707
+ }
708
+
709
+ // Load previously saved available lists -- these contains data
710
+ // computed at run-time, we will reuse this data if possible
711
+ const [ bin, registeredAssets, badlists ] = await Promise.all([
712
+ Object.keys(this.availableFilterLists).length !== 0
713
+ ? { availableFilterLists: this.availableFilterLists }
714
+ : vAPI.storage.get('availableFilterLists'),
715
+ io.metadata(),
716
+ this.badLists.size === 0 ? io.get('ublock-badlists') : false,
717
+ ]);
718
+
719
+ if ( badlists instanceof Object ) {
720
+ for ( const line of badlists.content.split(/\s*[\n\r]+\s*/) ) {
721
+ if ( line === '' || line.startsWith('#') ) { continue; }
722
+ const fields = line.split(/\s+/);
723
+ const remove = fields.length === 2;
724
+ this.badLists.set(fields[0], remove);
725
+ }
726
+ }
727
+
728
+ const oldAvailableLists = bin && bin.availableFilterLists || {};
729
+
730
+ for ( const [ assetKey, asset ] of Object.entries(registeredAssets) ) {
731
+ if ( asset.content !== 'filters' ) { continue; }
732
+ newAvailableLists[assetKey] = Object.assign({}, asset);
733
+ }
734
+
735
+ // Load set of currently selected filter lists
736
+ const selectedListset = new Set(this.selectedFilterLists);
737
+
738
+ // Remove imported filter lists which are already present in stock lists
739
+ for ( const [ stockAssetKey, stockEntry ] of Object.entries(newAvailableLists) ) {
740
+ if ( stockEntry.content !== 'filters' ) { continue; }
741
+ if ( stockEntry.group === 'user' ) { continue; }
742
+ if ( stockEntry.submitter === 'user' ) { continue; }
743
+ if ( stockAssetKey.includes('://') ) { continue; }
744
+ const contentURLs = Array.isArray(stockEntry.contentURL)
745
+ ? stockEntry.contentURL
746
+ : [ stockEntry.contentURL ];
747
+ for ( const importedAssetKey of contentURLs ) {
748
+ const importedEntry = newAvailableLists[importedAssetKey];
749
+ if ( importedEntry === undefined ) { continue; }
750
+ delete newAvailableLists[importedAssetKey];
751
+ io.unregisterAssetSource(importedAssetKey);
752
+ this.removeFilterList(importedAssetKey);
753
+ if ( selectedListset.has(importedAssetKey) ) {
754
+ selectedListset.add(stockAssetKey);
755
+ selectedListset.delete(importedAssetKey);
756
+ }
757
+ importedListKeys.delete(importedAssetKey);
758
+ break;
759
+ }
760
+ }
761
+
762
+ // Unregister lists in old listset not present in new listset.
763
+ // Convert a no longer existing stock list into an imported list, except
764
+ // when the removed stock list is deemed a "bad list".
765
+ for ( const [ assetKey, oldEntry ] of Object.entries(oldAvailableLists) ) {
766
+ if ( newAvailableLists[assetKey] !== undefined ) { continue; }
767
+ const on = selectedListset.delete(assetKey);
768
+ this.removeFilterList(assetKey);
769
+ io.unregisterAssetSource(assetKey);
770
+ if ( assetKey.includes('://') ) { continue; }
771
+ if ( on === false ) { continue; }
772
+ const listURL = Array.isArray(oldEntry.contentURL)
773
+ ? oldEntry.contentURL[0]
774
+ : oldEntry.contentURL;
775
+ if ( this.badLists.has(listURL) ) { continue; }
776
+ const newEntry = {
777
+ content: 'filters',
778
+ contentURL: listURL,
779
+ external: true,
780
+ group: 'custom',
781
+ submitter: 'user',
782
+ title: oldEntry.title || ''
783
+ };
784
+ newAvailableLists[listURL] = newEntry;
785
+ io.registerAssetSource(listURL, newEntry);
786
+ importedListKeys.add(listURL);
787
+ selectedListset.add(listURL);
788
+ }
789
+
790
+ // Remove unreferenced imported filter lists
791
+ for ( const [ assetKey, asset ] of Object.entries(newAvailableLists) ) {
792
+ if ( asset.submitter !== 'user' ) { continue; }
793
+ if ( importedListKeys.has(assetKey) ) { continue; }
794
+ selectedListset.delete(assetKey);
795
+ delete newAvailableLists[assetKey];
796
+ this.removeFilterList(assetKey);
797
+ io.unregisterAssetSource(assetKey);
798
+ }
799
+
800
+ // Mark lists as disabled/enabled according to selected listset
801
+ for ( const [ assetKey, asset ] of Object.entries(newAvailableLists) ) {
802
+ asset.off = selectedListset.has(assetKey) === false;
803
+ }
804
+
805
+ // Reuse existing metadata
806
+ for ( const [ assetKey, oldEntry ] of Object.entries(oldAvailableLists) ) {
807
+ const newEntry = newAvailableLists[assetKey];
808
+ if ( newEntry === undefined ) { continue; }
809
+ if ( oldEntry.entryCount !== undefined ) {
810
+ newEntry.entryCount = oldEntry.entryCount;
811
+ }
812
+ if ( oldEntry.entryUsedCount !== undefined ) {
813
+ newEntry.entryUsedCount = oldEntry.entryUsedCount;
814
+ }
815
+ // This may happen if the list name was pulled from the list content
816
+ // https://github.com/chrisaljoudi/uBlock/issues/982
817
+ // There is no guarantee the title was successfully extracted from
818
+ // the list content
819
+ if (
820
+ newEntry.title === '' &&
821
+ typeof oldEntry.title === 'string' &&
822
+ oldEntry.title !== ''
823
+ ) {
824
+ newEntry.title = oldEntry.title;
825
+ }
826
+ }
827
+
828
+ if ( Array.from(importedListKeys).join('\n') !== this.userSettings.importedLists.join('\n') ) {
829
+ this.userSettings.importedLists = Array.from(importedListKeys);
830
+ this.saveUserSettings();
831
+ }
832
+
833
+ if ( Array.from(selectedListset).join() !== this.selectedFilterLists.join() ) {
834
+ this.saveSelectedFilterLists(Array.from(selectedListset));
835
+ }
836
+
837
+ return newAvailableLists;
838
+ };
839
+
840
+ /******************************************************************************/
841
+
842
+ {
843
+ const loadedListKeys = [];
844
+ let loadingPromise;
845
+ let t0 = 0;
846
+
847
+ const onDone = ( ) => {
848
+ ubolog(`loadFilterLists() took ${Date.now()-t0} ms`);
849
+
850
+ staticNetFilteringEngine.freeze();
851
+ staticExtFilteringEngine.freeze();
852
+ redirectEngine.freeze();
853
+ vAPI.net.unsuspend();
854
+ µb.filteringBehaviorChanged();
855
+
856
+ vAPI.storage.set({ 'availableFilterLists': µb.availableFilterLists });
857
+
858
+ logger.writeOne({
859
+ realm: 'message',
860
+ type: 'info',
861
+ text: 'Reloading all filter lists: done'
862
+ });
863
+
864
+ vAPI.messaging.broadcast({
865
+ what: 'staticFilteringDataChanged',
866
+ parseCosmeticFilters: µb.userSettings.parseAllABPHideFilters,
867
+ ignoreGenericCosmeticFilters: µb.userSettings.ignoreGenericCosmeticFilters,
868
+ listKeys: loadedListKeys
869
+ });
870
+
871
+ µb.selfieManager.destroy();
872
+ lz4Codec.relinquish();
873
+ µb.compiledFormatChanged = false;
874
+
875
+ loadingPromise = undefined;
876
+ };
877
+
878
+ const applyCompiledFilters = (assetKey, compiled) => {
879
+ const snfe = staticNetFilteringEngine;
880
+ const sxfe = staticExtFilteringEngine;
881
+ let acceptedCount = snfe.acceptedCount + sxfe.acceptedCount;
882
+ let discardedCount = snfe.discardedCount + sxfe.discardedCount;
883
+ µb.applyCompiledFilters(compiled, assetKey === µb.userFiltersPath);
884
+ if ( µb.availableFilterLists.hasOwnProperty(assetKey) ) {
885
+ const entry = µb.availableFilterLists[assetKey];
886
+ entry.entryCount = snfe.acceptedCount + sxfe.acceptedCount -
887
+ acceptedCount;
888
+ entry.entryUsedCount = entry.entryCount -
889
+ (snfe.discardedCount + sxfe.discardedCount - discardedCount);
890
+ }
891
+ loadedListKeys.push(assetKey);
892
+ };
893
+
894
+ const onFilterListsReady = lists => {
895
+ logger.writeOne({
896
+ realm: 'message',
897
+ type: 'info',
898
+ text: 'Reloading all filter lists: start'
899
+ });
900
+
901
+ µb.availableFilterLists = lists;
902
+
903
+ if ( vAPI.Net.canSuspend() ) {
904
+ vAPI.net.suspend();
905
+ }
906
+ redirectEngine.reset();
907
+ staticExtFilteringEngine.reset();
908
+ staticNetFilteringEngine.reset();
909
+ µb.selfieManager.destroy();
910
+ staticFilteringReverseLookup.resetLists();
911
+
912
+ // We need to build a complete list of assets to pull first: this is
913
+ // because it *may* happens that some load operations are synchronous:
914
+ // This happens for assets which do not exist, or assets with no
915
+ // content.
916
+ const toLoad = [];
917
+ for ( const assetKey in lists ) {
918
+ if ( lists.hasOwnProperty(assetKey) === false ) { continue; }
919
+ if ( lists[assetKey].off ) { continue; }
920
+ toLoad.push(
921
+ µb.getCompiledFilterList(assetKey).then(details => {
922
+ applyCompiledFilters(details.assetKey, details.content);
923
+ })
924
+ );
925
+ }
926
+
927
+ if ( µb.inMemoryFilters.length !== 0 ) {
928
+ if ( µb.inMemoryFiltersCompiled === '' ) {
929
+ µb.inMemoryFiltersCompiled =
930
+ µb.compileFilters(µb.inMemoryFilters.join('\n'), {
931
+ assetKey: 'in-memory',
932
+ trustedSource: true,
933
+ });
934
+ }
935
+ if ( µb.inMemoryFiltersCompiled !== '' ) {
936
+ toLoad.push(
937
+ µb.applyCompiledFilters(µb.inMemoryFiltersCompiled, true)
938
+ );
939
+ }
940
+ }
941
+
942
+ return Promise.all(toLoad);
943
+ };
944
+
945
+ µb.loadFilterLists = function() {
946
+ if ( loadingPromise instanceof Promise ) { return loadingPromise; }
947
+ t0 = Date.now();
948
+ loadedListKeys.length = 0;
949
+ loadingPromise = Promise.all([
950
+ this.getAvailableLists().then(lists => onFilterListsReady(lists)),
951
+ this.loadRedirectResources(),
952
+ ]).then(( ) => {
953
+ onDone();
954
+ });
955
+ return loadingPromise;
956
+ };
957
+ }
958
+
959
+ /******************************************************************************/
960
+
961
+ µb.getCompiledFilterList = async function(assetKey) {
962
+ const compiledPath = 'compiled/' + assetKey;
963
+
964
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/1365
965
+ // Verify that the list version matches that of the current compiled
966
+ // format.
967
+ if (
968
+ this.compiledFormatChanged === false &&
969
+ this.badLists.has(assetKey) === false
970
+ ) {
971
+ const compiledDetails = await io.get(compiledPath);
972
+ const compilerVersion = `${this.systemSettings.compiledMagic}\n`;
973
+ if ( compiledDetails.content.startsWith(compilerVersion) ) {
974
+ compiledDetails.assetKey = assetKey;
975
+ return compiledDetails;
976
+ }
977
+ }
978
+
979
+ // Skip downloading really bad lists.
980
+ if ( this.badLists.get(assetKey) ) {
981
+ return { assetKey, content: '' };
982
+ }
983
+
984
+ const rawDetails = await io.get(assetKey, {
985
+ favorLocal: this.readyToFilter !== true,
986
+ silent: true,
987
+ });
988
+ // Compiling an empty string results in an empty string.
989
+ if ( rawDetails.content === '' ) {
990
+ rawDetails.assetKey = assetKey;
991
+ return rawDetails;
992
+ }
993
+
994
+ this.extractFilterListMetadata(assetKey, rawDetails.content);
995
+
996
+ // Skip compiling bad lists.
997
+ if ( this.badLists.has(assetKey) ) {
998
+ return { assetKey, content: '' };
999
+ }
1000
+
1001
+ const compiledContent = this.compileFilters(rawDetails.content, {
1002
+ assetKey,
1003
+ trustedSource: this.isTrustedList(assetKey),
1004
+ });
1005
+ io.put(compiledPath, compiledContent);
1006
+
1007
+ return { assetKey, content: compiledContent };
1008
+ };
1009
+
1010
+ /******************************************************************************/
1011
+
1012
+ µb.extractFilterListMetadata = function(assetKey, raw) {
1013
+ const listEntry = this.availableFilterLists[assetKey];
1014
+ if ( listEntry === undefined ) { return; }
1015
+ // https://github.com/gorhill/uBlock/issues/313
1016
+ // Always try to fetch the name if this is an external filter list.
1017
+ if ( listEntry.group !== 'custom' ) { return; }
1018
+ const data = io.extractMetadataFromList(raw, [ 'Title', 'Homepage' ]);
1019
+ const props = {};
1020
+ if ( data.title && data.title !== listEntry.title ) {
1021
+ props.title = listEntry.title = orphanizeString(data.title);
1022
+ }
1023
+ if ( data.homepage && /^https?:\/\/\S+/.test(data.homepage) ) {
1024
+ if ( data.homepage !== listEntry.supportURL ) {
1025
+ props.supportURL = listEntry.supportURL = orphanizeString(data.homepage);
1026
+ }
1027
+ }
1028
+ io.registerAssetSource(assetKey, props);
1029
+ };
1030
+
1031
+ /******************************************************************************/
1032
+
1033
+ µb.removeCompiledFilterList = function(assetKey) {
1034
+ io.remove('compiled/' + assetKey);
1035
+ };
1036
+
1037
+ µb.removeFilterList = function(assetKey) {
1038
+ this.removeCompiledFilterList(assetKey);
1039
+ io.remove(assetKey);
1040
+ };
1041
+
1042
+ /******************************************************************************/
1043
+
1044
+ µb.compileFilters = function(rawText, details = {}) {
1045
+ const writer = new CompiledListWriter();
1046
+
1047
+ // Populate the writer with information potentially useful to the
1048
+ // client compilers.
1049
+ const trustedSource = details.trustedSource === true;
1050
+ if ( details.assetKey ) {
1051
+ writer.properties.set('name', details.assetKey);
1052
+ writer.properties.set('trustedSource', trustedSource);
1053
+ }
1054
+ const assetName = details.assetKey ? details.assetKey : '?';
1055
+ const parser = new sfp.AstFilterParser({
1056
+ trustedSource,
1057
+ maxTokenLength: staticNetFilteringEngine.MAX_TOKEN_LENGTH,
1058
+ nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
1059
+ });
1060
+ const compiler = staticNetFilteringEngine.createCompiler(parser);
1061
+ const lineIter = new LineIterator(
1062
+ sfp.utils.preparser.prune(rawText, vAPI.webextFlavor.env)
1063
+ );
1064
+
1065
+ compiler.start(writer);
1066
+
1067
+ while ( lineIter.eot() === false ) {
1068
+ let line = lineIter.next();
1069
+
1070
+ while ( line.endsWith(' \\') ) {
1071
+ if ( lineIter.peek(4) !== ' ' ) { break; }
1072
+ line = line.slice(0, -2).trim() + lineIter.next().trim();
1073
+ }
1074
+
1075
+ parser.parse(line);
1076
+
1077
+ if ( parser.isFilter() === false ) { continue; }
1078
+ if ( parser.hasError() ) {
1079
+ logger.writeOne({
1080
+ realm: 'message',
1081
+ type: 'error',
1082
+ text: `Invalid filter (${assetName}): ${parser.raw}`
1083
+ });
1084
+ continue;
1085
+ }
1086
+
1087
+ if ( parser.isExtendedFilter() ) {
1088
+ staticExtFilteringEngine.compile(parser, writer);
1089
+ continue;
1090
+ }
1091
+
1092
+ if ( parser.isNetworkFilter() === false ) { continue; }
1093
+
1094
+ if ( compiler.compile(parser, writer) ) { continue; }
1095
+ if ( compiler.error !== undefined ) {
1096
+ logger.writeOne({
1097
+ realm: 'message',
1098
+ type: 'error',
1099
+ text: compiler.error
1100
+ });
1101
+ }
1102
+ }
1103
+
1104
+ compiler.finish(writer);
1105
+ parser.finish();
1106
+
1107
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/1365
1108
+ // Embed version into compiled list itself: it is encoded in as the
1109
+ // first digits followed by a whitespace.
1110
+ const compiledContent
1111
+ = `${this.systemSettings.compiledMagic}\n` + writer.toString();
1112
+
1113
+ return compiledContent;
1114
+ };
1115
+
1116
+ /******************************************************************************/
1117
+
1118
+ // https://github.com/gorhill/uBlock/issues/1395
1119
+ // Added `firstparty` argument: to avoid discarding cosmetic filters when
1120
+ // applying 1st-party filters.
1121
+
1122
+ µb.applyCompiledFilters = function(rawText, firstparty) {
1123
+ if ( rawText === '' ) { return; }
1124
+ const reader = new CompiledListReader(rawText);
1125
+ staticNetFilteringEngine.fromCompiled(reader);
1126
+ staticExtFilteringEngine.fromCompiledContent(reader, {
1127
+ skipGenericCosmetic: this.userSettings.ignoreGenericCosmeticFilters,
1128
+ skipCosmetic: !firstparty && !this.userSettings.parseAllABPHideFilters
1129
+ });
1130
+ };
1131
+
1132
+ /******************************************************************************/
1133
+
1134
+ µb.loadRedirectResources = async function() {
1135
+ try {
1136
+ const success = await redirectEngine.resourcesFromSelfie(io);
1137
+ if ( success === true ) { return true; }
1138
+
1139
+ const fetcher = (path, options = undefined) => {
1140
+ if ( path.startsWith('/web_accessible_resources/') ) {
1141
+ path += `?secret=${vAPI.warSecret.short()}`;
1142
+ return io.fetch(path, options);
1143
+ }
1144
+ return io.fetchText(path);
1145
+ };
1146
+
1147
+ const fetchPromises = [
1148
+ redirectEngine.loadBuiltinResources(fetcher)
1149
+ ];
1150
+
1151
+ const userResourcesLocation = this.hiddenSettings.userResourcesLocation;
1152
+ if ( userResourcesLocation !== 'unset' ) {
1153
+ for ( const url of userResourcesLocation.split(/\s+/) ) {
1154
+ fetchPromises.push(io.fetchText(url));
1155
+ }
1156
+ }
1157
+
1158
+ const results = await Promise.all(fetchPromises);
1159
+ if ( Array.isArray(results) === false ) { return results; }
1160
+
1161
+ let content = '';
1162
+ for ( let i = 1; i < results.length; i++ ) {
1163
+ const result = results[i];
1164
+ if (
1165
+ result instanceof Object === false ||
1166
+ typeof result.content !== 'string' ||
1167
+ result.content === ''
1168
+ ) {
1169
+ continue;
1170
+ }
1171
+ content += '\n\n' + result.content;
1172
+ }
1173
+
1174
+ redirectEngine.resourcesFromString(content);
1175
+ redirectEngine.selfieFromResources(io);
1176
+ } catch(ex) {
1177
+ ubolog(ex);
1178
+ return false;
1179
+ }
1180
+ return true;
1181
+ };
1182
+
1183
+ /******************************************************************************/
1184
+
1185
+ µb.loadPublicSuffixList = async function() {
1186
+ const psl = publicSuffixList;
1187
+
1188
+ // WASM is nice but not critical
1189
+ if ( vAPI.canWASM && this.hiddenSettings.disableWebAssembly !== true ) {
1190
+ const wasmModuleFetcher = function(path) {
1191
+ return fetch( `${path}.wasm`, {
1192
+ mode: 'same-origin'
1193
+ }).then(
1194
+ WebAssembly.compileStreaming
1195
+ ).catch(reason => {
1196
+ ubolog(reason);
1197
+ });
1198
+ };
1199
+ let result = false;
1200
+ try {
1201
+ result = await psl.enableWASM(wasmModuleFetcher,
1202
+ './lib/publicsuffixlist/wasm/'
1203
+ );
1204
+ } catch(reason) {
1205
+ ubolog(reason);
1206
+ }
1207
+ if ( result ) {
1208
+ ubolog(`WASM PSL ready ${Date.now()-vAPI.T0} ms after launch`);
1209
+ }
1210
+ }
1211
+
1212
+ try {
1213
+ const result = await io.get(`compiled/${this.pslAssetKey}`);
1214
+ if ( psl.fromSelfie(result.content, sparseBase64) ) { return; }
1215
+ } catch (reason) {
1216
+ ubolog(reason);
1217
+ }
1218
+
1219
+ const result = await io.get(this.pslAssetKey);
1220
+ if ( result.content !== '' ) {
1221
+ this.compilePublicSuffixList(result.content);
1222
+ }
1223
+ };
1224
+
1225
+ µb.compilePublicSuffixList = function(content) {
1226
+ const psl = publicSuffixList;
1227
+ psl.parse(content, punycode.toASCII);
1228
+ io.put(`compiled/${this.pslAssetKey}`, psl.toSelfie(sparseBase64));
1229
+ };
1230
+
1231
+ /******************************************************************************/
1232
+
1233
+ // This is to be sure the selfie is generated in a sane manner: the selfie will
1234
+ // be generated if the user doesn't change his filter lists selection for
1235
+ // some set time.
1236
+
1237
+ {
1238
+ // As of 2018-05-31:
1239
+ // JSON.stringify-ing ourselves results in a better baseline
1240
+ // memory usage at selfie-load time. For some reasons.
1241
+
1242
+ const create = async function() {
1243
+ if ( µb.inMemoryFilters.length !== 0 ) { return; }
1244
+ if ( Object.keys(µb.availableFilterLists).length === 0 ) { return; }
1245
+ await Promise.all([
1246
+ io.put(
1247
+ 'selfie/main',
1248
+ JSON.stringify({
1249
+ magic: µb.systemSettings.selfieMagic,
1250
+ availableFilterLists: µb.availableFilterLists,
1251
+ })
1252
+ ),
1253
+ redirectEngine.toSelfie('selfie/redirectEngine'),
1254
+ staticExtFilteringEngine.toSelfie(
1255
+ 'selfie/staticExtFilteringEngine'
1256
+ ),
1257
+ staticNetFilteringEngine.toSelfie(io,
1258
+ 'selfie/staticNetFilteringEngine'
1259
+ ),
1260
+ ]);
1261
+ lz4Codec.relinquish();
1262
+ µb.selfieIsInvalid = false;
1263
+ };
1264
+
1265
+ const loadMain = async function() {
1266
+ const details = await io.get('selfie/main');
1267
+ if (
1268
+ details instanceof Object === false ||
1269
+ typeof details.content !== 'string' ||
1270
+ details.content === ''
1271
+ ) {
1272
+ return false;
1273
+ }
1274
+ let selfie;
1275
+ try {
1276
+ selfie = JSON.parse(details.content);
1277
+ } catch(ex) {
1278
+ }
1279
+ if ( selfie instanceof Object === false ) { return false; }
1280
+ if ( selfie.magic !== µb.systemSettings.selfieMagic ) { return false; }
1281
+ if ( selfie.availableFilterLists instanceof Object === false ) { return false; }
1282
+ if ( Object.keys(selfie.availableFilterLists).length === 0 ) { return false; }
1283
+ µb.availableFilterLists = selfie.availableFilterLists;
1284
+ return true;
1285
+ };
1286
+
1287
+ const load = async function() {
1288
+ if ( µb.selfieIsInvalid ) { return false; }
1289
+ try {
1290
+ const results = await Promise.all([
1291
+ loadMain(),
1292
+ redirectEngine.fromSelfie('selfie/redirectEngine'),
1293
+ staticExtFilteringEngine.fromSelfie(
1294
+ 'selfie/staticExtFilteringEngine'
1295
+ ),
1296
+ staticNetFilteringEngine.fromSelfie(io,
1297
+ 'selfie/staticNetFilteringEngine'
1298
+ ),
1299
+ ]);
1300
+ if ( results.every(v => v) ) {
1301
+ return µb.loadRedirectResources();
1302
+ }
1303
+ }
1304
+ catch (reason) {
1305
+ ubolog(reason);
1306
+ }
1307
+ destroy();
1308
+ return false;
1309
+ };
1310
+
1311
+ const destroy = function() {
1312
+ if ( µb.selfieIsInvalid === false ) {
1313
+ io.remove(/^selfie\//);
1314
+ µb.selfieIsInvalid = true;
1315
+ }
1316
+ createTimer.offon({ min: µb.hiddenSettings.selfieAfter });
1317
+ };
1318
+
1319
+ const createTimer = vAPI.defer.create(create);
1320
+
1321
+ µb.selfieManager = { load, destroy };
1322
+ }
1323
+
1324
+ /******************************************************************************/
1325
+
1326
+ // https://github.com/gorhill/uBlock/issues/531
1327
+ // Overwrite user settings with admin settings if present.
1328
+ //
1329
+ // Admin settings match layout of a uBlock backup. Not all data is
1330
+ // necessarily present, i.e. administrators may removed entries which
1331
+ // values are left to the user's choice.
1332
+
1333
+ µb.restoreAdminSettings = async function() {
1334
+ let toOverwrite = {};
1335
+ let data;
1336
+ try {
1337
+ const store = await vAPI.adminStorage.get([
1338
+ 'adminSettings',
1339
+ 'toOverwrite',
1340
+ ]) || {};
1341
+ if ( store.toOverwrite instanceof Object ) {
1342
+ toOverwrite = store.toOverwrite;
1343
+ }
1344
+ const json = store.adminSettings;
1345
+ if ( typeof json === 'string' && json !== '' ) {
1346
+ data = JSON.parse(json);
1347
+ } else if ( json instanceof Object ) {
1348
+ data = json;
1349
+ }
1350
+ } catch (ex) {
1351
+ console.error(ex);
1352
+ }
1353
+
1354
+ if ( data instanceof Object === false ) { data = {}; }
1355
+
1356
+ const bin = {};
1357
+ let binNotEmpty = false;
1358
+
1359
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/666
1360
+ // Allows an admin to set their own 'assets.json' file, with their
1361
+ // own set of stock assets.
1362
+ if (
1363
+ typeof data.assetsBootstrapLocation === 'string' &&
1364
+ data.assetsBootstrapLocation !== ''
1365
+ ) {
1366
+ µb.assetsBootstrapLocation = data.assetsBootstrapLocation;
1367
+ }
1368
+
1369
+ if ( typeof data.userSettings === 'object' ) {
1370
+ const µbus = this.userSettings;
1371
+ const adminus = data.userSettings;
1372
+ for ( const name in µbus ) {
1373
+ if ( µbus.hasOwnProperty(name) === false ) { continue; }
1374
+ if ( adminus.hasOwnProperty(name) === false ) { continue; }
1375
+ bin[name] = adminus[name];
1376
+ binNotEmpty = true;
1377
+ }
1378
+ }
1379
+
1380
+ // 'selectedFilterLists' is an array of filter list tokens. Each token
1381
+ // is a reference to an asset in 'assets.json', or a URL for lists not
1382
+ // present in 'assets.json'.
1383
+ if (
1384
+ Array.isArray(toOverwrite.filterLists) &&
1385
+ toOverwrite.filterLists.length !== 0
1386
+ ) {
1387
+ const importedLists = [];
1388
+ for ( const list of toOverwrite.filterLists ) {
1389
+ if ( /^[a-z-]+:\/\//.test(list) === false ) { continue; }
1390
+ importedLists.push(list);
1391
+ }
1392
+ if ( importedLists.length !== 0 ) {
1393
+ bin.importedLists = importedLists;
1394
+ bin.externalLists = importedLists.join('\n');
1395
+ }
1396
+ bin.selectedFilterLists = toOverwrite.filterLists;
1397
+ binNotEmpty = true;
1398
+ } else if ( Array.isArray(data.selectedFilterLists) ) {
1399
+ bin.selectedFilterLists = data.selectedFilterLists;
1400
+ binNotEmpty = true;
1401
+ }
1402
+
1403
+ if (
1404
+ Array.isArray(toOverwrite.trustedSiteDirectives) &&
1405
+ toOverwrite.trustedSiteDirectives.length !== 0
1406
+ ) {
1407
+ µb.netWhitelistDefault = toOverwrite.trustedSiteDirectives.slice();
1408
+ bin.netWhitelist = toOverwrite.trustedSiteDirectives.slice();
1409
+ binNotEmpty = true;
1410
+ } else if ( Array.isArray(data.whitelist) ) {
1411
+ bin.netWhitelist = data.whitelist;
1412
+ binNotEmpty = true;
1413
+ } else if ( typeof data.netWhitelist === 'string' ) {
1414
+ bin.netWhitelist = data.netWhitelist.split('\n');
1415
+ binNotEmpty = true;
1416
+ }
1417
+
1418
+ if ( typeof data.dynamicFilteringString === 'string' ) {
1419
+ bin.dynamicFilteringString = data.dynamicFilteringString;
1420
+ binNotEmpty = true;
1421
+ }
1422
+
1423
+ if ( typeof data.urlFilteringString === 'string' ) {
1424
+ bin.urlFilteringString = data.urlFilteringString;
1425
+ binNotEmpty = true;
1426
+ }
1427
+
1428
+ if ( typeof data.hostnameSwitchesString === 'string' ) {
1429
+ bin.hostnameSwitchesString = data.hostnameSwitchesString;
1430
+ binNotEmpty = true;
1431
+ }
1432
+
1433
+ if ( binNotEmpty ) {
1434
+ vAPI.storage.set(bin);
1435
+ }
1436
+
1437
+ if (
1438
+ Array.isArray(toOverwrite.filters) &&
1439
+ toOverwrite.filters.length !== 0
1440
+ ) {
1441
+ this.saveUserFilters(toOverwrite.filters.join('\n'));
1442
+ } else if ( typeof data.userFilters === 'string' ) {
1443
+ this.saveUserFilters(data.userFilters);
1444
+ }
1445
+ };
1446
+
1447
+ /******************************************************************************/
1448
+
1449
+ // https://github.com/gorhill/uBlock/issues/2344
1450
+ // Support multiple locales per filter list.
1451
+ // https://github.com/gorhill/uBlock/issues/3210
1452
+ // Support ability to auto-enable a filter list based on user agent.
1453
+ // https://github.com/gorhill/uBlock/pull/3860
1454
+ // Get current language using extensions API (instead of `navigator.language`)
1455
+
1456
+ µb.listMatchesEnvironment = function(details) {
1457
+ // Matches language?
1458
+ if ( typeof details.lang === 'string' ) {
1459
+ let re = this.listMatchesEnvironment.reLang;
1460
+ if ( re === undefined ) {
1461
+ const match = /^[a-z]+/.exec(i18n.getUILanguage());
1462
+ if ( match !== null ) {
1463
+ re = new RegExp('\\b' + match[0] + '\\b');
1464
+ this.listMatchesEnvironment.reLang = re;
1465
+ }
1466
+ }
1467
+ if ( re !== undefined && re.test(details.lang) ) { return true; }
1468
+ }
1469
+ // Matches user agent?
1470
+ if ( typeof details.ua === 'string' ) {
1471
+ let re = new RegExp('\\b' + this.escapeRegex(details.ua) + '\\b', 'i');
1472
+ if ( re.test(self.navigator.userAgent) ) { return true; }
1473
+ }
1474
+ return false;
1475
+ };
1476
+
1477
+ /******************************************************************************/
1478
+
1479
+ {
1480
+ let next = 0;
1481
+ let lastEmergencyUpdate = 0;
1482
+
1483
+ const launchTimer = vAPI.defer.create(fetchDelay => {
1484
+ next = 0;
1485
+ io.updateStart({ delay: fetchDelay, auto: true });
1486
+ });
1487
+
1488
+ µb.scheduleAssetUpdater = async function(updateDelay) {
1489
+ launchTimer.off();
1490
+
1491
+ if ( updateDelay === 0 ) {
1492
+ next = 0;
1493
+ return;
1494
+ }
1495
+
1496
+ const now = Date.now();
1497
+ let needEmergencyUpdate = false;
1498
+
1499
+ // Respect cooldown period before launching an emergency update.
1500
+ const timeSinceLastEmergencyUpdate = (now - lastEmergencyUpdate) / 3600000;
1501
+ if ( timeSinceLastEmergencyUpdate > 1 ) {
1502
+ const entries = await io.getUpdateAges({
1503
+ filters: µb.selectedFilterLists,
1504
+ internal: [ '*' ],
1505
+ });
1506
+ for ( const entry of entries ) {
1507
+ if ( entry.ageNormalized < 2 ) { continue; }
1508
+ needEmergencyUpdate = true;
1509
+ lastEmergencyUpdate = now;
1510
+ break;
1511
+ }
1512
+ }
1513
+
1514
+ // Use the new schedule if and only if it is earlier than the previous
1515
+ // one.
1516
+ if ( next !== 0 ) {
1517
+ updateDelay = Math.min(updateDelay, Math.max(next - now, 0));
1518
+ }
1519
+
1520
+ if ( needEmergencyUpdate ) {
1521
+ updateDelay = Math.min(updateDelay, 15000);
1522
+ }
1523
+
1524
+ next = now + updateDelay;
1525
+
1526
+ const fetchDelay = needEmergencyUpdate
1527
+ ? 2000
1528
+ : this.hiddenSettings.autoUpdateAssetFetchPeriod * 1000 || 60000;
1529
+
1530
+ launchTimer.on(updateDelay, fetchDelay);
1531
+ };
1532
+ }
1533
+
1534
+ /******************************************************************************/
1535
+
1536
+ µb.assetObserver = function(topic, details) {
1537
+ // Do not update filter list if not in use.
1538
+ // Also, ignore really bad lists, i.e. those which should not even be
1539
+ // fetched from a remote server.
1540
+ if ( topic === 'before-asset-updated' ) {
1541
+ if ( details.type === 'filters' ) {
1542
+ if (
1543
+ this.availableFilterLists.hasOwnProperty(details.assetKey) === false ||
1544
+ this.selectedFilterLists.indexOf(details.assetKey) === -1 ||
1545
+ this.badLists.get(details.assetKey)
1546
+ ) {
1547
+ return;
1548
+ }
1549
+ }
1550
+ return true;
1551
+ }
1552
+
1553
+ // Compile the list while we have the raw version in memory
1554
+ if ( topic === 'after-asset-updated' ) {
1555
+ // Skip selfie-related content.
1556
+ if ( details.assetKey.startsWith('selfie/') ) { return; }
1557
+ const cached = typeof details.content === 'string' &&
1558
+ details.content !== '';
1559
+ if ( this.availableFilterLists.hasOwnProperty(details.assetKey) ) {
1560
+ if ( cached ) {
1561
+ if ( this.selectedFilterLists.indexOf(details.assetKey) !== -1 ) {
1562
+ this.extractFilterListMetadata(
1563
+ details.assetKey,
1564
+ details.content
1565
+ );
1566
+ if ( this.badLists.has(details.assetKey) === false ) {
1567
+ io.put(
1568
+ 'compiled/' + details.assetKey,
1569
+ this.compileFilters(details.content, {
1570
+ assetKey: details.assetKey,
1571
+ trustedSource: this.isTrustedList(details.assetKey),
1572
+ })
1573
+ );
1574
+ }
1575
+ }
1576
+ } else {
1577
+ this.removeCompiledFilterList(details.assetKey);
1578
+ }
1579
+ } else if ( details.assetKey === this.pslAssetKey ) {
1580
+ if ( cached ) {
1581
+ this.compilePublicSuffixList(details.content);
1582
+ }
1583
+ } else if ( details.assetKey === 'ublock-badlists' ) {
1584
+ this.badLists = new Map();
1585
+ }
1586
+ vAPI.messaging.broadcast({
1587
+ what: 'assetUpdated',
1588
+ key: details.assetKey,
1589
+ cached: cached
1590
+ });
1591
+ // https://github.com/gorhill/uBlock/issues/2585
1592
+ // Whenever an asset is overwritten, the current selfie is quite
1593
+ // likely no longer valid.
1594
+ this.selfieManager.destroy();
1595
+ return;
1596
+ }
1597
+
1598
+ // Update failed.
1599
+ if ( topic === 'asset-update-failed' ) {
1600
+ vAPI.messaging.broadcast({
1601
+ what: 'assetUpdated',
1602
+ key: details.assetKey,
1603
+ failed: true
1604
+ });
1605
+ return;
1606
+ }
1607
+
1608
+ // Reload all filter lists if needed.
1609
+ if ( topic === 'after-assets-updated' ) {
1610
+ if ( details.assetKeys.length !== 0 ) {
1611
+ // https://github.com/gorhill/uBlock/pull/2314#issuecomment-278716960
1612
+ if (
1613
+ this.hiddenSettings.userResourcesLocation !== 'unset' ||
1614
+ vAPI.webextFlavor.soup.has('devbuild')
1615
+ ) {
1616
+ redirectEngine.invalidateResourcesSelfie(io);
1617
+ }
1618
+ this.loadFilterLists();
1619
+ }
1620
+ if ( this.userSettings.autoUpdate ) {
1621
+ this.scheduleAssetUpdater(
1622
+ this.hiddenSettings.autoUpdatePeriod * 3600000 || 25200000
1623
+ );
1624
+ } else {
1625
+ this.scheduleAssetUpdater(0);
1626
+ }
1627
+ vAPI.messaging.broadcast({
1628
+ what: 'assetsUpdated',
1629
+ assetKeys: details.assetKeys
1630
+ });
1631
+ return;
1632
+ }
1633
+
1634
+ // New asset source became available, if it's a filter list, should we
1635
+ // auto-select it?
1636
+ if ( topic === 'builtin-asset-source-added' ) {
1637
+ if ( details.entry.content === 'filters' ) {
1638
+ if (
1639
+ details.entry.off === true &&
1640
+ this.listMatchesEnvironment(details.entry)
1641
+ ) {
1642
+ this.saveSelectedFilterLists([ details.assetKey ], true);
1643
+ }
1644
+ }
1645
+ return;
1646
+ }
1647
+
1648
+ if ( topic === 'assets.json-updated' ) {
1649
+ const { newDict, oldDict } = details;
1650
+ if ( newDict['assets.json'] === undefined ) { return; }
1651
+ if ( oldDict['assets.json'] === undefined ) { return; }
1652
+ const newDefaultListset = new Set(newDict['assets.json'].defaultListset || []);
1653
+ const oldDefaultListset = new Set(oldDict['assets.json'].defaultListset || []);
1654
+ if ( newDefaultListset.size === 0 ) { return; }
1655
+ if ( oldDefaultListset.size === 0 ) {
1656
+ Array.from(Object.entries(oldDict))
1657
+ .filter(a =>
1658
+ a[1].content === 'filters' &&
1659
+ a[1].off === undefined &&
1660
+ /^https?:\/\//.test(a[0]) === false
1661
+ )
1662
+ .map(a => a[0])
1663
+ .forEach(a => oldDefaultListset.add(a));
1664
+ if ( oldDefaultListset.size === 0 ) { return; }
1665
+ }
1666
+ const selectedListset = new Set(this.selectedFilterLists);
1667
+ let selectedListModified = false;
1668
+ for ( const assetKey of oldDefaultListset ) {
1669
+ if ( newDefaultListset.has(assetKey) ) { continue; }
1670
+ selectedListset.delete(assetKey);
1671
+ selectedListModified = true;
1672
+ }
1673
+ for ( const assetKey of newDefaultListset ) {
1674
+ if ( oldDefaultListset.has(assetKey) ) { continue; }
1675
+ selectedListset.add(assetKey);
1676
+ selectedListModified = true;
1677
+ }
1678
+ if ( selectedListModified ) {
1679
+ this.saveSelectedFilterLists(Array.from(selectedListset));
1680
+ }
1681
+ return;
1682
+ }
1683
+ };