Minor refactoring plus other minor changes

Added more evocative error messages to linter.

Made the content of _My filters_ trusted by default in
dev build.
This commit is contained in:
Raymond Hill 2023-10-22 08:53:01 -04:00
parent 5dd9584da2
commit e33c0f9d9c
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
9 changed files with 81 additions and 93 deletions

View File

@ -63,20 +63,14 @@ let cachedUserFilters = '';
let hintUpdateToken = 0; let hintUpdateToken = 0;
const getHints = async function() { const getHints = async function() {
const response = await vAPI.messaging.send('dashboard', { const hints = await vAPI.messaging.send('dashboard', {
what: 'getAutoCompleteDetails', what: 'getAutoCompleteDetails',
hintUpdateToken hintUpdateToken
}); });
if ( response instanceof Object === false ) { return; } if ( hints instanceof Object === false ) { return; }
if ( response.hintUpdateToken !== undefined ) { if ( hints.hintUpdateToken !== undefined ) {
const mode = cmEditor.getMode(); cmEditor.setOption('uboHints', hints);
if ( mode.setHints instanceof Function ) { hintUpdateToken = hints.hintUpdateToken;
mode.setHints(response);
}
if ( hintUpdateToken === 0 ) {
mode.parser.expertMode = response.expertMode !== false;
}
hintUpdateToken = response.hintUpdateToken;
} }
timer.on(2503); timer.on(2503);
}; };

View File

