@browserless.io/browserless 2.36.0 → 2.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -2
- package/build/browsers/index.d.ts +1 -0
- package/build/browsers/index.js +3 -2
- package/build/http.d.ts +3 -2
- package/build/http.js +3 -2
- package/build/routes/chrome/tests/kill-sessions.spec.js +0 -11
- package/build/routes/chrome/ws/function-connect.d.ts +7 -0
- package/build/routes/chrome/ws/function-connect.js +6 -0
- package/build/routes/chrome/ws/function-connect.query.json +120 -0
- package/build/routes/chromium/ws/function-connect.d.ts +1 -0
- package/build/routes/chromium/ws/function-connect.js +1 -0
- package/build/routes/chromium/ws/function-connect.query.json +120 -0
- package/build/routes/edge/ws/function-connect.d.ts +7 -0
- package/build/routes/edge/ws/function-connect.js +6 -0
- package/build/routes/edge/ws/function-connect.query.json +120 -0
- package/build/sdk-utils.js +1 -1
- package/build/shared/function-connect.ws.d.ts +15 -0
- package/build/shared/function-connect.ws.js +13 -0
- package/build/shared/utils/function/handler.js +6 -4
- package/build/types.d.ts +6 -0
- package/build/types.js +3 -0
- package/extensions/ublocklite/_locales/ar/messages.json +60 -24
- package/extensions/ublocklite/_locales/az/messages.json +36 -0
- package/extensions/ublocklite/_locales/be/messages.json +36 -0
- package/extensions/ublocklite/_locales/bg/messages.json +36 -0
- package/extensions/ublocklite/_locales/bn/messages.json +36 -0
- package/extensions/ublocklite/_locales/br_FR/messages.json +36 -0
- package/extensions/ublocklite/_locales/bs/messages.json +36 -0
- package/extensions/ublocklite/_locales/ca/messages.json +36 -0
- package/extensions/ublocklite/_locales/cs/messages.json +36 -0
- package/extensions/ublocklite/_locales/cv/messages.json +36 -0
- package/extensions/ublocklite/_locales/cy/messages.json +40 -4
- package/extensions/ublocklite/_locales/da/messages.json +39 -3
- package/extensions/ublocklite/_locales/de/messages.json +36 -0
- package/extensions/ublocklite/_locales/el/messages.json +36 -0
- package/extensions/ublocklite/_locales/en/messages.json +36 -0
- package/extensions/ublocklite/_locales/en_GB/messages.json +36 -0
- package/extensions/ublocklite/_locales/eo/messages.json +36 -0
- package/extensions/ublocklite/_locales/es/messages.json +36 -0
- package/extensions/ublocklite/_locales/et/messages.json +36 -0
- package/extensions/ublocklite/_locales/eu/messages.json +36 -0
- package/extensions/ublocklite/_locales/fa/messages.json +36 -0
- package/extensions/ublocklite/_locales/fi/messages.json +37 -1
- package/extensions/ublocklite/_locales/fil/messages.json +36 -0
- package/extensions/ublocklite/_locales/fr/messages.json +36 -0
- package/extensions/ublocklite/_locales/fy/messages.json +37 -1
- package/extensions/ublocklite/_locales/gl/messages.json +37 -1
- package/extensions/ublocklite/_locales/gu/messages.json +36 -0
- package/extensions/ublocklite/_locales/he/messages.json +36 -0
- package/extensions/ublocklite/_locales/hi/messages.json +36 -0
- package/extensions/ublocklite/_locales/hr/messages.json +36 -0
- package/extensions/ublocklite/_locales/hu/messages.json +36 -0
- package/extensions/ublocklite/_locales/hy/messages.json +36 -0
- package/extensions/ublocklite/_locales/id/messages.json +36 -0
- package/extensions/ublocklite/_locales/it/messages.json +36 -0
- package/extensions/ublocklite/_locales/ja/messages.json +36 -0
- package/extensions/ublocklite/_locales/ka/messages.json +36 -0
- package/extensions/ublocklite/_locales/kk/messages.json +36 -0
- package/extensions/ublocklite/_locales/kn/messages.json +36 -0
- package/extensions/ublocklite/_locales/ko/messages.json +36 -0
- package/extensions/ublocklite/_locales/lt/messages.json +36 -0
- package/extensions/ublocklite/_locales/lv/messages.json +36 -0
- package/extensions/ublocklite/_locales/mk/messages.json +36 -0
- package/extensions/ublocklite/_locales/ml/messages.json +36 -0
- package/extensions/ublocklite/_locales/mr/messages.json +36 -0
- package/extensions/ublocklite/_locales/ms/messages.json +36 -0
- package/extensions/ublocklite/_locales/nb/messages.json +53 -17
- package/extensions/ublocklite/_locales/nl/messages.json +36 -0
- package/extensions/ublocklite/_locales/oc/messages.json +36 -0
- package/extensions/ublocklite/_locales/pa/messages.json +36 -0
- package/extensions/ublocklite/_locales/pl/messages.json +36 -0
- package/extensions/ublocklite/_locales/pt_BR/messages.json +36 -0
- package/extensions/ublocklite/_locales/pt_PT/messages.json +36 -0
- package/extensions/ublocklite/_locales/ro/messages.json +36 -0
- package/extensions/ublocklite/_locales/ru/messages.json +36 -0
- package/extensions/ublocklite/_locales/si/messages.json +36 -0
- package/extensions/ublocklite/_locales/sk/messages.json +36 -0
- package/extensions/ublocklite/_locales/sl/messages.json +36 -0
- package/extensions/ublocklite/_locales/so/messages.json +36 -0
- package/extensions/ublocklite/_locales/sq/messages.json +36 -0
- package/extensions/ublocklite/_locales/sr/messages.json +36 -0
- package/extensions/ublocklite/_locales/sv/messages.json +36 -0
- package/extensions/ublocklite/_locales/sw/messages.json +36 -0
- package/extensions/ublocklite/_locales/ta/messages.json +36 -0
- package/extensions/ublocklite/_locales/te/messages.json +36 -0
- package/extensions/ublocklite/_locales/th/messages.json +36 -0
- package/extensions/ublocklite/_locales/tr/messages.json +36 -0
- package/extensions/ublocklite/_locales/uk/messages.json +36 -0
- package/extensions/ublocklite/_locales/ur/messages.json +36 -0
- package/extensions/ublocklite/_locales/vi/messages.json +36 -0
- package/extensions/ublocklite/_locales/zh_CN/messages.json +36 -0
- package/extensions/ublocklite/_locales/zh_TW/messages.json +36 -0
- package/extensions/ublocklite/css/dashboard-common.css +0 -1
- package/extensions/ublocklite/css/dashboard.css +8 -0
- package/extensions/ublocklite/css/settings.css +101 -1
- package/extensions/ublocklite/css/unpicker-ui.css +1 -0
- package/extensions/ublocklite/dashboard.html +48 -11
- package/extensions/ublocklite/js/background.js +49 -35
- package/extensions/ublocklite/js/backup-restore.js +153 -0
- package/extensions/ublocklite/js/config.js +2 -0
- package/extensions/ublocklite/js/dashboard.js +19 -0
- package/extensions/ublocklite/js/develop.js +2 -11
- package/extensions/ublocklite/js/dom.js +10 -0
- package/extensions/ublocklite/js/filter-lists.js +5 -5
- package/extensions/ublocklite/js/filter-manager-ui.js +486 -0
- package/extensions/ublocklite/js/filter-manager.js +85 -53
- package/extensions/ublocklite/js/mode-manager.js +8 -1
- package/extensions/ublocklite/js/picker-ui.js +2 -2
- package/extensions/ublocklite/js/popup.js +20 -20
- package/extensions/ublocklite/js/ro-dnr-editor.js +9 -5
- package/extensions/ublocklite/js/ruleset-manager.js +13 -8
- package/extensions/ublocklite/js/scripting/unpicker.js +3 -3
- package/extensions/ublocklite/js/settings.js +51 -0
- package/extensions/ublocklite/js/static-filtering-parser.js +4 -4
- package/extensions/ublocklite/js/unpicker-ui.js +5 -5
- package/extensions/ublocklite/js/utils.js +14 -0
- package/extensions/ublocklite/manifest.json +2 -2
- package/extensions/ublocklite/rulesets/generic-details.json +2 -3
- package/extensions/ublocklite/rulesets/main/adguard-mobile.json +3 -2
- package/extensions/ublocklite/rulesets/main/adguard-spyware-url.json +5 -4
- package/extensions/ublocklite/rulesets/main/annoyances-cookies.json +12 -4
- package/extensions/ublocklite/rulesets/main/annoyances-notifications.json +3 -1
- package/extensions/ublocklite/rulesets/main/annoyances-others.json +4 -3
- package/extensions/ublocklite/rulesets/main/annoyances-overlays.json +4 -3
- package/extensions/ublocklite/rulesets/main/annoyances-widgets.json +4 -2
- package/extensions/ublocklite/rulesets/main/block-lan.json +3 -1
- package/extensions/ublocklite/rulesets/main/chn-0.json +25 -16
- package/extensions/ublocklite/rulesets/main/deu-0.json +2 -9
- package/extensions/ublocklite/rulesets/main/easylist.json +26 -65
- package/extensions/ublocklite/rulesets/main/easyprivacy.json +94 -21
- package/extensions/ublocklite/rulesets/main/fin-0.json +2 -1
- package/extensions/ublocklite/rulesets/main/fra-0.json +1 -1
- package/extensions/ublocklite/rulesets/main/hun-0.json +3 -2
- package/extensions/ublocklite/rulesets/main/idn-0.json +22 -8
- package/extensions/ublocklite/rulesets/main/ind-0.json +62 -43
- package/extensions/ublocklite/rulesets/main/irn-0.json +5 -4
- package/extensions/ublocklite/rulesets/main/isr-0.json +2 -3
- package/extensions/ublocklite/rulesets/main/ita-0.json +9 -2
- package/extensions/ublocklite/rulesets/main/jpn-1.json +49 -31
- package/extensions/ublocklite/rulesets/main/kor-1.json +6 -3
- package/extensions/ublocklite/rulesets/main/nld-0.json +4 -1
- package/extensions/ublocklite/rulesets/main/pgl.json +30 -6
- package/extensions/ublocklite/rulesets/main/pol-0.json +1 -1
- package/extensions/ublocklite/rulesets/main/rou-1.json +4 -2
- package/extensions/ublocklite/rulesets/main/rus-0.json +18 -11
- package/extensions/ublocklite/rulesets/main/rus-1.json +3 -3
- package/extensions/ublocklite/rulesets/main/spa-1.json +6 -5
- package/extensions/ublocklite/rulesets/main/stevenblack-hosts.json +10500 -90447
- package/extensions/ublocklite/rulesets/main/swe-1.json +36 -27
- package/extensions/ublocklite/rulesets/main/tur-0.json +10 -7
- package/extensions/ublocklite/rulesets/main/ublock-badware.json +37 -13
- package/extensions/ublocklite/rulesets/main/ublock-filters.json +61 -34
- package/extensions/ublocklite/rulesets/main/ubol-tests.json +28 -0
- package/extensions/ublocklite/rulesets/main/ukr-0.json +1 -1
- package/extensions/ublocklite/rulesets/main/urlhaus-full.json +1575 -584
- package/extensions/ublocklite/rulesets/main/vie-1.json +40 -44
- package/extensions/ublocklite/rulesets/regex/chn-0.json +2 -2
- package/extensions/ublocklite/rulesets/regex/easylist.json +1 -1
- package/extensions/ublocklite/rulesets/regex/jpn-1.json +1 -2
- package/extensions/ublocklite/rulesets/regex/swe-1.json +0 -1
- package/extensions/ublocklite/rulesets/regex/ublock-badware.json +9 -3
- package/extensions/ublocklite/rulesets/regex/ublock-filters.json +22 -16
- package/extensions/ublocklite/rulesets/ruleset-details.json +206 -206
- package/extensions/ublocklite/rulesets/scripting/generic/annoyances-cookies.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/generic/annoyances-notifications.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/generic/annoyances-others.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/generic/annoyances-social.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/generic/chn-0.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/generic/easylist.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/generic/jpn-1.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/generic/rus-1.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/generic/swe-1.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/generic/ublock-filters.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/generichigh/easylist.css +2 -1
- package/extensions/ublocklite/rulesets/scripting/generichigh/idn-0.css +3 -0
- package/extensions/ublocklite/rulesets/scripting/generichigh/jpn-1.css +1 -0
- package/extensions/ublocklite/rulesets/scripting/generichigh/ublock-filters.css +9 -1
- package/extensions/ublocklite/rulesets/scripting/procedural/adguard-mobile.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/annoyances-cookies.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/annoyances-overlays.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/annoyances-social.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/chn-0.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/procedural/deu-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/easylist.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/fin-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/ind-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/irn-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/jpn-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/kor-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/ltu-0.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/procedural/rou-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/rus-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/rus-1.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/procedural/swe-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/tur-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/ublock-filters.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/procedural/vie-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/adguard-mobile.abort-current-script.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/adguard-mobile.adjust-setTimeout.js +332 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/adguard-mobile.json-prune-fetch-response.js +588 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/adguard-mobile.json-prune-xhr-response.js +597 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/adguard-mobile.remove-cookie.js +376 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/adguard-mobile.set-constant.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/adguard-mobile.set-cookie-reload.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/adguard-mobile.xml-prune.js +443 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.prevent-requestAnimationFrame.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.set-cookie-reload.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.set-cookie.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.set-local-storage-item.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.trusted-click-element.js +88 -77
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.trusted-set-cookie-reload.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.trusted-set-cookie.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-cookies.trusted-set-local-storage-item.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-others.set-local-storage-item.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-others.set-session-storage-item.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-overlays.abort-current-script.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-overlays.prevent-setTimeout.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-overlays.set-constant.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-overlays.trusted-click-element.js +88 -77
- package/extensions/ublocklite/rulesets/scripting/scriptlet/annoyances-overlays.trusted-set-local-storage-item.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/chn-0.addEventListener-defuser.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/easyprivacy.set-constant.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/fin-0.spoof-css.js +422 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/idn-0.prevent-window-open.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/irn-0.href-sanitizer.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/jpn-1.abort-current-script.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/jpn-1.addEventListener-defuser.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/jpn-1.href-sanitizer.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/jpn-1.json-prune.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/jpn-1.prevent-fetch.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/kor-1.abort-current-script.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/kor-1.json-prune-xhr-response.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/kor-1.prevent-fetch.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/kor-1.prevent-window-open.js +471 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/kor-1.prevent-xhr.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/kor-1.remove-cookie.js +376 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.abort-on-property-read.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.abort-on-property-write.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.addEventListener-defuser.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.close-window.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.href-sanitizer.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.json-prune-fetch-response.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.prevent-setTimeout.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.remove-node-text.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.set-attr.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-0.set-constant.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-1.json-prune-xhr-response.js +597 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/rus-1.set-constant.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/spa-1.abort-current-script.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/spa-1.json-prune.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/spa-1.noeval-if.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/spa-1.prevent-fetch.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/spa-1.prevent-window-open.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/spa-1.set-constant.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/swe-1.href-sanitizer.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/swe-1.prevent-setTimeout.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/tur-0.abort-on-property-read.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/tur-0.addEventListener-defuser.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/tur-0.prevent-setTimeout.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/tur-0.prevent-window-open.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/tur-0.remove-attr.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/tur-0.set-constant.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/tur-0.set-local-storage-item.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.abort-current-script.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.abort-on-property-read.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.abort-on-property-write.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.abort-on-stack-trace.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.addEventListener-defuser.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.adjust-setInterval.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.adjust-setTimeout.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.href-sanitizer.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.json-edit.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.json-prune-fetch-response.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.json-prune-xhr-response.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.json-prune.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.jsonl-edit-xhr-response.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.noeval-if.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-fetch.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-requestAnimationFrame.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-setInterval.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-setTimeout.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-window-open.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.prevent-xhr.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.remove-cookie.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.remove-node-text.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.set-attr.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.set-constant.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.set-local-storage-item.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.set-session-storage-item.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.spoof-css.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-click-element.js +86 -75
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-create-html.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-json-edit-fetch-response.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-json-edit.js +851 -0
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-replace-argument.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-replace-node-text.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-replace-outbound-text.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/ublock-filters.trusted-suppress-native-method.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/vie-1.abort-current-script.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/scriptlet/vie-1.abort-on-property-read.js +2 -2
- package/extensions/ublocklite/rulesets/scripting/specific/adguard-mobile.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/annoyances-cookies.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/annoyances-notifications.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/annoyances-others.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/annoyances-overlays.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/annoyances-social.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/chn-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/deu-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/easylist.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/fin-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/fra-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/idn-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/ind-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/irn-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/isr-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/ita-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/jpn-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/kor-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/ltu-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/nld-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/rou-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/rus-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/rus-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/spa-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/swe-1.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/tur-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/ublock-badware.js +1 -1
- package/extensions/ublocklite/rulesets/scripting/specific/ublock-filters.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/ukr-0.js +3 -3
- package/extensions/ublocklite/rulesets/scripting/specific/vie-1.js +3 -3
- package/extensions/ublocklite/rulesets/scriptlet-details.json +227 -126
- package/extensions/ublocklite/rulesets/strictblock/adguard-mobile.json +1 -0
- package/extensions/ublocklite/rulesets/strictblock/annoyances-others.json +1 -0
- package/extensions/ublocklite/rulesets/strictblock/chn-0.json +222 -1
- package/extensions/ublocklite/rulesets/strictblock/easylist.json +1 -1
- package/extensions/ublocklite/rulesets/strictblock/easyprivacy.json +62 -2
- package/extensions/ublocklite/rulesets/strictblock/idn-0.json +2 -0
- package/extensions/ublocklite/rulesets/strictblock/irn-0.json +4 -1
- package/extensions/ublocklite/rulesets/strictblock/isr-0.json +1 -0
- package/extensions/ublocklite/rulesets/strictblock/ita-0.json +1 -0
- package/extensions/ublocklite/rulesets/strictblock/jpn-1.json +203 -186
- package/extensions/ublocklite/rulesets/strictblock/pgl.json +30 -6
- package/extensions/ublocklite/rulesets/strictblock/pol-0.json +2 -0
- package/extensions/ublocklite/rulesets/strictblock/rou-1.json +1 -0
- package/extensions/ublocklite/rulesets/strictblock/stevenblack-hosts.json +10500 -90447
- package/extensions/ublocklite/rulesets/strictblock/swe-1.json +0 -3
- package/extensions/ublocklite/rulesets/strictblock/ublock-badware.json +655 -650
- package/extensions/ublocklite/rulesets/strictblock/ublock-filters.json +1 -1
- package/extensions/ublocklite/rulesets/strictblock/ukr-0.json +1 -0
- package/extensions/ublocklite/rulesets/strictblock/urlhaus-full.json +1575 -584
- package/extensions/ublocklite/rulesets/strictblock/vie-1.json +0 -3
- package/extensions/ublocklite/rulesets/urlskip/ublock-filters.json +31 -1
- package/extensions/ublocklite/ublock.zip +0 -0
- package/extensions/ublocklite/web_accessible_resources/google-ima.js +14 -7
- package/package.json +7 -7
- package/src/browsers/index.ts +5 -4
- package/src/http.ts +3 -2
- package/src/routes/chrome/tests/kill-sessions.spec.ts +0 -10
- package/src/routes/chrome/ws/function-connect.ts +12 -0
- package/src/routes/chromium/ws/function-connect.ts +1 -0
- package/src/routes/edge/ws/function-connect.ts +12 -0
- package/src/sdk-utils.ts +1 -1
- package/src/shared/function-connect.ws.ts +38 -0
- package/src/shared/utils/function/handler.ts +11 -6
- package/src/types.ts +4 -0
- package/static/docs/swagger.json +104 -2
- package/static/docs/swagger.min.json +103 -1
- package/static/function/client.js +14 -20
- package/static/function/index.html +14 -20
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
/*******************************************************************************
|
|
2
|
+
|
|
3
|
+
uBlock Origin Lite - a comprehensive, MV3-compliant content blocker
|
|
4
|
+
Copyright (C) 2025-present Raymond Hill
|
|
5
|
+
|
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
This program is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU General Public License
|
|
17
|
+
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
18
|
+
|
|
19
|
+
Home: https://github.com/gorhill/uBlock
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { browser, sendMessage } from './ext.js';
|
|
23
|
+
import { dom, qs$, qsa$ } from './dom.js';
|
|
24
|
+
import { nodeFromTemplate } from './dashboard.js';
|
|
25
|
+
import punycode from './punycode.js';
|
|
26
|
+
|
|
27
|
+
/******************************************************************************/
|
|
28
|
+
|
|
29
|
+
const dataContainer = qs$('section[data-pane="filters"] .hostnames');
|
|
30
|
+
|
|
31
|
+
/******************************************************************************/
|
|
32
|
+
|
|
33
|
+
function isValidHostname(hostname) {
|
|
34
|
+
try {
|
|
35
|
+
const url = new URL(`https://${hostname}/`);
|
|
36
|
+
return url.hostname === hostname;
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/******************************************************************************/
|
|
43
|
+
|
|
44
|
+
function toPrettySelector(selector) {
|
|
45
|
+
if ( selector.startsWith('{') === false ) { return selector; }
|
|
46
|
+
try {
|
|
47
|
+
return JSON.parse(selector).raw;
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
return selector;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/******************************************************************************/
|
|
54
|
+
|
|
55
|
+
function hostnameFromNode(node) {
|
|
56
|
+
const li = node.closest('li.hostname');
|
|
57
|
+
if ( li === null ) { return; }
|
|
58
|
+
const span = qs$(li, '.hostname[data-pretty]');
|
|
59
|
+
if ( span === null ) { return; }
|
|
60
|
+
return span.dataset.ugly || undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function selectorFromNode(node) {
|
|
64
|
+
const li = node.closest('li.selector');
|
|
65
|
+
if ( li === null ) { return; }
|
|
66
|
+
const span = qs$(li, '.selector[data-pretty]');
|
|
67
|
+
if ( span === null ) { return; }
|
|
68
|
+
return span.dataset.ugly || undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function selectorsFromNode(node, all = false) {
|
|
72
|
+
const li = node.closest('li.hostname');
|
|
73
|
+
if ( li === null ) { return []; }
|
|
74
|
+
const qsel = all
|
|
75
|
+
? 'li.selector [contenteditable]'
|
|
76
|
+
: 'li.selector:not(.removed) [contenteditable]';
|
|
77
|
+
return Array.from(qsa$(li, qsel)).map(a => a.dataset.ugly);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/******************************************************************************/
|
|
81
|
+
|
|
82
|
+
async function removeSelectorsFromHostname(node) {
|
|
83
|
+
const hostnameNode = node.closest('li.hostname');
|
|
84
|
+
if ( hostnameNode === null ) { return; }
|
|
85
|
+
const hostname = hostnameFromNode(hostnameNode);
|
|
86
|
+
if ( hostname === undefined ) { return; }
|
|
87
|
+
const selectors = Array.from(
|
|
88
|
+
qsa$(hostnameNode, 'li.selector.removed [contenteditable]')
|
|
89
|
+
).map(a => a.dataset.ugly);
|
|
90
|
+
if ( selectors.length === 0 ) { return; }
|
|
91
|
+
dom.cl.add(dom.body, 'busy');
|
|
92
|
+
updateContentEditability();
|
|
93
|
+
await sendMessage({ what: 'removeCustomFilters', hostname, selectors });
|
|
94
|
+
await debounceRenderCustomFilters();
|
|
95
|
+
dom.cl.remove(dom.body, 'busy');
|
|
96
|
+
updateContentEditability();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function unremoveSelectorsFromHostname(node) {
|
|
100
|
+
const hostnameNode = node.closest('li.hostname');
|
|
101
|
+
if ( hostnameNode === null ) { return; }
|
|
102
|
+
const hostname = hostnameFromNode(hostnameNode);
|
|
103
|
+
if ( hostname === undefined ) { return; }
|
|
104
|
+
const selectors = Array.from(
|
|
105
|
+
qsa$(hostnameNode, 'li.selector:not(.removed) [contenteditable]')
|
|
106
|
+
).map(a => a.dataset.ugly);
|
|
107
|
+
if ( selectors.length === 0 ) { return; }
|
|
108
|
+
dom.cl.add(dom.body, 'busy');
|
|
109
|
+
updateContentEditability();
|
|
110
|
+
await sendMessage({ what: 'addCustomFilters', hostname, selectors });
|
|
111
|
+
await debounceRenderCustomFilters();
|
|
112
|
+
dom.cl.remove(dom.body, 'busy');
|
|
113
|
+
updateContentEditability();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/******************************************************************************/
|
|
117
|
+
|
|
118
|
+
function dataFromDOM() {
|
|
119
|
+
const data = new Map();
|
|
120
|
+
for ( const hostnameNode of qsa$('li.hostname') ) {
|
|
121
|
+
const hostname = hostnameFromNode(hostnameNode);
|
|
122
|
+
const selectors = [];
|
|
123
|
+
for ( const selectorNode of qsa$(hostnameNode, 'li.selector') ) {
|
|
124
|
+
selectors.push(selectorFromNode(selectorNode));
|
|
125
|
+
}
|
|
126
|
+
data.set(hostname, selectors);
|
|
127
|
+
}
|
|
128
|
+
return data;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/******************************************************************************/
|
|
132
|
+
|
|
133
|
+
async function renderCustomFilters() {
|
|
134
|
+
const data = await sendMessage({ what: 'getAllCustomFilters' });
|
|
135
|
+
if ( Boolean(data) === false ) { return; }
|
|
136
|
+
const storedData = new Map(data);
|
|
137
|
+
const domData = dataFromDOM();
|
|
138
|
+
const hostnames = Array.from(
|
|
139
|
+
new Set([
|
|
140
|
+
...Array.from(storedData.keys()),
|
|
141
|
+
...Array.from(domData.keys()),
|
|
142
|
+
])
|
|
143
|
+
).sort();
|
|
144
|
+
const fragment = document.createDocumentFragment();
|
|
145
|
+
for ( const hostname of hostnames ) {
|
|
146
|
+
const hostnameNode = nodeFromTemplate('customFiltersHostname');
|
|
147
|
+
const label = qs$(hostnameNode, 'span.hostname');
|
|
148
|
+
label.dataset.ugly = hostname;
|
|
149
|
+
const pretty = punycode.toUnicode(hostname);
|
|
150
|
+
label.dataset.pretty = pretty;
|
|
151
|
+
dom.text(label, pretty);
|
|
152
|
+
const storedSelectors = new Set(storedData.get(hostname));
|
|
153
|
+
const domSelectors = new Set(domData.get(hostname));
|
|
154
|
+
const selectors = Array.from(
|
|
155
|
+
new Set([
|
|
156
|
+
...Array.from(storedSelectors),
|
|
157
|
+
...Array.from(domSelectors),
|
|
158
|
+
])
|
|
159
|
+
).sort();
|
|
160
|
+
const ulSelectors = qs$(hostnameNode, '.selectors');
|
|
161
|
+
for ( const selector of selectors ) {
|
|
162
|
+
const selectorNode = nodeFromTemplate('customFiltersSelector');
|
|
163
|
+
const label = qs$(selectorNode, 'span.selector');
|
|
164
|
+
label.dataset.ugly = selector;
|
|
165
|
+
const pretty = toPrettySelector(selector);
|
|
166
|
+
label.dataset.pretty = pretty;
|
|
167
|
+
dom.text(label, pretty);
|
|
168
|
+
if ( storedSelectors.has(selector) === false ) {
|
|
169
|
+
dom.cl.add(selectorNode, 'removed');
|
|
170
|
+
}
|
|
171
|
+
ulSelectors.append(selectorNode);
|
|
172
|
+
}
|
|
173
|
+
fragment.append(hostnameNode);
|
|
174
|
+
}
|
|
175
|
+
dom.remove('section[data-pane="filters"] .hostnames > .hostname');
|
|
176
|
+
dataContainer.prepend(fragment);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function debounceRenderCustomFilters() {
|
|
180
|
+
let { debouncer } = debounceRenderCustomFilters;
|
|
181
|
+
if ( debouncer === undefined ) {
|
|
182
|
+
debouncer = debounceRenderCustomFilters.debouncer = {};
|
|
183
|
+
debouncer.promise = new Promise(resolve => {
|
|
184
|
+
debouncer.resolve = resolve;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if ( debouncer.timer !== undefined ) {
|
|
188
|
+
self.clearTimeout(debouncer.timer);
|
|
189
|
+
}
|
|
190
|
+
debouncer.timer = self.setTimeout(( ) => {
|
|
191
|
+
const { resolve } = debounceRenderCustomFilters.debouncer;
|
|
192
|
+
debounceRenderCustomFilters.debouncer = undefined;
|
|
193
|
+
renderCustomFilters().then(resolve);
|
|
194
|
+
}, 151);
|
|
195
|
+
return debouncer.promise;
|
|
196
|
+
}
|
|
197
|
+
debounceRenderCustomFilters.debouncer = undefined;
|
|
198
|
+
|
|
199
|
+
/******************************************************************************/
|
|
200
|
+
|
|
201
|
+
function updateContentEditability() {
|
|
202
|
+
if ( dom.cl.has(dom.body, 'busy') ) {
|
|
203
|
+
dom.attr('[contenteditable]', 'contenteditable', 'false');
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
dom.attr('section[data-pane="filters"] li:not(.removed) [contenteditable]',
|
|
207
|
+
'contenteditable',
|
|
208
|
+
'plaintext-only'
|
|
209
|
+
);
|
|
210
|
+
// No point editing a removed hostname
|
|
211
|
+
dom.attr('section[data-pane="filters"] li.hostname:not(:has(li.selector:not(.removed))) > div [contenteditable]',
|
|
212
|
+
'contenteditable',
|
|
213
|
+
'false'
|
|
214
|
+
);
|
|
215
|
+
// No point editing a removed selector
|
|
216
|
+
dom.attr('section[data-pane="filters"] .selector.removed [contenteditable]',
|
|
217
|
+
'contenteditable',
|
|
218
|
+
'false'
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/******************************************************************************/
|
|
223
|
+
|
|
224
|
+
async function onHostnameChanged(target, before, after) {
|
|
225
|
+
const uglyAfter = punycode.toASCII(after);
|
|
226
|
+
if ( isValidHostname(uglyAfter) === false ) {
|
|
227
|
+
target.textContent = before;
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
dom.cl.add(dom.body, 'busy');
|
|
232
|
+
updateContentEditability();
|
|
233
|
+
|
|
234
|
+
// Remove old hostname from storage
|
|
235
|
+
await sendMessage({ what: 'removeAllCustomFilters',
|
|
236
|
+
hostname: target.dataset.ugly,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Add selectors under new hostname to storage
|
|
240
|
+
target.dataset.ugly = uglyAfter;
|
|
241
|
+
target.dataset.pretty = after;
|
|
242
|
+
await sendMessage({ what: 'addCustomFilters',
|
|
243
|
+
hostname: hostnameFromNode(target),
|
|
244
|
+
selectors: selectorsFromNode(target),
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
await debounceRenderCustomFilters();
|
|
248
|
+
dom.cl.remove(dom.body, 'busy');
|
|
249
|
+
updateContentEditability();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async function onSelectorChanged(target, before, after) {
|
|
253
|
+
// Validate selector
|
|
254
|
+
const parserModule = await import('./static-filtering-parser.js');
|
|
255
|
+
const compiler = new parserModule.ExtSelectorCompiler({ nativeCssHas: true });
|
|
256
|
+
const result = {};
|
|
257
|
+
if ( compiler.compile(after, result) === false ) {
|
|
258
|
+
target.textContent = before;
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const hostname = hostnameFromNode(target);
|
|
263
|
+
|
|
264
|
+
dom.cl.add(dom.body, 'busy');
|
|
265
|
+
updateContentEditability();
|
|
266
|
+
|
|
267
|
+
// Remove old selector from storage
|
|
268
|
+
await sendMessage({ what: 'removeCustomFilters',
|
|
269
|
+
hostname,
|
|
270
|
+
selectors: [ target.dataset.ugly ],
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Add new selector to storage
|
|
274
|
+
target.dataset.ugly = result.compiled;
|
|
275
|
+
target.dataset.pretty = result.raw;
|
|
276
|
+
await sendMessage({ what: 'addCustomFilters',
|
|
277
|
+
hostname,
|
|
278
|
+
selectors: [ result.compiled ],
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
await debounceRenderCustomFilters();
|
|
282
|
+
dom.cl.remove(dom.body, 'busy');
|
|
283
|
+
updateContentEditability();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function onTextChanged(target) {
|
|
287
|
+
const before = target.dataset.pretty;
|
|
288
|
+
const after = target.textContent.trim();
|
|
289
|
+
if ( after !== target.textContent ) {
|
|
290
|
+
target.textContent = after;
|
|
291
|
+
}
|
|
292
|
+
if ( after === before ) { return; }
|
|
293
|
+
if ( after === '' ) {
|
|
294
|
+
target.textContent = before;
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if ( target.matches('.hostname') ) {
|
|
298
|
+
onHostnameChanged(target, before, after);
|
|
299
|
+
} else if ( target.matches('.selector') ) {
|
|
300
|
+
onSelectorChanged(target, before, after);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/******************************************************************************/
|
|
305
|
+
|
|
306
|
+
function startEdit(ev) {
|
|
307
|
+
focusedEditableContent = ev.target;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function endEdit(ev) {
|
|
311
|
+
const { target } = ev;
|
|
312
|
+
if ( target.textContent !== target.dataset.pretty ) {
|
|
313
|
+
onTextChanged(target);
|
|
314
|
+
}
|
|
315
|
+
focusedEditableContent = null;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function commitEdit(ev) {
|
|
319
|
+
const { target } = ev;
|
|
320
|
+
if ( target === focusedEditableContent ) {
|
|
321
|
+
if ( ev.inputType === 'insertLineBreak' ) { target.blur(); }
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
onTextChanged(target);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
let focusedEditableContent = null;
|
|
328
|
+
|
|
329
|
+
/******************************************************************************/
|
|
330
|
+
|
|
331
|
+
function onTrashClicked(ev) {
|
|
332
|
+
const { target } = ev;
|
|
333
|
+
const node = target.closest('li.selector');
|
|
334
|
+
if ( node ) {
|
|
335
|
+
dom.cl.add(node, 'removed');
|
|
336
|
+
} else {
|
|
337
|
+
dom.cl.add(qsa$(target.closest('li.hostname'), 'li.selector'), 'removed');
|
|
338
|
+
}
|
|
339
|
+
removeSelectorsFromHostname(target);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function onUndoClicked(ev) {
|
|
343
|
+
const { target } = ev;
|
|
344
|
+
const node = target.closest('li.selector');
|
|
345
|
+
if ( node ) {
|
|
346
|
+
dom.cl.remove(node, 'removed');
|
|
347
|
+
} else {
|
|
348
|
+
dom.cl.remove(qsa$(target.closest('li.hostname'), 'li.selector'), 'removed');
|
|
349
|
+
}
|
|
350
|
+
unremoveSelectorsFromHostname(target);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/******************************************************************************/
|
|
354
|
+
|
|
355
|
+
async function importFromText(text) {
|
|
356
|
+
const parserModule = await import('./static-filtering-parser.js');
|
|
357
|
+
const parser = new parserModule.AstFilterParser({ nativeCssHas: true });
|
|
358
|
+
const lines = text.split(/\n/);
|
|
359
|
+
const hostnameToSelectorsMap = new Map();
|
|
360
|
+
|
|
361
|
+
for ( const line of lines ) {
|
|
362
|
+
parser.parse(line);
|
|
363
|
+
if ( parser.hasError() ) { continue; }
|
|
364
|
+
if ( parser.isCosmeticFilter() === false ) { continue; }
|
|
365
|
+
if ( parser.hasOptions() === false ) { continue; }
|
|
366
|
+
const { compiled, exception } = parser.result;
|
|
367
|
+
if ( compiled === undefined ) { continue; }
|
|
368
|
+
if ( exception ) { continue; }
|
|
369
|
+
const hostnames = new Set();
|
|
370
|
+
for ( const { hn, not, bad } of parser.getExtFilterDomainIterator() ) {
|
|
371
|
+
if ( bad ) { continue; }
|
|
372
|
+
if ( hn.includes('/') ) { continue; }
|
|
373
|
+
if ( hn.includes('*') ) { continue; }
|
|
374
|
+
if ( not ) { hostnames.length = 0; break; }
|
|
375
|
+
hostnames.add(hn);
|
|
376
|
+
}
|
|
377
|
+
for ( const hn of hostnames ) {
|
|
378
|
+
const selectors = hostnameToSelectorsMap.get(hn) || new Set();
|
|
379
|
+
if ( selectors.size === 0 ) {
|
|
380
|
+
hostnameToSelectorsMap.set(hn, selectors)
|
|
381
|
+
}
|
|
382
|
+
selectors.add(compiled);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if ( hostnameToSelectorsMap.size === 0 ) { return; }
|
|
387
|
+
|
|
388
|
+
dom.cl.add(dom.body, 'busy');
|
|
389
|
+
updateContentEditability();
|
|
390
|
+
|
|
391
|
+
const promises = [];
|
|
392
|
+
for ( const [ hostname, selectors ] of hostnameToSelectorsMap ) {
|
|
393
|
+
promises.push(
|
|
394
|
+
sendMessage({ what: 'addCustomFilters',
|
|
395
|
+
hostname,
|
|
396
|
+
selectors: Array.from(selectors),
|
|
397
|
+
})
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
await Promise.all(promises);
|
|
401
|
+
|
|
402
|
+
await debounceRenderCustomFilters();
|
|
403
|
+
dom.cl.remove(dom.body, 'busy');
|
|
404
|
+
updateContentEditability();
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/******************************************************************************/
|
|
408
|
+
|
|
409
|
+
function importFromTextarea() {
|
|
410
|
+
dom.prop('section[data-pane="filters"] details', 'open', false);
|
|
411
|
+
const textarea = qs$('section[data-pane="filters"] .importFromText textarea');
|
|
412
|
+
importFromText(textarea.value);
|
|
413
|
+
textarea.value = '';
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/******************************************************************************/
|
|
417
|
+
|
|
418
|
+
function importFromFile() {
|
|
419
|
+
const input = qs$('section[data-pane="filters"] input[type="file"]');
|
|
420
|
+
input.onchange = ev => {
|
|
421
|
+
input.onchange = null;
|
|
422
|
+
const file = ev.target.files[0];
|
|
423
|
+
if ( file === undefined || file.name === '' ) { return; }
|
|
424
|
+
const fr = new FileReader();
|
|
425
|
+
fr.onload = ( ) => {
|
|
426
|
+
if ( typeof fr.result !== 'string' ) { return; }
|
|
427
|
+
importFromText(fr.result);
|
|
428
|
+
};
|
|
429
|
+
fr.readAsText(file);
|
|
430
|
+
};
|
|
431
|
+
// Reset to empty string, this will ensure a change event is properly
|
|
432
|
+
// triggered if the user pick a file, even if it's the same as the last
|
|
433
|
+
// one picked.
|
|
434
|
+
input.value = '';
|
|
435
|
+
input.click();
|
|
436
|
+
dom.prop('section[data-pane="filters"] details', 'open', false);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/******************************************************************************/
|
|
440
|
+
|
|
441
|
+
function exportToFile() {
|
|
442
|
+
const lines = [];
|
|
443
|
+
for ( const hostnameNode of qsa$('.hostnames li.hostname') ) {
|
|
444
|
+
const hostname = punycode.toUnicode(hostnameFromNode(hostnameNode));
|
|
445
|
+
const selectors = selectorsFromNode(hostnameNode);
|
|
446
|
+
for ( const selector of selectors ) {
|
|
447
|
+
lines.push(`${hostname}##${toPrettySelector(selector)}`);
|
|
448
|
+
}
|
|
449
|
+
lines.push('');
|
|
450
|
+
}
|
|
451
|
+
const text = lines.join('\n').trim();
|
|
452
|
+
if ( text.length === 0 ) { return; }
|
|
453
|
+
const a = document.createElement('a');
|
|
454
|
+
a.href = `data:text/plain;charset=utf-8,${encodeURIComponent(text + '\n')}`;
|
|
455
|
+
dom.attr(a, 'download', 'my-ubol-filters.txt');
|
|
456
|
+
dom.attr(a, 'type', 'text/plain');
|
|
457
|
+
a.click();
|
|
458
|
+
dom.prop('section[data-pane="filters"] details', 'open', false);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/******************************************************************************/
|
|
462
|
+
|
|
463
|
+
async function start() {
|
|
464
|
+
renderCustomFilters();
|
|
465
|
+
|
|
466
|
+
dom.on(dataContainer, 'focusin', 'section[data-pane="filters"] [contenteditable]', startEdit);
|
|
467
|
+
dom.on(dataContainer, 'focusout', 'section[data-pane="filters"] [contenteditable]', endEdit);
|
|
468
|
+
dom.on(dataContainer, 'input', 'section[data-pane="filters"] [contenteditable]', commitEdit);
|
|
469
|
+
dom.on(dataContainer, 'click', 'section[data-pane="filters"] .remove', onTrashClicked);
|
|
470
|
+
dom.on(dataContainer, 'click', 'section[data-pane="filters"] .undo', onUndoClicked);
|
|
471
|
+
dom.on('section[data-pane="filters"] [data-i18n="addButton"]', 'click', importFromTextarea);
|
|
472
|
+
dom.on('section[data-pane="filters"] [data-i18n="importAndAppendButton"]', 'click', importFromFile);
|
|
473
|
+
dom.on('section[data-pane="filters"] [data-i18n="exportButton"]', 'click', exportToFile);
|
|
474
|
+
|
|
475
|
+
browser.storage.local.onChanged.addListener((changes, area) => {
|
|
476
|
+
if ( area !== undefined && area !== 'local' ) { return; }
|
|
477
|
+
if ( Object.keys(changes).some(a => a.startsWith('site.')) ) {
|
|
478
|
+
debounceRenderCustomFilters();
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/******************************************************************************/
|
|
484
|
+
|
|
485
|
+
// Update pane on-demand
|
|
486
|
+
dom.onFirstShown(start, qs$('section[data-pane="filters"]'));
|
|
@@ -38,15 +38,41 @@ import { ubolErr } from './debug.js';
|
|
|
38
38
|
|
|
39
39
|
/******************************************************************************/
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
async function flushWrites() {
|
|
42
|
+
while ( pendingWrites.length !== 0 ) {
|
|
43
|
+
const promises = pendingWrites;
|
|
44
|
+
pendingWrites.length = 0;
|
|
45
|
+
await Promise.all(promises);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function keysFromStorage() {
|
|
50
|
+
await flushWrites();
|
|
51
|
+
return localKeys();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function readFromStorage(key) {
|
|
55
|
+
await flushWrites();
|
|
56
|
+
return localRead(key);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function writeToStorage(key, value) {
|
|
60
|
+
pendingWrites.push(localWrite(key, value));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function removeFromStorage(key) {
|
|
64
|
+
pendingWrites.push(localRemove(key));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const pendingWrites = [];
|
|
42
68
|
|
|
43
69
|
/******************************************************************************/
|
|
44
70
|
|
|
45
|
-
export async function
|
|
71
|
+
export async function customFiltersFromHostname(hostname) {
|
|
46
72
|
const promises = [];
|
|
47
73
|
let hn = hostname;
|
|
48
74
|
while ( hn !== '' ) {
|
|
49
|
-
promises.push(
|
|
75
|
+
promises.push(readFromStorage(`site.${hn}`));
|
|
50
76
|
const pos = hn.indexOf('.');
|
|
51
77
|
if ( pos === -1 ) { break; }
|
|
52
78
|
hn = hn.slice(pos + 1);
|
|
@@ -66,19 +92,31 @@ export async function selectorsFromCustomFilters(hostname) {
|
|
|
66
92
|
/******************************************************************************/
|
|
67
93
|
|
|
68
94
|
export async function hasCustomFilters(hostname) {
|
|
69
|
-
const selectors = await
|
|
95
|
+
const selectors = await customFiltersFromHostname(hostname);
|
|
70
96
|
return selectors?.length ?? 0;
|
|
71
97
|
}
|
|
72
98
|
|
|
73
99
|
/******************************************************************************/
|
|
74
100
|
|
|
75
101
|
async function getAllCustomFilterKeys() {
|
|
76
|
-
const storageKeys = await
|
|
102
|
+
const storageKeys = await keysFromStorage() || [];
|
|
77
103
|
return storageKeys.filter(a => a.startsWith('site.'));
|
|
78
104
|
}
|
|
79
105
|
|
|
80
106
|
/******************************************************************************/
|
|
81
107
|
|
|
108
|
+
export async function getAllCustomFilters() {
|
|
109
|
+
const collect = async key => {
|
|
110
|
+
const selectors = await readFromStorage(key);
|
|
111
|
+
return [ key.slice(5), selectors.map(a => a.startsWith('0') ? a.slice(1) : a) ];
|
|
112
|
+
};
|
|
113
|
+
const keys = await getAllCustomFilterKeys();
|
|
114
|
+
const promises = keys.map(k => collect(k));
|
|
115
|
+
return Promise.all(promises);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/******************************************************************************/
|
|
119
|
+
|
|
82
120
|
export function startCustomFilters(tabId, frameId) {
|
|
83
121
|
return browser.scripting.executeScript({
|
|
84
122
|
files: [ '/js/scripting/css-user.js' ],
|
|
@@ -102,7 +140,7 @@ export function terminateCustomFilters(tabId, frameId) {
|
|
|
102
140
|
/******************************************************************************/
|
|
103
141
|
|
|
104
142
|
export async function injectCustomFilters(tabId, frameId, hostname) {
|
|
105
|
-
const selectors = await
|
|
143
|
+
const selectors = await customFiltersFromHostname(hostname);
|
|
106
144
|
if ( selectors.length === 0 ) { return; }
|
|
107
145
|
const promises = [];
|
|
108
146
|
const plainSelectors = selectors.filter(a => a.startsWith('{') === false);
|
|
@@ -136,9 +174,6 @@ export async function injectCustomFilters(tabId, frameId, hostname) {
|
|
|
136
174
|
/******************************************************************************/
|
|
137
175
|
|
|
138
176
|
export async function registerCustomFilters(context) {
|
|
139
|
-
if ( perSitePendingIO.size !== 0 ) {
|
|
140
|
-
await Promise.all(Array.from(perSitePendingIO.values()));
|
|
141
|
-
}
|
|
142
177
|
const siteKeys = await getAllCustomFilterKeys();
|
|
143
178
|
if ( siteKeys.length === 0 ) { return; }
|
|
144
179
|
|
|
@@ -174,37 +209,43 @@ export async function registerCustomFilters(context) {
|
|
|
174
209
|
|
|
175
210
|
/******************************************************************************/
|
|
176
211
|
|
|
177
|
-
export async function
|
|
178
|
-
const pending = perSitePendingIO.get(hostname);
|
|
179
|
-
const promise = pending
|
|
180
|
-
? pending.then(( ) => addCustomFilterByHostname(hostname, selector))
|
|
181
|
-
: addCustomFilterByHostname(hostname, selector);
|
|
182
|
-
perSitePendingIO.set(hostname, promise);
|
|
183
|
-
promise.then(( ) => {
|
|
184
|
-
if ( promise !== perSitePendingIO.get(hostname) ) { return; }
|
|
185
|
-
perSitePendingIO.delete(hostname);
|
|
186
|
-
});
|
|
187
|
-
return promise;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async function addCustomFilterByHostname(hostname, selector) {
|
|
212
|
+
export async function addCustomFilters(hostname, toAdd) {
|
|
191
213
|
if ( hostname === '' ) { return false; }
|
|
192
214
|
const key = `site.${hostname}`;
|
|
193
|
-
const selectors = await
|
|
194
|
-
|
|
195
|
-
|
|
215
|
+
const selectors = await readFromStorage(key) || [];
|
|
216
|
+
const countBefore = selectors.length;
|
|
217
|
+
for ( const selector of toAdd ) {
|
|
218
|
+
if ( selectors.includes(selector) ) { continue; }
|
|
219
|
+
selectors.push(selector);
|
|
220
|
+
}
|
|
221
|
+
if ( selectors.length === countBefore ) { return false; }
|
|
196
222
|
selectors.sort();
|
|
197
|
-
|
|
223
|
+
writeToStorage(key, selectors);
|
|
198
224
|
return true;
|
|
199
225
|
}
|
|
200
226
|
|
|
201
227
|
/******************************************************************************/
|
|
202
228
|
|
|
203
|
-
export async function
|
|
229
|
+
export async function removeAllCustomFilters(hostname) {
|
|
230
|
+
if ( hostname === '*' ) {
|
|
231
|
+
const keys = await getAllCustomFilterKeys();
|
|
232
|
+
if ( keys.length === 0 ) { return false; }
|
|
233
|
+
for ( const key of keys ) {
|
|
234
|
+
removeFromStorage(key);
|
|
235
|
+
}
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
const key = `site.${hostname}`;
|
|
239
|
+
const selectors = await readFromStorage(key) || [];
|
|
240
|
+
removeFromStorage(key);
|
|
241
|
+
return selectors.length !== 0;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export async function removeCustomFilters(hostname, selectors) {
|
|
204
245
|
const promises = [];
|
|
205
246
|
let hn = hostname;
|
|
206
247
|
while ( hn !== '' ) {
|
|
207
|
-
promises.push(
|
|
248
|
+
promises.push(removeCustomFiltersByKey(`site.${hn}`, selectors));
|
|
208
249
|
const pos = hn.indexOf('.');
|
|
209
250
|
if ( pos === -1 ) { break; }
|
|
210
251
|
hn = hn.slice(pos + 1);
|
|
@@ -213,33 +254,24 @@ export async function removeCustomFilter(hostname, selector) {
|
|
|
213
254
|
return results.some(a => a);
|
|
214
255
|
}
|
|
215
256
|
|
|
216
|
-
async function
|
|
217
|
-
const
|
|
218
|
-
const key = `site.${hostname}`;
|
|
219
|
-
const promise = pending
|
|
220
|
-
? pending.then(( ) => removeCustomFilterByKey(key, selector))
|
|
221
|
-
: removeCustomFilterByKey(key, selector);
|
|
222
|
-
perSitePendingIO.set(hostname, promise);
|
|
223
|
-
promise.then(( ) => {
|
|
224
|
-
if ( promise !== perSitePendingIO.get(hostname) ) { return; }
|
|
225
|
-
perSitePendingIO.delete(hostname);
|
|
226
|
-
});
|
|
227
|
-
return promise;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async function removeCustomFilterByKey(key, selector) {
|
|
231
|
-
const selectors = await localRead(key);
|
|
257
|
+
async function removeCustomFiltersByKey(key, toRemove) {
|
|
258
|
+
const selectors = await readFromStorage(key);
|
|
232
259
|
if ( selectors === undefined ) { return false; }
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
i = selectors.indexOf(
|
|
236
|
-
if ( i === -1 ) {
|
|
260
|
+
const beforeCount = selectors.length;
|
|
261
|
+
for ( const selector of toRemove ) {
|
|
262
|
+
let i = selectors.indexOf(selector);
|
|
263
|
+
if ( i === -1 ) {
|
|
264
|
+
i = selectors.indexOf(`0${selector}`);
|
|
265
|
+
if ( i === -1 ) { continue; }
|
|
266
|
+
}
|
|
267
|
+
selectors.splice(i, 1);
|
|
237
268
|
}
|
|
238
|
-
selectors.
|
|
239
|
-
if (
|
|
240
|
-
|
|
269
|
+
const afterCount = selectors.length;
|
|
270
|
+
if ( afterCount === beforeCount ) { return false; }
|
|
271
|
+
if ( afterCount !== 0 ) {
|
|
272
|
+
writeToStorage(key, selectors);
|
|
241
273
|
} else {
|
|
242
|
-
|
|
274
|
+
removeFromStorage(key);
|
|
243
275
|
}
|
|
244
276
|
return true;
|
|
245
277
|
}
|