Skip to content

Commit

Permalink
AG-31162 Improve logging in scriptlets. #411
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit ce58a21
Author: Adam Wróblewski <[email protected]>
Date:   Mon Jun 24 17:01:24 2024 +0200

    Change `logContent` to `verbose`
    Update docs

commit c2503ef
Author: Adam Wróblewski <[email protected]>
Date:   Tue Jun 18 11:46:12 2024 +0200

    Fix docs build

commit bdea52f
Author: Adam Wróblewski <[email protected]>
Date:   Tue Jun 18 09:41:24 2024 +0200

    Update docs

commit a17278d
Author: Adam Wróblewski <[email protected]>
Date:   Fri Jun 14 13:29:09 2024 +0200

    Update changelog

commit be4e0a8
Merge: a80d212 a2ac480
Author: Adam Wróblewski <[email protected]>
Date:   Fri Jun 14 13:21:43 2024 +0200

    Merge branch 'master' into fix/AG-31162

commit a80d212
Author: Adam Wróblewski <[email protected]>
Date:   Fri Jun 14 13:19:50 2024 +0200

    Add ability to log original and modified M3U content in m3u-prune scriptlet

commit 59d1348
Author: Adam Wróblewski <[email protected]>
Date:   Fri Jun 14 13:00:21 2024 +0200

    Add ability to log original and modified XML content in xml-prune scriptlet

commit ee3c9c9
Author: Adam Wróblewski <[email protected]>
Date:   Fri Jun 14 12:01:47 2024 +0200

    Add ability to log original and modified text content in trusted-replace-xhr-response scriptlet

commit 8a02970
Author: Adam Wróblewski <[email protected]>
Date:   Fri Jun 14 11:49:08 2024 +0200

    Add ability to log original and modified text content in trusted-replace-fetch-response scriptlet

commit 84e0757
Author: Adam Wróblewski <[email protected]>
Date:   Fri Jun 14 11:25:16 2024 +0200

    Add ability to log original and modified text content in trusted-replace-node-text scriptlet
  • Loading branch information
AdamWr committed Jun 25, 2024
1 parent a2ac480 commit 5614b1e
Show file tree
Hide file tree
Showing 11 changed files with 333 additions and 9 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
<!-- TODO: change `@added unknown` tag due to the actual version -->
<!-- during new scriptlets or redirects releasing -->

## [Unreleased]

### Added

