mirror of
https://github.com/gorhill/uBlock.git
synced 2026-03-11 09:04:36 +00:00
[mv3] Add support for custom DNR rules
This feature is hidden behind the "Developer mode" setting in the dashboard. When "Developer mode" is enabled, a tab named "Develop" will become available in the dashboard. This tab is meant to contain tools for technical users. At the moment, the "Develop" pane allows to create custom DNR rules through a (CodeMirror-based) editor. For the sake of convenience, the DNR rule must be entered in YAML-like format. The format is not really full compliant YAML, just YAML-like, and very strict in order to ensure the parser stays simple enough. Lines starting with `#` are comments and will be ignored by the parser. Any line which do not match the parser's expectation will be marked as invalid, and the whole DNR rule containing such invalid lines will be discarded. There must not be empty lines inside a rule definition. Each DNR rule must be separated with a `---` line, which is known as a YAML document separator. String values must not be quoted, otherwise the quotes will be considered part of the value. There is one exception: `''` will be parsed as "an empty string". The editor will attempt to auto-complete known DNR keywords. That feature will improve over time. Though the parser will identify some errors, not all invalid DNR rules are currently identified by the parser, and these will be reported when the rules are registered through the DNR API. Better identifying invalid DNR rules at edit time will improve over time. The editor will report `regexFilter` values which are not supported by the DNR engine on the current platform. The editor reacts to instances of `regexFilter: ...` to report whether a regex value is supported. This means you can test for a regex value by using `# regexFilter: ...` so that you do not have to create an actual DNR rules just for the sake of testing. Custom DNR rules can be exported into a JSON file (a format known by the DNR API as a "static ruleset"). JSON-based ruleset can be imported, the content will be converted to YAML-like syntax. The editor will attempt to convert to YAML pasted content which can be JSON-parsed. It's possible to paste partially or wholly JSON-based rulesets. When disabling "Developer mode", all custom DNR rules will be unregistered from the DNR API. The DNR rules content will be left intact in such case. Existing DNR rules will be registered into the DNR API when re-enabling "Developer mode". Administrators can prevent "Developer mode" from being enabled by adding `develop` token to `disabledFeatures` setting. Related discussion: https://github.com/uBlockOrigin/uBOL-home/discussions/323 The main motivation is to give list maintainers a tool to assist with resolving filter issues. Custom DNR rules can assist in crafting and validating filters meant to work with uBOL. A secondary motivation is to provide technical users the ability to further customize their content blocker. More conveniences will be added over time, this is a first version.
This commit is contained in:
parent
4e2585545b
commit
9339a75952
89 changed files with 3700 additions and 74 deletions
19
Makefile
19
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
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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æbertilstand",
|
||||
"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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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": "Elemintwiskermodus 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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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": "Elementwissermodus 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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. <b>Do not add content from untrusted sources.</b>",
|
||||
"description": "Short description of the DNR rules editor pane"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
112
platform/mv3/extension/css/develop.css
Normal file
112
platform/mv3/extension/css/develop.css
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -13,18 +13,20 @@
|
|||
<link rel="stylesheet" href="css/dashboard-common.css">
|
||||
<link rel="stylesheet" href="css/filtering-mode.css">
|
||||
<link rel="stylesheet" href="css/settings.css">
|
||||
<link rel="stylesheet" href="css/develop.css">
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="img/icon_64.png"/>
|
||||
<link rel="icon" type="image/png" href="img/icon_64.png"/>
|
||||
</head>
|
||||
|
||||
<body data-pane="settings" class="loading">
|
||||
<!-- -------- -->
|
||||
<div id="dashboard-nav">
|
||||
<nav id="dashboard-nav">
|
||||
<span class="logo"><img data-i18n-title="extName" src="img/ublock.svg" alt="uBO Lite"></span><!--
|
||||
--><button class="tabButton" type="button" data-pane="settings" data-i18n="settingsPageName" tabindex="0"></button><!--
|
||||
--><button class="tabButton" type="button" data-pane="rulesets" data-i18n="aboutFilterLists" tabindex="0"></button><!--
|
||||
--><button class="tabButton" type="button" data-pane="develop" tabindex="0">Develop</button><!--
|
||||
--><button class="tabButton" type="button" data-pane="about" data-i18n="aboutPageName" tabindex="0"></button>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- -------- -->
|
||||
<section data-pane="settings">
|
||||
<div>
|
||||
|
|
@ -85,7 +87,7 @@
|
|||
</label>
|
||||
</div>
|
||||
<p><label id="strictBlockMode" data-i18n="enableStrictBlockLabel"><span class="input checkbox"><input type="checkbox"><svg viewBox="0 0 24 24"><path d="M1.73,12.91 8.1,19.28 22.79,4.59"/></svg></span>_</label><legend data-i18n="enableStrictBlockLegend"></legend>
|
||||
<p id="developerMode" hidden><label><span class="input checkbox"><input type="checkbox"><svg viewBox="0 0 24 24"><path d="M1.73,12.91 8.1,19.28 22.79,4.59"/></svg></span>Developer mode</label>
|
||||
<p id="developerMode"><label data-i18n="developerModeLabel"><span class="input checkbox"><input type="checkbox"><svg viewBox="0 0 24 24"><path d="M1.73,12.91 8.1,19.28 22.79,4.59"/></svg></span>_</label><legend data-i18n="developerModeLegend"></legend>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
@ -103,6 +105,20 @@
|
|||
<div id="lists"></div>
|
||||
</section>
|
||||
<!-- -------- -->
|
||||
<section data-pane="develop">
|
||||
<div>
|
||||
<p>
|
||||
<button id="dnrRulesApply" class="preferred iconified" type="button" disabled><span class="fa-icon">save</span><span data-i18n="saveButton">_</span><span class="hover"></span></button>
|
||||
<button id="dnrRulesRevert" class="iconified" type="button" disabled><span class="fa-icon">undo</span><span data-i18n="revertButton">_</span><span class="hover"></span></button>
|
||||
 
