Support removing whole lines of text with regex in m3u-prune scriptlet

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/2508

If the first argument is a regex with multine flag set, the
scriptlet will execute the regex against the whole text, and
remove matching text from the whole text.

If the matching text does not contains whole lines, the text
won't be removed, i.e. it is not allowed to remove only part
of a line.
This commit is contained in:
Raymond Hill 2023-03-12 17:45:02 -04:00
parent f80c84ab40
commit b3821e6869
No known key found for this signature in database
GPG key ID: 25E1490B761470C2

View file

@ -1668,7 +1668,6 @@
})();
/// xml-prune.js
(function() {
let selector = '{{1}}';
@ -1739,7 +1738,6 @@
})();
/// m3u-prune.js
// https://en.wikipedia.org/wiki/M3U
(function() {
@ -1753,7 +1751,12 @@
}
const regexFromArg = arg => {
if ( arg === '' ) { return /^/; }
if ( /^\/.*\/$/.test(arg) ) { return new RegExp(arg.slice(1, -1)); }
const match = /^\/(.+)\/([gms]*)$/.exec(arg);
if ( match !== null ) {
let flags = match[2] || '';
if ( flags.includes('m') ) { flags += 's'; }
return new RegExp(match[1], flags);
}
return new RegExp(
arg.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*+/g, '.*?')
);
@ -1790,6 +1793,22 @@
};
const pruner = text => {
if ( (/^\s*#EXTM3U/.test(text)) === false ) { return text; }
if ( reM3u.multiline ) {
reM3u.lastIndex = 0;
for (;;) {
const match = reM3u.exec(text);
if ( match === null ) { break; }
const before = text.slice(0, match.index);
if ( before.length === 0 || /[\n\r]+\s*$/.test(before) ) {
const after = text.slice(match.index + match[0].length);
if ( after.length === 0 || /^\s*[\n\r]+/.test(after) ) {
text = before.trim() + '\n' + after.trim();
reM3u.lastIndex = before.length + 1;
}
}
if ( reM3u.global === false ) { break; }
}
}
const lines = text.split(/\n\r|\n|\r/);
for ( let i = 0; i < lines.length; i++ ) {
if ( lines[i] === undefined ) { continue; }
@ -1841,7 +1860,6 @@
})();
/// href-sanitizer.js
(function() {
let selector = '{{1}}';