1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-11-07 03:12:33 +01:00

Minor improvements to syntax highlight of static filters

Double-cliking on a URL will cause the whole URL to be
selected, thus making it easier to navigate to this
URL (through your browser "Open in new tab" entry in
contextual menu).

Unrecognized scriptlet names will be highlighted so as
to warn that the filter is not going to be effective.
This commit is contained in:
Raymond Hill 2020-09-30 10:01:10 -04:00
parent 3693755e94
commit fef375a594
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
3 changed files with 88 additions and 10 deletions

View File

@ -24,7 +24,7 @@
/* CodeMirror theme overrides */ /* CodeMirror theme overrides */
.cm-s-default .cm-value { color: #930; } .cm-s-default .cm-value { color: #930; }
.cm-s-default .cm-comment { color: #777; } .cm-s-default .cm-comment { color: var(--sf-comment-ink); }
.cm-s-default .cm-keyword { color: #90b; } .cm-s-default .cm-keyword { color: #90b; }
.cm-s-default .cm-regex { .cm-s-default .cm-regex {
text-underline-position: under; text-underline-position: under;
@ -41,6 +41,16 @@
text-decoration: underline red; text-decoration: underline red;
text-underline-position: under; text-underline-position: under;
} }
.cm-s-default .cm-warning {
text-decoration: underline var(--sf-warning-ink);
text-underline-position: under;
}
.cm-s-default .cm-link {
text-decoration: none;
}
.cm-s-default .cm-link:hover {
color: var(--link-ink);
}
.cm-directive { color: #333; font-weight: bold; } .cm-directive { color: #333; font-weight: bold; }
.cm-staticext { color: #008; } .cm-staticext { color: #008; }

View File

@ -159,6 +159,10 @@
--bg-popup-cell-block-own: hsla(0, 100%, 40%, 1); --bg-popup-cell-block-own: hsla(0, 100%, 40%, 1);
--bg-popup-cell-label-mixed: hsla(45, 100%, 38%, 1); --bg-popup-cell-label-mixed: hsla(45, 100%, 38%, 1);
--popup-icon-x-ink: var(--red-60); --popup-icon-x-ink: var(--red-60);
/* syntax highlight: static filtering */
--sf-comment-ink: var(--light-gray-90);
--sf-warning-ink: var(--yellow-50);
} }
/** /**

View File

@ -44,22 +44,33 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
if ( StaticFilteringParser instanceof Object === false ) { return; } if ( StaticFilteringParser instanceof Object === false ) { return; }
const parser = new StaticFilteringParser({ interactive: true }); const parser = new StaticFilteringParser({ interactive: true });
const reURL = /\bhttps?:\/\/\S+/;
const rePreparseDirectives = /^!#(?:if|endif|include )\b/; const rePreparseDirectives = /^!#(?:if|endif|include )\b/;
const rePreparseIfDirective = /^(!#if ?)(.*)$/; const rePreparseIfDirective = /^(!#if ?)(.*)$/;
let parserSlot = 0; let parserSlot = 0;
let netOptionValueMode = false; let netOptionValueMode = false;
const colorCommentSpan = function(stream) { const colorCommentSpan = function(stream) {
if ( rePreparseDirectives.test(stream.string) === false ) { const { string, pos } = stream;
if ( rePreparseDirectives.test(string) === false ) {
const match = reURL.exec(string.slice(pos));
if ( match !== null ) {
if ( match.index === 0 ) {
stream.pos += match[0].length;
return 'comment link';
}
stream.pos += match.index;
return 'comment';
}
stream.skipToEnd(); stream.skipToEnd();
return 'comment'; return 'comment';
} }
const match = rePreparseIfDirective.exec(stream.string); const match = rePreparseIfDirective.exec(string);
if ( match === null ) { if ( match === null ) {
stream.skipToEnd(); stream.skipToEnd();
return 'variable strong'; return 'variable strong';
} }
if ( stream.pos < match[1].length ) { if ( pos < match[1].length ) {
stream.pos += match[1].length; stream.pos += match[1].length;
return 'variable strong'; return 'variable strong';
} }
@ -95,19 +106,29 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
}; };
const colorExtScriptletPatternSpan = function(stream) { const colorExtScriptletPatternSpan = function(stream) {
const { pos, string } = stream;
const { i, len } = parser.patternSpan; const { i, len } = parser.patternSpan;
if ( stream.pos === parser.slices[i+1] ) { const patternBeg = parser.slices[i+1];
stream.pos += 4; if ( pos === patternBeg ) {
stream.pos = pos + 4;
return 'def'; return 'def';
} }
if ( len > 3 ) { if ( len > 3 ) {
if ( pos === patternBeg + 4 ) {
const match = /^[^,)]+/.exec(string.slice(pos));
const token = match && match[0].trim();
if ( token && scriptletNames.has(token) === false ) {
stream.pos = pos + match[0].length;
return 'warning';
}
}
const r = parser.slices[i+len+1] - 1; const r = parser.slices[i+len+1] - 1;
if ( stream.pos < r ) { if ( pos < r ) {
stream.pos = r; stream.pos = r;
return 'variable'; return 'variable';
} }
if ( stream.pos === r ) { if ( pos === r ) {
stream.pos += 1; stream.pos = pos + 1;
return 'def'; return 'def';
} }
} }
@ -483,7 +504,6 @@ const initHints = function() {
/******************************************************************************/ /******************************************************************************/
CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => { CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
const foldIfEndif = function(startLineNo, startLine, cm) { const foldIfEndif = function(startLineNo, startLine, cm) {
const lastLineNo = cm.lastLine(); const lastLineNo = cm.lastLine();
let endLineNo = startLineNo; let endLineNo = startLineNo;
@ -539,6 +559,50 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
/******************************************************************************/ /******************************************************************************/
// Enhanced word selection
{
const Pass = CodeMirror.Pass;
const selectWordAt = function(cm, pos) {
const { line, ch } = pos;
// Leave current selection alone
if ( cm.somethingSelected() ) {
const from = cm.getCursor('from');
const to = cm.getCursor('to');
if (
(line > from.line || line === from.line && ch > from.ch) &&
(line < to.line || line === to.line && ch < to.ch)
) {
return Pass;
}
}
const s = cm.getLine(line);
// Select URL
let lmatch = /\bhttps?:\/\/\S+$/.exec(s.slice(0, ch));
let rmatch = /^\S+/.exec(s.slice(ch));
// TODO: add more convenient word-matching cases here
// if ( lmatch === null || rmatch === null ) { ... }
if ( lmatch === null || rmatch === null ) { return Pass; }
cm.setSelection(
{ line, ch: lmatch.index },
{ line, ch: ch + rmatch.index + rmatch[0].length }
);
};
CodeMirror.defineInitHook(cm => {
cm.addKeyMap({
'LeftDoubleClick': selectWordAt,
});
});
}
/******************************************************************************/
// <<<<< end of local scope // <<<<< end of local scope
} }