- ability to log original and modified content in `trusted-replace-node-text`, `xml-prune`, `m3u-prune`,
`trusted-replace-fetch-response` and `trusted-replace-xhr-response` scriptlets [#411]

[Unreleased]: https://github.com/AdguardTeam/Scriptlets/compare/v1.11.1...HEAD
[#411]: https://github.com/AdguardTeam/Scriptlets/issues/411

## [v1.11.1] - 2024-06-13

### Added
Expand Down
32 changes: 28 additions & 4 deletions src/scriptlets/m3u-prune.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import {
* - `propsToRemove` — optional, string or regular expression
* to match the URL line (segment) which will be removed alongside with its tags
* - `urlToMatch` — optional, string or regular expression for matching the request's URL
* - `verbose` — optional, boolean, if set to 'true' will log original and modified M3U content
*
* > `verbose` may be useful for debugging but it is not allowed for prod versions of filter lists.
*
* > Usage with no arguments will log response payload and URL to browser console;
* > it may be useful for debugging but it is not allowed for prod versions of filter lists.
Expand All @@ -53,6 +56,12 @@ import {
* example.org#%#//scriptlet('m3u-prune', 'example.com/video/', '.m3u8')
* ```
*
* 1. Removes a line which contains `example.com/video/`, only if request's URL contains `.m3u8` and log content
*
* ```adblock
* example.org#%#//scriptlet('m3u-prune', 'example.com/video/', '.m3u8', 'true')
* ```
*
* 1. Call with no arguments will log response payload and URL at the console
*
* ```adblock
Expand All @@ -69,7 +78,7 @@ import {
*/
/* eslint-enable max-len */

export function m3uPrune(source, propsToRemove, urlToMatch = '') {
export function m3uPrune(source, propsToRemove, urlToMatch = '', verbose = false) {
// do nothing if browser does not support fetch or Proxy (e.g. Internet Explorer)
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Expand All @@ -83,6 +92,8 @@ export function m3uPrune(source, propsToRemove, urlToMatch = '') {

let shouldPruneResponse = false;

const shouldLogContent = verbose === 'true';

const urlMatchRegexp = toRegExp(urlToMatch);

const SEGMENT_MARKER = '#';
Expand Down Expand Up @@ -307,16 +318,23 @@ export function m3uPrune(source, propsToRemove, urlToMatch = '') {
*/
// TODO: make it compatible with $hls modifier
const pruneM3U = (text) => {
if (shouldLogContent) {
logMessage(source, `Original M3U content:\n${text}`);
}

let lines = text.split(/\r?\n/);

if (text.includes(COMCAST_AD_MARKER.VMAP_AD_BREAK)) {
lines = pruneVmapBlock(lines);
return lines.filter((l) => !!l).join('\n');
lines = lines.filter((l) => !!l).join('\n');
if (shouldLogContent) {
logMessage(source, `Modified M3U content:\n${lines}`);
}
return lines;
}

lines = pruneSegments(lines);

return lines
lines = lines
.map((line, index, array) => {
if (typeof line === 'undefined') {
return line;
Expand All @@ -329,6 +347,12 @@ export function m3uPrune(source, propsToRemove, urlToMatch = '') {
})
.filter((l) => !!l)
.join('\n');

if (shouldLogContent) {
logMessage(source, `Modified M3U content:\n${lines}`);
}

return lines;
};

const nativeOpen = window.XMLHttpRequest.prototype.open;
Expand Down
25 changes: 24 additions & 1 deletion src/scriptlets/trusted-replace-fetch-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ import {
* - `name` is [`init` option name](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters)
* - `value` is string or regular expression for matching the value of the option passed to fetch call;
* invalid regular expression will cause any value matching
* <!-- markdownlint-disable-next-line line-length -->
* - `verbose` — optional, boolean, if set to 'true' will log original and modified text content of fetch responses.
*
* > `verbose` may be useful for debugging but it is not allowed for prod versions of filter lists.
*
* > Usage with no arguments will log fetch calls to browser console;
* > it may be useful for debugging but it is not allowed for prod versions of filter lists.
Expand Down Expand Up @@ -93,10 +97,22 @@ import {
* example.org#%#//scriptlet('trusted-replace-fetch-response', '*', '', 'example.com')
* ```
*
* 1. Replace "foo" text content with "bar" of all fetch responses for example.com and log original and modified text content <!-- markdownlint-disable-line line-length -->
*
* ```adblock
* example.org#%#//scriptlet('trusted-replace-fetch-response', 'foo', 'bar', 'example.com', 'true')
* ```
*
* @added v1.7.3.
*/
/* eslint-enable max-len */
export function trustedReplaceFetchResponse(source, pattern = '', replacement = '', propsToMatch = '') {
export function trustedReplaceFetchResponse(
source,
pattern = '',
replacement = '',
propsToMatch = '',
verbose = false,
) {
// do nothing if browser does not support fetch or Proxy (e.g. Internet Explorer)
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Expand All @@ -112,6 +128,7 @@ export function trustedReplaceFetchResponse(source, pattern = '', replacement =
return;
}
const shouldLog = pattern === '' && replacement === '';
const shouldLogContent = verbose === 'true';

const nativeRequestClone = Request.prototype.clone;
const nativeFetch = fetch;
Expand Down Expand Up @@ -144,7 +161,13 @@ export function trustedReplaceFetchResponse(source, pattern = '', replacement =
? /(\n|.)*/
: toRegExp(pattern);

if (shouldLogContent) {
logMessage(source, `Original text content: ${bodyText}`);
}
const modifiedTextContent = bodyText.replace(patternRegexp, replacement);
if (shouldLogContent) {
logMessage(source, `Modified text content: ${modifiedTextContent}`);
}
const forgedResponse = forgeResponse(response, modifiedTextContent);

hit(source);
Expand Down
25 changes: 25 additions & 0 deletions src/scriptlets/trusted-replace-node-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
replaceNodeText,
isTargetNode,
parseNodeTextParams,
logMessage,
// following helpers should be imported and injected
// because they are used by helpers above
hit,
Expand Down Expand Up @@ -32,6 +33,9 @@ import {
* If matched, the whole text will be removed. Case sensitive.
* - `pattern` — required, string or regexp for matching contents of `node.textContent` that should be replaced.
* - `replacement` — required, string to replace text content matched by `pattern`.
* - `...extraArgs` — optional, string, if includes 'verbose' will log original and modified text content.
*
* > `verbose` may be useful for debugging but it is not allowed for prod versions of filter lists.
*
* ### Examples
*
Expand Down Expand Up @@ -71,6 +75,12 @@ import {
* <span>some text</span>
* ```
*
* 3. Replace node's text content and log original and modified text content:
*
* ```adblock
* example.org#%#//scriptlet('trusted-replace-node-text', 'div', 'some', 'text', 'other text', 'verbose')
* ```
*
* @added v1.9.37.
*/
/* eslint-enable max-len */
Expand Down Expand Up @@ -100,6 +110,8 @@ export function trustedReplaceNodeText(source, nodeName, textMatch, pattern, rep
}
}

const shouldLog = extraArgs.includes('verbose');

const {
selector,
nodeNameMatch,
Expand All @@ -123,7 +135,19 @@ export function trustedReplaceNodeText(source, nodeName, textMatch, pattern, rep
textContentMatch,
);
if (shouldReplace) {
if (shouldLog) {
const originalText = node.textContent;
if (originalText) {
logMessage(source, `Original text content: ${originalText}`);
}
}
replaceNodeText(source, node, patternMatch, replacement);
if (shouldLog) {
const modifiedText = node.textContent;
if (modifiedText) {
logMessage(source, `Modified text content: ${modifiedText}`);
}
}
}
});

Expand All @@ -148,6 +172,7 @@ trustedReplaceNodeText.injections = [
replaceNodeText,
isTargetNode,
parseNodeTextParams,
logMessage,
// following helpers should be imported and injected
// because they are used by helpers above
hit,
Expand Down
20 changes: 18 additions & 2 deletions src/scriptlets/trusted-replace-xhr-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ import {
* - `name` — string or regular expression for matching XMLHttpRequest property name
* - `value` — string or regular expression for matching the value of the option
* passed to `XMLHttpRequest.open()` call
* - `verbose` — optional, boolean, if set to 'true' will log original and modified text content of XMLHttpRequests.
*
* > `verbose` may be useful for debugging but it is not allowed for prod versions of filter lists.
*
* > Usage with no arguments will log XMLHttpRequest objects to browser console;
* > it may be useful for debugging but it is not allowed for prod versions of filter lists.
Expand Down Expand Up @@ -77,16 +80,22 @@ import {
* example.org#%#//scriptlet('trusted-replace-xhr-response', '/#EXT-X-VMAP-AD-BREAK[\s\S]*?/', '#EXT-X-ENDLIST', '/\.m3u8/ method:/GET|HEAD/') <!-- markdownlint-disable-line line-length -->
* ```
*
* 1. Remove all text content of all XMLHttpRequests for example.com
* 1. Remove all text content of all XMLHttpRequests for example.com
*
* ```adblock
* example.org#%#//scriptlet('trusted-replace-xhr-response', '*', '', 'example.com')
* ```
*
* 1. Replace "foo" text content with "bar" of all XMLHttpRequests for example.com and log original and modified text content <!-- markdownlint-disable-line line-length -->
*
* ```adblock
* example.org#%#//scriptlet('trusted-replace-xhr-response', 'foo', 'bar', 'example.com', 'true')
* ```
*
* @added v1.7.3.
*/
/* eslint-enable max-len */
export function trustedReplaceXhrResponse(source, pattern = '', replacement = '', propsToMatch = '') {
export function trustedReplaceXhrResponse(source, pattern = '', replacement = '', propsToMatch = '', verbose = false) {
// do nothing if browser does not support Proxy (e.g. Internet Explorer)
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
if (typeof Proxy === 'undefined') {
Expand All @@ -101,6 +110,7 @@ export function trustedReplaceXhrResponse(source, pattern = '', replacement = ''
}

const shouldLog = pattern === '' && replacement === '';
const shouldLogContent = verbose === 'true';

const nativeOpen = window.XMLHttpRequest.prototype.open;
const nativeSend = window.XMLHttpRequest.prototype.send;
Expand Down Expand Up @@ -182,7 +192,13 @@ export function trustedReplaceXhrResponse(source, pattern = '', replacement = ''
? /(\n|.)*/
: toRegExp(pattern);

if (shouldLogContent) {
logMessage(source, `Original text content: ${content}`);
}
const modifiedContent = content.replace(patternRegexp, replacement);
if (shouldLogContent) {
logMessage(source, `Modified text content: ${modifiedContent}`);
}

// Manually put required values into target XHR object
// as thisArg can't be redefined and XHR objects can't be (re)assigned or copied
Expand Down
23 changes: 22 additions & 1 deletion src/scriptlets/xml-prune.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import {
* - `propsToMatch` — optional, XPath or selector of elements which will be removed from XML
* - `optionalProp` — optional, selector of elements that must occur in XML document
* - `urlToMatch` — optional, string or regular expression for matching the request's URL
* - `verbose` — optional, boolean, if set to 'true' will log original and modified XML content
*
* > `verbose` may be useful for debugging but it is not allowed for prod versions of filter lists.
*
* > Usage with no arguments will log response payload and URL to browser console;
* > it may be useful for debugging but it is not allowed for prod versions of filter lists.
Expand All @@ -59,6 +62,12 @@ import {
* example.org#%#//scriptlet('xml-prune', 'Period[id*="-ad-"]', '', '.mpd')
* ```
*
* 1. Remove `Period` tag whose `id` contains `-ad-`, only if request's URL contains `.mpd` and log content
*
* ```adblock
* example.org#%#//scriptlet('xml-prune', 'Period[id*="-ad-"]', '', '.mpd', 'true')
* ```
*
* 1. Remove `Period` tag whose `id` contains `pre-roll` and remove `duration` attribute from the `Period` tag
* by using XPath expression
*
Expand Down Expand Up @@ -86,7 +95,7 @@ import {
*/
/* eslint-enable max-len */

export function xmlPrune(source, propsToRemove, optionalProp = '', urlToMatch = '') {
export function xmlPrune(source, propsToRemove, optionalProp = '', urlToMatch = '', verbose = false) {
// do nothing if browser does not support Reflect, fetch or Proxy (e.g. Internet Explorer)
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Expand All @@ -100,6 +109,8 @@ export function xmlPrune(source, propsToRemove, optionalProp = '', urlToMatch =

let shouldPruneResponse = false;

const shouldLogContent = verbose === 'true';

const urlMatchRegexp = toRegExp(urlToMatch);

const XPATH_MARKER = 'xpath(';
Expand Down Expand Up @@ -193,13 +204,23 @@ export function xmlPrune(source, propsToRemove, optionalProp = '', urlToMatch =
shouldPruneResponse = false;
return text;
}
if (shouldLogContent) {
// It's necessary to clone the XML document because xmlDoc is logged with removed elements
const cloneXmlDoc = xmlDoc.cloneNode(true);
logMessage(source, 'Original xml:');
logMessage(source, cloneXmlDoc, true, false);
}
if (isXpath) {
xPathPruning(elements);
} else {
elements.forEach((elem) => {
elem.remove();
});
}
if (shouldLogContent) {
logMessage(source, 'Modified xml:');
logMessage(source, xmlDoc, true, false);
}
const serializer = new XMLSerializer();
text = serializer.serializeToString(xmlDoc);
return text;
Expand Down
Loading

0 comments on commit 5614b1e

Please sign in to comment.