From 6d3ad553b47805ad9eb9e9f5f75e9380b740e39d Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sun, 27 Dec 2020 09:32:50 -0500 Subject: [PATCH] Fix word-based selection in filter list editor/viewer This commit fixes mouse double-click-and-drag operations, which was broken due to the implementation of a custom word selection in the filter list editor/viewer. --- src/js/codemirror/ubo-static-filtering.js | 93 ++++++++++++----------- src/js/static-filtering-parser.js | 2 +- 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/js/codemirror/ubo-static-filtering.js b/src/js/codemirror/ubo-static-filtering.js index 0d38c14ed..891c3c072 100644 --- a/src/js/codemirror/ubo-static-filtering.js +++ b/src/js/codemirror/ubo-static-filtering.js @@ -336,12 +336,20 @@ CodeMirror.defineMode('ubo-static-filtering', function() { return 'comment'; } if ( parser.category === parser.CATStaticExtFilter ) { - const style = colorExtSpan(stream); - return style ? `ext ${style}` : 'ext'; + const style = colorExtSpan(stream) || ''; + let flavor = ''; + if ( (parser.flavorBits & parser.BITFlavorExtCosmetic) !== 0 ) { + flavor = 'line-cm-ext-dom'; + } else if ( (parser.flavorBits & parser.BITFlavorExtScriptlet) !== 0 ) { + flavor = 'line-cm-ext-js'; + } else if ( (parser.flavorBits & parser.BITFlavorExtHTML) !== 0 ) { + flavor = 'line-cm-ext-html'; + } + return `${flavor} ${style}`.trim(); } if ( parser.category === parser.CATStaticNetFilter ) { const style = colorNetSpan(stream); - return style ? `net ${style}` : 'net'; + return style ? `line-cm-net ${style}` : 'line-cm-net'; } stream.skipToEnd(); return null; @@ -679,25 +687,10 @@ 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); - const token = cm.getTokenTypeAt(pos); + const { type: token } = cm.getTokenAt(pos); let beg, end; // Select URL in comments @@ -712,30 +705,34 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => { } } - // Better word selection for cosmetic filters - else if ( /\bext\b/.test(token) ) { - if ( /\bvalue\b/.test(token) ) { - const l = /[^,.]*$/i.exec(s.slice(0, ch)); - const r = /^[^#,]*/i.exec(s.slice(ch)); - if ( l && r ) { - beg = l.index; - end = ch + r[0].length; - } - } else if ( /\bvariable\b/.test(token) ) { - const l = /[#.][a-z0-9_-]+$/i.exec(s.slice(0, ch)); - const r = /^[a-z0-9_-]+/i.exec(s.slice(ch)); - if ( l && r ) { - beg = l.index; - end = ch + r[0].length; - if ( /\bdef\b/.test(cm.getTokenTypeAt({ line, ch: beg + 1 })) ) { - beg += 1; - } + // Better word selection for extended filters: prefix + else if ( + /\bline-cm-ext-(?:dom|html|js)\b/.test(token) && + /\bvalue\b/.test(token) + ) { + const l = /[^,.]*$/i.exec(s.slice(0, ch)); + const r = /^[^#,]*/i.exec(s.slice(ch)); + if ( l && r ) { + beg = l.index; + end = ch + r[0].length; + } + } + + // Better word selection for cosmetic and HTML filters: suffix + else if ( /\bline-cm-ext-(?:dom|html)\b/.test(token) ) { + const l = /[#.]?[a-z0-9_-]+$/i.exec(s.slice(0, ch)); + const r = /^[a-z0-9_-]+/i.exec(s.slice(ch)); + if ( l && r ) { + beg = l.index; + end = ch + r[0].length; + if ( /\bdef\b/.test(cm.getTokenTypeAt({ line, ch: beg + 1 })) ) { + beg += 1; } } } // Better word selection for network filters - else if ( /\bnet\b/.test(token) ) { + else if ( /\bline-cm-net\b/.test(token) ) { if ( /\bvalue\b/.test(token) ) { const l = /[^ ,.=|]*$/i.exec(s.slice(0, ch)); const r = /^[^ #,|]*/i.exec(s.slice(ch)); @@ -753,16 +750,22 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => { } } - if ( beg === undefined ) { return Pass; } - cm.setSelection( - { line, ch: beg }, - { line, ch: end } - ); + if ( beg === undefined ) { + const { anchor, head } = cm.findWordAt(pos); + return { from: anchor, to: head }; + } + + return { + from: { line, ch: beg }, + to: { line, ch: end }, + }; }; CodeMirror.defineInitHook(cm => { - cm.addKeyMap({ - 'LeftDoubleClick': selectWordAt, + cm.setOption('configureMouse', function(cm, repeat) { + return { + unit: repeat === 'double' ? selectWordAt : null, + }; }); }); } diff --git a/src/js/static-filtering-parser.js b/src/js/static-filtering-parser.js index d3c81d46e..4c484f5d8 100644 --- a/src/js/static-filtering-parser.js +++ b/src/js/static-filtering-parser.js @@ -2782,7 +2782,7 @@ Parser.tokenizableStrFromRegex = (( ) => { } return s; } - case 2: /* T_ALTERNATION,'Alternation' */ + case 2: /* T_ALTERNATION, 'Alternation' */ case 8: /* T_CHARGROUP, 'CharacterGroup' */ { let firstChar = 0; let lastChar = 0;