@ -72,9 +72,7 @@ import './codemirror/ubo-static-filtering.js';
what: 'getAutoCompleteDetails' what: 'getAutoCompleteDetails'
}).then(hints => { }).then(hints => {
if ( hints instanceof Object === false ) { return; } if ( hints instanceof Object === false ) { return; }
const mode = cmEditor.getMode(); cmEditor.setOption('uboHints', hints);
if ( mode.setHints instanceof Function === false ) { return; }
mode.setHints(hints);
}); });
vAPI.messaging.send('dashboard', { vAPI.messaging.send('dashboard', {

View File

@ -89,6 +89,10 @@ const hiddenSettingsDefault = {
userResourcesLocation: 'unset', userResourcesLocation: 'unset',
}; };
if ( vAPI.webextFlavor.soup.has('devbuild') ) {
hiddenSettingsDefault.trustedListPrefixes += ' user-';
}
const userSettingsDefault = { const userSettingsDefault = {
advancedUserEnabled: false, advancedUserEnabled: false,
alwaysDetachLogger: true, alwaysDetachLogger: true,

View File

@ -39,22 +39,19 @@ let hintHelperRegistered = false;
/******************************************************************************/ /******************************************************************************/
const trustedScriptletTokens = new Set(); CodeMirror.defineOption('trustedSource', false, (cm, state) => {
let trustedSource = false; if ( typeof state !== 'boolean' ) { return; }
self.dispatchEvent(new CustomEvent('trustedSource', {
CodeMirror.defineOption('trustedSource', false, (cm, value) => { detail: state,
trustedSource = value; }));
self.dispatchEvent(new Event('trustedSource'));
}); });
CodeMirror.defineOption('trustedScriptletTokens', trustedScriptletTokens, (cm, tokens) => { CodeMirror.defineOption('trustedScriptletTokens', undefined, (cm, tokens) => {
if ( tokens === undefined || tokens === null ) { return; } if ( tokens === undefined || tokens === null ) { return; }
if ( typeof tokens[Symbol.iterator] !== 'function' ) { return; } if ( typeof tokens[Symbol.iterator] !== 'function' ) { return; }
trustedScriptletTokens.clear(); self.dispatchEvent(new CustomEvent('trustedScriptletTokens', {
for ( const token of tokens ) { detail: new Set(tokens),
trustedScriptletTokens.add(token); }));
}
self.dispatchEvent(new Event('trustedScriptletTokens'));
}); });
/******************************************************************************/ /******************************************************************************/
@ -63,8 +60,6 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
const astParser = new sfp.AstFilterParser({ const astParser = new sfp.AstFilterParser({
interactive: true, interactive: true,
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'), nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
trustedSource,
trustedScriptletTokens,
}); });
const astWalker = astParser.getWalker(); const astWalker = astParser.getWalker();
let currentWalkerNode = 0; let currentWalkerNode = 0;
@ -226,12 +221,12 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
return '+'; return '+';
}; };
self.addEventListener('trustedSource', ( ) => { self.addEventListener('trustedSource', ev => {
astParser.options.trustedSource = trustedSource; astParser.options.trustedSource = ev.detail;
}); });
self.addEventListener('trustedScriptletTokens', ( ) => { self.addEventListener('trustedScriptletTokens', ev => {
astParser.options.trustedScriptletTokens = trustedScriptletTokens; astParser.options.trustedScriptletTokens = ev.detail;
}); });
return { return {
@ -283,38 +278,6 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
style = style.trim(); style = style.trim();
return style !== '' ? style : null; return style !== '' ? style : null;
}, },
setHints: function(details) {
if ( Array.isArray(details.redirectResources) ) {
for ( const [ name, desc ] of details.redirectResources ) {
const displayText = desc.aliasOf !== ''
? `${name} (${desc.aliasOf})`
: '';
if ( desc.canRedirect ) {
redirectNames.set(name, displayText);
}
if ( desc.canInject && name.endsWith('.js') ) {
scriptletNames.set(name.slice(0, -3), displayText);
}
}
}
if ( Array.isArray(details.preparseDirectiveEnv)) {
preparseDirectiveEnv.length = 0;
preparseDirectiveEnv.push(...details.preparseDirectiveEnv);
}
if ( Array.isArray(details.preparseDirectiveHints)) {
preparseDirectiveHints.push(...details.preparseDirectiveHints);
}
if ( Array.isArray(details.originHints) ) {
originHints.length = 0;
for ( const hint of details.originHints ) {
originHints.push(hint);
}
}
if ( hintHelperRegistered === false ) {
hintHelperRegistered = true;
initHints();
}
},
parser: astParser, parser: astParser,
}; };
}); });
@ -324,7 +287,40 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
// Following code is for auto-completion. Reference: // Following code is for auto-completion. Reference:
// https://codemirror.net/demo/complete.html // https://codemirror.net/demo/complete.html
const initHints = function() { CodeMirror.defineOption('uboHints', null, (cm, hints) => {
if ( hints instanceof Object === false ) { return; }
if ( Array.isArray(hints.redirectResources) ) {
for ( const [ name, desc ] of hints.redirectResources ) {
const displayText = desc.aliasOf !== ''
? `${name} (${desc.aliasOf})`
: '';
if ( desc.canRedirect ) {
redirectNames.set(name, displayText);
}
if ( desc.canInject && name.endsWith('.js') ) {
scriptletNames.set(name.slice(0, -3), displayText);
}
}
}
if ( Array.isArray(hints.preparseDirectiveEnv)) {
preparseDirectiveEnv.length = 0;
preparseDirectiveEnv.push(...hints.preparseDirectiveEnv);
}
if ( Array.isArray(hints.preparseDirectiveHints)) {
preparseDirectiveHints.push(...hints.preparseDirectiveHints);
}
if ( Array.isArray(hints.originHints) ) {
originHints.length = 0;
for ( const hint of hints.originHints ) {
originHints.push(hint);
}
}
if ( hintHelperRegistered ) { return; }
hintHelperRegistered = true;
initHints();
});
function initHints() {
const astParser = new sfp.AstFilterParser({ const astParser = new sfp.AstFilterParser({
interactive: true, interactive: true,
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'), nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
@ -629,7 +625,7 @@ const initHints = function() {
} }
return getOriginHints(cursor, line); return getOriginHints(cursor, line);
}); });
}; }
/******************************************************************************/ /******************************************************************************/
@ -695,8 +691,6 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
const astParser = new sfp.AstFilterParser({ const astParser = new sfp.AstFilterParser({
interactive: true, interactive: true,
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'), nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
trustedSource,
trustedScriptletTokens,
}); });
const changeset = []; const changeset = [];
@ -724,6 +718,9 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
case sfp.AST_ERROR_DOMAIN_NAME: case sfp.AST_ERROR_DOMAIN_NAME:
msg = `${msg}: Bad domain name`; msg = `${msg}: Bad domain name`;
break; break;
case sfp.AST_ERROR_OPTION_BADVALUE:
msg = `${msg}: Bad value assigned to a valid option`;
break;
case sfp.AST_ERROR_OPTION_DUPLICATE: case sfp.AST_ERROR_OPTION_DUPLICATE:
msg = `${msg}: Duplicate filter option`; msg = `${msg}: Duplicate filter option`;
break; break;
@ -1011,12 +1008,12 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
} }
}; };
self.addEventListener('trustedSource', ( ) => { self.addEventListener('trustedSource', ev => {
astParser.options.trustedSource = trustedSource; astParser.options.trustedSource = ev.detail;
}); });
self.addEventListener('trustedScriptletTokens', ( ) => { self.addEventListener('trustedScriptletTokens', ev => {
astParser.options.trustedScriptletTokens = trustedScriptletTokens; astParser.options.trustedScriptletTokens = ev.detail;
}); });
CodeMirror.defineInitHook(cm => { CodeMirror.defineInitHook(cm => {

View File

@ -89,13 +89,10 @@ const cmEditor = new CodeMirror(document.querySelector('.codeMirrorContainer'),
vAPI.messaging.send('dashboard', { vAPI.messaging.send('dashboard', {
what: 'getAutoCompleteDetails' what: 'getAutoCompleteDetails'
}).then(response => { }).then(hints => {
// For unknown reasons, `instanceof Object` does not work here in Firefox. // For unknown reasons, `instanceof Object` does not work here in Firefox.
if ( typeof response !== 'object' ) { return; } if ( hints instanceof Object === false ) { return; }
const mode = cmEditor.getMode(); cmEditor.setOption('uboHints', hints);
if ( mode.setHints instanceof Function ) {
mode.setHints(response);
}
}); });
/******************************************************************************/ /******************************************************************************/

View File

@ -1602,9 +1602,7 @@ const onMessage = function(request, sender, callback) {
if ( (request.hintUpdateToken || 0) === 0 ) { if ( (request.hintUpdateToken || 0) === 0 ) {
response.redirectResources = redirectEngine.getResourceDetails(); response.redirectResources = redirectEngine.getResourceDetails();
response.preparseDirectiveEnv = vAPI.webextFlavor.env.slice(); response.preparseDirectiveEnv = vAPI.webextFlavor.env.slice();
response.preparseDirectiveHints = response.preparseDirectiveHints = sfp.utils.preparser.getHints();
sfp.utils.preparser.getHints();
response.expertMode = µb.hiddenSettings.filterAuthorMode;
} }
if ( request.hintUpdateToken !== µb.pageStoresToken ) { if ( request.hintUpdateToken !== µb.pageStoresToken ) {
response.originHints = getOriginHints(); response.originHints = getOriginHints();

View File

@ -130,7 +130,6 @@ const fromNetFilter = async function(rawFilter) {
const writer = new CompiledListWriter(); const writer = new CompiledListWriter();
const parser = new sfp.AstFilterParser({ const parser = new sfp.AstFilterParser({
expertMode: true,
trustedSource: true, trustedSource: true,
maxTokenLength: staticNetFilteringEngine.MAX_TOKEN_LENGTH, maxTokenLength: staticNetFilteringEngine.MAX_TOKEN_LENGTH,
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'), nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
@ -169,7 +168,6 @@ const fromExtendedFilter = async function(details) {
const hostname = hostnameFromURI(details.url); const hostname = hostnameFromURI(details.url);
const parser = new sfp.AstFilterParser({ const parser = new sfp.AstFilterParser({
expertMode: true,
trustedSource: true, trustedSource: true,
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'), nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
}); });

View File

@ -99,6 +99,7 @@ export const AST_ERROR_PATTERN = 1 << iota++;
export const AST_ERROR_DOMAIN_NAME = 1 << iota++; export const AST_ERROR_DOMAIN_NAME = 1 << iota++;
export const AST_ERROR_OPTION_DUPLICATE = 1 << iota++; export const AST_ERROR_OPTION_DUPLICATE = 1 << iota++;
export const AST_ERROR_OPTION_UNKNOWN = 1 << iota++; export const AST_ERROR_OPTION_UNKNOWN = 1 << iota++;
export const AST_ERROR_OPTION_BADVALUE = 1 << iota++;
export const AST_ERROR_IF_TOKEN_UNKNOWN = 1 << iota++; export const AST_ERROR_IF_TOKEN_UNKNOWN = 1 << iota++;
export const AST_ERROR_UNTRUSTED_SOURCE = 1 << iota++; export const AST_ERROR_UNTRUSTED_SOURCE = 1 << iota++;
@ -845,7 +846,6 @@ export class AstFilterParser {
// Options // Options
this.options = options; this.options = options;
this.interactive = options.interactive || false; this.interactive = options.interactive || false;
this.expertMode = options.expertMode || false;
this.badTypes = new Set(options.badTypes || []); this.badTypes = new Set(options.badTypes || []);
this.maxTokenLength = options.maxTokenLength || 7; this.maxTokenLength = options.maxTokenLength || 7;
// TODO: rethink this // TODO: rethink this
@ -1475,11 +1475,17 @@ export class AstFilterParser {
break; break;
} }
case NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM: case NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM:
realBad = abstractTypeCount || behaviorTypeCount || unredirectableTypeCount || realBad = abstractTypeCount || behaviorTypeCount || unredirectableTypeCount;
this.options.trustedSource !== true; if ( realBad ) { break; }
if ( realBad !== true ) { if ( this.options.trustedSource !== true ) {
const path = this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM); this.astError = AST_ERROR_UNTRUSTED_SOURCE;
realBad = path.charCodeAt(0) !== 0x2F /* / */; realBad = true;
break;
}
const path = this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM);
if ( path.charCodeAt(0) !== 0x2F /* / */ ) {
this.astError = AST_ERROR_OPTION_BADVALUE;
realBad = true;
} }
break; break;
case NODE_TYPE_NET_OPTION_NAME_REMOVEPARAM: case NODE_TYPE_NET_OPTION_NAME_REMOVEPARAM:

View File

@ -1069,11 +1069,7 @@ import {
writer.properties.set('trustedSource', trustedSource); writer.properties.set('trustedSource', trustedSource);
} }
const assetName = details.assetKey ? details.assetKey : '?'; const assetName = details.assetKey ? details.assetKey : '?';
const expertMode =
details.assetKey !== this.userFiltersPath ||
this.hiddenSettings.filterAuthorMode !== false;
const parser = new sfp.AstFilterParser({ const parser = new sfp.AstFilterParser({
expertMode,
trustedSource, trustedSource,
maxTokenLength: staticNetFilteringEngine.MAX_TOKEN_LENGTH, maxTokenLength: staticNetFilteringEngine.MAX_TOKEN_LENGTH,
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'), nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),