From 97b3069af3443cd721de8c5409fb9a8242ac0fc2 Mon Sep 17 00:00:00 2001 From: HoJeong Go Date: Wed, 10 Jan 2024 16:29:09 +0900 Subject: [PATCH] feat: modifier replacer for NetworkFilter.toString (#3699) * feat: modifier replacer for NetworkFilter.toString To make minimal performance impact on current codes using adblocker library, I chose to use Array.prototype.map function instead of putting `if` statements or using empty proxying function: `(str: text) => str` as default value. refs https://github.com/ghostery/adblocker/issues/3693 * chore: fix types use `as const` keyword * chore(test): fix test output refs https://github.com/ghostery/adblocker/pull/3681 * fix(test): test expectation to match latest commit refs #3681 --- packages/adblocker/src/filters/network.ts | 8 ++++++-- packages/adblocker/test/parsing.test.ts | 23 +++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/adblocker/src/filters/network.ts b/packages/adblocker/src/filters/network.ts index 8c8640e6a8..8ade11380e 100644 --- a/packages/adblocker/src/filters/network.ts +++ b/packages/adblocker/src/filters/network.ts @@ -1087,7 +1087,7 @@ export default class NetworkFilter implements IFilter { * there are things which cannot be recovered though, like domains options * of which only hashes are stored. */ - public toString() { + public toString(modifierReplacer?: (modifier: string) => string) { if (this.rawLine !== undefined) { return this.rawLine; } @@ -1201,7 +1201,11 @@ export default class NetworkFilter implements IFilter { } if (options.length > 0) { - filter += `$${options.join(',')}`; + if (typeof modifierReplacer === 'function') { + filter += `$${options.map(modifierReplacer).join(',')}`; + } else { + filter += `$${options.join(',')}`; + } } return filter; diff --git a/packages/adblocker/test/parsing.test.ts b/packages/adblocker/test/parsing.test.ts index 166401b40d..79fc46726f 100644 --- a/packages/adblocker/test/parsing.test.ts +++ b/packages/adblocker/test/parsing.test.ts @@ -117,11 +117,16 @@ const DEFAULT_NETWORK_FILTER = { describe('Network filters', () => { describe('toString', () => { - const checkToString = (line: string, expected: string, debug: boolean = false) => { + const checkToString = ( + line: string, + expected: string, + debug: boolean = false, + modifierReplacer = (modifier: string) => modifier, + ) => { const parsed = NetworkFilter.parse(line, debug); expect(parsed).not.to.be.null; if (parsed !== null) { - expect(parsed.toString()).to.equal(expected); + expect(parsed.toString(modifierReplacer)).to.equal(expected); } }; @@ -178,6 +183,16 @@ describe('Network filters', () => { true, ); }); + + it('pprint longer form of modifiers', () => { + checkToString('||foo.com^$3p', '||foo.com^$third-party', false, (modifier) => { + if (modifier === '3p') { + return 'third-party'; + } + + return modifier; + }); + }); }); it('parses pattern', () => { @@ -1365,9 +1380,9 @@ describe('Network filters', () => { [new Uint32Array([NORMALIZED_TYPE_TOKEN.document])], ], ['@@/wp-content/themes/$script', [hashStrings(['content'])]], - ]) { + ] as const) { it(`get tokens for ${filter}`, () => { - const parsed = NetworkFilter.parse(filter as string, true); + const parsed = NetworkFilter.parse(filter, true); expect(parsed).not.to.be.null; if (parsed !== null) { expect(parsed.getTokens()).to.eql(regexTokens);