diff --git a/platform/chromium/managed_storage.json b/platform/chromium/managed_storage.json
index 71cefe284..cca1122c8 100644
--- a/platform/chromium/managed_storage.json
+++ b/platform/chromium/managed_storage.json
@@ -7,26 +7,24 @@
"description": "All entries present will overwrite local settings.",
"type": "string"
},
- "toSet": {
- "title": "Settings to overwrite at launch time",
- "type": "object",
- "properties": {
- "hiddenSettings": {
- "title": "A list of [name,value] pairs to populate hidden settings",
- "type": "array",
- "items": {
- "title": "A [name,value] pair",
- "type": "array",
- "items": { "type": "string" }
- }
- },
- "trustedSiteDirectives": {
- "title": "A list of trusted-site directives",
- "type": "array",
- "items": { "type": "string" }
- }
+ "advancedSettings": {
+ "title": "A list of [name,value] pairs to populate advanced settings",
+ "type": "array",
+ "items": {
+ "title": "A [name,value] pair",
+ "type": "array",
+ "items": { "type": "string" }
}
},
+ "disableDashboard": {
+ "title": "Set to true to prevent access to configuration options",
+ "type": "boolean"
+ },
+ "disabledPopupPanelParts": {
+ "title": "An array of strings used to remove parts of the popup panel",
+ "type": "array",
+ "items": { "type": "string" }
+ },
"toAdd": {
"title": "Settings to add at launch time",
"type": "object",
@@ -38,6 +36,17 @@
"items": { "type": "string" }
}
}
+ },
+ "toOverwrite": {
+ "title": "Settings to overwrite at launch time",
+ "type": "object",
+ "properties": {
+ "trustedSiteDirectives": {
+ "title": "A list of trusted-site directives",
+ "type": "array",
+ "items": { "type": "string" }
+ }
+ }
}
}
}
diff --git a/src/css/dashboard.css b/src/css/dashboard.css
index a6933af6c..fa17451a7 100644
--- a/src/css/dashboard.css
+++ b/src/css/dashboard.css
@@ -72,6 +72,12 @@ iframe {
body:not(.canUpdateShortcuts) .tabButton[data-pane="shortcuts.html"] {
display: none;
}
+body .tabButton[data-pane="no-dashboard.html"] {
+ display: none;
+ }
+body.noDashboard #dashboard-nav {
+ display: none;
+ }
/* high dpi devices */
:root.hidpi .tabButton {
diff --git a/src/dashboard.html b/src/dashboard.html
index 0668cdf12..53ee2dae9 100644
--- a/src/dashboard.html
+++ b/src/dashboard.html
@@ -19,7 +19,8 @@
-->
+ -->
diff --git a/src/js/background.js b/src/js/background.js
index f23ec0c4c..735e8af1e 100644
--- a/src/js/background.js
+++ b/src/js/background.js
@@ -111,6 +111,8 @@ const µBlock = (( ) => { // jshint ignore:line
hiddenSettingsAdmin: {},
hiddenSettings: Object.assign({}, hiddenSettingsDefault),
+ noDashboard: false,
+
// Features detection.
privacySettingsSupported: vAPI.browserSettings instanceof Object,
cloudStorageSupported: vAPI.cloud instanceof Object,
diff --git a/src/js/dashboard.js b/src/js/dashboard.js
index 19f7a94a3..46dcadbef 100644
--- a/src/js/dashboard.js
+++ b/src/js/dashboard.js
@@ -84,7 +84,9 @@ const loadDashboardPanel = function(pane, first) {
tabButton.classList.add('selected');
tabButton.scrollIntoView();
uDom.nodeFromId('iframe').setAttribute('src', pane);
- vAPI.localStorage.setItem('dashboardLastVisitedPane', pane);
+ if ( pane !== 'no-dashboard.html' ) {
+ vAPI.localStorage.setItem('dashboardLastVisitedPane', pane);
+ }
};
if ( first ) {
return loadPane();
@@ -104,25 +106,48 @@ const onTabClickHandler = function(ev) {
loadDashboardPanel(ev.target.getAttribute('data-pane'));
};
-// https://github.com/uBlockOrigin/uBlock-issues/issues/106
-vAPI.messaging.send('dashboard', {
- what: 'canUpdateShortcuts',
-}).then(response => {
- document.body.classList.toggle('canUpdateShortcuts', response === true);
-});
+if ( self.location.hash.slice(1) === 'no-dashboard.html' ) {
+ document.body.classList.add('noDashboard');
+}
-vAPI.localStorage.getItemAsync('dashboardLastVisitedPane').then(value => {
- loadDashboardPanel(value !== null ? value : 'settings.html', true);
+(async ( ) => {
+ const results = await Promise.all([
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/106
+ vAPI.messaging.send('dashboard', { what: 'dashboardConfig' }),
+ vAPI.localStorage.getItemAsync('dashboardLastVisitedPane'),
+ ]);
- uDom('.tabButton').on('click', onTabClickHandler);
+ {
+ const details = results[0];
+ document.body.classList.toggle(
+ 'canUpdateShortcuts',
+ details.canUpdateShortcuts === true
+ );
+ if ( details.noDashboard ) {
+ self.location.hash = '#no-dashboard.html';
+ document.body.classList.add('noDashboard');
+ } else if ( self.location.hash === '#no-dashboard.html' ) {
+ self.location.hash = '';
+ }
+ }
- // https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
- window.addEventListener('beforeunload', ( ) => {
- if ( discardUnsavedData(true) ) { return; }
- event.preventDefault();
- event.returnValue = '';
- });
-});
+ {
+ let pane = results[1];
+ if ( self.location.hash !== '' ) {
+ pane = self.location.hash.slice(1) || null;
+ }
+ loadDashboardPanel(pane !== null ? pane : 'settings.html', true);
+
+ uDom('.tabButton').on('click', onTabClickHandler);
+
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
+ window.addEventListener('beforeunload', ( ) => {
+ if ( discardUnsavedData(true) ) { return; }
+ event.preventDefault();
+ event.returnValue = '';
+ });
+ }
+})();
/******************************************************************************/
diff --git a/src/js/messaging.js b/src/js/messaging.js
index 693fa56fa..e107ace75 100644
--- a/src/js/messaging.js
+++ b/src/js/messaging.js
@@ -1214,8 +1214,11 @@ const onMessage = function(request, sender, callback) {
let response;
switch ( request.what ) {
- case 'canUpdateShortcuts':
- response = µb.canUpdateShortcuts;
+ case 'dashboardConfig':
+ response = {
+ canUpdateShortcuts: µb.canUpdateShortcuts,
+ noDashboard: µb.noDashboard,
+ };
break;
case 'getAutoCompleteDetails':
diff --git a/src/js/storage.js b/src/js/storage.js
index 02a03c371..2b70d42fa 100644
--- a/src/js/storage.js
+++ b/src/js/storage.js
@@ -97,23 +97,49 @@
const hsUser = this.hiddenSettings;
const results = await Promise.all([
- vAPI.adminStorage.get('toSet'),
+ vAPI.adminStorage.get([
+ 'advancedSettings',
+ 'disableDashboard',
+ 'disabledPopupPanelParts',
+ ]),
vAPI.storage.get('hiddenSettings'),
]);
- if (
- results[0] instanceof Object &&
- Array.isArray(results[0].hiddenSettings)
- ) {
- for ( const entry of results[0].hiddenSettings ) {
- if ( entry.length < 1 ) { continue; }
- const name = entry[0];
- if ( hsDefault.hasOwnProperty(name) === false ) { continue; }
- const value = entry.length < 2
- ? hsDefault[name]
- : this.hiddenSettingValueFromString(name, entry[1]);
- if ( value === undefined ) { continue; }
- hsDefault[name] = hsAdmin[name] = hsUser[name] = value;
+ if ( results[0] instanceof Object ) {
+ const {
+ advancedSettings,
+ disableDashboard,
+ disabledPopupPanelParts
+ } = results[0];
+ if ( Array.isArray(advancedSettings) ) {
+ for ( const entry of advancedSettings ) {
+ if ( entry.length < 1 ) { continue; }
+ const name = entry[0];
+ if ( hsDefault.hasOwnProperty(name) === false ) { continue; }
+ const value = entry.length < 2
+ ? hsDefault[name]
+ : this.hiddenSettingValueFromString(name, entry[1]);
+ if ( value === undefined ) { continue; }
+ hsDefault[name] = hsAdmin[name] = hsUser[name] = value;
+ }
+ }
+ µBlock.noDashboard = disableDashboard === true;
+ if ( Array.isArray(disabledPopupPanelParts) ) {
+ const partNameToBit = new Map([
+ [ 'globalStats', 0b00010 ],
+ [ 'basicTools', 0b00100 ],
+ [ 'extraTools', 0b01000 ],
+ [ 'firewall', 0b10000 ],
+ ]);
+ let bits = hsDefault.popupPanelDisabledSections;
+ for ( const part of disabledPopupPanelParts ) {
+ const bit = partNameToBit.get(part);
+ if ( bit === undefined ) { continue; }
+ bits |= bit;
+ }
+ hsDefault.popupPanelDisabledSections =
+ hsAdmin.popupPanelDisabledSections =
+ hsUser.popupPanelDisabledSections = bits;
}
}
@@ -1260,15 +1286,15 @@ self.addEventListener('hiddenSettingsChanged', ( ) => {
// values are left to the user's choice.
µBlock.restoreAdminSettings = async function() {
- let toSet = {};
+ let toOverwrite = {};
let data;
try {
const store = await vAPI.adminStorage.get([
'adminSettings',
- 'toSet',
+ 'toOverwrite',
]) || {};
- if ( store.toSet instanceof Object ) {
- toSet = store.toSet;
+ if ( store.toOverwrite instanceof Object ) {
+ toOverwrite = store.toOverwrite;
}
const json = store.adminSettings;
if ( typeof json === 'string' && json !== '' ) {
@@ -1315,9 +1341,9 @@ self.addEventListener('hiddenSettingsChanged', ( ) => {
binNotEmpty = true;
}
- if ( Array.isArray(toSet.trustedSiteDirectives) ) {
- µBlock.netWhitelistDefault = toSet.trustedSiteDirectives.slice();
- bin.netWhitelist = toSet.trustedSiteDirectives.slice();
+ if ( Array.isArray(toOverwrite.trustedSiteDirectives) ) {
+ µBlock.netWhitelistDefault = toOverwrite.trustedSiteDirectives.slice();
+ bin.netWhitelist = toOverwrite.trustedSiteDirectives.slice();
binNotEmpty = true;
} else if ( Array.isArray(data.whitelist) ) {
bin.netWhitelist = data.whitelist;