mirror of https://github.com/gorhill/uBlock.git
[mv3] Add ability for admins to disable features
New managed setting: "disabledFeatures": { "title": "User interface features to disable", "description": "A list of tokens, each of which correspond to a user interface feature to disable.", "type": "array", "items": { "type": "string" } } Supported tokens: - `dashboard`: Prevent access to all dashboard settings - `filteringMode`: Prevent changes to the default filtering mode, or the current filtering mode of any site Related feedback: https://github.com/uBlockOrigin/uBOL-home/discussions/35#discussioncomment-11326086
This commit is contained in:
parent
4979aa51f5
commit
346b5ded7c
|
@ -13,7 +13,7 @@
|
||||||
border-radius: 30% 15% / 15% 30%;
|
border-radius: 30% 15% / 15% 30%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 25%;
|
width: calc(25% + 2px);
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,12 +39,18 @@
|
||||||
|
|
||||||
.filteringModeSlider span[data-level] {
|
.filteringModeSlider span[data-level] {
|
||||||
background-color: var(--accent-surface-1);
|
background-color: var(--accent-surface-1);
|
||||||
|
border: 1px solid var(--accent-surface-1);
|
||||||
|
box-sizing: border-box;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
height: 30%;
|
height: 30%;
|
||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filteringModeSlider span[data-level]:first-of-type {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.filteringModeSlider.moving span[data-level] {
|
.filteringModeSlider.moving span[data-level] {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
@ -53,13 +59,13 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
.filteringModeSlider[data-level="1"] .filteringModeButton {
|
.filteringModeSlider[data-level="1"] .filteringModeButton {
|
||||||
left: 25%;
|
left: calc(25% - 1px);
|
||||||
}
|
}
|
||||||
.filteringModeSlider[data-level="2"] .filteringModeButton {
|
.filteringModeSlider[data-level="2"] .filteringModeButton {
|
||||||
left: 50%;
|
left: calc(50% - 1px);
|
||||||
}
|
}
|
||||||
.filteringModeSlider[data-level="3"] .filteringModeButton {
|
.filteringModeSlider[data-level="3"] .filteringModeButton {
|
||||||
left: 75%;
|
left: calc(75% - 1px);
|
||||||
}
|
}
|
||||||
[dir="rtl"] .filteringModeSlider[data-level="0"] .filteringModeButton {
|
[dir="rtl"] .filteringModeSlider[data-level="0"] .filteringModeButton {
|
||||||
left: 75%;
|
left: 75%;
|
||||||
|
@ -77,14 +83,17 @@
|
||||||
|
|
||||||
.filteringModeSlider[data-level="0"] span[data-level] {
|
.filteringModeSlider[data-level="0"] span[data-level] {
|
||||||
background-color: var(--surface-2);
|
background-color: var(--surface-2);
|
||||||
|
border-color: var(--surface-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filteringModeSlider[data-level="1"] span[data-level]:nth-of-type(1) ~ span[data-level] {
|
.filteringModeSlider[data-level="1"] span[data-level]:nth-of-type(1) ~ span[data-level] {
|
||||||
background-color: var(--surface-2);
|
background-color: var(--surface-2);
|
||||||
|
border-color: var(--surface-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filteringModeSlider[data-level="2"] span[data-level]:nth-of-type(2) ~ span[data-level] {
|
.filteringModeSlider[data-level="2"] span[data-level]:nth-of-type(2) ~ span[data-level] {
|
||||||
background-color: var(--surface-2);
|
background-color: var(--surface-2);
|
||||||
|
border-color: var(--surface-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filteringModeSlider[data-level]:not(.moving) span[data-level]:hover {
|
.filteringModeSlider[data-level]:not(.moving) span[data-level]:hover {
|
||||||
|
|
|
@ -63,6 +63,13 @@ hr {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body[data-forbid~="filteringMode"] .filteringModeSlider {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
body[data-forbid~="dashboard"] #gotoDashboard {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#filteringModeText {
|
#filteringModeText {
|
||||||
color: var(--ink-3);
|
color: var(--ink-3);
|
||||||
margin: var(--default-gap-small);
|
margin: var(--default-gap-small);
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
body.loading {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
body .firstRun {
|
body .firstRun {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +16,17 @@ p {
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body[data-forbid~="dashboard"] #dashboard-nav [data-pane="settings"],
|
||||||
|
body[data-forbid~="dashboard"] section[data-pane="settings"],
|
||||||
|
body[data-forbid~="dashboard"] #dashboard-nav [data-pane="rulesets"],
|
||||||
|
body[data-forbid~="dashboard"] section[data-pane="rulesets"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
body[data-forbid~="filteringMode"] section[data-pane="settings"] > div:has(> h3[data-i18n="defaultFilteringModeSectionLabel"]),
|
||||||
|
body[data-forbid~="filteringMode"] section[data-pane="settings"] > div:has(> h3[data-i18n="filteringMode0Name"]) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#showBlockedCount:has(input[type="checkbox"][disabled]) {
|
#showBlockedCount:has(input[type="checkbox"][disabled]) {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<link rel="shortcut icon" type="image/png" href="img/icon_64.png"/>
|
<link rel="shortcut icon" type="image/png" href="img/icon_64.png"/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body data-pane="settings">
|
<body data-pane="settings" class="loading">
|
||||||
<!-- -------- -->
|
<!-- -------- -->
|
||||||
<div id="dashboard-nav">
|
<div id="dashboard-nav">
|
||||||
<span class="logo"><img data-i18n-title="extName" src="img/ublock.svg" alt="uBO Lite"></span><!--
|
<span class="logo"><img data-i18n-title="extName" src="img/ublock.svg" alt="uBO Lite"></span><!--
|
||||||
|
|
|
@ -40,6 +40,11 @@ import {
|
||||||
windows,
|
windows,
|
||||||
} from './ext.js';
|
} from './ext.js';
|
||||||
|
|
||||||
|
import {
|
||||||
|
adminReadEx,
|
||||||
|
getAdminRulesets,
|
||||||
|
} from './admin.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
enableRulesets,
|
enableRulesets,
|
||||||
getEnabledRulesetsDetails,
|
getEnabledRulesetsDetails,
|
||||||
|
@ -62,7 +67,6 @@ import {
|
||||||
} from './config.js';
|
} from './config.js';
|
||||||
|
|
||||||
import { broadcastMessage } from './utils.js';
|
import { broadcastMessage } from './utils.js';
|
||||||
import { getAdminRulesets } from './admin.js';
|
|
||||||
import { registerInjectables } from './scripting-manager.js';
|
import { registerInjectables } from './scripting-manager.js';
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -189,6 +193,7 @@ function onMessage(request, sender, callback) {
|
||||||
getRulesetDetails(),
|
getRulesetDetails(),
|
||||||
dnr.getEnabledRulesets(),
|
dnr.getEnabledRulesets(),
|
||||||
getAdminRulesets(),
|
getAdminRulesets(),
|
||||||
|
adminReadEx('disabledFeatures'),
|
||||||
]).then(results => {
|
]).then(results => {
|
||||||
const [
|
const [
|
||||||
defaultFilteringMode,
|
defaultFilteringMode,
|
||||||
|
@ -196,6 +201,7 @@ function onMessage(request, sender, callback) {
|
||||||
rulesetDetails,
|
rulesetDetails,
|
||||||
enabledRulesets,
|
enabledRulesets,
|
||||||
adminRulesets,
|
adminRulesets,
|
||||||
|
disabledFeatures,
|
||||||
] = results;
|
] = results;
|
||||||
callback({
|
callback({
|
||||||
defaultFilteringMode,
|
defaultFilteringMode,
|
||||||
|
@ -210,6 +216,7 @@ function onMessage(request, sender, callback) {
|
||||||
firstRun: process.firstRun,
|
firstRun: process.firstRun,
|
||||||
isSideloaded,
|
isSideloaded,
|
||||||
developerMode: rulesetConfig.developerMode,
|
developerMode: rulesetConfig.developerMode,
|
||||||
|
disabledFeatures,
|
||||||
});
|
});
|
||||||
process.firstRun = false;
|
process.firstRun = false;
|
||||||
});
|
});
|
||||||
|
@ -251,6 +258,7 @@ function onMessage(request, sender, callback) {
|
||||||
hasOmnipotence(),
|
hasOmnipotence(),
|
||||||
hasGreatPowers(request.origin),
|
hasGreatPowers(request.origin),
|
||||||
getEnabledRulesetsDetails(),
|
getEnabledRulesetsDetails(),
|
||||||
|
adminReadEx('disabledFeatures'),
|
||||||
]).then(results => {
|
]).then(results => {
|
||||||
callback({
|
callback({
|
||||||
level: results[0],
|
level: results[0],
|
||||||
|
@ -260,6 +268,7 @@ function onMessage(request, sender, callback) {
|
||||||
rulesetDetails: results[3],
|
rulesetDetails: results[3],
|
||||||
isSideloaded,
|
isSideloaded,
|
||||||
developerMode: rulesetConfig.developerMode,
|
developerMode: rulesetConfig.developerMode,
|
||||||
|
disabledFeatures: results[4],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
@ -416,6 +425,11 @@ async function start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleDeveloperMode(rulesetConfig.developerMode);
|
toggleDeveloperMode(rulesetConfig.developerMode);
|
||||||
|
|
||||||
|
// Required to ensure the up to date property is available when needed
|
||||||
|
if ( process.wakeupRun === false ) {
|
||||||
|
adminReadEx('disabledFeatures');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/uBlockOrigin/uBOL-home/issues/199
|
// https://github.com/uBlockOrigin/uBOL-home/issues/199
|
||||||
|
|
|
@ -44,6 +44,14 @@ function normalizedHostname(hn) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
function renderAdminRules() {
|
||||||
|
const { disabledFeatures: forbid = [] } = popupPanelData;
|
||||||
|
if ( forbid.length === 0 ) { return; }
|
||||||
|
dom.body.dataset.forbid = forbid.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
const BLOCKING_MODE_MAX = 3;
|
const BLOCKING_MODE_MAX = 3;
|
||||||
|
|
||||||
function setFilteringMode(level, commit = false) {
|
function setFilteringMode(level, commit = false) {
|
||||||
|
@ -325,6 +333,8 @@ async function init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderAdminRules();
|
||||||
|
|
||||||
setFilteringMode(popupPanelData.level);
|
setFilteringMode(popupPanelData.level);
|
||||||
|
|
||||||
dom.text('#hostname', punycode.toUnicode(tabHostname));
|
dom.text('#hostname', punycode.toUnicode(tabHostname));
|
||||||
|
|
|
@ -36,6 +36,17 @@ function hashFromIterable(iter) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
function renderAdminRules() {
|
||||||
|
const { disabledFeatures: forbid = [] } = cachedRulesetData;
|
||||||
|
if ( forbid.length === 0 ) { return; }
|
||||||
|
dom.body.dataset.forbid = forbid.join(' ');
|
||||||
|
if ( forbid.includes('dashboard') ) {
|
||||||
|
dom.body.dataset.pane = 'about';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
function renderWidgets() {
|
function renderWidgets() {
|
||||||
if ( cachedRulesetData.firstRun ) {
|
if ( cachedRulesetData.firstRun ) {
|
||||||
dom.cl.add(dom.body, 'firstRun');
|
dom.cl.add(dom.body, 'firstRun');
|
||||||
|
@ -256,8 +267,10 @@ sendMessage({
|
||||||
if ( !data ) { return; }
|
if ( !data ) { return; }
|
||||||
cachedRulesetData = data;
|
cachedRulesetData = data;
|
||||||
try {
|
try {
|
||||||
|
renderAdminRules();
|
||||||
renderFilterLists(cachedRulesetData);
|
renderFilterLists(cachedRulesetData);
|
||||||
renderWidgets();
|
renderWidgets();
|
||||||
|
dom.cl.remove(dom.body, 'loading');
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
}
|
}
|
||||||
listen();
|
listen();
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
"description": "Prefix a ruleset id with '+' to add, or '-' to remove. Use '-*' to disable all non-default lists.",
|
"description": "Prefix a ruleset id with '+' to add, or '-' to remove. Use '-*' to disable all non-default lists.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": { "type": "string" }
|
"items": { "type": "string" }
|
||||||
|
},
|
||||||
|
"disabledFeatures": {
|
||||||
|
"title": "User interface features to disable",
|
||||||
|
"description": "A list of tokens, each of which correspond to a user interface feature to disable.",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "type": "string" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<span></span>
|
<span></span>
|
||||||
<span id="showMatchedRules" class="fa-icon tool" tabindex="0" title="Show matched rules">list-alt<span class="caption">Show matched rules</span></span>
|
<span id="showMatchedRules" class="fa-icon tool" tabindex="0" title="Show matched rules">list-alt<span class="caption">Show matched rules</span></span>
|
||||||
<span id="reportFilterIssue" class="fa-icon tool enabled" data-i18n-title="popupTipReport">comment-alt<span class="caption" data-i18n="popupTipReport"></span></span>
|
<span id="reportFilterIssue" class="fa-icon tool enabled" data-i18n-title="popupTipReport">comment-alt<span class="caption" data-i18n="popupTipReport"></span></span>
|
||||||
<span class="fa-icon tool enabled" tabindex="0" data-i18n-title="popupTipDashboard">cogs<span class="caption" data-i18n="popupTipDashboard"></span></span>
|
<span id="gotoDashboard" class="fa-icon tool enabled" tabindex="0" data-i18n-title="popupTipDashboard">cogs<span class="caption" data-i18n="popupTipDashboard"></span></span>
|
||||||
</div>
|
</div>
|
||||||
<!-- -------- -->
|
<!-- -------- -->
|
||||||
<div id="rulesetStats" data-section="a">
|
<div id="rulesetStats" data-section="a">
|
||||||
|
|
Loading…
Reference in New Issue