-
bolt
-
eye-dropper
-
comment-alt
-
list-alt
+
+
+ sun-o
+ sun
+
+
+
+
cogs
-
-
-
+
+
_ angle-up
@@ -61,6 +63,10 @@
+
+
diff --git a/platform/mv3/make-rulesets.js b/platform/mv3/make-rulesets.js
index 0b2374000..90f637ac6 100644
--- a/platform/mv3/make-rulesets.js
+++ b/platform/mv3/make-rulesets.js
@@ -25,7 +25,9 @@
import fs from 'fs/promises';
import https from 'https';
+import path from 'path';
import process from 'process';
+import { createHash } from 'crypto';
import { dnrRulesetFromRawLists } from './js/static-dnr-filtering.js';
import { StaticFilteringParser } from './js/static-filtering-parser.js';
@@ -91,25 +93,51 @@ const log = (text, silent = false) => {
/******************************************************************************/
-const fetchList = url => {
+const urlToFileName = url => {
+ return url
+ .replace(/^https?:\/\//, '')
+ .replace(/\//g, '_')
+ ;
+};
+
+const fetchList = (url, cacheDir) => {
return new Promise((resolve, reject) => {
- log(`\tFetching ${url}`);
- https.get(url, response => {
- const data = [];
- response.on('data', chunk => {
- data.push(chunk.toString());
+ const fname = urlToFileName(url);
+ fs.readFile(`${cacheDir}/${fname}`, { encoding: 'utf8' }).then(content => {
+ log(`\tFetched local ${url}`);
+ resolve({ url, content });
+ }).catch(( ) => {
+ log(`\tFetching remote ${url}`);
+ https.get(url, response => {
+ const data = [];
+ response.on('data', chunk => {
+ data.push(chunk.toString());
+ });
+ response.on('end', ( ) => {
+ const content = data.join('');
+ try {
+ writeFile(`${cacheDir}/${fname}`, content);
+ } catch (ex) {
+ }
+ resolve({ url, content });
+ });
+ }).on('error', error => {
+ reject(error);
});
- response.on('end', ( ) => {
- resolve({ url, content: data.join('') });
- });
- }).on('error', error => {
- reject(error);
});
});
};
/******************************************************************************/
+const writeFile = async (fname, data) => {
+ const dir = path.dirname(fname);
+ await fs.mkdir(dir, { recursive: true });
+ return fs.writeFile(fname, data);
+};
+
+/******************************************************************************/
+
async function main() {
const env = [ 'chromium' ];
@@ -117,7 +145,7 @@ async function main() {
const writeOps = [];
const ruleResources = [];
const rulesetDetails = [];
- const regexRulesetDetails = new Map();
+ const cssDetails = new Map();
const outputDir = commandLineArgs.get('output') || '.';
// Get manifest content
@@ -159,11 +187,8 @@ async function main() {
};
const rulesetDir = `${outputDir}/rulesets`;
- const rulesetDirPromise = fs.mkdir(`${rulesetDir}`, { recursive: true });
-
- const writeFile = (path, data) =>
- rulesetDirPromise.then(( ) =>
- fs.writeFile(path, data));
+ const cacheDir = `${outputDir}/../mv3-data`;
+ const cssDir = `${outputDir}/content-css`;
const rulesetFromURLS = async function(assetDetails) {
log('============================');
@@ -187,7 +212,7 @@ async function main() {
}
fetchedURLs.add(part.url);
newParts.push(
- fetchList(part.url).then(details => {
+ fetchList(part.url, cacheDir).then(details => {
const { url } = details;
const content = details.content.trim();
if ( typeof content === 'string' && content !== '' ) {
@@ -213,11 +238,12 @@ async function main() {
return;
}
- const details = await dnrRulesetFromRawLists([ { name: assetDetails.id, text } ], { env });
- const { ruleset: rules } = details;
- log(`Input filter count: ${details.filterCount}`);
- log(`\tAccepted filter count: ${details.acceptedFilterCount}`);
- log(`\tRejected filter count: ${details.rejectedFilterCount}`);
+ const results = await dnrRulesetFromRawLists([ { name: assetDetails.id, text } ], { env });
+ const { network } = results;
+ const { ruleset: rules } = network;
+ log(`Input filter count: ${network.filterCount}`);
+ log(`\tAccepted filter count: ${network.acceptedFilterCount}`);
+ log(`\tRejected filter count: ${network.rejectedFilterCount}`);
log(`Output rule count: ${rules.length}`);
const good = rules.filter(rule => isGood(rule) && isRegex(rule) === false);
@@ -253,15 +279,51 @@ async function main() {
true
);
+ writeOps.push(
+ writeFile(
+ `${rulesetDir}/${assetDetails.id}.json`,
+ `${JSON.stringify(good, replacer)}\n`
+ )
+ );
+
+ if ( regexes.length !== 0 ) {
+ writeOps.push(
+ writeFile(
+ `${rulesetDir}/${assetDetails.id}.regexes.json`,
+ `${JSON.stringify(regexes, replacer)}\n`
+ )
+ );
+ }
+
+ const { cosmetic } = results;
+ const cssEntries = [];
+ for ( const entry of cosmetic ) {
+ const fname = createHash('sha256').update(entry.css).digest('hex').slice(0,8);
+ const fpath = `${assetDetails.id}/${fname.slice(0,1)}/${fname.slice(1,8)}`;
+ writeOps.push(
+ writeFile(
+ `${cssDir}/${fpath}.css`,
+ `${entry.css}\n{display:none!important;}\n`
+ )
+ );
+ entry.css = fname;
+ cssEntries.push(entry);
+ }
+ log(`CSS entries: ${cssEntries.length}`);
+ if ( cssEntries.length !== 0 ) {
+ cssDetails.set(assetDetails.id, cssEntries);
+ }
+
rulesetDetails.push({
id: assetDetails.id,
name: assetDetails.name,
enabled: assetDetails.enabled,
lang: assetDetails.lang,
+ homeURL: assetDetails.homeURL,
filters: {
- total: details.filterCount,
- accepted: details.acceptedFilterCount,
- rejected: details.rejectedFilterCount,
+ total: network.filterCount,
+ accepted: network.acceptedFilterCount,
+ rejected: network.rejectedFilterCount,
},
rules: {
total: rules.length,
@@ -270,24 +332,11 @@ async function main() {
rejected: bad.length,
regexes: regexes.length,
},
+ css: {
+ specific: cssEntries.length,
+ },
});
- writeOps.push(
- writeFile(
- `${rulesetDir}/${assetDetails.id}.json`,
- `${JSON.stringify(good, replacer, 2)}\n`
- )
- );
-
- regexRulesetDetails.set(assetDetails.id, regexes);
-
- writeOps.push(
- writeFile(
- `${rulesetDir}/${assetDetails.id}.regexes.json`,
- `${JSON.stringify(regexes, replacer, 2)}\n`
- )
- );
-
ruleResources.push({
id: assetDetails.id,
enabled: assetDetails.enabled,
@@ -321,6 +370,7 @@ async function main() {
name: 'Ads, trackers, miners, and more' ,
enabled: true,
urls: contentURLs,
+ homeURL: 'https://github.com/uBlockOrigin/uAssets',
});
// Regional rulesets
@@ -338,10 +388,11 @@ async function main() {
name: asset.title,
enabled: false,
urls: [ contentURL ],
+ homeURL: asset.supportURL,
});
}
- // Handpicked rulesets
+ // Handpicked rulesets from assets.json
const handpicked = [ 'block-lan', 'dpollock-0' ];
for ( const id of handpicked ) {
const asset = assets[id];
@@ -355,13 +406,30 @@ async function main() {
name: asset.title,
enabled: false,
urls: [ contentURL ],
+ homeURL: asset.supportURL,
});
}
+ // Handpicked rulesets from abroad
+ await rulesetFromURLS({
+ id: 'stevenblack-hosts',
+ name: 'Steven Black\'s hosts file',
+ enabled: false,
+ urls: [ 'https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts' ],
+ homeURL: 'https://github.com/StevenBlack/hosts#readme',
+ });
+
writeOps.push(
writeFile(
`${rulesetDir}/ruleset-details.json`,
- `${JSON.stringify(rulesetDetails, replacer, 2)}\n`
+ `${JSON.stringify(rulesetDetails, null, 2)}\n`
+ )
+ );
+
+ writeOps.push(
+ writeFile(
+ `${cssDir}/css-specific.json`,
+ `${JSON.stringify(Array.from(cssDetails), null, 2)}\n`
)
);
diff --git a/src/css/fa-icons.css b/src/css/fa-icons.css
index a212889a5..a912e7aa5 100644
--- a/src/css/fa-icons.css
+++ b/src/css/fa-icons.css
@@ -75,6 +75,10 @@
.fa-icon > .fa-icon_list-alt {
width: calc(1em * 1792 / 1792);
}
+.fa-icon > .fa-icon_sun,
+.fa-icon > .fa-icon_sun-o {
+ width: calc(1em * 1708 / 1792);
+ }
.fa-icon > .fa-icon_download-alt,
.fa-icon > .fa-icon_font,
.fa-icon > .fa-icon_search,
@@ -85,6 +89,9 @@
.fa-icon > .fa-icon_zoom-out {
width: calc(1em * 1664 / 1792);
}
+.fa-icon > .fa-icon_magic {
+ width: calc(1em * 1637 / 1792);
+ }
.fa-icon > .fa-icon_home {
width: calc(1em * 1612 / 1792);
}
diff --git a/src/js/fa-icons.js b/src/js/fa-icons.js
index 67638ba68..a9a9d3be0 100644
--- a/src/js/fa-icons.js
+++ b/src/js/fa-icons.js
@@ -59,6 +59,7 @@ const faIconsInit = (( ) => {
[ 'info-circle', { viewBox: '0 0 1536 1536', path: 'm 1024,1248 0,-160 q 0,-14 -9,-23 -9,-9 -23,-9 l -96,0 0,-512 q 0,-14 -9,-23 -9,-9 -23,-9 l -320,0 q -14,0 -23,9 -9,9 -9,23 l 0,160 q 0,14 9,23 9,9 23,9 l 96,0 0,320 -96,0 q -14,0 -23,9 -9,9 -9,23 l 0,160 q 0,14 9,23 9,9 23,9 l 448,0 q 14,0 23,-9 9,-9 9,-23 z M 896,352 896,192 q 0,-14 -9,-23 -9,-9 -23,-9 l -192,0 q -14,0 -23,9 -9,9 -9,23 l 0,160 q 0,14 9,23 9,9 23,9 l 192,0 q 14,0 23,-9 9,-9 9,-23 z m 640,416 q 0,209 -103,385.5 Q 1330,1330 1153.5,1433 977,1536 768,1536 559,1536 382.5,1433 206,1330 103,1153.5 0,977 0,768 0,559 103,382.5 206,206 382.5,103 559,0 768,0 977,0 1153.5,103 1330,206 1433,382.5 1536,559 1536,768 Z' } ],
[ 'list-alt', { viewBox: '0 0 1792 1408', path: 'm 384,1056 0,64 q 0,13 -9.5,22.5 -9.5,9.5 -22.5,9.5 l -64,0 q -13,0 -22.5,-9.5 Q 256,1133 256,1120 l 0,-64 q 0,-13 9.5,-22.5 9.5,-9.5 22.5,-9.5 l 64,0 q 13,0 22.5,9.5 9.5,9.5 9.5,22.5 z m 0,-256 0,64 q 0,13 -9.5,22.5 Q 365,896 352,896 l -64,0 q -13,0 -22.5,-9.5 Q 256,877 256,864 l 0,-64 q 0,-13 9.5,-22.5 Q 275,768 288,768 l 64,0 q 13,0 22.5,9.5 9.5,9.5 9.5,22.5 z m 0,-256 0,64 q 0,13 -9.5,22.5 Q 365,640 352,640 l -64,0 q -13,0 -22.5,-9.5 Q 256,621 256,608 l 0,-64 q 0,-13 9.5,-22.5 Q 275,512 288,512 l 64,0 q 13,0 22.5,9.5 9.5,9.5 9.5,22.5 z m 1152,512 0,64 q 0,13 -9.5,22.5 -9.5,9.5 -22.5,9.5 l -960,0 q -13,0 -22.5,-9.5 Q 512,1133 512,1120 l 0,-64 q 0,-13 9.5,-22.5 9.5,-9.5 22.5,-9.5 l 960,0 q 13,0 22.5,9.5 9.5,9.5 9.5,22.5 z m 0,-256 0,64 q 0,13 -9.5,22.5 -9.5,9.5 -22.5,9.5 l -960,0 q -13,0 -22.5,-9.5 Q 512,877 512,864 l 0,-64 q 0,-13 9.5,-22.5 Q 531,768 544,768 l 960,0 q 13,0 22.5,9.5 9.5,9.5 9.5,22.5 z m 0,-256 0,64 q 0,13 -9.5,22.5 -9.5,9.5 -22.5,9.5 l -960,0 q -13,0 -22.5,-9.5 Q 512,621 512,608 l 0,-64 q 0,-13 9.5,-22.5 Q 531,512 544,512 l 960,0 q 13,0 22.5,9.5 9.5,9.5 9.5,22.5 z m 128,704 0,-832 q 0,-13 -9.5,-22.5 Q 1645,384 1632,384 l -1472,0 q -13,0 -22.5,9.5 Q 128,403 128,416 l 0,832 q 0,13 9.5,22.5 9.5,9.5 22.5,9.5 l 1472,0 q 13,0 22.5,-9.5 9.5,-9.5 9.5,-22.5 z m 128,-1088 0,1088 q 0,66 -47,113 -47,47 -113,47 l -1472,0 Q 94,1408 47,1361 0,1314 0,1248 L 0,160 Q 0,94 47,47 94,0 160,0 l 1472,0 q 66,0 113,47 47,47 47,113 z' } ],
[ 'lock', { viewBox: '0 0 1152 1408', path: 'm 320,640 512,0 0,-192 q 0,-106 -75,-181 -75,-75 -181,-75 -106,0 -181,75 -75,75 -75,181 l 0,192 z m 832,96 0,576 q 0,40 -28,68 -28,28 -68,28 l -960,0 Q 56,1408 28,1380 0,1352 0,1312 L 0,736 q 0,-40 28,-68 28,-28 68,-28 l 32,0 0,-192 Q 128,264 260,132 392,0 576,0 q 184,0 316,132 132,132 132,316 l 0,192 32,0 q 40,0 68,28 28,28 28,68 z' } ],
+ [ 'magic', { viewBox: '0 0 1637 1637', path: 'M 1163,581 1456,288 1349,181 1056,474 Z m 447,-293 q 0,27 -18,45 L 306,1619 q -18,18 -45,18 -27,0 -45,-18 L 18,1421 Q 0,1403 0,1376 0,1349 18,1331 L 1304,45 q 18,-18 45,-18 27,0 45,18 l 198,198 q 18,18 18,45 z M 259,98 l 98,30 -98,30 -30,98 -30,-98 -98,-30 98,-30 30,-98 z M 609,260 805,320 609,380 549,576 489,380 293,320 489,260 549,64 Z m 930,478 98,30 -98,30 -30,98 -30,-98 -98,-30 98,-30 30,-98 z M 899,98 l 98,30 -98,30 -30,98 -30,-98 -98,-30 98,-30 30,-98 z' } ],
[ 'pause-circle-o', { viewBox: '0 0 1536 1536', path: 'M 768,0 Q 977,0 1153.5,103 1330,206 1433,382.5 1536,559 1536,768 1536,977 1433,1153.5 1330,1330 1153.5,1433 977,1536 768,1536 559,1536 382.5,1433 206,1330 103,1153.5 0,977 0,768 0,559 103,382.5 206,206 382.5,103 559,0 768,0 Z m 0,1312 q 148,0 273,-73 125,-73 198,-198 73,-125 73,-273 0,-148 -73,-273 -73,-125 -198,-198 -125,-73 -273,-73 -148,0 -273,73 -125,73 -198,198 -73,125 -73,273 0,148 73,273 73,125 198,198 125,73 273,73 z m 96,-224 q -14,0 -23,-9 -9,-9 -9,-23 l 0,-576 q 0,-14 9,-23 9,-9 23,-9 l 192,0 q 14,0 23,9 9,9 9,23 l 0,576 q 0,14 -9,23 -9,9 -23,9 l -192,0 z m -384,0 q -14,0 -23,-9 -9,-9 -9,-23 l 0,-576 q 0,-14 9,-23 9,-9 23,-9 l 192,0 q 14,0 23,9 9,9 9,23 l 0,576 q 0,14 -9,23 -9,9 -23,9 l -192,0 z' } ],
[ 'play-circle-o', { viewBox: '0 0 1536 1536', path: 'm 1184,768 q 0,37 -32,55 l -544,320 q -15,9 -32,9 -16,0 -32,-8 -32,-19 -32,-56 l 0,-640 q 0,-37 32,-56 33,-18 64,1 l 544,320 q 32,18 32,55 z m 128,0 q 0,-148 -73,-273 -73,-125 -198,-198 -125,-73 -273,-73 -148,0 -273,73 -125,73 -198,198 -73,125 -73,273 0,148 73,273 73,125 198,198 125,73 273,73 148,0 273,-73 125,-73 198,-198 73,-125 73,-273 z m 224,0 q 0,209 -103,385.5 Q 1330,1330 1153.5,1433 977,1536 768,1536 559,1536 382.5,1433 206,1330 103,1153.5 0,977 0,768 0,559 103,382.5 206,206 382.5,103 559,0 768,0 977,0 1153.5,103 1330,206 1433,382.5 1536,559 1536,768 Z' } ],
[ 'plus', { viewBox: '0 0 1408 1408', path: 'm 1408,608 0,192 q 0,40 -28,68 -28,28 -68,28 l -416,0 0,416 q 0,40 -28,68 -28,28 -68,28 l -192,0 q -40,0 -68,-28 -28,-28 -28,-68 l 0,-416 -416,0 Q 56,896 28,868 0,840 0,800 L 0,608 q 0,-40 28,-68 28,-28 68,-28 l 416,0 0,-416 Q 512,56 540,28 568,0 608,0 l 192,0 q 40,0 68,28 28,28 28,68 l 0,416 416,0 q 40,0 68,28 28,28 28,68 z' } ],
@@ -69,6 +70,8 @@ const faIconsInit = (( ) => {
[ 'search', { viewBox: '0 0 1664 1664', path: 'M 1152,704 Q 1152,519 1020.5,387.5 889,256 704,256 519,256 387.5,387.5 256,519 256,704 256,889 387.5,1020.5 519,1152 704,1152 889,1152 1020.5,1020.5 1152,889 1152,704 Z m 512,832 q 0,52 -38,90 -38,38 -90,38 -54,0 -90,-38 L 1103,1284 Q 924,1408 704,1408 561,1408 430.5,1352.5 300,1297 205.5,1202.5 111,1108 55.5,977.5 0,847 0,704 0,561 55.5,430.5 111,300 205.5,205.5 300,111 430.5,55.5 561,0 704,0 q 143,0 273.5,55.5 130.5,55.5 225,150 94.5,94.5 150,225 55.5,130.5 55.5,273.5 0,220 -124,399 l 343,343 q 37,37 37,90 z' } ],
[ 'sliders', { viewBox: '0 0 1536 1408', path: 'm 352,1152 0,128 -352,0 0,-128 352,0 z m 352,-128 q 26,0 45,19 19,19 19,45 l 0,256 q 0,26 -19,45 -19,19 -45,19 l -256,0 q -26,0 -45,-19 -19,-19 -19,-45 l 0,-256 q 0,-26 19,-45 19,-19 45,-19 l 256,0 z m 160,-384 0,128 -864,0 0,-128 864,0 z m -640,-512 0,128 -224,0 0,-128 224,0 z m 1312,1024 0,128 -736,0 0,-128 736,0 z M 576,0 q 26,0 45,19 19,19 19,45 l 0,256 q 0,26 -19,45 -19,19 -45,19 l -256,0 q -26,0 -45,-19 -19,-19 -19,-45 L 256,64 Q 256,38 275,19 294,0 320,0 l 256,0 z m 640,512 q 26,0 45,19 19,19 19,45 l 0,256 q 0,26 -19,45 -19,19 -45,19 l -256,0 q -26,0 -45,-19 -19,-19 -19,-45 l 0,-256 q 0,-26 19,-45 19,-19 45,-19 l 256,0 z m 320,128 0,128 -224,0 0,-128 224,0 z m 0,-512 0,128 -864,0 0,-128 864,0 z' } ],
[ 'spinner', { viewBox: '0 0 1664 1728', path: 'm 462,1394 q 0,53 -37.5,90.5 -37.5,37.5 -90.5,37.5 -52,0 -90,-38 -38,-38 -38,-90 0,-53 37.5,-90.5 37.5,-37.5 90.5,-37.5 53,0 90.5,37.5 37.5,37.5 37.5,90.5 z m 498,206 q 0,53 -37.5,90.5 Q 885,1728 832,1728 779,1728 741.5,1690.5 704,1653 704,1600 q 0,-53 37.5,-90.5 37.5,-37.5 90.5,-37.5 53,0 90.5,37.5 Q 960,1547 960,1600 Z M 256,896 q 0,53 -37.5,90.5 Q 181,1024 128,1024 75,1024 37.5,986.5 0,949 0,896 0,843 37.5,805.5 75,768 128,768 q 53,0 90.5,37.5 Q 256,843 256,896 Z m 1202,498 q 0,52 -38,90 -38,38 -90,38 -53,0 -90.5,-37.5 -37.5,-37.5 -37.5,-90.5 0,-53 37.5,-90.5 37.5,-37.5 90.5,-37.5 53,0 90.5,37.5 37.5,37.5 37.5,90.5 z M 494,398 q 0,66 -47,113 -47,47 -113,47 -66,0 -113,-47 -47,-47 -47,-113 0,-66 47,-113 47,-47 113,-47 66,0 113,47 47,47 47,113 z m 1170,498 q 0,53 -37.5,90.5 -37.5,37.5 -90.5,37.5 -53,0 -90.5,-37.5 Q 1408,949 1408,896 q 0,-53 37.5,-90.5 37.5,-37.5 90.5,-37.5 53,0 90.5,37.5 Q 1664,843 1664,896 Z M 1024,192 q 0,80 -56,136 -56,56 -136,56 -80,0 -136,-56 -56,-56 -56,-136 0,-80 56,-136 56,-56 136,-56 80,0 136,56 56,56 56,136 z m 530,206 q 0,93 -66,158.5 -66,65.5 -158,65.5 -93,0 -158.5,-65.5 Q 1106,491 1106,398 q 0,-92 65.5,-158 65.5,-66 158.5,-66 92,0 158,66 66,66 66,158 z' } ],
+ [ 'sun', { viewBox: '0 0 1708 1792', path: 'm 1706,1172.5 c -3,10 -11,17 -20,20 l -292,96 v 306 c 0,10 -5,20 -13,26 -9,6 -19,8 -29,4 l -292,-94 -180,248 c -6,8 -16,13 -26,13 -10,0 -20,-5 -26,-13 l -180,-248 -292,94 c -10,4 -20,2 -29,-4 -8,-6 -13,-16 -13,-26 v -306 l -292,-96 c -9,-3 -17,-10 -20,-20 -3,-10 -2,-21 4,-29 l 180,-248 -180,-248 c -6,-9 -7,-19 -4,-29 3,-10 11,-17 20,-20 l 292,-96 v -306 c 0,-10 5,-20 13,-26 9,-6 19,-8 29,-4 l 292,94 180,-248 c 12,-16 40,-16 52,0 L 1060,260.5 l 292,-94 c 10,-4 20,-2 29,4 8,6 13,16 13,26 v 306 l 292,96 c 9,3 17,10 20,20 3,10 2,20 -4,29 l -180,248 180,248 c 6,8 7,19 4,29 z' } ],
+ [ 'sun-o', { viewBox: '0 0 1708 1792', path: 'm 1430,895.5 c 0,-318 -258,-576 -576,-576 -318,0 -576,258 -576,576 0,318 258,576 576,576 C 1172,1471.5 1430,1213.5 1430,895.5 Z m 276,277 c -3,10 -11,17 -20,20 l -292,96 v 306 c 0,10 -5,20 -13,26 -9,6 -19,8 -29,4 l -292,-94 -180,248 c -6,8 -16,13 -26,13 -10,0 -20,-5 -26,-13 l -180,-248 -292,94 c -10,4 -20,2 -29,-4 -8,-6 -13,-16 -13,-26 v -306 l -292,-96 c -9,-3 -17,-10 -20,-20 -3,-10 -2,-21 4,-29 l 180,-248 -180,-248 c -6,-9 -7,-19 -4,-29 3,-10 11,-17 20,-20 l 292,-96 v -306 c 0,-10 5,-20 13,-26 9,-6 19,-8 29,-4 l 292,94 180,-248 c 12,-16 40,-16 52,0 L 1060,260.5 l 292,-94 c 10,-4 20,-2 29,4 8,6 13,16 13,26 v 306 l 292,96 c 9,3 17,10 20,20 3,10 2,20 -4,29 l -180,248 180,248 c 6,8 7,19 4,29 z' } ],
[ 'times', { viewBox: '0 0 1188 1188', path: 'm 1188,956 q 0,40 -28,68 l -136,136 q -28,28 -68,28 -40,0 -68,-28 L 594,866 300,1160 q -28,28 -68,28 -40,0 -68,-28 L 28,1024 Q 0,996 0,956 0,916 28,888 L 322,594 28,300 Q 0,272 0,232 0,192 28,164 L 164,28 Q 192,0 232,0 272,0 300,28 L 594,322 888,28 q 28,-28 68,-28 40,0 68,28 l 136,136 q 28,28 28,68 0,40 -28,68 l -294,294 294,294 q 28,28 28,68 z' } ],
[ 'trash-o', { viewBox: '0 0 1408 1536', path: 'm 512,608 v 576 q 0,14 -9,23 -9,9 -23,9 h -64 q -14,0 -23,-9 -9,-9 -9,-23 V 608 q 0,-14 9,-23 9,-9 23,-9 h 64 q 14,0 23,9 9,9 9,23 z m 256,0 v 576 q 0,14 -9,23 -9,9 -23,9 h -64 q -14,0 -23,-9 -9,-9 -9,-23 V 608 q 0,-14 9,-23 9,-9 23,-9 h 64 q 14,0 23,9 9,9 9,23 z m 256,0 v 576 q 0,14 -9,23 -9,9 -23,9 h -64 q -14,0 -23,-9 -9,-9 -9,-23 V 608 q 0,-14 9,-23 9,-9 23,-9 h 64 q 14,0 23,9 9,9 9,23 z m 128,724 V 384 H 256 v 948 q 0,22 7,40.5 7,18.5 14.5,27 7.5,8.5 10.5,8.5 h 832 q 3,0 10.5,-8.5 7.5,-8.5 14.5,-27 7,-18.5 7,-40.5 z M 480,256 H 928 L 880,139 q -7,-9 -17,-11 H 546 q -10,2 -17,11 z m 928,32 v 64 q 0,14 -9,23 -9,9 -23,9 h -96 v 948 q 0,83 -47,143.5 -47,60.5 -113,60.5 H 288 q -66,0 -113,-58.5 Q 128,1419 128,1336 V 384 H 32 Q 18,384 9,375 0,366 0,352 v -64 q 0,-14 9,-23 9,-9 23,-9 H 341 L 411,89 Q 426,52 465,26 504,0 544,0 h 320 q 40,0 79,26 39,26 54,63 l 70,167 h 309 q 14,0 23,9 9,9 9,23 z' } ],
[ 'undo', { viewBox: '0 0 1536 1536', path: 'm 1536,768 q 0,156 -61,298 -61,142 -164,245 -103,103 -245,164 -142,61 -298,61 -172,0 -327,-72.5 Q 286,1391 177,1259 q -7,-10 -6.5,-22.5 0.5,-12.5 8.5,-20.5 l 137,-138 q 10,-9 25,-9 16,2 23,12 73,95 179,147 106,52 225,52 104,0 198.5,-40.5 Q 1061,1199 1130,1130 1199,1061 1239.5,966.5 1280,872 1280,768 1280,664 1239.5,569.5 1199,475 1130,406 1061,337 966.5,296.5 872,256 768,256 670,256 580,291.5 490,327 420,393 l 137,138 q 31,30 14,69 -17,40 -59,40 H 64 Q 38,640 19,621 0,602 0,576 V 128 Q 0,86 40,69 79,52 109,83 L 239,212 Q 346,111 483.5,55.5 621,0 768,0 q 156,0 298,61 142,61 245,164 103,103 164,245 61,142 61,298 z' } ],
diff --git a/src/js/messaging.js b/src/js/messaging.js
index 5d19080af..6c83d5555 100644
--- a/src/js/messaging.js
+++ b/src/js/messaging.js
@@ -19,6 +19,8 @@
Home: https://github.com/gorhill/uBlock
*/
+/* globals browser */
+
'use strict';
/******************************************************************************/
@@ -161,7 +163,8 @@ const onMessage = function(request, sender, callback) {
env: vAPI.webextFlavor.env,
};
const t0 = Date.now();
- dnrRulesetFromRawLists(listPromises, options).then(details => {
+ dnrRulesetFromRawLists(listPromises, options).then(result => {
+ const { network } = result;
const replacer = (k, v) => {
if ( k.startsWith('__') ) { return; }
if ( Array.isArray(v) ) {
@@ -193,13 +196,13 @@ const onMessage = function(request, sender, callback) {
rule.action.type === 'redirect' &&
rule.action.redirect.transform !== undefined;
const runtime = Date.now() - t0;
- const { ruleset } = details;
+ const { ruleset } = network;
const out = [
`dnrRulesetFromRawLists(${JSON.stringify(listNames, null, 2)})`,
`Run time: ${runtime} ms`,
- `Filters count: ${details.filterCount}`,
- `Accepted filter count: ${details.acceptedFilterCount}`,
- `Rejected filter count: ${details.rejectedFilterCount}`,
+ `Filters count: ${network.filterCount}`,
+ `Accepted filter count: ${network.acceptedFilterCount}`,
+ `Rejected filter count: ${network.rejectedFilterCount}`,
`Resulting DNR rule count: ${ruleset.length}`,
];
const good = ruleset.filter(rule =>
@@ -237,6 +240,12 @@ const onMessage = function(request, sender, callback) {
isUnsupported(rule)
);
out.push(`+ Unsupported filters (${bad.length}): ${JSON.stringify(bad, replacer, 2)}`);
+
+ out.push(`\n+ Cosmetic filters: ${result.cosmetic.length}`);
+ for ( const details of result.cosmetic ) {
+ out.push(` ${JSON.stringify(details)}`);
+ }
+
callback(out.join('\n'));
});
return;
diff --git a/src/js/static-dnr-filtering.js b/src/js/static-dnr-filtering.js
index 0063a62ee..4a441585b 100644
--- a/src/js/static-dnr-filtering.js
+++ b/src/js/static-dnr-filtering.js
@@ -34,6 +34,92 @@ import {
/******************************************************************************/
+function addExtendedToDNR(context, parser) {
+ if ( parser.category !== parser.CATStaticExtFilter ) { return false; }
+
+ if ( (parser.flavorBits & parser.BITFlavorUnsupported) !== 0 ) {
+ return true;
+ }
+
+ // Scriptlet injection
+ if ( (parser.flavorBits & parser.BITFlavorExtScriptlet) !== 0 ) {
+ return true;
+ }
+
+ // Response header filtering
+ if ( (parser.flavorBits & parser.BITFlavorExtResponseHeader) !== 0 ) {
+ return true;
+ }
+
+ // HTML filtering
+ if ( (parser.flavorBits & parser.BITFlavorExtHTML) !== 0 ) {
+ return true;
+ }
+
+ // Cosmetic filtering
+ if ( context.cosmeticFilters === undefined ) {
+ context.cosmeticFilters = new Map();
+ }
+
+ // https://github.com/chrisaljoudi/uBlock/issues/151
+ // Negated hostname means the filter applies to all non-negated hostnames
+ // of same filter OR globally if there is no non-negated hostnames.
+ for ( const { hn, not, bad } of parser.extOptions() ) {
+ if ( bad ) { continue; }
+ const { compiled, exception } = parser.result;
+ if ( compiled.startsWith('{') ) { continue; }
+ if ( exception ) { continue; }
+ if ( hn.endsWith('.*') ) { continue; }
+ let cssdetails = context.cosmeticFilters.get(compiled);
+ if ( cssdetails === undefined ) {
+ cssdetails = {
+ };
+ context.cosmeticFilters.set(compiled, cssdetails);
+ }
+ if ( not ) {
+ if ( cssdetails.excludeMatches === undefined ) {
+ cssdetails.excludeMatches = [];
+ }
+ cssdetails.excludeMatches.push(hn);
+ continue;
+ }
+ if ( cssdetails.matches === undefined ) {
+ cssdetails.matches = [];
+ }
+ if ( cssdetails.matches.includes('*') ) { continue; }
+ if ( hn === '*' ) {
+ cssdetails.matches = [ '*' ];
+ continue;
+ }
+ cssdetails.matches.push(hn);
+ }
+}
+
+/******************************************************************************/
+
+function optimizeCosmeticFilters(filters) {
+ if ( filters === undefined ) { return []; }
+ const merge = new Map();
+ for ( const [ selector, details ] of filters ) {
+ const json = JSON.stringify(details);
+ let entries = merge.get(json);
+ if ( entries === undefined ) {
+ entries = new Set();
+ merge.set(json, entries);
+ }
+ entries.add(selector);
+ }
+ const out = [];
+ for ( const [ json, selectors ] of merge ) {
+ const details = JSON.parse(json);
+ details.css = Array.from(selectors).join(',\n');
+ out.push(details);
+ }
+ return out;
+}
+
+/******************************************************************************/
+
function addToDNR(context, list) {
const writer = new CompiledListWriter();
const lineIter = new LineIterator(
@@ -58,7 +144,11 @@ function addToDNR(context, list) {
parser.analyze(line);
if ( parser.shouldIgnore() ) { continue; }
- if ( parser.category !== parser.CATStaticNetFilter ) { continue; }
+
+ if ( parser.category !== parser.CATStaticNetFilter ) {
+ addExtendedToDNR(context, parser);
+ continue;
+ }
// https://github.com/gorhill/uBlock/issues/2599
// convert hostname to punycode if needed
@@ -98,7 +188,11 @@ async function dnrRulesetFromRawLists(lists, options = {}) {
}
}
await Promise.all(toLoad);
- return staticNetFilteringEngine.dnrFromCompiled('end', context);
+
+ return {
+ network: staticNetFilteringEngine.dnrFromCompiled('end', context),
+ cosmetic: optimizeCosmeticFilters(context.cosmeticFilters),
+ };
}
/******************************************************************************/
diff --git a/tools/make-mv3.sh b/tools/make-mv3.sh
index 9398d0195..1e03b0a69 100755
--- a/tools/make-mv3.sh
+++ b/tools/make-mv3.sh
@@ -51,7 +51,7 @@ if [ "$1" != "quick" ]; then
cp platform/mv3/*.js $TMPDIR/
cp assets/assets.json $TMPDIR/
cd $TMPDIR
- node --no-warnings make-rulesets.js output=$DES quick=$QUICK
+ node --no-warnings make-rulesets.js output=$DES
cd - > /dev/null
rm -rf $TMPDIR
fi