From 0b5f53923fc4fd7e6927ce57cd9226a61bcbdb88 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Wed, 9 Dec 2020 08:16:28 -0500 Subject: [PATCH] Add basic compatibility with ABP's `rewrite` option Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/857 The recognized resources are: - abp-resource:blank-mp3 - abp-resource:blank-js ABP's tokens are excluded from auto-complete so as to not get in the way of uBO's filter list maintainers. --- src/js/codemirror/ubo-static-filtering.js | 17 ++++++++++++++--- src/js/pagestore.js | 19 +++++++++---------- src/js/redirect-engine.js | 11 ++++++++--- src/js/static-filtering-parser.js | 2 ++ 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/js/codemirror/ubo-static-filtering.js b/src/js/codemirror/ubo-static-filtering.js index 183af09099d78..1b987b22b8218 100644 --- a/src/js/codemirror/ubo-static-filtering.js +++ b/src/js/codemirror/ubo-static-filtering.js @@ -185,7 +185,7 @@ CodeMirror.defineMode('ubo-static-filtering', function() { // Warn about unknown redirect tokens. if ( string.charCodeAt(pos - 1) === 0x3D /* '=' */ && - /[$,]redirect(-rule)?=$/.test(string.slice(0, pos)) + /[$,](redirect(-rule)?|rewrite)=$/.test(string.slice(0, pos)) ) { style = 'value'; const end = parser.skipUntil( @@ -418,6 +418,12 @@ const initHints = function() { return (item[1] & 0b01) !== 0; }) ); + const excludedHints = new Set([ + 'genericblock', + 'object-subrequest', + 'rewrite', + 'webrtc', + ]); const pickBestHints = function(cursor, seedLeft, seedRight, hints) { const seed = (seedLeft + seedRight).trim(); @@ -471,6 +477,7 @@ const initHints = function() { const isException = parser.isException(); const hints = []; for ( let [ text, bits ] of parser.netOptionTokenDescriptors ) { + if ( excludedHints.has(text) ) { continue; } if ( isNegated && (bits & parser.OPTCanNegate) === 0 ) { continue; } if ( isException ) { if ( (bits & parser.OPTBlockOnly) !== 0 ) { continue; } @@ -488,6 +495,7 @@ const initHints = function() { const getNetRedirectHints = function(cursor, seedLeft, seedRight) { const hints = []; for ( const text of redirectNames.keys() ) { + if ( text.startsWith('abp-resource:') ) { continue; } hints.push(text); } return pickBestHints(cursor, seedLeft, seedRight, hints); @@ -495,7 +503,10 @@ const initHints = function() { const getNetHints = function(cursor, line) { const beg = cursor.ch; - if ( parser.optionsSpan.len === 0 ) { + if ( + parser.optionsAnchorSpan.len === 0 && + line.endsWith('$') === false + ) { if ( /[^\w\x80-\xF4#,.-]/.test(line) === false ) { return getOriginHints(cursor, line); } @@ -511,7 +522,7 @@ const initHints = function() { if ( assignPos === -1 ) { return getNetOptionHints(cursor, matchLeft[0], matchRight[0]); } - if ( /^redirect(-rule)?=/.test(matchLeft[0]) ) { + if ( /^(redirect(-rule)?|rewrite)=/.test(matchLeft[0]) ) { return getNetRedirectHints( cursor, matchLeft[0].slice(assignPos + 1), diff --git a/src/js/pagestore.js b/src/js/pagestore.js index cecabc3b7ca7d..980ba3afbb17d 100644 --- a/src/js/pagestore.js +++ b/src/js/pagestore.js @@ -377,16 +377,15 @@ const PageStore = class { setFrameURL(frameId, frameURL) { let frameStore = this.frames.get(frameId); if ( frameStore !== undefined ) { - if ( frameURL !== frameStore.rawURL ) { - frameStore.init(frameURL); - } - } else { - frameStore = FrameStore.factory(frameURL); - this.frames.set(frameId, frameStore); - this.frameAddCount += 1; - if ( (this.frameAddCount & 0b111111) === 0 ) { - this.pruneFrames(); - } + return frameURL === frameStore.rawURL + ? frameStore + : frameStore.init(frameURL); + } + frameStore = FrameStore.factory(frameURL); + this.frames.set(frameId, frameStore); + this.frameAddCount += 1; + if ( (this.frameAddCount & 0b111111) === 0 ) { + this.pruneFrames(); } return frameStore; } diff --git a/src/js/redirect-engine.js b/src/js/redirect-engine.js index dc89afe674bf6..bd1147fd3a7e0 100644 --- a/src/js/redirect-engine.js +++ b/src/js/redirect-engine.js @@ -121,7 +121,7 @@ const redirectableResources = new Map([ data: 'text', } ], [ 'noop-0.1s.mp3', { - alias: 'noopmp3-0.1s', + alias: [ 'noopmp3-0.1s', 'abp-resource:blank-mp3' ], data: 'blob', } ], [ 'noop-1s.mp4', { @@ -132,7 +132,7 @@ const redirectableResources = new Map([ alias: 'noopframe', } ], [ 'noop.js', { - alias: 'noopjs', + alias: [ 'noopjs', 'abp-resource:blank-js' ], data: 'text', } ], [ 'noop.txt', { @@ -461,7 +461,12 @@ RedirectEngine.prototype.loadBuiltinResources = function() { params: details.params, }); this.resources.set(name, entry); - if ( details.alias !== undefined ) { + if ( details.alias === undefined ) { return; } + if ( Array.isArray(details.alias) ) { + for ( const alias of details.alias ) { + this.aliases.set(alias, name); + } + } else { this.aliases.set(details.alias, name); } }; diff --git a/src/js/static-filtering-parser.js b/src/js/static-filtering-parser.js index dd4ff1b8a2996..3d4a4cb452fd5 100644 --- a/src/js/static-filtering-parser.js +++ b/src/js/static-filtering-parser.js @@ -2183,6 +2183,7 @@ const netOptionTokenDescriptors = new Map([ [ 'queryprune', OPTTokenQueryprune | OPTMayAssign | OPTModifierType | OPTNonCspableType | OPTNonRedirectableType ], [ 'removeparam', OPTTokenQueryprune | OPTMayAssign | OPTModifierType | OPTNonCspableType | OPTNonRedirectableType ], [ 'redirect', OPTTokenRedirect | OPTMustAssign | OPTAllowMayAssign | OPTModifierType ], + [ 'rewrite', OPTTokenRedirect | OPTMustAssign | OPTAllowMayAssign | OPTModifierType ], [ 'redirect-rule', OPTTokenRedirectRule | OPTMustAssign | OPTAllowMayAssign | OPTModifierType | OPTNonCspableType ], [ 'script', OPTTokenScript | OPTCanNegate | OPTNetworkType | OPTModifiableType | OPTRedirectableType | OPTNonCspableType ], [ 'shide', OPTTokenShide | OPTNonNetworkType | OPTNonCspableType | OPTNonRedirectableType ], @@ -2241,6 +2242,7 @@ Parser.netOptionTokenIds = new Map([ [ 'queryprune', OPTTokenQueryprune ], [ 'removeparam', OPTTokenQueryprune ], [ 'redirect', OPTTokenRedirect ], + [ 'rewrite', OPTTokenRedirect ], [ 'redirect-rule', OPTTokenRedirectRule ], [ 'script', OPTTokenScript ], [ 'shide', OPTTokenShide ],