|
||||
<button id="dnrRulesImport" class="iconified" type="button"><span class="fa-icon">download-alt</span><span data-i18n="importAndAppendButton">_</span><span class="hover"></span></button>
|
||||
<button id="dnrRulesExport" class="iconified" type="button"><span class="fa-icon">upload-alt</span><span data-i18n="exportButton">_</span><span class="hover"></span></button><input type="file" accept="json/application">
|
||||
</p>
|
||||
<p data-i18n="dnrRulesSummary"></p>
|
||||
<div id="cm-dnrRules"></div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- -------- -->
|
||||
<section data-pane="about">
|
||||
<div class="body">
|
||||
<div id="aboutNameVer" class="li"></div>
|
||||
|
|
@ -125,6 +141,7 @@
|
|||
<div class="li"><span><a href="https://fontawesome.com/" target="_blank">FontAwesome font family</a> by <a href="https://github.com/davegandy">Dave Gandy</a></span></div>
|
||||
<div class="li"><span><a href="https://github.com/mathiasbynens/punycode.js" target="_blank">Punycode.js</a> by <a href="https://github.com/mathiasbynens">Mathias Bynens</a></span></div>
|
||||
<div class="li"><span><a href="https://flagpedia.net/" target="_blank">Flags of the World</a> by <a href="https://www.davidkrmela.com/">David Krmela</a></span></div>
|
||||
<div class="li"><span><a href="https://codemirror.net/" target="_blank">CodeMirror 6</a> by <a href="https://github.com/marijnh">Marijn Haverbeke</a></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -155,12 +172,28 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<template class="summary-panel">
|
||||
<div class="info-panel summary-panel">
|
||||
<div class="info"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template class="feedback-panel">
|
||||
<div class="info-panel feedback-panel">
|
||||
<div class="info"></div>
|
||||
<div class="close"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template class="badmark-tooltip">
|
||||
<div class="badmark-tooltip">
|
||||
</div>
|
||||
</template>
|
||||
<script src="lib/codemirror/cm6.bundle.ubol.min.js"></script>
|
||||
<script src="js/theme.js" type="module"></script>
|
||||
<script src="js/fa-icons.js" type="module"></script>
|
||||
<script src="js/i18n.js" type="module"></script>
|
||||
<script src="js/dashboard.js" type="module"></script>
|
||||
<script src="js/settings.js" type="module"></script>
|
||||
<script src="js/develop.js" type="module"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
|||
687
platform/mv3/extension/js/develop.js
Normal file
687
platform/mv3/extension/js/develop.js
Normal file
|
|
@ -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' });
|
||||
});
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
607
platform/mv3/extension/js/dnr-parser.js
Normal file
607
platform/mv3/extension/js/dnr-parser.js
Normal file
|
|
@ -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');
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 7067d0c2a9745bfddceedb46e1428a0b545954bd
|
||||
Subproject commit 1d352d4489fea6f4aa10a32417eba4abd67db5c9
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
Requires a local server in root of uBlock repo:
|
||||
python3 -m http.server
|
||||
|
||||
Then load the following URL in the browser:
|
||||
http://localhost:8000/tools/jsonpath-tool.html
|
||||
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
|
@ -43,8 +52,39 @@ main {
|
|||
<body>
|
||||
<h2>uBO-flavored JSONPath tool</h2>
|
||||
<main>
|
||||
<textarea id="json-data" placeholder="JSON data" spellcheck="false"></textarea>
|
||||
<input id="jsonpath-input" placeholder="JSON path expression" spellcheck="false" />
|
||||
<textarea id="json-data" placeholder="JSON data" spellcheck="false">{
|
||||
"store": {
|
||||
"book": [
|
||||
{ "category": "reference",
|
||||
"author": "Nigel Rees",
|
||||
"title": "Sayings of the Century",
|
||||
"price": 8.95
|
||||
},
|
||||
{ "category": "fiction",
|
||||
"author": "Evelyn Waugh",
|
||||
"title": "Sword of Honour",
|
||||
"price": 12.99
|
||||
},
|
||||
{ "category": "fiction",
|
||||
"author": "Herman Melville",
|
||||
"title": "Moby Dick",
|
||||
"isbn": "0-553-21311-3",
|
||||
"price": 8.99
|
||||
},
|
||||
{ "category": "fiction",
|
||||
"author": "J. R. R. Tolkien",
|
||||
"title": "The Lord of the Rings",
|
||||
"isbn": "0-395-19395-8",
|
||||
"price": 22.99
|
||||
}
|
||||
],
|
||||
"bicycle": {
|
||||
"color": "red",
|
||||
"price": 19.95
|
||||
}
|
||||
}
|
||||
}</textarea>
|
||||
<input id="jsonpath-input" placeholder="JSON path expression" spellcheck="false" value="$..book[?@.price<10]" />
|
||||
<div id="jsonpath-result"> </div>
|
||||
</main>
|
||||
|
||||
|
|
@ -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();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue