Improve "Whitelist pane"; remove now useless built-in switch rule

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/214

Built-in whitelist directives are now rendered differently
than user-defined whitelist directives. Also, removing a
built-in whitelist directive will only cause that directive
to be commented out, so that users do not have to remember
built-in directives should they want to bring them back.

Related issue:
 https://github.com/uBlockOrigin/uBlock-issues/issues/494

The built-in per-site switch rule
`no-scripting: behind-the-scene false` has been removed,
it should not ever be needed since there will always be a
valid root context for main- and sub-frames.
This commit is contained in:
Raymond Hill 2019-05-18 14:20:05 -04:00
parent de41c1bf53
commit f7bbc80717
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
7 changed files with 125 additions and 81 deletions

View file

@ -10,3 +10,9 @@ body {
text-align: left; text-align: left;
width: 100%; width: 100%;
} }
.codeMirrorContainer .cm-builtin {
color: #00F;
}
.codeMirrorContainer .cm-comment.cm-builtin {
color: #88F;
}

View file

@ -57,16 +57,6 @@ const µBlock = (function() { // jshint ignore:line
userResourcesLocation: 'unset' userResourcesLocation: 'unset'
}; };
const whitelistDefault = [
'about-scheme',
'chrome-extension-scheme',
'chrome-scheme',
'moz-extension-scheme',
'opera-scheme',
'vivaldi-scheme',
'wyciwyg-scheme', // Firefox's "What-You-Cache-Is-What-You-Get"
];
return { return {
firstInstall: false, firstInstall: false,
@ -126,7 +116,15 @@ const µBlock = (function() { // jshint ignore:line
// Whitelist directives need to be loaded once the PSL is available // Whitelist directives need to be loaded once the PSL is available
netWhitelist: {}, netWhitelist: {},
netWhitelistModifyTime: 0, netWhitelistModifyTime: 0,
netWhitelistDefault: whitelistDefault.join('\n'), netWhitelistDefault: [
'about-scheme',
'chrome-extension-scheme',
'chrome-scheme',
'moz-extension-scheme',
'opera-scheme',
'vivaldi-scheme',
'wyciwyg-scheme', // Firefox's "What-You-Cache-Is-What-You-Get"
],
localSettings: { localSettings: {
blockedRequestCount: 0, blockedRequestCount: 0,

View file

@ -91,7 +91,7 @@
µBlock.normalizePageURL(0, details.documentUrl) µBlock.normalizePageURL(0, details.documentUrl)
); );
this.setDocOrigin(origin).setTabOrigin(origin); this.setDocOrigin(origin).setTabOrigin(origin);
} else if ( this.type === 'sub_frame' ) { } else if ( this.type.endsWith('_frame') ) {
const origin = this.originFromURI(this.url); const origin = this.originFromURI(this.url);
this.setDocOrigin(origin).setTabOrigin(origin); this.setDocOrigin(origin).setTabOrigin(origin);
} else { } else {

View file

@ -30,24 +30,17 @@
/******************************************************************************/ /******************************************************************************/
var µb = µBlock; const µb = µBlock;
/******************************************************************************/ /******************************************************************************/
var getDomainNames = function(targets) { const getDomainNames = function(targets) {
var out = []; const µburi = µb.URI;
var µburi = µb.URI; return targets.map(target =>
var target, domain; target.indexOf('/') !== -1
for ( var i = 0; i < targets.length; i++ ) { ? µburi.domainFromURI(target) || ''
target = targets[i]; : µburi.domainFromHostname(target) || target
if ( target.indexOf('/') !== -1 ) { );
domain = µburi.domainFromURI(target) || '';
} else {
domain = µburi.domainFromHostname(target) || target;
}
out.push(domain);
}
return out;
}; };
/******************************************************************************/ /******************************************************************************/
@ -128,7 +121,8 @@ const onMessage = function(request, sender, callback) {
case 'getWhitelist': case 'getWhitelist':
response = { response = {
whitelist: µb.stringFromWhitelist(µb.netWhitelist), whitelist: µb.arrayFromWhitelist(µb.netWhitelist),
whitelistDefault: µb.netWhitelistDefault,
reBadHostname: µb.reWhitelistBadHostname.source, reBadHostname: µb.reWhitelistBadHostname.source,
reHostnameExtractor: µb.reWhitelistHostnameExtractor.source reHostnameExtractor: µb.reWhitelistHostnameExtractor.source
}; };

View file

@ -208,9 +208,11 @@ const onVersionReady = function(lastVersion) {
const lastVersionInt = intFromVersion(lastVersion); const lastVersionInt = intFromVersion(lastVersion);
if ( lastVersionInt <= 1016021007 ) { // https://github.com/uBlockOrigin/uBlock-issues/issues/494
µb.sessionSwitches.toggle('no-scripting', 'behind-the-scene', 2); // Remove useless per-site switches.
µb.permanentSwitches.toggle('no-scripting', 'behind-the-scene', 2); if ( lastVersionInt <= 1019003007 ) {
µb.sessionSwitches.toggle('no-scripting', 'behind-the-scene', 0);
µb.permanentSwitches.toggle('no-scripting', 'behind-the-scene', 0);
µb.saveHostnameSwitches(); µb.saveHostnameSwitches();
} }
@ -347,13 +349,12 @@ const createDefaultProps = function() {
'urlFilteringString': '', 'urlFilteringString': '',
'hostnameSwitchesString': [ 'hostnameSwitchesString': [
'no-large-media: behind-the-scene false', 'no-large-media: behind-the-scene false',
'no-scripting: behind-the-scene false'
].join('\n'), ].join('\n'),
'lastRestoreFile': '', 'lastRestoreFile': '',
'lastRestoreTime': 0, 'lastRestoreTime': 0,
'lastBackupFile': '', 'lastBackupFile': '',
'lastBackupTime': 0, 'lastBackupTime': 0,
'netWhitelist': µb.netWhitelistDefault, 'netWhitelist': µb.netWhitelistDefault.join('\n'),
'selfieMagic': 0, 'selfieMagic': 0,
'version': '0.0.0.0' 'version': '0.0.0.0'
}; };

View file

@ -177,17 +177,19 @@ var matchBucket = function(url, hostname, bucket, start) {
/******************************************************************************/ /******************************************************************************/
µBlock.arrayFromWhitelist = function(whitelist) {
const out = new Set();
for ( const key in whitelist ) {
const bucket = whitelist[key];
for ( const directive of bucket ) {
out.add(directive);
}
}
return Array.from(out).sort((a, b) => a.localeCompare(b));
};
µBlock.stringFromWhitelist = function(whitelist) { µBlock.stringFromWhitelist = function(whitelist) {
var r = {}; return this.arrayFromWhitelist(whitelist).join('\n');
var i, bucket;
for ( var key in whitelist ) {
bucket = whitelist[key];
i = bucket.length;
while ( i-- ) {
r[bucket[i]] = true;
}
}
return Object.keys(r).sort(function(a,b){return a.localeCompare(b);}).join('\n');
}; };
/******************************************************************************/ /******************************************************************************/

View file

@ -25,26 +25,42 @@
/******************************************************************************/ /******************************************************************************/
(function() { (( ) => {
/******************************************************************************/
const reComment = /^\s*#\s*/;
const directiveFromLine = function(line) {
const match = reComment.exec(line);
return match === null
? line.trim()
: line.slice(match.index + match[0].length).trim();
};
/******************************************************************************/ /******************************************************************************/
CodeMirror.defineMode("ubo-whitelist-directives", function() { CodeMirror.defineMode("ubo-whitelist-directives", function() {
var reComment = /^\s*#/, const reRegex = /^\/.+\/$/;
reRegex = /^\/.+\/$/;
return { return {
token: function(stream) { token: function(stream) {
var line = stream.string.trim(); const line = stream.string.trim();
stream.skipToEnd(); stream.skipToEnd();
if ( reBadHostname === undefined ) { if ( reBadHostname === undefined ) {
return null; return null;
} }
if ( reComment.test(line) ) { if ( reComment.test(line) ) {
return 'comment'; return whitelistDefaultSet.has(directiveFromLine(line))
? 'builtin comment'
: 'comment';
} }
if ( line.indexOf('/') === -1 ) { if ( line.indexOf('/') === -1 ) {
return reBadHostname.test(line) ? 'error' : null; if ( reBadHostname.test(line) ) { return 'error'; }
if ( whitelistDefaultSet.has(line.trim()) ) {
return 'builtin';
}
return null;
} }
if ( reRegex.test(line) ) { if ( reRegex.test(line) ) {
try { try {
@ -59,16 +75,18 @@ CodeMirror.defineMode("ubo-whitelist-directives", function() {
}; };
}); });
var reBadHostname, let reBadHostname;
reHostnameExtractor; let reHostnameExtractor;
let whitelistDefaultSet = new Set();
/******************************************************************************/ /******************************************************************************/
var messaging = vAPI.messaging, const messaging = vAPI.messaging;
cachedWhitelist = '', const noopFunc = function(){};
noopFunc = function(){};
var cmEditor = new CodeMirror( let cachedWhitelist = '';
const cmEditor = new CodeMirror(
document.getElementById('whitelist'), document.getElementById('whitelist'),
{ {
autofocus: true, autofocus: true,
@ -82,11 +100,11 @@ uBlockDashboard.patchCodeMirrorEditor(cmEditor);
/******************************************************************************/ /******************************************************************************/
var whitelistChanged = function() { const whitelistChanged = function() {
var whitelistElem = uDom.nodeFromId('whitelist'); const whitelistElem = uDom.nodeFromId('whitelist');
var bad = whitelistElem.querySelector('.cm-error') !== null; const bad = whitelistElem.querySelector('.cm-error') !== null;
var changedWhitelist = cmEditor.getValue().trim(); const changedWhitelist = cmEditor.getValue().trim();
var changed = changedWhitelist !== cachedWhitelist; const changed = changedWhitelist !== cachedWhitelist;
uDom.nodeFromId('whitelistApply').disabled = !changed || bad; uDom.nodeFromId('whitelistApply').disabled = !changed || bad;
uDom.nodeFromId('whitelistRevert').disabled = !changed; uDom.nodeFromId('whitelistRevert').disabled = !changed;
CodeMirror.commands.save = changed && !bad ? applyChanges : noopFunc; CodeMirror.commands.save = changed && !bad ? applyChanges : noopFunc;
@ -96,15 +114,39 @@ cmEditor.on('changes', whitelistChanged);
/******************************************************************************/ /******************************************************************************/
var renderWhitelist = function() { const renderWhitelist = function() {
var onRead = function(details) { const onRead = details => {
var first = reBadHostname === undefined; const first = reBadHostname === undefined;
if ( first ) { if ( first ) {
reBadHostname = new RegExp(details.reBadHostname); reBadHostname = new RegExp(details.reBadHostname);
reHostnameExtractor = new RegExp(details.reHostnameExtractor); reHostnameExtractor = new RegExp(details.reHostnameExtractor);
whitelistDefaultSet = new Set(details.whitelistDefault);
} }
cachedWhitelist = details.whitelist.trim(); const toAdd = new Set(whitelistDefaultSet);
cmEditor.setValue(cachedWhitelist + '\n'); for ( const line of details.whitelist ) {
const directive = directiveFromLine(line);
if ( whitelistDefaultSet.has(directive) === false ) { continue; }
toAdd.delete(directive);
if ( toAdd.size === 0 ) { break; }
}
if ( toAdd.size !== 0 ) {
details.whitelist.push(...Array.from(toAdd).map(a => `# ${a}`));
}
details.whitelist.sort((a, b) => {
const ad = directiveFromLine(a);
const bd = directiveFromLine(b);
const abuiltin = whitelistDefaultSet.has(ad);
if ( abuiltin !== whitelistDefaultSet.has(bd) ) {
return abuiltin ? -1 : 1;
}
return ad.localeCompare(bd);
});
let whitelistStr = details.whitelist.join('\n').trim();
cachedWhitelist = whitelistStr;
if ( whitelistStr !== '' ) {
whitelistStr += '\n';
}
cmEditor.setValue(whitelistStr);
if ( first ) { if ( first ) {
cmEditor.clearHistory(); cmEditor.clearHistory();
} }
@ -114,8 +156,8 @@ var renderWhitelist = function() {
/******************************************************************************/ /******************************************************************************/
var handleImportFilePicker = function() { const handleImportFilePicker = function() {
var fileReaderOnLoadHandler = function() { const fileReaderOnLoadHandler = ( ) => {
cmEditor.setValue( cmEditor.setValue(
[ [
cmEditor.getValue().trim(), cmEditor.getValue().trim(),
@ -123,18 +165,18 @@ var handleImportFilePicker = function() {
].join('\n').trim() ].join('\n').trim()
); );
}; };
var file = this.files[0]; const file = this.files[0];
if ( file === undefined || file.name === '' ) { return; } if ( file === undefined || file.name === '' ) { return; }
if ( file.type.indexOf('text') !== 0 ) { return; } if ( file.type.indexOf('text') !== 0 ) { return; }
var fr = new FileReader(); const fr = new FileReader();
fr.onload = fileReaderOnLoadHandler; fr.onload = fileReaderOnLoadHandler;
fr.readAsText(file); fr.readAsText(file);
}; };
/******************************************************************************/ /******************************************************************************/
var startImportFilePicker = function() { const startImportFilePicker = function() {
var input = document.getElementById('importFilePicker'); const input = document.getElementById('importFilePicker');
// Reset to empty string, this will ensure an change event is properly // Reset to empty string, this will ensure an change event is properly
// triggered if the user pick a file, even if it is the same as the last // triggered if the user pick a file, even if it is the same as the last
// one picked. // one picked.
@ -144,21 +186,22 @@ var startImportFilePicker = function() {
/******************************************************************************/ /******************************************************************************/
var exportWhitelistToFile = function() { const exportWhitelistToFile = function() {
var val = cmEditor.getValue().trim(); const val = cmEditor.getValue().trim();
if ( val === '' ) { return; } if ( val === '' ) { return; }
var filename = vAPI.i18n('whitelistExportFilename') const filename =
vAPI.i18n('whitelistExportFilename')
.replace('{{datetime}}', uBlockDashboard.dateNowToSensibleString()) .replace('{{datetime}}', uBlockDashboard.dateNowToSensibleString())
.replace(/ +/g, '_'); .replace(/ +/g, '_');
vAPI.download({ vAPI.download({
'url': 'data:text/plain;charset=utf-8,' + encodeURIComponent(val + '\n'), 'url': `data:text/plain;charset=utf-8,${encodeURIComponent(val + '\n')}`,
'filename': filename 'filename': filename
}); });
}; };
/******************************************************************************/ /******************************************************************************/
var applyChanges = function() { const applyChanges = function() {
cachedWhitelist = cmEditor.getValue().trim(); cachedWhitelist = cmEditor.getValue().trim();
messaging.send( messaging.send(
'dashboard', 'dashboard',
@ -170,19 +213,19 @@ var applyChanges = function() {
); );
}; };
var revertChanges = function() { const revertChanges = function() {
var content = cachedWhitelist; let content = cachedWhitelist;
if ( content !== '' ) { content += '\n'; } if ( content !== '' ) { content += '\n'; }
cmEditor.setValue(content); cmEditor.setValue(content);
}; };
/******************************************************************************/ /******************************************************************************/
var getCloudData = function() { const getCloudData = function() {
return cmEditor.getValue(); return cmEditor.getValue();
}; };
var setCloudData = function(data, append) { const setCloudData = function(data, append) {
if ( typeof data !== 'string' ) { return; } if ( typeof data !== 'string' ) { return; }
if ( append ) { if ( append ) {
data = uBlockDashboard.mergeNewLines(cmEditor.getValue().trim(), data); data = uBlockDashboard.mergeNewLines(cmEditor.getValue().trim(), data);