diff --git a/Makefile b/Makefile index 2ce9beb54..ddec8e4dc 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,17 @@ run_options := $(filter-out $@,$(MAKECMDGOALS)) .PHONY: all clean cleanassets test lint chromium opera firefox npm dig \ - mv3-chromium mv3-firefox mv3-edge mv3-safari \ + mv3-chromium mv3-firefox mv3-edge mv3-safari ubol-codemirror \ compare maxcost medcost mincost modifiers record wasm sources := ./dist/version $(shell find ./assets -type f) $(shell find ./src -type f) platform := $(wildcard platform/*/*) assets := dist/build/uAssets -mv3-sources := $(shell find ./src -type f) $(wildcard platform/mv3/*) $(shell find ./platform/mv3/extension -type f) +mv3-sources := \ + $(shell find ./src -type f) \ + $(wildcard platform/mv3/*) \ + $(shell find ./platform/mv3/extension -name codemirror-ubol -prune -o -type f) \ + platform/mv3/extension/lib/codemirror/codemirror-ubol/dist/cm6.bundle.ubol.min.js mv3-data := $(shell find ./dist/build/mv3-data -type f) mv3-edge-deps := $(wildcard platform/mv3/edge/*) @@ -69,25 +73,28 @@ dig-snfe: dig dist/build/mv3-data: mkdir -p dist/build/mv3-data +ubol-codemirror: + $(MAKE) -sC platform/mv3/extension/lib/codemirror/codemirror-ubol/ ubol.bundle + dist/build/uBOLite.chromium: tools/make-mv3.sh $(mv3-sources) $(platform) $(mv3-data) dist/build/mv3-data tools/make-mv3.sh chromium -mv3-chromium: dist/build/uBOLite.chromium +mv3-chromium: ubol-codemirror dist/build/uBOLite.chromium dist/build/uBOLite.firefox: tools/make-mv3.sh $(mv3-sources) $(platform) $(mv3-data) dist/build/mv3-data tools/make-mv3.sh firefox -mv3-firefox: dist/build/uBOLite.firefox +mv3-firefox: ubol-codemirror dist/build/uBOLite.firefox dist/build/uBOLite.edge: tools/make-mv3.sh $(mv3-sources) $(mv3-edge-deps) $(mv3-data) dist/build/mv3-data tools/make-mv3.sh edge -mv3-edge: dist/build/uBOLite.edge +mv3-edge: ubol-codemirror dist/build/uBOLite.edge dist/build/uBOLite.safari: tools/make-mv3.sh $(mv3-sources) $(mv3-safari-deps) $(mv3-data) dist/build/mv3-data tools/make-mv3.sh safari -mv3-safari: dist/build/uBOLite.safari +mv3-safari: ubol-codemirror dist/build/uBOLite.safari dist/build/uAssets: tools/pull-assets.sh diff --git a/platform/mv3/extension/_locales/ar/messages.json b/platform/mv3/extension/_locales/ar/messages.json index 58bd71e00..f7b0a4906 100644 --- a/platform/mv3/extension/_locales/ar/messages.json +++ b/platform/mv3/extension/_locales/ar/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "سيتم حظر التنقل إلى المواقع غير المرغوب فيها، وسيتم تقديم خيار لك للمتابعة.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "البحث عن القوائم", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/az/messages.json b/platform/mv3/extension/_locales/az/messages.json index 31968c558..27f7fc1b6 100644 --- a/platform/mv3/extension/_locales/az/messages.json +++ b/platform/mv3/extension/_locales/az/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/be/messages.json b/platform/mv3/extension/_locales/be/messages.json index c41e4e05a..b35b66c65 100644 --- a/platform/mv3/extension/_locales/be/messages.json +++ b/platform/mv3/extension/_locales/be/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Пераход да патэнцыйна непажаданых сайтаў будзе заблакаваны, і вам будзе прапанавана магчымасць працягнуць.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Знайсці спісы", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Выйсці з рэжыму імгненнага хавання элементаў", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/bg/messages.json b/platform/mv3/extension/_locales/bg/messages.json index fde7add85..753cd2fe9 100644 --- a/platform/mv3/extension/_locales/bg/messages.json +++ b/platform/mv3/extension/_locales/bg/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Навигацията към потенциално нежелани сайтове ще бъде блокирана и ще ви бъде предложена възможността да продължите.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Намиране на списъци", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Излизане от режима на временно скриване на елемента", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/bn/messages.json b/platform/mv3/extension/_locales/bn/messages.json index 9bad885a7..bc87ca583 100644 --- a/platform/mv3/extension/_locales/bn/messages.json +++ b/platform/mv3/extension/_locales/bn/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "সম্ভাব্য অযাচিত ওয়েবসাইট অবরুদ্ধ করা হবে, আর সেখানে আগানোর উপায় দেওয়া থাকবে।", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "তালিকা খুঁজো", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/br_FR/messages.json b/platform/mv3/extension/_locales/br_FR/messages.json index e8fbb70c5..72e2d5e8f 100644 --- a/platform/mv3/extension/_locales/br_FR/messages.json +++ b/platform/mv3/extension/_locales/br_FR/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Stanket e vo ar merdeiñ etrezek lec'hiennoù a c'hallfe bezañ dañjerus, ha moaien a vo deoc'h dibab da genderc'hel pe get.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Kavout rolloù", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Kuitaat ar mod \"dilemel elfennoù\"", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/bs/messages.json b/platform/mv3/extension/_locales/bs/messages.json index 2694cb074..bded4c964 100644 --- a/platform/mv3/extension/_locales/bs/messages.json +++ b/platform/mv3/extension/_locales/bs/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ca/messages.json b/platform/mv3/extension/_locales/ca/messages.json index 1c65daf6f..250e13088 100644 --- a/platform/mv3/extension/_locales/ca/messages.json +++ b/platform/mv3/extension/_locales/ca/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Es blocarà la navegació en webs potencialment no desitjables, oferint-vos la possibilitat de continuar.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Cerca llistes", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Surt del mode d'eliminació d'elements", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/cs/messages.json b/platform/mv3/extension/_locales/cs/messages.json index c60b63a9d..43324e823 100644 --- a/platform/mv3/extension/_locales/cs/messages.json +++ b/platform/mv3/extension/_locales/cs/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigace na potenciálně nežádoucí stránky bude zablokována a bude vám nabídnuta možnost pokračovat.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Najít seznamy", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Opustit režim dočasného skrytí prvků", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/cv/messages.json b/platform/mv3/extension/_locales/cv/messages.json index ace2c1d9f..136a025b9 100644 --- a/platform/mv3/extension/_locales/cv/messages.json +++ b/platform/mv3/extension/_locales/cv/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/cy/messages.json b/platform/mv3/extension/_locales/cy/messages.json index 65790d0d8..e034be897 100644 --- a/platform/mv3/extension/_locales/cy/messages.json +++ b/platform/mv3/extension/_locales/cy/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/da/messages.json b/platform/mv3/extension/_locales/da/messages.json index 0422b4f55..8e0dc1661 100644 --- a/platform/mv3/extension/_locales/da/messages.json +++ b/platform/mv3/extension/_locales/da/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigering til potentielt uønskede websteder blokeres, men man tilbydes muligheden for at fortsætte.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lister", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Forlad elementdræber­tilstand", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/de/messages.json b/platform/mv3/extension/_locales/de/messages.json index 0e73a10db..22bb53da4 100644 --- a/platform/mv3/extension/_locales/de/messages.json +++ b/platform/mv3/extension/_locales/de/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Die Navigation zu potenziell unerwünschten Websites wird verhindert, jedoch wird eine Möglichkeit zum Fortfahren angeboten.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Listen suchen", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Temporären Modus beenden", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/el/messages.json b/platform/mv3/extension/_locales/el/messages.json index b451e0fde..d9f343099 100644 --- a/platform/mv3/extension/_locales/el/messages.json +++ b/platform/mv3/extension/_locales/el/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Θα απετραπεί η πρόσβαση σε πιθανά ανεπιθύμητους ιστοτόπους. Θα σας προσφερθεί η επιλογή να συνεχίσετε.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Εύρεση λιστών", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Έξοδος από λειτουργία αφαίρεσης στοιχείων", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/en/messages.json b/platform/mv3/extension/_locales/en/messages.json index f4dc76f3c..03e28740d 100644 --- a/platform/mv3/extension/_locales/en/messages.json +++ b/platform/mv3/extension/_locales/en/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enables access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,29 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" + }, + "dnrRulesCountInfo": { + "message": "Number of registered rules: {count}", + "description": "Short sentence to report the number of currently registered DNR rules" } } diff --git a/platform/mv3/extension/_locales/en_GB/messages.json b/platform/mv3/extension/_locales/en_GB/messages.json index 36e895564..f61236cc6 100644 --- a/platform/mv3/extension/_locales/en_GB/messages.json +++ b/platform/mv3/extension/_locales/en_GB/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/eo/messages.json b/platform/mv3/extension/_locales/eo/messages.json index 726dcd0bd..acc785f1d 100644 --- a/platform/mv3/extension/_locales/eo/messages.json +++ b/platform/mv3/extension/_locales/eo/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/es/messages.json b/platform/mv3/extension/_locales/es/messages.json index 67af6f640..13f08971f 100644 --- a/platform/mv3/extension/_locales/es/messages.json +++ b/platform/mv3/extension/_locales/es/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "La navegación a sitios potencialmente no deseados será bloqueada, y se te ofrecerá la opción de continuar.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Encontrar listas", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Salir del modo eliminación de elementos", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/et/messages.json b/platform/mv3/extension/_locales/et/messages.json index 7718b5b06..3fe467a1d 100644 --- a/platform/mv3/extension/_locales/et/messages.json +++ b/platform/mv3/extension/_locales/et/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Kahtlastele veebilehtedele suunamist takistatakse ja pakutakse võimalust jätkamiseks.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Otsi nimekirju", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Välju elemendi hävitusrežiimist", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/eu/messages.json b/platform/mv3/extension/_locales/eu/messages.json index 9b189acec..22594ceb4 100644 --- a/platform/mv3/extension/_locales/eu/messages.json +++ b/platform/mv3/extension/_locales/eu/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Irten elementua zapper moduan", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/fa/messages.json b/platform/mv3/extension/_locales/fa/messages.json index 28c60c1b4..743cc736a 100644 --- a/platform/mv3/extension/_locales/fa/messages.json +++ b/platform/mv3/extension/_locales/fa/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/fi/messages.json b/platform/mv3/extension/_locales/fi/messages.json index 92bee243e..e29c903ff 100644 --- a/platform/mv3/extension/_locales/fi/messages.json +++ b/platform/mv3/extension/_locales/fi/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Potentiaalisesti ei-toivottujen sivustojen avaaminen estetään mahdollisuudella jatkaa.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Etsi listoja", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/fil/messages.json b/platform/mv3/extension/_locales/fil/messages.json index abd45087f..a9ed6840d 100644 --- a/platform/mv3/extension/_locales/fil/messages.json +++ b/platform/mv3/extension/_locales/fil/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/fr/messages.json b/platform/mv3/extension/_locales/fr/messages.json index 1b103c3fe..7bc28e98a 100644 --- a/platform/mv3/extension/_locales/fr/messages.json +++ b/platform/mv3/extension/_locales/fr/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "La navigation vers des sites potentiellement indésirables sera bloquée, et vous aurez la possibilité de continuer", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Trouver des listes", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Quitter le mode Zappeur d'élément", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/fy/messages.json b/platform/mv3/extension/_locales/fy/messages.json index 37f87477d..b2d0f0b1b 100644 --- a/platform/mv3/extension/_locales/fy/messages.json +++ b/platform/mv3/extension/_locales/fy/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigaasje nei potinsjeel net-winske websites wurdt blokkearre, en jo krije de opsje om troch te gean.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Listen sykje", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Elemint­wisker­modus slute", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/gl/messages.json b/platform/mv3/extension/_locales/gl/messages.json index b6d4e0084..4640caa73 100644 --- a/platform/mv3/extension/_locales/gl/messages.json +++ b/platform/mv3/extension/_locales/gl/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Vaise bloquear a navegación en webs potencialmente non desexables, e ofrecerase a opción de bloquealas.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Atopa listas", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Sair do modo eliminador de elementos", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/gu/messages.json b/platform/mv3/extension/_locales/gu/messages.json index ace2c1d9f..136a025b9 100644 --- a/platform/mv3/extension/_locales/gu/messages.json +++ b/platform/mv3/extension/_locales/gu/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/he/messages.json b/platform/mv3/extension/_locales/he/messages.json index 7118496ce..c27390163 100644 --- a/platform/mv3/extension/_locales/he/messages.json +++ b/platform/mv3/extension/_locales/he/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "ניווט אפשרי לאתרים לא רצויים יחסם ותהיה אפשרות להחליט להמשיך.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "חיפוש רשימות", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/hi/messages.json b/platform/mv3/extension/_locales/hi/messages.json index f28896b99..42fae5800 100644 --- a/platform/mv3/extension/_locales/hi/messages.json +++ b/platform/mv3/extension/_locales/hi/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/hr/messages.json b/platform/mv3/extension/_locales/hr/messages.json index f3086f263..ed9ea6c1d 100644 --- a/platform/mv3/extension/_locales/hr/messages.json +++ b/platform/mv3/extension/_locales/hr/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigacija do potencijalno nepoželjnih stranica bit će blokirana i bit će vam ponuđena opcija za nastavak.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Pronađi liste", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Zatvori način rada uklanjanja elementa", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/hu/messages.json b/platform/mv3/extension/_locales/hu/messages.json index fa53a4550..d7eee7347 100644 --- a/platform/mv3/extension/_locales/hu/messages.json +++ b/platform/mv3/extension/_locales/hu/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Az esetleges nem kívánatos webhelyekre való navigáció blokkolva lesz, és rákérdez arra, hogy folytatja-e.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Listák keresése", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Kilépés az elemeltávolító módból", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/hy/messages.json b/platform/mv3/extension/_locales/hy/messages.json index 60c32c406..853b02071 100644 --- a/platform/mv3/extension/_locales/hy/messages.json +++ b/platform/mv3/extension/_locales/hy/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/id/messages.json b/platform/mv3/extension/_locales/id/messages.json index 1f0e33840..9760f0e83 100644 --- a/platform/mv3/extension/_locales/id/messages.json +++ b/platform/mv3/extension/_locales/id/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigasi ke situs yang mungkin tidak diinginkan akan diblokir, dan Anda akan ditawari opsi untuk melanjutkan.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Temukan daftar", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/it/messages.json b/platform/mv3/extension/_locales/it/messages.json index b0a15c153..53b04b95c 100644 --- a/platform/mv3/extension/_locales/it/messages.json +++ b/platform/mv3/extension/_locales/it/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "La navigazione verso siti potenzialmente indesiderati verrà bloccata e ti verrà offerta la possibilità di procedere.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Trova elenchi", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Esci dalla modalità blocco rapido", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ja/messages.json b/platform/mv3/extension/_locales/ja/messages.json index 454941642..0e00e22a7 100644 --- a/platform/mv3/extension/_locales/ja/messages.json +++ b/platform/mv3/extension/_locales/ja/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "望ましくない可能性のあるサイトへのナビゲーションはブロックされ、次に進むためのオプションが表示されます。", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "リストを検索", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "要素抹消モードを終了", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ka/messages.json b/platform/mv3/extension/_locales/ka/messages.json index b47d3bae9..59b33f61b 100644 --- a/platform/mv3/extension/_locales/ka/messages.json +++ b/platform/mv3/extension/_locales/ka/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "შეიზღუდა სავარაუდოდ არასასურველ გვერდებზე გადასვლა, საშუალება გეძლევათ, მაინც განაგრძოთ.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "სიების მოძიება", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "ნაწილების ამოჭრის რეჟიმიდან გასვლა", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/kk/messages.json b/platform/mv3/extension/_locales/kk/messages.json index ace2c1d9f..136a025b9 100644 --- a/platform/mv3/extension/_locales/kk/messages.json +++ b/platform/mv3/extension/_locales/kk/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/kn/messages.json b/platform/mv3/extension/_locales/kn/messages.json index fca0ab51c..357c70f7e 100644 --- a/platform/mv3/extension/_locales/kn/messages.json +++ b/platform/mv3/extension/_locales/kn/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ko/messages.json b/platform/mv3/extension/_locales/ko/messages.json index 4776053f3..f18e86be1 100644 --- a/platform/mv3/extension/_locales/ko/messages.json +++ b/platform/mv3/extension/_locales/ko/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "잠재적으로 좋지 않은 사이트로의 접속을 차단하고, 사용자가 진행할지 선택하도록 합니다.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "목록 찾기", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "구성 요소 제거 모드 종료", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/lt/messages.json b/platform/mv3/extension/_locales/lt/messages.json index 810d9a3a6..60955d7cd 100644 --- a/platform/mv3/extension/_locales/lt/messages.json +++ b/platform/mv3/extension/_locales/lt/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/lv/messages.json b/platform/mv3/extension/_locales/lv/messages.json index 204e683bc..c308f2c46 100644 --- a/platform/mv3/extension/_locales/lv/messages.json +++ b/platform/mv3/extension/_locales/lv/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Iespējami nevēlamu vietņu apmeklēšana tiks aizturēta, un tiks piedāvāta iespēja turpināt.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Atrast sarakstus", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Iziet no elementu iznīcināšanas", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/mk/messages.json b/platform/mv3/extension/_locales/mk/messages.json index 0d6146d37..431dba89a 100644 --- a/platform/mv3/extension/_locales/mk/messages.json +++ b/platform/mv3/extension/_locales/mk/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Најди листи", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ml/messages.json b/platform/mv3/extension/_locales/ml/messages.json index 8bb8f3961..4e6a284b4 100644 --- a/platform/mv3/extension/_locales/ml/messages.json +++ b/platform/mv3/extension/_locales/ml/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/mr/messages.json b/platform/mv3/extension/_locales/mr/messages.json index ace2c1d9f..136a025b9 100644 --- a/platform/mv3/extension/_locales/mr/messages.json +++ b/platform/mv3/extension/_locales/mr/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ms/messages.json b/platform/mv3/extension/_locales/ms/messages.json index a1031f761..a0c5b761b 100644 --- a/platform/mv3/extension/_locales/ms/messages.json +++ b/platform/mv3/extension/_locales/ms/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/nb/messages.json b/platform/mv3/extension/_locales/nb/messages.json index 6d9ac5503..7282364c2 100644 --- a/platform/mv3/extension/_locales/nb/messages.json +++ b/platform/mv3/extension/_locales/nb/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigering til potensielt uønskede nettsteder blir blokkert, og du får tilbud om å fortsette.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Finn lister", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/nl/messages.json b/platform/mv3/extension/_locales/nl/messages.json index 9d2692b86..1de06d4a0 100644 --- a/platform/mv3/extension/_locales/nl/messages.json +++ b/platform/mv3/extension/_locales/nl/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigatie naar mogelijk ongewenste websites wordt geblokkeerd, en u krijgt de mogelijkheid om door te gaan.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Lijsten zoeken", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Element­wisser­modus sluiten", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/oc/messages.json b/platform/mv3/extension/_locales/oc/messages.json index ace2c1d9f..136a025b9 100644 --- a/platform/mv3/extension/_locales/oc/messages.json +++ b/platform/mv3/extension/_locales/oc/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/pa/messages.json b/platform/mv3/extension/_locales/pa/messages.json index 107f4b98e..035a82fc7 100644 --- a/platform/mv3/extension/_locales/pa/messages.json +++ b/platform/mv3/extension/_locales/pa/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/pl/messages.json b/platform/mv3/extension/_locales/pl/messages.json index e36a317bc..46e37a83c 100644 --- a/platform/mv3/extension/_locales/pl/messages.json +++ b/platform/mv3/extension/_locales/pl/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Nawigacja do potencjalnie niepożądanych witryn zostanie zablokowana i pojawi się opcja kontynuowania.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Znajdź listy", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Wyjdź z trybu usuwania elementów", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/pt_BR/messages.json b/platform/mv3/extension/_locales/pt_BR/messages.json index 56f2e6b65..c852e5b9e 100644 --- a/platform/mv3/extension/_locales/pt_BR/messages.json +++ b/platform/mv3/extension/_locales/pt_BR/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "A navegação até sites potencialmente indesejáveis ​​será bloqueada e será oferecido a você a opção de prosseguir.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Achar listas", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Sair do modo do elemento zapper", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/pt_PT/messages.json b/platform/mv3/extension/_locales/pt_PT/messages.json index dbd8d3949..a3cadf195 100644 --- a/platform/mv3/extension/_locales/pt_PT/messages.json +++ b/platform/mv3/extension/_locales/pt_PT/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "A navegação para sites potencialmente indesejáveis será bloqueada e ser-lhe-á dada a opção de proceder.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Encontrar listas", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Sair do modo \"element zapper\"", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ro/messages.json b/platform/mv3/extension/_locales/ro/messages.json index 7213dc0ab..ce522a2bd 100644 --- a/platform/mv3/extension/_locales/ro/messages.json +++ b/platform/mv3/extension/_locales/ro/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigarea către site-uri potențial nedorite va fi blocată și vi se va oferi opțiunea de a continua.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Căutați liste", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ru/messages.json b/platform/mv3/extension/_locales/ru/messages.json index adb7c1470..0eca35d9e 100644 --- a/platform/mv3/extension/_locales/ru/messages.json +++ b/platform/mv3/extension/_locales/ru/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Переход к потенциально нежелательным сайтам будет заблокирован, и будет дана возможность продолжить переход на сайт", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Найти списки", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Покинуть режим временного скрытия элемента", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/si/messages.json b/platform/mv3/extension/_locales/si/messages.json index 841ea098c..5d6467aa9 100644 --- a/platform/mv3/extension/_locales/si/messages.json +++ b/platform/mv3/extension/_locales/si/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "අනවශ්‍ය විය හැකි අඩවි වෙත සංචාලනය අවහිර කරනු ලබන අතර, ඉදිරියට යාමට ඔබට විකල්පය ලබා දෙනු ඇත.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "ලැයිස්තු සොයන්න", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "මූලද්‍රව්‍ය zapper ප්‍රකාරයෙන් ඉවත් වන්න", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/sk/messages.json b/platform/mv3/extension/_locales/sk/messages.json index 79d5336bd..22aad57c3 100644 --- a/platform/mv3/extension/_locales/sk/messages.json +++ b/platform/mv3/extension/_locales/sk/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigácia na potenciálne nežiaduce stránky sa zablokuje a ponúkne sa vám možnosť pokračovať.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Nájsť zoznamy", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Ukončiť režim dočasného skrytia prvkov", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/sl/messages.json b/platform/mv3/extension/_locales/sl/messages.json index ace2c1d9f..136a025b9 100644 --- a/platform/mv3/extension/_locales/sl/messages.json +++ b/platform/mv3/extension/_locales/sl/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/so/messages.json b/platform/mv3/extension/_locales/so/messages.json index ace2c1d9f..136a025b9 100644 --- a/platform/mv3/extension/_locales/so/messages.json +++ b/platform/mv3/extension/_locales/so/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/sq/messages.json b/platform/mv3/extension/_locales/sq/messages.json index 85591ef8b..97675a6b6 100644 --- a/platform/mv3/extension/_locales/sq/messages.json +++ b/platform/mv3/extension/_locales/sq/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Uebsajtet potencialisht të padëshirueshme do të bllokohen dhe do t'ju jepet mundësia për të vazhduar.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Gjej listat", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Mbyll asgjësuesin e elementeve", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/sr/messages.json b/platform/mv3/extension/_locales/sr/messages.json index f94879cd9..2ba999653 100644 --- a/platform/mv3/extension/_locales/sr/messages.json +++ b/platform/mv3/extension/_locales/sr/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Навигација до потенцијално непожељних сајтова ће бити блокирана и биће вам понуђена опција да наставите.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Пронађи листе", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/sv/messages.json b/platform/mv3/extension/_locales/sv/messages.json index 93c337c91..79a345a5e 100644 --- a/platform/mv3/extension/_locales/sv/messages.json +++ b/platform/mv3/extension/_locales/sv/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigering till potentiellt oönskade webbplatser kommer att blockeras och du kommer att erbjudas alternativet att fortsätta.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Hitta listor", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Lämna elementzapperläge", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/sw/messages.json b/platform/mv3/extension/_locales/sw/messages.json index ace2c1d9f..136a025b9 100644 --- a/platform/mv3/extension/_locales/sw/messages.json +++ b/platform/mv3/extension/_locales/sw/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ta/messages.json b/platform/mv3/extension/_locales/ta/messages.json index ace2c1d9f..136a025b9 100644 --- a/platform/mv3/extension/_locales/ta/messages.json +++ b/platform/mv3/extension/_locales/ta/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/te/messages.json b/platform/mv3/extension/_locales/te/messages.json index 7f3f7d115..e96f32008 100644 --- a/platform/mv3/extension/_locales/te/messages.json +++ b/platform/mv3/extension/_locales/te/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/th/messages.json b/platform/mv3/extension/_locales/th/messages.json index a15decaa9..2d498371d 100644 --- a/platform/mv3/extension/_locales/th/messages.json +++ b/platform/mv3/extension/_locales/th/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "การนำทางไปยังเว็บไซต์ที่ไม่พึงประสงค์จะถูกบล็อก และคุณจะได้รับตัวเลือกเพื่อดำเนินการต่อ", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "หารายการ", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/tr/messages.json b/platform/mv3/extension/_locales/tr/messages.json index 077a95202..c8e8a857f 100644 --- a/platform/mv3/extension/_locales/tr/messages.json +++ b/platform/mv3/extension/_locales/tr/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "İstenmeyebilecek sitelere erişim engellenecek ve devam etme seçeneği sunulacaktır.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Liste bul", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Öge silme modundan çık", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/uk/messages.json b/platform/mv3/extension/_locales/uk/messages.json index cfba6ab1f..5046caa79 100644 --- a/platform/mv3/extension/_locales/uk/messages.json +++ b/platform/mv3/extension/_locales/uk/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Перехід до потенційно небажаних сайтів буде заблоковано, та вам буде запропоновано можливість продовжити", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Знайти списки", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Вийти з режиму тимчасового приховування елементів", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/ur/messages.json b/platform/mv3/extension/_locales/ur/messages.json index b433dd5a0..1a11f8f4e 100644 --- a/platform/mv3/extension/_locales/ur/messages.json +++ b/platform/mv3/extension/_locales/ur/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Navigation to potentially undesirable sites will be blocked, and you will be offered the option to proceed.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Find lists", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Exit element zapper mode", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/vi/messages.json b/platform/mv3/extension/_locales/vi/messages.json index 548be6fe6..bbe6c7d4f 100644 --- a/platform/mv3/extension/_locales/vi/messages.json +++ b/platform/mv3/extension/_locales/vi/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "Việc điều hướng đến các trang web có khả năng không mong muốn sẽ bị chặn và bạn sẽ được cung cấp tùy chọn để tiếp tục.", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "Tìm danh sách", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "Thoát khỏi chế độ chặn phần tử tạm thời", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/zh_CN/messages.json b/platform/mv3/extension/_locales/zh_CN/messages.json index f133d6336..69640caf4 100644 --- a/platform/mv3/extension/_locales/zh_CN/messages.json +++ b/platform/mv3/extension/_locales/zh_CN/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "导航至潜在不良网站的操作将被拦截,并且您将可以选择继续前往。", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "查找列表", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "退出临时元素移除模式", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/_locales/zh_TW/messages.json b/platform/mv3/extension/_locales/zh_TW/messages.json index 3c9005fa3..76c75bcea 100644 --- a/platform/mv3/extension/_locales/zh_TW/messages.json +++ b/platform/mv3/extension/_locales/zh_TW/messages.json @@ -233,8 +233,16 @@ }, "enableStrictBlockLegend": { "message": "前往潛在不良網站的導航將被阻止,您可以選擇是否繼續前往。", + "description": "Short description for a checkbox in the options page" + }, + "developerModeLabel": { + "message": "Developer mode", "description": "Label for a checkbox in the options page" }, + "developerModeLegend": { + "message": "Enable access to features suitable for technical users.", + "description": "Short description for a checkbox in the options page" + }, "findListsPlaceholder": { "message": "尋找清單", "description": "Placeholder for the input field used to find lists" @@ -282,5 +290,25 @@ "zapperTipQuit": { "message": "離開元素臨時移除模式", "description": "Tooltip for the button used to exit zapper mode" + }, + "saveButton": { + "message": "Save", + "description": "Text for buttons used to save changes" + }, + "revertButton": { + "message": "Revert", + "description": "Text for buttons used to revert changes" + }, + "importAndAppendButton": { + "message": "Import and append…", + "description": "Text for buttons used to import and append content" + }, + "exportButton": { + "message": "Export…", + "description": "Text for buttons used to export content" + }, + "dnrRulesSummary": { + "message": "Enter your own DNR rules below. Do not add content from untrusted sources.", + "description": "Short description of the DNR rules editor pane" } } diff --git a/platform/mv3/extension/css/dashboard-common.css b/platform/mv3/extension/css/dashboard-common.css index 8621d0870..ebef32f60 100644 --- a/platform/mv3/extension/css/dashboard-common.css +++ b/platform/mv3/extension/css/dashboard-common.css @@ -39,9 +39,15 @@ a { color: var(--info3-ink); fill: var(--info3-ink); } + input[type="number"] { width: 5em; } + +input[type="file"] { + display: none; + } + @media (max-height: 640px), (max-height: 800px) and (max-width: 480px) { .body > p, .body > ul { diff --git a/platform/mv3/extension/css/dashboard.css b/platform/mv3/extension/css/dashboard.css index 63aaeaa15..84f75d158 100644 --- a/platform/mv3/extension/css/dashboard.css +++ b/platform/mv3/extension/css/dashboard.css @@ -1,4 +1,4 @@ -#dashboard-nav { +nav { background-color: var(--surface-1); border: 0; border-bottom: 1px solid var(--border-1); @@ -11,7 +11,7 @@ top: 0; z-index: 100; } -.tabButton { +nav > .tabButton { background-color: transparent; border: 0; border-bottom: 3px solid transparent; @@ -24,29 +24,34 @@ text-decoration: none; white-space: nowrap; } -.tabButton:focus { +nav > .tabButton:focus { outline: 0; } -.tabButton:hover { +nav > .tabButton:hover { background-color: var(--dashboard-tab-hover-surface); border-bottom-color: var(--dashboard-tab-hover-border); } body[data-pane="settings"] #dashboard-nav .tabButton[data-pane="settings"], body[data-pane="rulesets"] #dashboard-nav .tabButton[data-pane="rulesets"], +body[data-pane="develop"] #dashboard-nav .tabButton[data-pane="develop"], body[data-pane="about"] #dashboard-nav .tabButton[data-pane="about"] { background-color: var(--dashboard-tab-active-surface); border-bottom: 3px solid var(--dashboard-tab-active-ink); color: var(--dashboard-tab-active-ink); fill: var(--dashboard-tab-active-ink); } +body:not([data-develop="true"]) #dashboard-nav .tabButton[data-pane="develop"] { + display: none; + } body > section { display: none; - padding-bottom: 8rem; + padding-bottom: 2rem; } body[data-pane="settings"] > section[data-pane="settings"], body[data-pane="rulesets"] > section[data-pane="rulesets"], +body[data-pane="develop"] > section[data-pane="develop"], body[data-pane="about"] > section[data-pane="about"] { display: block; } @@ -59,10 +64,10 @@ body[data-pane="about"] > section[data-pane="about"] { } /* touch-screen devices */ -:root.mobile #dashboard-nav { +:root.mobile nav { flex-wrap: nowrap; overflow-x: auto; } -:root.mobile #dashboard-nav .logo { +:root.mobile nav .logo { display: none; } diff --git a/platform/mv3/extension/css/develop.css b/platform/mv3/extension/css/develop.css new file mode 100644 index 000000000..616849509 --- /dev/null +++ b/platform/mv3/extension/css/develop.css @@ -0,0 +1,112 @@ +body[data-pane="develop"] { + height: 100vh; + } + +section[data-pane="develop"] { + display: none; + flex-grow: 1; + overflow: hidden; + } + +section[data-pane="develop"] > div { + display: flex; + flex-direction: column; + height: 100%; + } + +section[data-pane="develop"] > div > * { + margin-bottom: 0; + margin-top: 1em; + } + +#cm-dnrRules { + flex-grow: 1; + font-size: var(--monospace-size); + overflow: hidden; + } + +/* https://discuss.codemirror.net/t/how-to-set-max-height-of-the-editor/2882/2 */ +#cm-dnrRules .cm-editor { + background-color: var(--surface-0); + height: 100%; + } + +#cm-dnrRules .cm-editor .cm-line { + border-bottom: 1px dotted transparent; + border-top: 1px dotted transparent; + } + +#cm-dnrRules .cm-editor .cm-line:has(.ͼ5) { + border-bottom: 1px dotted var(--border-1); + border-top: 1px dotted var(--border-1); + } + +#cm-dnrRules .cm-editor .cm-line.badline:not(.cm-activeLine) { + background-color: color-mix(in srgb, var(--info3-ink) 15%, transparent 85%); + } + +#cm-dnrRules .cm-editor .cm-line .badmark { + text-decoration: underline var(--cm-negative) wavy; + text-decoration-skip-ink: none; + } + +#cm-dnrRules .cm-editor .cm-panel.cm-search { + display: flex; + flex-wrap: wrap; + font-family: sans-serif; + font-size: var(--font-size); + gap: 0.5em 1em; + padding: 0.5em 1.5em 0.5em 0.5em; + } + +#cm-dnrRules .cm-editor .cm-panel.cm-search > * { + margin: 0; + } + +#cm-dnrRules .cm-editor .cm-panel.cm-search .cm-textfield, +#cm-dnrRules .cm-editor .cm-panel.cm-search .cm-button, +#cm-dnrRules .cm-editor .cm-panel.cm-search label { + background-image: inherit; + border: inherit; + flex-grow: 0; + font-size: var(--button-font-size); + min-height: calc(var(--button-font-size) * 1.8); + } + +#cm-dnrRules .cm-editor .cm-panel.info-panel { + display: flex; + flex-wrap: nowrap; + font-size: var(--font-size); + padding: var(--default-gap-xxsmall) var(--default-gap-xsmall); + } +#cm-dnrRules .cm-editor .cm-panel.info-panel .info { + flex-grow: 1; + overflow: auto; + } +#cm-dnrRules .cm-editor .cm-panel.info-panel .close { + cursor: default; + flex-shrink: 0; + padding-inline-start: 1em; + } +#cm-dnrRules .cm-editor .cm-panel.info-panel .close::after { + content: '\2715'; + } +#cm-dnrRules .cm-editor .cm-panel.summary-panel { + background-color: color-mix(in srgb, var(--info1-ink) 15%, transparent 85%); + } + +#cm-dnrRules .cm-editor .cm-panel.feedback-panel { + background-color: color-mix(in srgb, var(--info3-ink) 15%, transparent 85%); + white-space: pre; + max-height: 10cqh; + } + +#cm-dnrRules .cm-editor .cm-gutterElement { + cursor: default; + user-select: none; + } + +#cm-dnrRules .cm-editor .cm-tooltip .badmark-tooltip { + background-color: color-mix(in srgb, var(--info3-ink) 15%, transparent 85%); + padding: var(--default-gap-xxsmall) var(--default-gap-xsmall); + } \ No newline at end of file diff --git a/platform/mv3/extension/css/settings.css b/platform/mv3/extension/css/settings.css index a9b4ad6d5..4e6618da6 100644 --- a/platform/mv3/extension/css/settings.css +++ b/platform/mv3/extension/css/settings.css @@ -25,6 +25,9 @@ body[data-forbid~="filteringMode"] section[data-pane="settings"] > div:has(> h3[ body[data-forbid~="filteringMode"] section[data-pane="settings"] > div:has(> h3[data-i18n="filteringMode0Name"]) { display: none; } +body[data-forbid~="develop"] #developerMode { + display: none; + } label:has(input[type="checkbox"][disabled]), label:has(input[type="checkbox"][disabled]) + legend { diff --git a/platform/mv3/extension/dashboard.html b/platform/mv3/extension/dashboard.html index 300921557..3acecd569 100644 --- a/platform/mv3/extension/dashboard.html +++ b/platform/mv3/extension/dashboard.html @@ -13,18 +13,20 @@ + - + -
+
+
@@ -85,7 +87,7 @@

-

@@ -103,6 +105,20 @@
+
+
+

+ + +   + + +

+

+
+
+
+
@@ -125,6 +141,7 @@ +
@@ -155,12 +172,28 @@ + + + + diff --git a/platform/mv3/extension/js/background.js b/platform/mv3/extension/js/background.js index 7d7661a37..5cd59ce8d 100644 --- a/platform/mv3/extension/js/background.js +++ b/platform/mv3/extension/js/background.js @@ -59,6 +59,7 @@ import { setStrictBlockMode, updateDynamicRules, updateSessionRules, + updateUserRules, } from './ruleset-manager.js'; import { @@ -135,6 +136,17 @@ async function onPermissionsAdded(permissions) { /******************************************************************************/ +function setDeveloperMode(state) { + rulesetConfig.developerMode = state === true; + toggleDeveloperMode(rulesetConfig.developerMode); + return Promise.all([ + updateUserRules(), + saveRulesetConfig(), + ]); +} + +/******************************************************************************/ + function onMessage(request, sender, callback) { // Does not require trusted origin. @@ -275,9 +287,7 @@ function onMessage(request, sender, callback) { return true; case 'setDeveloperMode': - rulesetConfig.developerMode = request.state; - toggleDeveloperMode(rulesetConfig.developerMode); - saveRulesetConfig().then(( ) => { + setDeveloperMode(request.state).then(( ) => { callback(); }); return true; @@ -390,6 +400,12 @@ function onMessage(request, sender, callback) { }); break; + case 'updateUserDnrRules': + updateUserRules().then(result => { + callback(result); + }); + return true; + default: break; } @@ -472,8 +488,15 @@ async function startSession() { } } - // Required to ensure the up to date property is available when needed - adminReadEx('disabledFeatures'); + // Required to ensure up to date properties are available when needed + adminReadEx('disabledFeatures').then(items => { + if ( Array.isArray(items) === false ) { return; } + if ( items.includes('develop') ) { + if ( rulesetConfig.developerMode ) { + setDeveloperMode(false); + } + } + }); } /******************************************************************************/ diff --git a/platform/mv3/extension/js/dashboard.js b/platform/mv3/extension/js/dashboard.js index d43f45c5b..20f6b5ed5 100644 --- a/platform/mv3/extension/js/dashboard.js +++ b/platform/mv3/extension/js/dashboard.js @@ -19,6 +19,12 @@ Home: https://github.com/gorhill/uBlock */ +import { + localRead, + localRemove, + localWrite, +} from './ext.js'; + import { dom } from './dom.js'; import { runtime } from './ext.js'; @@ -32,7 +38,18 @@ import { runtime } from './ext.js'; dom.attr('a', 'target', '_blank'); dom.on('#dashboard-nav', 'click', '.tabButton', ev => { - dom.body.dataset.pane = ev.target.dataset.pane; + const { pane } = ev.target.dataset; + dom.body.dataset.pane = pane; + if ( pane === 'settings' ) { + localRemove('activeDashboardPane'); + } else { + localWrite('activeDashboardPane', pane); + } +}); + +localRead('activeDashboardPane').then(pane => { + if ( typeof pane !== 'string' ) { return; } + dom.body.dataset.pane = pane; }); /******************************************************************************/ diff --git a/platform/mv3/extension/js/develop.js b/platform/mv3/extension/js/develop.js new file mode 100644 index 000000000..86f60bccf --- /dev/null +++ b/platform/mv3/extension/js/develop.js @@ -0,0 +1,687 @@ +/******************************************************************************* + + uBlock Origin Lite - a comprehensive, MV3-compliant content blocker + Copyright (C) 2014-present Raymond Hill + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://github.com/gorhill/uBlock +*/ + +import { + browser, + localRead, + localRemove, + localWrite, + sendMessage, +} from './ext.js'; +import { dom, qs$ } from './dom.js'; +import { rulesFromText, textFromRules } from './dnr-parser.js'; +import { dnr } from './ext-compat.js'; +import { i18n$ } from './i18n.js'; + +/******************************************************************************/ + +// Details of YAML document(s) intersecting with a text span. If the text span +// starts on a YAML document divider, the previous YAML document will be +// included. If the text span ends on a YAML document divider, the next YAML +// document will be included. + +function snapToYamlDocument(doc, start, end) { + let yamlDocStart = doc.lineAt(start).number; + if ( reYamlDocSeparator.test(doc.line(yamlDocStart).text) ) { + if ( yamlDocStart > 1 ) { + yamlDocStart -= 1; + } + } + while ( yamlDocStart > 1 ) { + const line = doc.line(yamlDocStart); + if ( reYamlDocSeparator.test(line.text) ) { break; } + yamlDocStart -= 1; + } + const lastLine = doc.lines; + let yamlDocEnd = doc.lineAt(end).number; + if ( reYamlDocSeparator.test(doc.line(yamlDocEnd).text) ) { + if ( yamlDocEnd < lastLine ) { + yamlDocEnd += 1; + } + } + while ( yamlDocEnd < lastLine ) { + const line = doc.line(yamlDocEnd); + if ( reYamlDocSeparator.test(line.text) ) { break; } + yamlDocEnd += 1; + } + return { yamlDocStart, yamlDocEnd }; +} + +function addToModifiedRange(doc, start, end) { + const { yamlDocStart, yamlDocEnd } = snapToYamlDocument(doc, start, end); + if ( modifiedRange.start === -1 || yamlDocStart < modifiedRange.start ) { + modifiedRange.start = yamlDocStart; + } + if ( modifiedRange.end === -1 || yamlDocEnd > modifiedRange.end ) { + modifiedRange.end = yamlDocEnd; + } +} + +const reYamlDocSeparator = /^(?:---|...)\s*$/; +const modifiedRange = { start: -1, end: -1 }; + +/******************************************************************************/ + +function rulesFromJSON(json) { + let content = json.trim(); + if ( /^[[{]/.test(content) === false ) { + const match = /^[^[{]+/.exec(content); + if ( match === null ) { return; } + content = content.slice(match[0].length); + } + const firstChar = content.charAt(0); + const expectedLastChar = firstChar === '[' ? ']' : '}'; + if ( content.at(-1) !== expectedLastChar ) { + const re = new RegExp(`\\${expectedLastChar}[^\\${expectedLastChar}]+$`); + const match = re.exec(content); + if ( match === null ) { return; } + content = content.slice(0, match.index+1); + } + if ( content.startsWith('{') && content.endsWith('}') ) { + content = `[${content}]`; + } + try { + const rules = JSON.parse(content); + if ( Array.isArray(rules) ) { return rules; } + } + catch { + } +} + +/******************************************************************************/ + +function lineIndentAt(line) { + const match = /^(?: {2})*/.exec(line.text); + const indent = match !== null ? match[0].length : -1; + if ( indent === -1 || (indent & 1) !== 0 ) { return -1; } + return indent / 2; +} + +function getScopeAt(from) { + const { doc } = cmRules.state; + const lineFrom = doc.lineAt(from); + let depth = lineIndentAt(lineFrom); + if ( depth === -1 ) { return; } + const text = lineFrom.text.trim(); + if ( text.startsWith('#') ) { return; } + const path = []; + const pos = text.indexOf(':'); + if ( pos !== -1 ) { + path.push(text.slice(0, pos+1)); + } + let lineNo = lineFrom.number; + while ( depth > 0 && lineNo > 1 ) { + lineNo -= 1; + const lineBefore = doc.line(lineNo); + const text = lineBefore.text.trim(); + if ( text.startsWith('#') ) { continue; } + if ( lineIndentAt(lineBefore) > (depth-1) ) { continue; } + const match = /^- ([^:]+:)/.exec(text); + if ( match !== null ) { + path.unshift(match[1]); + } else { + path.unshift(text); + } + depth -= 1; + } + return path.join(''); +} + +function getAutocompleteCandidates(from) { + const scope = getScopeAt(from); + switch ( scope ) { + case '': + return { + before: /^$/, + candidates: [ + { token: 'action:', after: '\n ' }, + { token: 'condition:', after: '\n ' }, + { token: 'priority:', after: ' ' }, + { token: '---', after: '\n' }, + ] + }; + case 'action:': + return { + before: /^ {2}$/, + candidates: [ + { token: 'type:', after: ' ' }, + { token: 'redirect:', after: '\n ' }, + { token: 'requestHeaders:', after: '\n - header: ' }, + { token: 'responseHeaders:', after: '\n - header: ' }, + ], + }; + case 'action:type:': + return { + before: /: $/, + candidates: [ + { token: 'block', after: '\n ' }, + { token: 'redirect', after: '\n ' }, + { token: 'allow', after: '\n ' }, + { token: 'modifyHeaders', after: '\n ' }, + { token: 'upgradeScheme', after: '\n ' }, + { token: 'allowAllRequest', after: '\n ' }, + ], + }; + case 'action:redirect:': + return { + before: /^ {4}$/, + candidates: [ + { token: 'extensionPath:', after: ' ' }, + { token: 'regexSubstitution:', after: ' ' }, + { token: 'transform:', after: '\n ' }, + { token: 'url:', after: ' ' }, + ], + }; + case 'action:redirect:transform:': + return { + before: /^ {6}$/, + candidates: [ + { token: 'fragment:', after: ' ' }, + { token: 'host:', after: ' ' }, + { token: 'path:', after: ' ' }, + { token: 'port:', after: ' ' }, + { token: 'query:', after: ' ' }, + { token: 'scheme:', after: ' ' }, + { token: 'queryTransform:', after: '\n ' }, + ], + }; + case 'action:redirect:transform:queryTransform:': + return { + before: /^ {8}$/, + candidates: [ + { token: 'addOrReplaceParams:', after: '\n - ' }, + { token: 'removeParams:', after: '\n - ' }, + ], + }; + case 'action:responseHeaders:': + return { + before: /^ {4}- $/, + candidates: [ + { token: 'header:', after: ' ' }, + ], + }; + case 'action:responseHeaders:header:': + return { + before: /^ {6}$/, + candidates: [ + { token: 'operation:', after: ' ' }, + { token: 'value:', after: ' ' }, + ], + }; + case 'action:responseHeaders:header:operation:': + return { + before: /: $/, + candidates: [ + { token: 'append', after: '\n value: ' }, + { token: 'set', after: '\n value: ' }, + { token: 'remove', after: '\n ' }, + ], + }; + case 'condition:': + return { + before: /^ {2}$/, + candidates: [ + { token: 'domainType:', after: ' ' }, + { token: 'isUrlFilterCaseSensitive:', after: ' ' }, + { token: 'regexFilter:', after: ' ' }, + { token: 'urlFilter:', after: ' ' }, + { token: 'initiatorDomains:', after: '\n - ' }, + { token: 'excludedInitiatorDomains:', after: '\n - ' }, + { token: 'requestDomains:', after: '\n - ' }, + { token: 'excludedRequestDomains:', after: '\n - ' }, + { token: 'resourceTypes:', after: '\n - ' }, + { token: 'excludedResourceTypes:', after: '\n - ' }, + { token: 'requestMethods:', after: '\n - ' }, + { token: 'excludedRequestMethods:', after: '\n - ' }, + { token: 'responseHeaders:', after: '\n - ' }, + { token: 'excludedResponseHeaders:', after: '\n - ' }, + ], + }; + case 'condition:domainType:': + return { + before: /: $/, + candidates: [ + { token: 'firstParty', after: '\n ' }, + { token: 'thirdParty', after: '\n ' }, + ], + }; + case 'condition:isUrlFilterCaseSensitive:': + return { + before: /: $/, + candidates: [ + { token: 'true', after: '\n ' }, + { token: 'false', after: '\n ' }, + ], + }; + case 'condition:requestMethods:': + case 'condition:excludedRequestMethods:': + return { + before: /^ {4}- $/, + candidates: [ + { token: 'connect', after: '\n - ' }, + { token: 'delete', after: '\n - ' }, + { token: 'get', after: '\n - ' }, + { token: 'head', after: '\n - ' }, + { token: 'options', after: '\n - ' }, + { token: 'patch', after: '\n - ' }, + { token: 'post', after: '\n - ' }, + { token: 'put', after: '\n - ' }, + { token: 'other', after: '\n ' }, + ], + }; + case 'condition:resourceTypes:': + case 'condition:excludedResourceTypes:': + return { + before: /^ {4}- $/, + candidates: [ + { token: 'main_frame', after: '\n - ' }, + { token: 'sub_frame', after: '\n - ' }, + { token: 'stylesheet', after: '\n - ' }, + { token: 'script', after: '\n - ' }, + { token: 'image', after: '\n - ' }, + { token: 'font', after: '\n - ' }, + { token: 'object', after: '\n - ' }, + { token: 'xmlhttprequest', after: '\n - ' }, + { token: 'ping', after: '\n - ' }, + { token: 'csp_report', after: '\n - ' }, + { token: 'media', after: '\n - ' }, + { token: 'websocket', after: '\n - ' }, + { token: 'webtransport', after: '\n - ' }, + { token: 'webbundle', after: '\n - ' }, + { token: 'other', after: '\n ' }, + ], + }; + } +} + +function autoComplete(context) { + const match = context.matchBefore(/[\w-]*/); + if ( match === undefined ) { return null; } + const result = getAutocompleteCandidates(match.from); + if ( result === undefined ) { return null; } + if ( result.before !== undefined ) { + const { doc } = context.state; + const line = doc.lineAt(context.pos); + const before = doc.sliceString(line.from, match.from); + if ( result.before.test(before) === false ) { return null; } + } + const filtered = result.candidates.filter(e => + e.token !== match.text || e.after !== '\n' + ); + return { + from: match.from, + options: filtered.map(e => ({ label: e.token, apply: `${e.token}${e.after}` })), + validFor: /\w*/, + }; +} + +/******************************************************************************/ + +function setEditorText(text) { + if ( text === undefined ) { return; } + if ( text !== '' ) { text += '\n'; } + cmRules.dispatch({ + changes: { + from: 0, to: cmRules.state.doc.length, + insert: text + }, + }); +} + +function getEditorText() { + return cmRules.state.doc.toString(); +} + +/******************************************************************************/ + +function saveEditorText() { + const text = getEditorText().trim(); + const promise = text.length !== 0 + ? localWrite('userDnrRules', text) + : localRemove('userDnrRules'); + promise.then(( ) => { + lastSavedText = text; + updateView(); + }).then(( ) => + sendMessage({ what: 'updateUserDnrRules' }) + ).then(result => { + if ( result instanceof Object === false ) { return; } + updateFeedbackPanel(result); + }); +} + +/******************************************************************************/ + +async function validateRegexes(regexes) { + if ( regexes.length === 0 ) { return; } + const promises = regexes.map(regex => validateRegex(regex)); + await Promise.all(promises); + for ( const regex of regexes ) { + const i = validatedRegexes.regexes.indexOf(regex); + if ( i === -1 ) { continue; } + const reason = validatedRegexes.results[i]; + if ( reason === true ) { continue; } + const entries = self.cm6.findAll(cmRules, + `(?<=\\bregexFilter: )${RegExp.escape(regex)}` + ); + for ( const entry of entries ) { + self.cm6.spanErrorAdd(cmRules, entry.from, entry.to, reason); + } + } +} + +async function validateRegex(regex) { + const details = await dnr.isRegexSupported({ regex }); + const result = details.isSupported || details.reason; + if ( validatedRegexes.regexes.length > 32 ) { + validatedRegexes.regexes.pop(); + validatedRegexes.results.pop(); + } + validatedRegexes.regexes.unshift(regex); + validatedRegexes.results.unshift(result); +} + +const validatedRegexes = { + regexes: [], + results: [], +}; + +/******************************************************************************/ + +function updateView() { + const { doc } = cmRules.state; + const changed = doc.toString().trim() !== + lastSavedText.trim(); + dom.attr('#dnrRulesApply', 'disabled', changed ? null : ''); + dom.attr('#dnrRulesRevert', 'disabled', changed ? null : ''); + const { start, end } = modifiedRange; + if ( start === -1 || end === -1 ) { return; } + modifiedRange.start = modifiedRange.end = -1; + self.cm6.lineErrorClear(cmRules, start, end); + self.cm6.spanErrorClear(cmRules, start, end); + const firstLine = doc.line(start); + const lastLine = doc.line(end); + const text = doc.sliceString(firstLine.from, lastLine.to); + const { bad } = rulesFromText(text); + if ( Array.isArray(bad) && bad.length !== 0 ) { + self.cm6.lineErrorAdd(cmRules, bad.map(i => i + start)); + } + const entries = self.cm6.findAll( + cmRules, + '\\bregexFilter: (\\S+)', + firstLine.from, + lastLine.to + ); + const regexes = []; + for ( const entry of entries ) { + const regex = entry.match[1]; + const i = validatedRegexes.regexes.indexOf(regex); + if ( i !== -1 ) { + const reason = validatedRegexes.results[i]; + if ( reason === true ) { continue; } + self.cm6.spanErrorAdd(cmRules, entry.from+13, entry.to, reason); + } else { + regexes.push(regex); + } + } + validateRegexes(regexes); +} + +function updateViewAsync() { + if ( updateViewAsync.timer !== undefined ) { return; } + updateViewAsync.timer = self.setTimeout(( ) => { + updateViewAsync.timer = undefined; + updateView(); + }, 71); +} + +/******************************************************************************/ + +function updateSummaryPanel(info) { + self.cm6.showSummaryPanel(cmRules, { + template: '.summary-panel', + text: i18n$('dnrRulesCountInfo') + .replace('{count}', (info.userDnrRuleCount || 0).toLocaleString()), + }); +} + +browser.storage.onChanged.addListener((changes, area) => { + if ( area !== 'local' ) { return; } + const { userDnrRuleCount } = changes; + if ( userDnrRuleCount instanceof Object === false ) { return; } + const { newValue } = changes.userDnrRuleCount; + updateSummaryPanel({ userDnrRuleCount: newValue }); +}); + +localRead('userDnrRuleCount').then(userDnrRuleCount => { + updateSummaryPanel({ userDnrRuleCount }) +}); + +function updateFeedbackPanel(info) { + const errors = []; + if ( Array.isArray(info.errors) ) { + info.errors.forEach(e => errors.push(e)); + } + const text = errors.join('\n'); + self.cm6.showFeedbackPanel(cmRules, { template: '.feedback-panel', text }); +} + +/******************************************************************************/ + +function importRulesFromFile() { + const input = qs$('input[type="file"]'); + input.onchange = ev => { + input.onchange = null; + const file = ev.target.files[0]; + if ( file === undefined || file.name === '' ) { return; } + if ( file.type !== 'application/json' ) { return; } + const fr = new FileReader(); + fr.onload = ( ) => { + if ( typeof fr.result !== 'string' ) { return; } + const rules = rulesFromJSON(fr.result); + if ( rules === undefined ) { return; } + const text = textFromRules(rules); + if ( text === undefined ) { return; } + const { doc } = cmRules.state; + const lastChars = doc.toString().trimEnd().slice(-4); + const lastLine = doc.line(doc.lines); + let from = lastLine.to; + let prepend = ''; + if ( lastLine.text !== '' ) { + prepend = '\n'; + } else { + from = lastLine.from; + } + if ( /(?:^|\n)---$/.test(lastChars) === false ) { + prepend = `${prepend}---\n`; + } + cmRules.dispatch({ changes: { from, insert: `${prepend}${text}` } }); + cmRules.focus(); + }; + fr.readAsText(file); + }; + // Reset to empty string, this will ensure a change event is properly + // triggered if the user pick a file, even if it's the same as the last + // one picked. + input.value = ''; + input.click(); +} + +dom.on('#dnrRulesImport', 'click', importRulesFromFile); + +/******************************************************************************/ + +function exportRulesToFile() { + const text = getEditorText(); + const { rules } = rulesFromText(text); + if ( Array.isArray(rules) === false ) { return; } + let ruleId = 1; + for ( const rule of rules ) { + rule.id = ruleId++; + } + const filename = 'my-ubol-dnr-rules.json'; + const a = document.createElement('a'); + a.href = `data:application/json;charset=utf-8,${JSON.stringify(rules, null, 2)}`; + dom.attr(a, 'download', filename || ''); + dom.attr(a, 'type', 'application/json'); + a.click(); +} + +dom.on('#dnrRulesExport', 'click', exportRulesToFile); + +/******************************************************************************/ + +function importRulesFromPaste(from, to) { + if ( from === undefined || to === undefined ) { return; } + // Paste position must match start of a line + const { doc } = cmRules.state; + const lineFrom = doc.lineAt(from); + if ( lineFrom.from !== from ) { return; } + // Paste position must match a rule boundary + if ( lineFrom.number !== 1 ) { + const lineBefore = doc.line(lineFrom.number-1); + if ( /^---\s*$/.test(lineBefore.text) === false ) { return; } + } + const pastedText = doc.sliceString(from, to); + const rules = rulesFromJSON(pastedText); + if ( rules === undefined ) { return; } + const yamlText = textFromRules(rules); + if ( yamlText === undefined ) { return; } + cmRules.dispatch({ changes: { from, to, insert: yamlText } }); +} + +/******************************************************************************/ + +function cmUpdateListener(info) { + if ( info.docChanged === false ) { return; } + const doc = info.state.doc; + info.changes.iterChangedRanges((fromA, toA, fromB, toB) => { + addToModifiedRange(doc, fromB, toB); + }); + for ( const transaction of info.transactions ) { + if ( transaction.isUserEvent('input.paste') === false ) { continue; } + if ( transaction.docChanged === false ) { continue; } + let from, to; + transaction.changes.iterChangedRanges((fromA, toA, fromB, toB) => { + if ( from === undefined || fromB < from ) { from = fromB; } + if ( to === undefined || toB > to ) { to = toB; } + }); + importRulesFromPaste(from, to); + break; + } + updateViewAsync(); +} + +/******************************************************************************/ + +function gutterClick(view, info) { + const reSeparator = /^---\s*/; + const { doc } = view.state; + const lineFirst = doc.lineAt(info.from); + if ( lineFirst.text === '' ) { return false; } + let { from, to } = lineFirst; + if ( reSeparator.test(lineFirst.text) ) { + let lineNo = lineFirst.number + 1; + while ( lineNo < doc.lines ) { + const line = doc.line(lineNo); + if ( reSeparator.test(line.text) ) { break; } + to = line.to; + lineNo += 1; + } + } + view.dispatch({ + selection: { anchor: from, head: to+1 } + }); + view.focus(); + return true; +} + +/******************************************************************************/ + +function hoverTooltip(view, pos, side) { + const details = view.domAtPos(pos); + const textNode = details.node; + if ( textNode.nodeType !== 3 ) { return null; } + const { parentElement } = textNode; + const targetElement = parentElement.closest('[data-tooltip]'); + if ( targetElement === null ) { return null; } + const tooltipText = targetElement.getAttribute('data-tooltip'); + if ( Boolean(tooltipText) === false ) { return null; } + const start = pos - details.offset; + const end = start + textNode.nodeValue.length; + if ( start === pos && side < 0 || end === pos && side > 0 ) { return null; } + return { + above: true, + pos: start, + end, + create() { + const template = document.querySelector('.badmark-tooltip'); + const fragment = template.content.cloneNode(true); + const dom = fragment.querySelector('.badmark-tooltip'); + dom.textContent = tooltipText; + return { dom }; + }, + }; +} + +/******************************************************************************/ + +const cmRules = (( ) => { + return self.cm6.createEditorView({ + dnrRules: true, + oneDark: dom.cl.has(':root', 'dark'), + updateListener: cmUpdateListener, + saveListener: ( ) => { + saveEditorText(); + }, + lineError: true, + spanError: true, + // https://codemirror.net/examples/autocompletion/ + autocompletion: { + override: [ autoComplete ], + activateOnCompletion: ( ) => true, + }, + gutterClick, + hoverTooltip, + }, qs$('#cm-dnrRules')); +})(); + +/******************************************************************************/ + +let lastSavedText = ''; + +localRead('userDnrRules').then(text => { + text ||= ''; + setEditorText(text); + lastSavedText = text; + self.cm6.resetUndoRedo(cmRules); + + dom.on('#dnrRulesApply', 'click', ( ) => { + saveEditorText(); + }); + + dom.on('#dnrRulesRevert', 'click', ( ) => { + setEditorText(lastSavedText); + sendMessage({ what: 'updateUserDnrRules' }); + }); +}); + +/******************************************************************************/ diff --git a/platform/mv3/extension/js/dnr-parser.js b/platform/mv3/extension/js/dnr-parser.js new file mode 100644 index 000000000..8c4799b88 --- /dev/null +++ b/platform/mv3/extension/js/dnr-parser.js @@ -0,0 +1,607 @@ +/******************************************************************************* + + uBlock Origin Lite - a comprehensive, MV3-compliant content blocker + Copyright (C) 2014-present Raymond Hill + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://github.com/gorhill/uBlock +*/ + +/******************************************************************************/ + +const validActionValues = [ + 'block', + 'redirect', + 'allow', + 'upgradeScheme', + 'modifyHeaders', + 'allowAllRequests', +]; + +const validBoolValues = [ + 'false', + 'true', +]; + +const validHeaderOpValues = [ + 'append', + 'remove', + 'set', +]; + +const validDomainTypeValues = [ + 'firstParty', + 'thirdParty', +]; + +const validRequestMethodValues = [ + 'connect', + 'delete', + 'get', + 'head', + 'options', + 'patch', + 'post', + 'put', + 'other', +]; + +const validResourceTypeValues = [ + 'main_frame', + 'sub_frame', + 'stylesheet', + 'script', + 'image', + 'font', + 'object', + 'xmlhttprequest', + 'ping', + 'csp_report', + 'media', + 'websocket', + 'webtransport', + 'webbundle', + 'other', +]; + +/******************************************************************************/ + +function selectParser(scope, rule, node) { + const parser = perScopeParsers[scope.join('.')]; + if ( parser === undefined ) { return false; } + return parser(scope, rule, node); +} + +const perScopeParsers = { + '': function(scope, rule, node) { + const { key, val } = node; + switch ( key ) { + case 'action': + if ( val !== undefined ) { return false; } + rule.action = {}; + scope.push('action'); + break; + case 'condition': + if ( val !== undefined ) { return false; } + rule.condition = {}; + scope.push('condition'); + break; + case 'priority': { + const n = parseInt(val, 10); + if ( isNaN(n) || n <= 1 ) { return false; } + rule.priority = n; + break; + } + default: + return false; + } + return true; + }, + 'action': function(scope, rule, node) { + const { key, val } = node; + switch ( key ) { + case 'type': + if ( validActionValues.includes(val) === false ) { return false; } + rule.action.type = val; + break; + case 'redirect': + rule.action.redirect = {}; + scope.push('redirect'); + break; + case 'requestHeaders': + rule.action.requestHeaders = []; + scope.push('requestHeaders'); + break; + case 'responseHeaders': + rule.action.responseHeaders = []; + scope.push('responseHeaders'); + break; + default: + return false; + } + return true; + }, + 'action.redirect': function(scope, rule, node) { + const { key, val } = node; + switch ( key ) { + case 'extensionPath': + rule.action.redirect.extensionPath = val; + break; + case 'regexSubstitution': + rule.action.redirect.regexSubstitution = val; + break; + case 'transform': + rule.action.redirect.transform = {}; + scope.push('transform'); + break; + case 'url': + rule.action.redirect.url = val; + break; + default: + return false; + } + return true; + }, + 'action.redirect.transform': function(scope, rule, node) { + const { key, val } = node; + switch ( key ) { + case 'fragment': + case 'host': + case 'path': + case 'port': + case 'query': + case 'scheme': { + if ( val === undefined ) { return false; } + rule.action.redirect.transform[key] = val; + break; + } + case 'queryTransform': + rule.action.redirect.transform.queryTransform = {}; + scope.push('queryTransform'); + break; + default: + return false; + } + return true; + }, + 'action.redirect.transform.queryTransform': function(scope, rule, node) { + const { key, val } = node; + if ( val !== undefined ) { return false; } + switch ( key ) { + case 'addOrReplaceParams': + rule.action.redirect.transform.queryTransform.addOrReplaceParams = []; + scope.push('addOrReplaceParams'); + break; + case 'removeParams': + rule.action.redirect.transform.queryTransform.removeParams = []; + scope.push('removeParams'); + break; + default: + return false; + } + return true; + }, + 'action.redirect.transform.queryTransform.addOrReplaceParams': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.action.redirect.transform.queryTransform.addOrReplaceParams.push({}); + scope.push('@'); + return selectParser(scope, rule, node); + }, + 'action.redirect.transform.queryTransform.addOrReplaceParams.@': function(scope, rule, node) { + const { key, val } = node; + if ( val === undefined ) { return false; } + const item = rule.action.redirect.transform.queryTransform.addOrReplaceParams.at(-1); + switch ( key ) { + case 'key': + item.key = val; + break; + case 'value': + item.value = val; + break; + case 'replaceOnly': + if ( validBoolValues.includes(val) === false ) { return false; } + item.replaceOnly = val === 'true'; + break; + default: + return false; + } + return true; + }, + 'action.redirect.transform.queryTransform.removeParams': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.action.redirect.transform.queryTransform.removeParams.push(node.val); + return true; + }, + 'action.requestHeaders': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.action.requestHeaders.push({}); + scope.push('@'); + return selectParser(scope, rule, node); + }, + 'action.requestHeaders.@': function(scope, rule, node) { + const { key, val } = node; + const item = rule.action.requestHeaders.at(-1); + switch ( key ) { + case 'header': + item.header = val; + break; + case 'value': + item.value = val; + break; + case 'operation': + if ( validHeaderOpValues.includes(val) === false ) { return false; } + item.operation = val; + break; + default: + return false; + } + return true; + }, + 'action.responseHeaders': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.action.responseHeaders.push({}); + scope.push('@'); + return selectParser(scope, rule, node); + }, + 'action.responseHeaders.@': function(scope, rule, node) { + const { key, val } = node; + const item = rule.action.responseHeaders.at(-1); + switch ( key ) { + case 'header': + item.header = val; + break; + case 'value': + item.value = val; + break; + case 'operation': + if ( validHeaderOpValues.includes(val) === false ) { return false; } + item.operation = val; + break; + default: + return false; + } + return true; + }, + 'condition': function(scope, rule, node) { + const { key, val } = node; + switch ( key ) { + case 'domainType': + if ( validDomainTypeValues.includes(val) === false ) { return false; } + rule.condition.domainType = val; + break; + case 'isUrlFilterCaseSensitive': + if ( validBoolValues.includes(val) === false ) { return false; } + rule.condition.isUrlFilterCaseSensitive = val === 'true'; + break; + case 'regexFilter': + if ( val === undefined ) { return false; } + rule.condition.regexFilter = val; + break; + case 'urlFilter': + if ( val === undefined ) { return false; } + rule.condition.urlFilter = val; + break; + case 'initiatorDomains': + rule.condition.initiatorDomains = []; + scope.push('initiatorDomains'); + break; + case 'excludedInitiatorDomains': + rule.condition.excludedInitiatorDomains = []; + scope.push('excludedInitiatorDomains'); + break; + case 'requestDomains': + rule.condition.requestDomains = []; + scope.push('requestDomains'); + break; + case 'excludedRequestDomains': + rule.condition.excludedRequestDomains = []; + scope.push('excludedRequestDomains'); + break; + case 'resourceTypes': + rule.condition.resourceTypes = []; + scope.push('resourceTypes'); + break; + case 'excludedResourceTypes': + rule.condition.excludedResourceTypes = []; + scope.push('excludedResourceTypes'); + break; + case 'requestMethods': + rule.condition.requestMethods = []; + scope.push('requestMethods'); + break; + case 'excludedRequestMethods': + rule.condition.excludedRequestMethods = []; + scope.push('excludedRequestMethods'); + break; + case 'responseHeaders': + rule.condition.responseHeaders = []; + scope.push('responseHeaders'); + break; + case 'excludedResponseHeaders': + rule.condition.excludedResponseHeaders = []; + scope.push('excludedResponseHeaders'); + break; + default: + return false; + } + return true; + }, + 'condition.initiatorDomains': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.condition.initiatorDomains.push(node.val); + return true; + }, + 'condition.excludedInitiatorDomains': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.condition.excludedInitiatorDomains.push(node.val); + return true; + }, + 'condition.requestDomains': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.condition.requestDomains.push(node.val); + return true; + }, + 'condition.excludedRequestDomains': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.condition.excludedRequestDomains.push(node.val); + return true; + }, + 'condition.resourceTypes': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + if ( validResourceTypeValues.includes(node.val) === false ) { return false; } + rule.condition.resourceTypes.push(node.val); + return true; + }, + 'condition.excludedResourceTypes': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + if ( validResourceTypeValues.includes(node.val) === false ) { return false; } + rule.condition.excludedResourceTypes.push(node.val); + return true; + }, + 'condition.requestMethods': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + if ( validRequestMethodValues.includes(node.val) === false ) { return false; } + rule.condition.requestMethods.push(node.val); + return true; + }, + 'condition.excludedRequestMethods': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + if ( validRequestMethodValues.includes(node.val) === false ) { return false; } + rule.condition.excludedRequestMethods.push(node.val); + return true; + }, + 'condition.responseHeaders': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.condition.responseHeaders.push({}); + scope.push('@'); + return selectParser(scope, rule, node); + }, + 'condition.responseHeaders.@': function(scope, rule, node) { + const item = rule.condition.responseHeaders.at(-1); + switch ( node.key ) { + case 'header': + if ( node.val === undefined ) { return false; } + item.header = node.val; + break; + case 'values': + item.values = []; + scope.push('values'); + break; + case 'excludedValues': + item.excludedValues = []; + scope.push('excludedValues'); + break; + default: + return false; + } + return true; + }, + 'condition.responseHeaders.@.values': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + const item = rule.condition.responseHeaders.at(-1); + item.values.push(node.val); + return true; + }, + 'condition.responseHeaders.@.excludedValues': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + const item = rule.condition.responseHeaders.at(-1); + item.excludedValues.push(node.val); + return true; + }, + 'condition.excludedResponseHeaders': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + rule.condition.excludedResponseHeaders.push({}); + scope.push('@'); + return selectParser(scope, rule, node); + }, + 'condition.excludedResponseHeaders.@': function(scope, rule, node) { + const item = rule.condition.excludedResponseHeaders.at(-1); + switch ( node.key ) { + case 'header': + if ( node.val === undefined ) { return false; } + item.header = node.val; + break; + case 'values': + item.values = []; + scope.push('values'); + break; + case 'excludedValues': + item.excludedValues = []; + scope.push('excludedValues'); + break; + default: + return false; + } + return true; + }, + 'condition.excludedResponseHeaders.@.values': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + const item = rule.condition.excludedResponseHeaders.at(-1); + item.values.push(node.val); + return true; + }, + 'condition.excludedResponseHeaders.@.excludedValues': function(scope, rule, node) { + if ( node.list !== true ) { return false; } + const item = rule.condition.excludedResponseHeaders.at(-1); + item.excludedValues.push(node.val); + return true; + }, +}; + +/******************************************************************************/ + +function depthFromIndent(line) { + const match = /^\s*/.exec(line); + const count = match[0].length; + if ( (count & 1) !== 0 ) { return -1; } + return count / 2; +} + +/******************************************************************************/ + +function nodeFromLine(line) { + const match = reNodeParser.exec(line); + const out = {}; + if ( match === null ) { return out; } + if ( match[1] ) { + out.list = true; + } + if ( match[4] ) { + out.val = match[4].trim(); + } else if ( match[3] ) { + out.key = match[2]; + out.val = match[3].trim(); + if ( out.val === "''" ) { out.val = '' }; + } else { + out.key = match[2]; + } + return out; +} + +const reNodeParser = /^\s*(- )?(?:(\S+):( \S.*)?|(\S.*))$/; + +/******************************************************************************/ + +function ruleFromLines(lines, indices) { + const rule = {}; + const bad = []; + const scope = []; + for ( const i of indices ) { + const line = lines[i]; + const depth = depthFromIndent(line); + if ( depth < 0 ) { + bad.push(i); + continue; + } + scope.length = depth; + const node = nodeFromLine(line); + const result = selectParser(scope, rule, node); + if ( result === false ) { + bad.push(i); + } + } + if ( bad.length !== 0 ) { return { bad }; } + return { rule }; +} + +/******************************************************************************/ + +export function rulesFromText(text) { + const rules = []; + const bad = []; + const lines = [ ...text.split(/\n\r|\r\n|\n|\r/), '---' ]; + const indices = []; + for ( let i = 0; i < lines.length; i++ ) { + const line = lines[i].trimEnd(); + const trimmed = line.trimStart(); + if ( trimmed.startsWith('#') ) { continue; } + // Discard leading empty lines + if ( trimmed === '' ) { + if ( indices.length === 0 ) { continue; } + } + if ( line !== '---' && line !== '...' ) { + indices.push(i); + continue; + } + // Discard trailing empty lines + while ( indices.length !== 0 ) { + const s = lines[indices.at(-1)].trim(); + if ( s.length !== 0 ) { break; } + indices.pop(); + } + if ( indices.length === 0 ) { continue; } + const result = ruleFromLines(lines, indices); + if ( result.bad ) { + bad.push(...result.bad); + } else if ( result.rule ) { + rules.push(result.rule); + } + indices.length = 0; + } + return { rules, bad }; +} + +/******************************************************************************/ + +function textFromValue(val, depth) { + const indent = ' '.repeat(depth); + switch ( typeof val ) { + case 'boolean': + case 'number': + return `${val}`; + case 'string': + if ( val === '' ) { return "''"; } + return val; + } + const out = []; + if ( Array.isArray(val) ) { + for ( const a of val ) { + const s = textFromValue(a, depth+1); + if ( s === undefined ) { continue; } + out.push(`${indent}- ${s.trimStart()}`); + } + return out.join('\n'); + } + if ( val instanceof Object ) { + for ( const [ a, b ] of Object.entries(val) ) { + const s = textFromValue(b, depth+1); + if ( s === undefined ) { continue; } + if ( b instanceof Object ) { + out.push(`${indent}${a}:\n${s}`); + } else { + out.push(`${indent}${a}: ${s}`); + } + } + return out.join('\n'); + } +} + +/******************************************************************************/ + +export function textFromRules(rules) { + if ( Array.isArray(rules) === false ) { + if ( rules instanceof Object === false ) { return; } + rules = [ rules ]; + } + const out = []; + for ( const rule of rules ) { + if ( rule.id ) { rule.id = undefined }; + const text = textFromValue(rule, 0); + if ( text === undefined ) { continue; } + out.push(text, '---' ); + } + out.push(''); + return out.join('\n'); +} diff --git a/platform/mv3/extension/js/ext-compat.js b/platform/mv3/extension/js/ext-compat.js index 9e8469ce7..06f0c8c91 100644 --- a/platform/mv3/extension/js/ext-compat.js +++ b/platform/mv3/extension/js/ext-compat.js @@ -36,7 +36,7 @@ const isSameRules = (a, b) => { /******************************************************************************/ -dnr.setAllowAllRules = async function(id, allowed, notAllowed, reverse) { +dnr.setAllowAllRules = async function(id, allowed, notAllowed, reverse, priority) { const [ beforeDynamicRules, beforeSessionRules, @@ -53,7 +53,7 @@ dnr.setAllowAllRules = async function(id, allowed, notAllowed, reverse) { condition: { resourceTypes: [ 'main_frame' ], }, - priority: 1000000, + priority, }; if ( allowed.length ) { rule0.condition.requestDomains = allowed.slice(); @@ -69,7 +69,7 @@ dnr.setAllowAllRules = async function(id, allowed, notAllowed, reverse) { condition: { tabIds: [ webext.tabs.TAB_ID_NONE ], }, - priority: 1000000, + priority, }; if ( allowed.length ) { rule1.condition.initiatorDomains = allowed.slice(); diff --git a/platform/mv3/extension/js/ruleset-manager.js b/platform/mv3/extension/js/ruleset-manager.js index d87133fc9..7876ab821 100644 --- a/platform/mv3/extension/js/ruleset-manager.js +++ b/platform/mv3/extension/js/ruleset-manager.js @@ -35,11 +35,16 @@ import { dnr } from './ext-compat.js'; import { fetchJSON } from './fetch.js'; import { getAdminRulesets } from './admin.js'; import { hasBroadHostPermissions } from './utils.js'; +import { rulesFromText } from './dnr-parser.js'; import { ubolLog } from './debug.js'; /******************************************************************************/ +const SPECIAL_RULES_REALM = 5000000; +const USER_RULES_BASE_RULE_ID = 9000000; +const USER_RULES_PRIORITY = 1000000; const TRUSTED_DIRECTIVE_BASE_RULE_ID = 8000000; +const TRUSTED_DIRECTIVE_PRIORITY = USER_RULES_PRIORITY + 1000000; const STRICTBLOCK_PRIORITY = 29; let dynamicRegexCount = 0; @@ -80,15 +85,12 @@ function getRulesetDetails() { /******************************************************************************/ -async function pruneInvalidRegexRules(realm, rulesIn) { - const rejectedRegexRules = []; - +async function pruneInvalidRegexRules(realm, rulesIn, rejected = []) { const validateRegex = regex => { return dnr.isRegexSupported({ regex, isCaseSensitive: false }).then(result => { - const isSupported = result?.isSupported || false; - pruneInvalidRegexRules.validated.set(regex, isSupported); - if ( isSupported ) { return true; } - rejectedRegexRules.push(`\t${regex} ${result?.reason}`); + pruneInvalidRegexRules.validated.set(regex, result?.reason || true); + if ( result.isSupported ) { return true; } + rejected.push({ regex, reason: result?.reason }); return false; }); }; @@ -101,8 +103,11 @@ async function pruneInvalidRegexRules(realm, rulesIn) { continue; } const { regexFilter } = rule.condition; - if ( pruneInvalidRegexRules.validated.has(regexFilter) ) { - toCheck.push(pruneInvalidRegexRules.validated.get(regexFilter)); + const reason = pruneInvalidRegexRules.validated.get(regexFilter); + if ( reason !== undefined ) { + toCheck.push(reason === true); + if ( reason === true ) { continue; } + rejected.push({ regex: regexFilter, reason }); continue; } toCheck.push(validateRegex(regexFilter)); @@ -111,9 +116,9 @@ async function pruneInvalidRegexRules(realm, rulesIn) { // Collate results const isValid = await Promise.all(toCheck); - if ( rejectedRegexRules.length !== 0 ) { + if ( rejected.length !== 0 ) { ubolLog(`${realm} realm: rejected regexes:\n`, - rejectedRegexRules.join('\n') + rejected.map(e => `${e.regex} → ${e.reason}`).join('\n') ); } @@ -126,6 +131,7 @@ pruneInvalidRegexRules.validated = new Map(); async function updateRegexRules(currentRules, addRules, removeRuleIds) { // Remove existing regex-related block rules for ( const rule of currentRules ) { + if ( rule.id >= SPECIAL_RULES_REALM ) { continue; } const { type } = rule.action; if ( type !== 'block' && type !== 'allow' ) { continue; } if ( rule.condition.regexFilter === undefined ) { continue; } @@ -164,6 +170,7 @@ async function updateRegexRules(currentRules, addRules, removeRuleIds) { async function updateRemoveparamRules(currentRules, addRules, removeRuleIds) { // Remove existing removeparam-related rules for ( const rule of currentRules ) { + if ( rule.id >= SPECIAL_RULES_REALM ) { continue; } if ( rule.action.type !== 'redirect' ) { continue; } if ( rule.action.redirect.transform === undefined ) { continue; } removeRuleIds.push(rule.id); @@ -179,7 +186,6 @@ async function updateRemoveparamRules(currentRules, addRules, removeRuleIds) { } const removeparamRulesets = await Promise.all(toFetch); - // Removeparam rules can only be enforced with omnipotence const allRules = []; for ( const rules of removeparamRulesets ) { if ( Array.isArray(rules) === false ) { continue; } @@ -201,6 +207,7 @@ async function updateRemoveparamRules(currentRules, addRules, removeRuleIds) { async function updateRedirectRules(currentRules, addRules, removeRuleIds) { // Remove existing redirect-related rules for ( const rule of currentRules ) { + if ( rule.id >= SPECIAL_RULES_REALM ) { continue; } if ( rule.action.type !== 'redirect' ) { continue; } if ( rule.action.redirect.extensionPath === undefined ) { continue; } removeRuleIds.push(rule.id); @@ -216,7 +223,6 @@ async function updateRedirectRules(currentRules, addRules, removeRuleIds) { } const redirectRulesets = await Promise.all(toFetch); - // Redirect rules can only be enforced with omnipotence const allRules = []; for ( const rules of redirectRulesets ) { if ( Array.isArray(rules) === false ) { continue; } @@ -238,6 +244,7 @@ async function updateRedirectRules(currentRules, addRules, removeRuleIds) { async function updateModifyHeadersRules(currentRules, addRules, removeRuleIds) { // Remove existing header modification-related rules for ( const rule of currentRules ) { + if ( rule.id >= SPECIAL_RULES_REALM ) { continue; } if ( rule.action.type !== 'modifyHeaders' ) { continue; } removeRuleIds.push(rule.id); } @@ -252,7 +259,6 @@ async function updateModifyHeadersRules(currentRules, addRules, removeRuleIds) { } const rulesets = await Promise.all(toFetch); - // Redirect rules can only be enforced with omnipotence const allRules = []; for ( const rules of rulesets ) { if ( Array.isArray(rules) === false ) { continue; } @@ -278,6 +284,7 @@ async function updateDynamicRules() { // Remove potentially left-over strict-block rules from previous version for ( const rule of currentRules ) { + if ( rule.id >= SPECIAL_RULES_REALM ) { continue; } if ( isStrictBlockRule(rule) === false ) { continue; } removeRuleIds.push(rule.id); } @@ -294,7 +301,6 @@ async function updateDynamicRules() { let ruleId = 1; for ( const rule of addRules ) { if ( rule?.condition.regexFilter ) { dynamicRegexCount += 1; } - if ( (rule.id || 0) >= TRUSTED_DIRECTIVE_BASE_RULE_ID ) { continue; } rule.id = ruleId++; } if ( dynamicRegexCount !== 0 ) { @@ -467,7 +473,8 @@ async function filteringModesToDNR(modes) { TRUSTED_DIRECTIVE_BASE_RULE_ID, requestDomains.sort(), excludedRequestDomains.sort(), - allowEverywhere + allowEverywhere, + TRUSTED_DIRECTIVE_PRIORITY ).then(modified => { if ( modified === false ) { return; } ubolLog(`${allowEverywhere ? 'Enabled' : 'Disabled'} DNR filtering for ${noneCount} sites`); @@ -662,6 +669,84 @@ async function getEnabledRulesetsDetails() { /******************************************************************************/ +async function getUserRules() { + const allRules = await dnr.getDynamicRules(); + const userRules = []; + for ( const rule of allRules ) { + if ( rule.id < USER_RULES_BASE_RULE_ID ) { continue; } + userRules.push(rule); + } + return userRules; +} + +async function updateUserRules() { + const [ + userRules, + userRulesText = '', + ] = await Promise.all([ + getUserRules(), + localRead('userDnrRules'), + ]); + + const effectiveRulesText = rulesetConfig.developerMode + ? userRulesText + : ''; + + const parsed = rulesFromText(effectiveRulesText); + const { rules } = parsed; + const removeRuleIds = [ ...userRules.map(a => a.id) ]; + const rejectedRegexes = []; + const addRules = await pruneInvalidRegexRules('user', rules, rejectedRegexes); + const out = { added: 0, removed: 0, errors: [] }; + + if ( rejectedRegexes.length !== 0 ) { + rejectedRegexes.forEach(e => + out.errors.push(`regexFilter: ${e.regex} → ${e.reason}`) + ); + } + + if ( removeRuleIds.length === 0 && addRules.length === 0 ) { + await localRemove('userDnrRuleCount'); + return out; + } + + let ruleId = 0; + for ( const rule of addRules ) { + rule.id = USER_RULES_BASE_RULE_ID + ruleId++; + rule.priority = (rule.priority || 1) + USER_RULES_PRIORITY; + } + + // Rules are first removed separately to ensure registered rules match + // user rules text. A bad rule in user rules text would prevent the + // rules from being removed if the removal was done at the same time as + // adding rules. + try { + await dnr.updateDynamicRules({ removeRuleIds }); + await dnr.updateDynamicRules({ addRules }); + if ( removeRuleIds.length !== 0 ) { + ubolLog(`updateUserRules() / Removed ${removeRuleIds.length} dynamic DNR rules`); + } + if ( addRules.length !== 0 ) { + ubolLog(`updateUserRules() / Added ${addRules.length} DNR rules`); + } + out.added = addRules.length; + out.removed = removeRuleIds.length; + } catch(reason) { + console.info(`updateUserRules() / ${reason}`); + out.errors.push(`${reason}`); + } finally { + const userRules = await getUserRules(); + if ( userRules.length === 0 ) { + await localRemove('userDnrRuleCount'); + } else { + await localWrite('userDnrRuleCount', addRules.length); + } + } + return out; +} + +/******************************************************************************/ + export { enableRulesets, excludeFromStrictBlock, @@ -672,4 +757,5 @@ export { setStrictBlockMode, updateDynamicRules, updateSessionRules, + updateUserRules, }; diff --git a/platform/mv3/extension/js/settings.js b/platform/mv3/extension/js/settings.js index 19303e406..ed1e9a99e 100644 --- a/platform/mv3/extension/js/settings.js +++ b/platform/mv3/extension/js/settings.js @@ -29,17 +29,16 @@ import { renderFilterLists } from './filter-lists.js'; /******************************************************************************/ const cm6 = self.cm6; -const cmView = (( ) => { + +const cmTrustedSites = (( ) => { const options = {}; if ( dom.cl.has(':root', 'dark') ) { options.oneDark = true; } options.placeholder = i18n$('noFilteringModePlaceholder'); - return cm6.createEditorView( - cm6.createEditorState('', options), - qs$('#trustedSites') - ); + return cm6.createEditorView(options, qs$('#trustedSites')); })(); + let cachedRulesetData = {}; /******************************************************************************/ @@ -83,12 +82,10 @@ function renderWidgets() { } { - dom.prop('#developerMode input[type="checkbox"]', 'checked', - Boolean(cachedRulesetData.developerMode) - ); - if ( cachedRulesetData.isSideloaded ) { - dom.attr('#developerMode', 'hidden', null); - } + const state = Boolean(cachedRulesetData.developerMode) && + cachedRulesetData.disabledFeatures?.includes('develop') !== true; + dom.body.dataset.develop = `${state}`; + dom.prop('#developerMode input[type="checkbox"]', 'checked', state); } } @@ -171,10 +168,9 @@ dom.on('#strictBlockMode input[type="checkbox"]', 'change', ev => { }); dom.on('#developerMode input[type="checkbox"]', 'change', ev => { - sendMessage({ - what: 'setDeveloperMode', - state: ev.target.checked, - }); + const state = ev.target.checked; + sendMessage({ what: 'setDeveloperMode', state }); + dom.body.dataset.develop = `${state}`; }); /******************************************************************************/ @@ -183,9 +179,9 @@ function renderTrustedSites() { const hostnames = cachedRulesetData.trustedSites || []; let text = hostnames.map(hn => punycode.toUnicode(hn)).join('\n'); if ( text !== '' ) { text += '\n'; } - cmView.dispatch({ + cmTrustedSites.dispatch({ changes: { - from: 0, to: cmView.state.doc.length, + from: 0, to: cmTrustedSites.state.doc.length, insert: text }, }); @@ -202,7 +198,7 @@ function changeTrustedSites() { } function getStagedTrustedSites() { - const text = cmView.state.doc.toString(); + const text = cmTrustedSites.state.doc.toString(); return text.split(/\s/).map(hn => { try { return punycode.toASCII( @@ -214,7 +210,7 @@ function getStagedTrustedSites() { }).filter(hn => hn !== ''); } -dom.on(cmView.contentDOM, 'blur', changeTrustedSites); +dom.on(cmTrustedSites.contentDOM, 'blur', changeTrustedSites); self.addEventListener('beforeunload', changeTrustedSites); diff --git a/platform/mv3/extension/lib/codemirror/codemirror-ubol b/platform/mv3/extension/lib/codemirror/codemirror-ubol index 7067d0c2a..1d352d448 160000 --- a/platform/mv3/extension/lib/codemirror/codemirror-ubol +++ b/platform/mv3/extension/lib/codemirror/codemirror-ubol @@ -1 +1 @@ -Subproject commit 7067d0c2a9745bfddceedb46e1428a0b545954bd +Subproject commit 1d352d4489fea6f4aa10a32417eba4abd67db5c9 diff --git a/platform/mv3/safari/ext-compat.js b/platform/mv3/safari/ext-compat.js index 5e89492f7..50c8dd0e4 100644 --- a/platform/mv3/safari/ext-compat.js +++ b/platform/mv3/safari/ext-compat.js @@ -122,7 +122,7 @@ export const dnr = { if ( optionsAfter === undefined ) { return; } return nativeDNR.updateSessionRules(optionsAfter); }, - async setAllowAllRules(id, allowed, notAllowed, reverse) { + async setAllowAllRules(id, allowed, notAllowed, reverse, priority) { const beforeRules = await this.getDynamicRules({ ruleIds: [ id+0 ] }); const addRules = []; if ( reverse || allowed.length || notAllowed.length ) { @@ -130,7 +130,7 @@ export const dnr = { id: id+0, action: { type: 'allow' }, condition: { urlFilter: '*' }, - priority: 1000000, + priority, }; if ( allowed.length ) { rule0.condition.domains = allowed; diff --git a/src/css/common.css b/src/css/common.css index fae4bb5d6..42b196dfd 100644 --- a/src/css/common.css +++ b/src/css/common.css @@ -37,6 +37,7 @@ --default-gap-small: 12px; --default-gap-xsmall: 8px; --default-gap-xxsmall: 4px; + --button-font-size: max(calc(var(--font-size) * 0.875), 14px); } /* Common uBO styles */ @@ -85,7 +86,7 @@ button { color: var(--button-ink); display: inline-flex; fill: var(--button-ink); - font-size: max(calc(var(--font-size) * 0.875), 14px); + font-size: var(--button-font-size); justify-content: center; min-height: 36px; padding: 0 var(--font-size); diff --git a/tools/jsonpath-tool.html b/tools/jsonpath-tool.html index 17a5877dd..2da7f7897 100644 --- a/tools/jsonpath-tool.html +++ b/tools/jsonpath-tool.html @@ -1,4 +1,13 @@ + @@ -43,8 +52,39 @@ main {

uBO-flavored JSONPath tool

- - + +
 
@@ -57,6 +97,18 @@ main { import { JSONPath } from '../src/js/jsonpath.js'; + function readJSON() { + const textarea = document.querySelector('#json-data'); + try { + jsonData = JSON.parse(textarea.value); + } catch { + jsonData = {}; + } + if ( typeof jsonData !== 'object' || jsonData === null ) { + jsonData = {}; + } + } + function formatResult(a) { if ( a === undefined ) { return 'undefined'; } if ( jsonp.valid === false ) { return 'bad expression'; } @@ -85,13 +137,7 @@ main { { const textarea = document.querySelector('#json-data'); textarea.addEventListener('input', ( ) => { - try { - jsonData = JSON.parse(textarea.value); - } catch { - } - if ( typeof jsonData !== 'object' || jsonData === null ) { - jsonData = {}; - } + readJSON(); process(); }); } @@ -102,6 +148,9 @@ main { process(); }); } + + readJSON(); + process(); diff --git a/tools/make-mv3.sh b/tools/make-mv3.sh index 8791487b8..cb2f19c56 100755 --- a/tools/make-mv3.sh +++ b/tools/make-mv3.sh @@ -107,6 +107,8 @@ cp platform/mv3/extension/lib/codemirror/* \ "$UBOL_DIR"/lib/codemirror/ 2>/dev/null || : cp platform/mv3/extension/lib/codemirror/codemirror-ubol/dist/cm6.bundle.ubol.min.js \ "$UBOL_DIR"/lib/codemirror/ +cp platform/mv3/extension/lib/codemirror/codemirror-ubol/LICENSE \ + "$UBOL_DIR"/lib/codemirror/ echo "*** uBOLite.mv3: Generating rulesets" UBOL_BUILD_DIR=$(mktemp -d)