mirror of
https://github.com/gorhill/uBlock.git
synced 2024-10-04 16:47:15 +02:00
Add per-site on/off switch to mv3 experimental version
This commit is contained in:
parent
e420b75b91
commit
224410a6f5
10
.github/workflows/main.yml
vendored
10
.github/workflows/main.yml
vendored
@ -39,13 +39,17 @@ jobs:
|
|||||||
tag_name: ${{ steps.release_info.outputs.VERSION }}
|
tag_name: ${{ steps.release_info.outputs.VERSION }}
|
||||||
release_name: ${{ steps.release_info.outputs.VERSION }}
|
release_name: ${{ steps.release_info.outputs.VERSION }}
|
||||||
prerelease: true
|
prerelease: true
|
||||||
- name: Build all packages
|
- name: Build MV2 packages
|
||||||
run: |
|
run: |
|
||||||
tools/make-chromium.sh ${{ steps.release_info.outputs.VERSION }}
|
tools/make-chromium.sh ${{ steps.release_info.outputs.VERSION }}
|
||||||
tools/make-firefox.sh ${{ steps.release_info.outputs.VERSION }}
|
tools/make-firefox.sh ${{ steps.release_info.outputs.VERSION }}
|
||||||
tools/make-thunderbird.sh ${{ steps.release_info.outputs.VERSION }}
|
tools/make-thunderbird.sh ${{ steps.release_info.outputs.VERSION }}
|
||||||
tools/make-npm.sh ${{ steps.release_info.outputs.VERSION }}
|
tools/make-npm.sh ${{ steps.release_info.outputs.VERSION }}
|
||||||
tools/make-mv3.sh all
|
tools/make-mv3.sh all
|
||||||
|
- name: Build MV3 packages
|
||||||
|
run: |
|
||||||
|
tools/make-mv3.sh
|
||||||
|
echo ::set-output name=MV3PACKAGE::$(basename $(ls dist/build/uBlock0_*.mv3.zip))
|
||||||
- name: Upload Chromium package
|
- name: Upload Chromium package
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
env:
|
env:
|
||||||
@ -88,6 +92,6 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
asset_path: dist/build/uBlock0.mv3.zip
|
asset_path: dist/build/${{ env.MV3PACKAGE }}
|
||||||
asset_name: uBlock0.mv3.zip
|
asset_name: ${{ env.MV3PACKAGE }}
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
9
Makefile
9
Makefile
@ -5,7 +5,7 @@ run_options := $(filter-out $@,$(MAKECMDGOALS))
|
|||||||
compare maxcost medcost mincost modifiers record wasm
|
compare maxcost medcost mincost modifiers record wasm
|
||||||
|
|
||||||
sources := $(wildcard assets/resources/* src/* src/*/* src/*/*/* src/*/*/*/*)
|
sources := $(wildcard assets/resources/* src/* src/*/* src/*/*/* src/*/*/*/*)
|
||||||
platform := $(wildcard platform/* platform/*/*)
|
platform := $(wildcard platform/* platform/*/* platform/*/*/*)
|
||||||
assets := $(wildcard submodules/uAssets/* \
|
assets := $(wildcard submodules/uAssets/* \
|
||||||
submodules/uAssets/*/* \
|
submodules/uAssets/*/* \
|
||||||
submodules/uAssets/*/*/* \
|
submodules/uAssets/*/*/* \
|
||||||
@ -52,10 +52,11 @@ dig: dist/build/uBlock0.dig
|
|||||||
dig-snfe: dig
|
dig-snfe: dig
|
||||||
cd dist/build/uBlock0.dig && npm run snfe $(run_options)
|
cd dist/build/uBlock0.dig && npm run snfe $(run_options)
|
||||||
|
|
||||||
dist/build/uBlock0.mv3: tools/make-mv3.sh $(sources) $(platform)
|
mv3: tools/make-mv3.sh $(sources) $(platform)
|
||||||
tools/make-mv3.sh all
|
tools/make-mv3.sh
|
||||||
|
|
||||||
mv3: dist/build/uBlock0.mv3
|
mv3-quick: tools/make-mv3.sh $(sources) $(platform)
|
||||||
|
tools/make-mv3.sh quick
|
||||||
|
|
||||||
# Update submodules.
|
# Update submodules.
|
||||||
update-submodules:
|
update-submodules:
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import regexRulesets from '/rulesets/regexes.js';
|
|
||||||
|
|
||||||
const dnr = chrome.declarativeNetRequest;
|
|
||||||
|
|
||||||
dnr.setExtensionActionOptions({ displayActionCountAsBadgeText: true });
|
|
||||||
|
|
||||||
(async ( ) => {
|
|
||||||
const allRules = [];
|
|
||||||
const toCheck = [];
|
|
||||||
for ( const regexRuleset of regexRulesets ) {
|
|
||||||
if ( regexRuleset.enabled !== true ) { continue; }
|
|
||||||
for ( const rule of regexRuleset.rules ) {
|
|
||||||
const regex = rule.condition.regexFilter;
|
|
||||||
const isCaseSensitive = rule.condition.isUrlFilterCaseSensitive === true;
|
|
||||||
allRules.push(rule);
|
|
||||||
toCheck.push(dnr.isRegexSupported({ regex, isCaseSensitive }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const results = await Promise.all(toCheck);
|
|
||||||
const newRules = [];
|
|
||||||
for ( let i = 0; i < allRules.length; i++ ) {
|
|
||||||
const rule = allRules[i];
|
|
||||||
const result = results[i];
|
|
||||||
if ( result instanceof Object && result.isSupported ) {
|
|
||||||
newRules.push(rule);
|
|
||||||
} else {
|
|
||||||
console.info(`${result.reason}: ${rule.condition.regexFilter}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const oldRules = await dnr.getDynamicRules();
|
|
||||||
const oldRuleMap = new Map(oldRules.map(rule => [ rule.id, rule ]));
|
|
||||||
const newRuleMap = new Map(newRules.map(rule => [ rule.id, rule ]));
|
|
||||||
const addRules = [];
|
|
||||||
const removeRuleIds = [];
|
|
||||||
for ( const oldRule of oldRules ) {
|
|
||||||
const newRule = newRuleMap.get(oldRule.id);
|
|
||||||
if ( newRule === undefined ) {
|
|
||||||
removeRuleIds.push(oldRule.id);
|
|
||||||
} else if ( JSON.stringify(oldRule) !== JSON.stringify(newRule) ) {
|
|
||||||
removeRuleIds.push(oldRule.id);
|
|
||||||
addRules.push(newRule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for ( const newRule of newRuleMap.values() ) {
|
|
||||||
if ( oldRuleMap.has(newRule.id) ) { continue; }
|
|
||||||
addRules.push(newRule);
|
|
||||||
}
|
|
||||||
if ( addRules.length !== 0 || removeRuleIds.length !== 0 ) {
|
|
||||||
await dnr.updateDynamicRules({ addRules, removeRuleIds });
|
|
||||||
}
|
|
||||||
|
|
||||||
const dynamicRules = await dnr.getDynamicRules();
|
|
||||||
console.log(`Dynamic rule count: ${dynamicRules.length}`);
|
|
||||||
|
|
||||||
const enabledRulesets = await dnr.getEnabledRulesets();
|
|
||||||
console.log(`Enabled rulesets: ${enabledRulesets}`);
|
|
||||||
|
|
||||||
console.log(`Available dynamic rule count: ${dnr.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES - dynamicRules.length}`);
|
|
||||||
|
|
||||||
dnr.getAvailableStaticRuleCount().then(count => {
|
|
||||||
console.log(`Available static rule count: ${count}`);
|
|
||||||
});
|
|
||||||
})();
|
|
227
platform/mv3/extension/css/popup.css
Normal file
227
platform/mv3/extension/css/popup.css
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
/* External CSS values override */
|
||||||
|
.fa-icon.fa-icon-badged > .fa-icon-badge {
|
||||||
|
bottom: auto;
|
||||||
|
top: -20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Internal CSS values */
|
||||||
|
:root body {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
:root body,
|
||||||
|
:root.mobile body {
|
||||||
|
--font-size: 14px;
|
||||||
|
--popup-gap: var(--font-size);
|
||||||
|
--popup-gap-thin: calc(0.5 * var(--popup-gap));
|
||||||
|
--popup-gap-extra-thin: calc(0.25 * var(--popup-gap));
|
||||||
|
--popup-main-min-width: 18em;
|
||||||
|
--popup-firewall-min-width: 30em;
|
||||||
|
--popup-rule-cell-width: 5em;
|
||||||
|
font-size: var(--font-size);
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
:root body.loading {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: var(--ink-1);
|
||||||
|
fill: var(--ink-1);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main {
|
||||||
|
align-self: flex-start;
|
||||||
|
max-width: 340px;
|
||||||
|
min-width: var(--popup-main-min-width);
|
||||||
|
}
|
||||||
|
:root.portrait #main {
|
||||||
|
align-self: inherit;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-top: 1px solid var(--hr-ink);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sticky {
|
||||||
|
background-color: var(--surface-1);
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
#stickyTools {
|
||||||
|
align-items: stretch;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
#switch {
|
||||||
|
color: var(--popup-power-ink);
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
fill: var(--popup-power-ink);
|
||||||
|
flex-grow: 1;
|
||||||
|
font-size: 96px;
|
||||||
|
justify-content: center;
|
||||||
|
margin: var(--popup-gap-thin) var(--popup-gap-thin) 0;
|
||||||
|
padding: 0;
|
||||||
|
stroke: none;
|
||||||
|
stroke-width: 64;
|
||||||
|
}
|
||||||
|
body.off #switch {
|
||||||
|
fill: var(--surface-1);
|
||||||
|
stroke: var(--checkbox-ink);
|
||||||
|
}
|
||||||
|
.rulesetTools {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
.rulesetTools [id] {
|
||||||
|
background-color: var(--popup-ruleset-tool-surface);
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
fill: var(--popup-ruleset-tool-ink);
|
||||||
|
flex-grow: 1;
|
||||||
|
font-size: 2.2em;
|
||||||
|
padding: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.rulesetTools [id]:not(:first-of-type) {
|
||||||
|
margin-block-start: 1px;
|
||||||
|
}
|
||||||
|
.rulesetTools [id] > svg {
|
||||||
|
fill: var(--ink-4);
|
||||||
|
}
|
||||||
|
body.needReload #refresh,
|
||||||
|
body.needSave #saveRules,
|
||||||
|
body.needSave #revertRules {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
#hostname {
|
||||||
|
margin: var(--popup-gap) var(--popup-gap-extra-thin);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#hostname > span {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
#hostname > span + span {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemRibbon {
|
||||||
|
column-gap: var(--popup-gap);
|
||||||
|
display: grid;
|
||||||
|
grid-auto-columns: 1fr;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
grid-template: auto / 1fr 1fr;
|
||||||
|
margin: var(--popup-gap);
|
||||||
|
}
|
||||||
|
.itemRibbon > span + span {
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolRibbon {
|
||||||
|
align-items: start;
|
||||||
|
background-color: var(--popup-toolbar-surface);
|
||||||
|
display: grid;
|
||||||
|
grid-auto-columns: 1fr;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
grid-template: auto / repeat(4, 1fr);
|
||||||
|
justify-items: center;
|
||||||
|
margin: 0;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
.toolRibbon .tool {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 1.4em;
|
||||||
|
min-width: 32px;
|
||||||
|
padding: var(--popup-gap)
|
||||||
|
var(--popup-gap-thin);
|
||||||
|
unicode-bidi: embed;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.toolRibbon .tool:hover {
|
||||||
|
color: var(--ink-1);
|
||||||
|
fill: var(--ink-1);
|
||||||
|
}
|
||||||
|
.toolRibbon .tool.enabled {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.toolRibbon .tool .caption {
|
||||||
|
font: 10px/12px sans-serif;
|
||||||
|
margin-top: 6px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
body.mobile.no-tooltips .toolRibbon .tool {
|
||||||
|
font-size: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#basicTools {
|
||||||
|
margin-top: var(--default-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configurable UI elements */
|
||||||
|
:root:not(.mobile) .toolRibbon .caption,
|
||||||
|
:root.mobile body.no-tooltips .toolRibbon .caption,
|
||||||
|
:root.mobile body[data-ui~="-captions"] .toolRibbon .caption {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
:root.mobile .toolRibbon .caption,
|
||||||
|
:root:not(.mobile) body[data-ui~="+captions"] .toolRibbon .caption {
|
||||||
|
display: inherit;
|
||||||
|
}
|
||||||
|
:root:not(.mobile) .toolRibbon .tool,
|
||||||
|
:root.mobile body.no-tooltips .toolRibbon .tool,
|
||||||
|
:root.mobile body[data-ui~="-captions"] .toolRibbon .tool {
|
||||||
|
padding: var(--popup-gap) var(--popup-gap-thin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* horizontally-constrained viewport */
|
||||||
|
:root.portrait body {
|
||||||
|
overflow-y: auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
:root.portrait #main {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
/* mouse-driven devices */
|
||||||
|
:root.desktop {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
:root.desktop body {
|
||||||
|
--popup-gap: calc(var(--font-size) * 0.875);
|
||||||
|
}
|
||||||
|
:root.desktop body:not(.off) #switch:hover {
|
||||||
|
fill: rgb(var(--popup-power-ink-rgb) / 90%);
|
||||||
|
}
|
||||||
|
:root.desktop body.off #switch:hover {
|
||||||
|
stroke: var(--popup-power-ink);
|
||||||
|
}
|
||||||
|
:root.desktop .rulesetTools [id]:hover {
|
||||||
|
background-color: var(--popup-ruleset-tool-surface-hover);
|
||||||
|
}
|
||||||
|
:root.desktop .rulesetTools [id]:hover > svg {
|
||||||
|
fill: var(--ink-2);
|
||||||
|
}
|
||||||
|
:root.desktop #firewall {
|
||||||
|
direction: rtl;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
:root.desktop .tool:hover {
|
||||||
|
background-color: var(--popup-toolbar-surface-hover);
|
||||||
|
}
|
||||||
|
:root.desktop #moreOrLess > span:hover {
|
||||||
|
background-color: var(--surface-2);
|
||||||
|
/* background-color: var(--popup-toolbar-surface-hover); */
|
||||||
|
}
|
188
platform/mv3/extension/js/background.js
Normal file
188
platform/mv3/extension/js/background.js
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import regexRulesets from '/rulesets/regexes.js';
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
const dnr = chrome.declarativeNetRequest;
|
||||||
|
const TRUSTED_DIRECTIVE_BASE_RULE_ID = 1000000;
|
||||||
|
const dynamicRuleMap = new Map();
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
async function updateRegexRules() {
|
||||||
|
const allRules = [];
|
||||||
|
const toCheck = [];
|
||||||
|
for ( const regexRuleset of regexRulesets ) {
|
||||||
|
if ( regexRuleset.enabled !== true ) { continue; }
|
||||||
|
for ( const rule of regexRuleset.rules ) {
|
||||||
|
const regex = rule.condition.regexFilter;
|
||||||
|
const isCaseSensitive = rule.condition.isUrlFilterCaseSensitive === true;
|
||||||
|
allRules.push(rule);
|
||||||
|
toCheck.push(dnr.isRegexSupported({ regex, isCaseSensitive }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const results = await Promise.all(toCheck);
|
||||||
|
const newRules = [];
|
||||||
|
for ( let i = 0; i < allRules.length; i++ ) {
|
||||||
|
const rule = allRules[i];
|
||||||
|
const result = results[i];
|
||||||
|
if ( result instanceof Object && result.isSupported ) {
|
||||||
|
newRules.push(rule);
|
||||||
|
} else {
|
||||||
|
console.info(`${result.reason}: ${rule.condition.regexFilter}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const newRuleMap = new Map(newRules.map(rule => [ rule.id, rule ]));
|
||||||
|
const addRules = [];
|
||||||
|
const removeRuleIds = [];
|
||||||
|
for ( const oldRule of dynamicRuleMap.values() ) {
|
||||||
|
if ( oldRule.id >= TRUSTED_DIRECTIVE_BASE_RULE_ID ) { continue; }
|
||||||
|
const newRule = newRuleMap.get(oldRule.id);
|
||||||
|
if ( newRule === undefined ) {
|
||||||
|
removeRuleIds.push(oldRule.id);
|
||||||
|
dynamicRuleMap.delete(oldRule.id);
|
||||||
|
} else if ( JSON.stringify(oldRule) !== JSON.stringify(newRule) ) {
|
||||||
|
removeRuleIds.push(oldRule.id);
|
||||||
|
addRules.push(newRule);
|
||||||
|
dynamicRuleMap.set(oldRule.id, newRule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( const newRule of newRuleMap.values() ) {
|
||||||
|
if ( dynamicRuleMap.has(newRule.id) ) { continue; }
|
||||||
|
addRules.push(newRule);
|
||||||
|
dynamicRuleMap.set(newRule.id, newRule);
|
||||||
|
}
|
||||||
|
if ( addRules.length !== 0 || removeRuleIds.length !== 0 ) {
|
||||||
|
return dnr.updateDynamicRules({ addRules, removeRuleIds });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
async function matchesTrustedSiteDirective(details) {
|
||||||
|
const url = new URL(details.origin);
|
||||||
|
let rule = dynamicRuleMap.get(TRUSTED_DIRECTIVE_BASE_RULE_ID);
|
||||||
|
if ( rule === undefined ) { return false; }
|
||||||
|
const domainSet = new Set(rule.condition.requestDomains);
|
||||||
|
let hostname = url.hostname;
|
||||||
|
for (;;) {
|
||||||
|
if ( domainSet.has(hostname) ) { return true; }
|
||||||
|
const pos = hostname.indexOf('.');
|
||||||
|
if ( pos === -1 ) { break; }
|
||||||
|
hostname = hostname.slice(pos+1);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addTrustedSiteDirective(details) {
|
||||||
|
const url = new URL(details.origin);
|
||||||
|
let rule = dynamicRuleMap.get(TRUSTED_DIRECTIVE_BASE_RULE_ID);
|
||||||
|
if ( rule !== undefined ) {
|
||||||
|
rule.condition.initiatorDomains = undefined;
|
||||||
|
if ( Array.isArray(rule.condition.requestDomains) === false ) {
|
||||||
|
rule.condition.requestDomains = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( rule === undefined ) {
|
||||||
|
rule = {
|
||||||
|
id: TRUSTED_DIRECTIVE_BASE_RULE_ID,
|
||||||
|
action: {
|
||||||
|
type: 'allowAllRequests',
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
requestDomains: [ url.hostname ],
|
||||||
|
resourceTypes: [ 'main_frame' ],
|
||||||
|
},
|
||||||
|
priority: TRUSTED_DIRECTIVE_BASE_RULE_ID,
|
||||||
|
};
|
||||||
|
dynamicRuleMap.set(TRUSTED_DIRECTIVE_BASE_RULE_ID, rule);
|
||||||
|
} else if ( rule.condition.requestDomains.includes(url.hostname) === false ) {
|
||||||
|
rule.condition.requestDomains.push(url.hostname);
|
||||||
|
}
|
||||||
|
await dnr.updateDynamicRules({
|
||||||
|
addRules: [ rule ],
|
||||||
|
removeRuleIds: [ TRUSTED_DIRECTIVE_BASE_RULE_ID ],
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeTrustedSiteDirective(details) {
|
||||||
|
const url = new URL(details.origin);
|
||||||
|
let rule = dynamicRuleMap.get(TRUSTED_DIRECTIVE_BASE_RULE_ID);
|
||||||
|
if ( rule === undefined ) { return false; }
|
||||||
|
rule.condition.initiatorDomains = undefined;
|
||||||
|
if ( Array.isArray(rule.condition.requestDomains) === false ) {
|
||||||
|
rule.condition.requestDomains = [];
|
||||||
|
}
|
||||||
|
const domainSet = new Set(rule.condition.requestDomains);
|
||||||
|
const beforeCount = domainSet.size;
|
||||||
|
let hostname = url.hostname;
|
||||||
|
for (;;) {
|
||||||
|
domainSet.delete(hostname);
|
||||||
|
const pos = hostname.indexOf('.');
|
||||||
|
if ( pos === -1 ) { break; }
|
||||||
|
hostname = hostname.slice(pos+1);
|
||||||
|
}
|
||||||
|
if ( domainSet.size === beforeCount ) { return false; }
|
||||||
|
if ( domainSet.size === 0 ) {
|
||||||
|
dynamicRuleMap.delete(TRUSTED_DIRECTIVE_BASE_RULE_ID);
|
||||||
|
await dnr.updateDynamicRules({
|
||||||
|
removeRuleIds: [ TRUSTED_DIRECTIVE_BASE_RULE_ID ]
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
rule.condition.requestDomains = Array.from(domainSet);
|
||||||
|
await dnr.updateDynamicRules({
|
||||||
|
addRules: [ rule ],
|
||||||
|
removeRuleIds: [ TRUSTED_DIRECTIVE_BASE_RULE_ID ],
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function toggleTrustedSiteDirective(details) {
|
||||||
|
return details.state
|
||||||
|
? removeTrustedSiteDirective(details)
|
||||||
|
: addTrustedSiteDirective(details);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
(async ( ) => {
|
||||||
|
const dynamicRules = await dnr.getDynamicRules();
|
||||||
|
for ( const rule of dynamicRules ) {
|
||||||
|
dynamicRuleMap.set(rule.id, rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
await updateRegexRules();
|
||||||
|
|
||||||
|
console.log(`Dynamic rule count: ${dynamicRuleMap.size}`);
|
||||||
|
|
||||||
|
const enabledRulesets = await dnr.getEnabledRulesets();
|
||||||
|
console.log(`Enabled rulesets: ${enabledRulesets}`);
|
||||||
|
|
||||||
|
console.log(`Available dynamic rule count: ${dnr.MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES - dynamicRuleMap.size}`);
|
||||||
|
|
||||||
|
dnr.getAvailableStaticRuleCount().then(count => {
|
||||||
|
console.log(`Available static rule count: ${count}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
dnr.setExtensionActionOptions({ displayActionCountAsBadgeText: true });
|
||||||
|
|
||||||
|
chrome.runtime.onMessage.addListener((request, sender, callback) => {
|
||||||
|
switch ( request.what ) {
|
||||||
|
case 'matchesTrustedSiteDirective':
|
||||||
|
matchesTrustedSiteDirective(request).then(response => {
|
||||||
|
callback(response);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
case 'toggleTrustedSiteDirective':
|
||||||
|
toggleTrustedSiteDirective(request).then(response => {
|
||||||
|
callback(response);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
114
platform/mv3/extension/js/popup.js
Normal file
114
platform/mv3/extension/js/popup.js
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
uBlock Origin - a browser extension to block requests.
|
||||||
|
Copyright (C) 2014-present Raymond Hill
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
|
||||||
|
Home: https://github.com/gorhill/uBlock
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
let currentTab = {};
|
||||||
|
let originalTrustedState = false;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
async function toggleTrustedSiteDirective() {
|
||||||
|
let url;
|
||||||
|
try {
|
||||||
|
url = new URL(currentTab.url);
|
||||||
|
} catch(ex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( url instanceof URL === false ) { return; }
|
||||||
|
const targetTrustedState = document.body.classList.contains('off');
|
||||||
|
const newTrustedState = await chrome.runtime.sendMessage({
|
||||||
|
what: 'toggleTrustedSiteDirective',
|
||||||
|
origin: url.origin,
|
||||||
|
state: targetTrustedState,
|
||||||
|
tabId: currentTab.id,
|
||||||
|
}).catch(( ) => targetTrustedState === false);
|
||||||
|
document.body.classList.toggle('off', newTrustedState === true);
|
||||||
|
document.body.classList.toggle(
|
||||||
|
'needReload',
|
||||||
|
newTrustedState !== originalTrustedState
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
function reloadTab(ev) {
|
||||||
|
chrome.tabs.reload(currentTab.id, {
|
||||||
|
bypassCache: ev.ctrlKey || ev.metaKey || ev.shiftKey,
|
||||||
|
});
|
||||||
|
document.body.classList.remove('needReload');
|
||||||
|
originalTrustedState = document.body.classList.contains('off');
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
const [ tab ] = await chrome.tabs.query({ active: true });
|
||||||
|
if ( tab instanceof Object === false ) { return true; }
|
||||||
|
currentTab = tab;
|
||||||
|
|
||||||
|
let url;
|
||||||
|
try {
|
||||||
|
url = new URL(currentTab.url);
|
||||||
|
} catch(ex) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( url !== undefined ) {
|
||||||
|
originalTrustedState = await chrome.runtime.sendMessage({
|
||||||
|
what: 'matchesTrustedSiteDirective',
|
||||||
|
origin: url.origin,
|
||||||
|
}) === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = document.body;
|
||||||
|
body.classList.toggle('off', originalTrustedState);
|
||||||
|
const elemHn = document.querySelector('#hostname');
|
||||||
|
|
||||||
|
elemHn.textContent = url && url.hostname || '';
|
||||||
|
|
||||||
|
document.querySelector('#switch').addEventListener(
|
||||||
|
'click',
|
||||||
|
toggleTrustedSiteDirective
|
||||||
|
);
|
||||||
|
|
||||||
|
document.querySelector('#refresh').addEventListener(
|
||||||
|
'click',
|
||||||
|
reloadTab
|
||||||
|
);
|
||||||
|
|
||||||
|
document.body.classList.remove('loading');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function tryInit() {
|
||||||
|
try {
|
||||||
|
await init();
|
||||||
|
} catch(ex) {
|
||||||
|
setTimeout(tryInit, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tryInit();
|
||||||
|
|
||||||
|
/******************************************************************************/
|
@ -1,7 +1,15 @@
|
|||||||
{
|
{
|
||||||
|
"action": {
|
||||||
|
"default_icon": {
|
||||||
|
"16": "img/icon_16.png",
|
||||||
|
"32": "img/icon_32.png",
|
||||||
|
"64": "img/icon_64.png"
|
||||||
|
},
|
||||||
|
"default_popup": "popup.html"
|
||||||
|
},
|
||||||
"author": "Raymond Hill",
|
"author": "Raymond Hill",
|
||||||
"background": {
|
"background": {
|
||||||
"service_worker": "background.js",
|
"service_worker": "/js/background.js",
|
||||||
"type": "module"
|
"type": "module"
|
||||||
},
|
},
|
||||||
"declarative_net_request": {
|
"declarative_net_request": {
|
||||||
@ -19,7 +27,8 @@
|
|||||||
"minimum_chrome_version": "101.0",
|
"minimum_chrome_version": "101.0",
|
||||||
"name": "uBO Minus (MV3)",
|
"name": "uBO Minus (MV3)",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"activeTab",
|
||||||
"declarativeNetRequest"
|
"declarativeNetRequest"
|
||||||
],
|
],
|
||||||
"version": "0.1.0"
|
"version": "0.1"
|
||||||
}
|
}
|
||||||
|
57
platform/mv3/extension/popup.html
Normal file
57
platform/mv3/extension/popup.html
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html id="uBO-popup-panel" class="desktop">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="css/default.css">
|
||||||
|
<link rel="stylesheet" href="css/common.css">
|
||||||
|
<link rel="stylesheet" href="css/fa-icons.css">
|
||||||
|
<link rel="stylesheet" href="css/popup.css">
|
||||||
|
<title data-i18n="extName"></title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="loading">
|
||||||
|
<div id="main">
|
||||||
|
<div id="sticky">
|
||||||
|
<div id="stickyTools">
|
||||||
|
<div class="rulesetTools">
|
||||||
|
<span id="saveRules" class="fa-icon" data-i18n-title="popupTipSaveRules">lock</span>
|
||||||
|
<span id="revertRules" class="fa-icon" data-i18n-title="popupTipRevertRules">eraser</span>
|
||||||
|
</div>
|
||||||
|
<div id="switch" role="button" aria-label tabindex="0" title>
|
||||||
|
<span class="fa-icon"><!--
|
||||||
|
Power button taken from Font Awesome v4.7.0 by Dave Gandy.
|
||||||
|
Unlike other FA icons, the power button is inlined here so
|
||||||
|
that we can use a clip-path in order to ensure that the stroke
|
||||||
|
does not "bleed" outside the fill area.
|
||||||
|
--><svg viewBox="0 0 1536 1664">
|
||||||
|
<defs>
|
||||||
|
<path id="power-off-path" d="m 1536,896 q 0,156 -61,298 -61,142 -164,245 -103,103 -245,164 -142,61 -298,61 -156,0 -298,-61 Q 328,1542 225,1439 122,1336 61,1194 0,1052 0,896 0,714 80.5,553 161,392 307,283 q 43,-32 95.5,-25 52.5,7 83.5,50 32,42 24.5,94.5 Q 503,455 461,487 363,561 309.5,668 256,775 256,896 q 0,104 40.5,198.5 40.5,94.5 109.5,163.5 69,69 163.5,109.5 94.5,40.5 198.5,40.5 104,0 198.5,-40.5 Q 1061,1327 1130,1258 1199,1189 1239.5,1094.5 1280,1000 1280,896 1280,775 1226.5,668 1173,561 1075,487 1033,455 1025.5,402.5 1018,350 1050,308 q 31,-43 84,-50 53,-7 95,25 146,109 226.5,270 80.5,161 80.5,343 z m -640,-768 0,640 q 0,52 -38,90 -38,38 -90,38 -52,0 -90,-38 -38,-38 -38,-90 l 0,-640 q 0,-52 38,-90 38,-38 90,-38 52,0 90,38 38,38 38,90 z"/>
|
||||||
|
<clipPath id="power-off-clip"><use href="#power-off-path"/></clipPath>
|
||||||
|
</defs>
|
||||||
|
<use href="#power-off-path" clip-path="url(#power-off-clip)"/>
|
||||||
|
</svg><!--
|
||||||
|
--></span>
|
||||||
|
</div>
|
||||||
|
<div class="rulesetTools">
|
||||||
|
<span id="refresh" class="fa-icon">refresh</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="hostname"><span></span>­<span></span></div>
|
||||||
|
</div>
|
||||||
|
<div id="basicTools" class="toolRibbon">
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<a href="dashboard.html" class="fa-icon tool" target="uBODashboard" tabindex="0" data-i18n-title="popupTipDashboard">cogs<span class="caption" data-i18n="popupTipDashboard"></span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="js/fa-icons.js"></script>
|
||||||
|
<script src="js/popup.js" type="module"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -137,6 +137,7 @@ async function main() {
|
|||||||
for ( const ruleset of rulesetConfigs ) {
|
for ( const ruleset of rulesetConfigs ) {
|
||||||
const lists = [];
|
const lists = [];
|
||||||
|
|
||||||
|
log('============================');
|
||||||
log(`Listset for '${ruleset.id}':`);
|
log(`Listset for '${ruleset.id}':`);
|
||||||
|
|
||||||
if ( Array.isArray(ruleset.paths) ) {
|
if ( Array.isArray(ruleset.paths) ) {
|
||||||
@ -152,11 +153,14 @@ async function main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rules = await dnrRulesetFromRawLists(lists, {
|
const details = await dnrRulesetFromRawLists(lists, {
|
||||||
env: [ 'chromium' ],
|
env: [ 'chromium' ],
|
||||||
});
|
});
|
||||||
|
const { ruleset: rules } = details;
|
||||||
log(`Ruleset size for '${ruleset.id}': ${rules.length}`);
|
log(`Input filter count: ${details.filterCount}`);
|
||||||
|
log(`\tAccepted filter count: ${details.acceptedFilterCount}`);
|
||||||
|
log(`\tRejected filter count: ${details.rejectedFilterCount}`);
|
||||||
|
log(`Output rule count: ${rules.length}`);
|
||||||
|
|
||||||
const good = rules.filter(rule => isGood(rule) && isRegex(rule) === false);
|
const good = rules.filter(rule => isGood(rule) && isRegex(rule) === false);
|
||||||
log(`\tGood: ${good.length}`);
|
log(`\tGood: ${good.length}`);
|
||||||
@ -227,11 +231,19 @@ async function main() {
|
|||||||
log(`Total regex rules count: ${maybeGoodTotalCount}`);
|
log(`Total regex rules count: ${maybeGoodTotalCount}`);
|
||||||
|
|
||||||
// Patch manifest
|
// Patch manifest
|
||||||
const manifest = await fs.readFile(`${outputDir}/manifest.json`, { encoding: 'utf8' })
|
const manifest = await fs.readFile(
|
||||||
.then(text => JSON.parse(text));
|
`${outputDir}/manifest.json`,
|
||||||
|
{ encoding: 'utf8' }
|
||||||
|
).then(text =>
|
||||||
|
JSON.parse(text)
|
||||||
|
);
|
||||||
manifest.declarative_net_request = { rule_resources: ruleResources };
|
manifest.declarative_net_request = { rule_resources: ruleResources };
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
manifest.version = `0.1.${now.getUTCFullYear() - 2000}.${now.getUTCMonth() * 100 + now.getUTCDate()}`;
|
const yearPart = now.getUTCFullYear() - 2000;
|
||||||
|
const monthPart = (now.getUTCMonth() + 1) * 1000;
|
||||||
|
const dayPart = now.getUTCDate() * 10;
|
||||||
|
const hourPart = Math.floor(now.getUTCHours() / 3) + 1;
|
||||||
|
manifest.version = manifest.version + `.${yearPart}.${monthPart + dayPart + hourPart}`;
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
`${outputDir}/manifest.json`,
|
`${outputDir}/manifest.json`,
|
||||||
JSON.stringify(manifest, null, 2) + '\n'
|
JSON.stringify(manifest, null, 2) + '\n'
|
||||||
|
@ -160,7 +160,7 @@ const onMessage = function(request, sender, callback) {
|
|||||||
env: vAPI.webextFlavor.env,
|
env: vAPI.webextFlavor.env,
|
||||||
};
|
};
|
||||||
const t0 = Date.now();
|
const t0 = Date.now();
|
||||||
dnrRulesetFromRawLists(listPromises, options).then(ruleset => {
|
dnrRulesetFromRawLists(listPromises, options).then(details => {
|
||||||
const replacer = (k, v) => {
|
const replacer = (k, v) => {
|
||||||
if ( k.startsWith('__') ) { return; }
|
if ( k.startsWith('__') ) { return; }
|
||||||
if ( Array.isArray(v) ) {
|
if ( Array.isArray(v) ) {
|
||||||
@ -192,9 +192,14 @@ const onMessage = function(request, sender, callback) {
|
|||||||
rule.action.type === 'redirect' &&
|
rule.action.type === 'redirect' &&
|
||||||
rule.action.redirect.transform !== undefined;
|
rule.action.redirect.transform !== undefined;
|
||||||
const runtime = Date.now() - t0;
|
const runtime = Date.now() - t0;
|
||||||
|
const { ruleset } = details;
|
||||||
const out = [
|
const out = [
|
||||||
`dnrRulesetFromRawLists(${JSON.stringify(listNames, null, 2)})`,
|
`dnrRulesetFromRawLists(${JSON.stringify(listNames, null, 2)})`,
|
||||||
`Run time: ${runtime} ms`,
|
`Run time: ${runtime} ms`,
|
||||||
|
`Filters count: ${details.filterCount}`,
|
||||||
|
`Accepted filter count: ${details.acceptedFilterCount}`,
|
||||||
|
`Rejected filter count: ${details.rejectedFilterCount}`,
|
||||||
|
`Resulting DNR rule count: ${ruleset.length}`,
|
||||||
];
|
];
|
||||||
const good = ruleset.filter(rule =>
|
const good = ruleset.filter(rule =>
|
||||||
isUnsupported(rule) === false &&
|
isUnsupported(rule) === false &&
|
||||||
|
@ -46,7 +46,6 @@ function addToDNR(context, list) {
|
|||||||
const compiler = staticNetFilteringEngine.createCompiler(parser);
|
const compiler = staticNetFilteringEngine.createCompiler(parser);
|
||||||
|
|
||||||
writer.properties.set('name', list.name);
|
writer.properties.set('name', list.name);
|
||||||
parser.setMaxTokenLength(staticNetFilteringEngine.MAX_TOKEN_LENGTH);
|
|
||||||
compiler.start(writer);
|
compiler.start(writer);
|
||||||
|
|
||||||
while ( lineIter.eot() === false ) {
|
while ( lineIter.eot() === false ) {
|
||||||
@ -95,8 +94,7 @@ async function dnrRulesetFromRawLists(lists, options = {}) {
|
|||||||
toLoad.push(list.then(list => toDNR(context, list)));
|
toLoad.push(list.then(list => toDNR(context, list)));
|
||||||
}
|
}
|
||||||
await Promise.all(toLoad);
|
await Promise.all(toLoad);
|
||||||
const ruleset = staticNetFilteringEngine.dnrFromCompiled('end', context);
|
return staticNetFilteringEngine.dnrFromCompiled('end', context);
|
||||||
return ruleset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -3852,6 +3852,9 @@ FilterContainer.prototype.dnrFromCompiled = function(op, context, ...args) {
|
|||||||
good: new Set(),
|
good: new Set(),
|
||||||
bad: new Set(),
|
bad: new Set(),
|
||||||
invalid: new Set(),
|
invalid: new Set(),
|
||||||
|
filterCount: 0,
|
||||||
|
acceptedFilterCount: 0,
|
||||||
|
rejectedFilterCount: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3859,6 +3862,7 @@ FilterContainer.prototype.dnrFromCompiled = function(op, context, ...args) {
|
|||||||
const reader = args[0];
|
const reader = args[0];
|
||||||
reader.select('NETWORK_FILTERS:GOOD');
|
reader.select('NETWORK_FILTERS:GOOD');
|
||||||
while ( reader.next() ) {
|
while ( reader.next() ) {
|
||||||
|
context.filterCount += 1;
|
||||||
if ( context.good.has(reader.line) === false ) {
|
if ( context.good.has(reader.line) === false ) {
|
||||||
context.good.add(reader.line);
|
context.good.add(reader.line);
|
||||||
}
|
}
|
||||||
@ -3878,8 +3882,10 @@ FilterContainer.prototype.dnrFromCompiled = function(op, context, ...args) {
|
|||||||
|
|
||||||
for ( const line of good ) {
|
for ( const line of good ) {
|
||||||
if ( bad.has(line) ) {
|
if ( bad.has(line) ) {
|
||||||
|
context.rejectedFilterCount += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
context.acceptedFilterCount += 1;
|
||||||
|
|
||||||
const args = unserialize(line);
|
const args = unserialize(line);
|
||||||
const bits = args[0];
|
const bits = args[0];
|
||||||
@ -4201,7 +4207,12 @@ FilterContainer.prototype.dnrFromCompiled = function(op, context, ...args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Array.from(rulesetMap.values());
|
return {
|
||||||
|
ruleset: Array.from(rulesetMap.values()),
|
||||||
|
filterCount: context.filterCount,
|
||||||
|
acceptedFilterCount: context.acceptedFilterCount,
|
||||||
|
rejectedFilterCount: context.rejectedFilterCount,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -7,36 +7,61 @@ set -e
|
|||||||
echo "*** uBlock0.mv3: Creating extension"
|
echo "*** uBlock0.mv3: Creating extension"
|
||||||
|
|
||||||
DES="dist/build/uBlock0.mv3"
|
DES="dist/build/uBlock0.mv3"
|
||||||
rm -rf $DES
|
|
||||||
|
if [ "$1" != "quick" ]; then
|
||||||
|
rm -rf $DES
|
||||||
|
fi
|
||||||
|
|
||||||
mkdir -p $DES
|
mkdir -p $DES
|
||||||
cd $DES
|
cd $DES
|
||||||
DES=$(pwd)
|
DES=$(pwd)
|
||||||
cd - > /dev/null
|
cd - > /dev/null
|
||||||
TMPDIR=$(mktemp -d)
|
|
||||||
mkdir -p $TMPDIR
|
|
||||||
|
|
||||||
echo "*** uBlock0.mv3: Copying mv3-specific files"
|
mkdir -p $DES/css/fonts
|
||||||
cp -R platform/mv3/extension/* $DES/
|
mkdir -p $DES/js
|
||||||
|
mkdir -p $DES/img
|
||||||
|
|
||||||
echo "*** uBlock0.mv3: Copying common files"
|
echo "*** uBlock0.mv3: Copying common files"
|
||||||
|
cp -R src/css/fonts/* $DES/css/fonts/
|
||||||
|
cp src/css/themes/default.css $DES/css/
|
||||||
|
cp src/css/common.css $DES/css/
|
||||||
|
cp src/css/fa-icons.css $DES/css/
|
||||||
|
cp src/js/fa-icons.js $DES/js/
|
||||||
|
|
||||||
cp LICENSE.txt $DES/
|
cp LICENSE.txt $DES/
|
||||||
|
|
||||||
echo "*** uBlock0.mv3: Generating rulesets"
|
echo "*** uBlock0.mv3: Copying mv3-specific files"
|
||||||
./tools/make-nodejs.sh $TMPDIR
|
cp platform/mv3/extension/*.html $DES/
|
||||||
cp platform/mv3/package.json $TMPDIR/
|
cp platform/mv3/extension/css/* $DES/css/
|
||||||
cp platform/mv3/*.js $TMPDIR/
|
cp platform/mv3/extension/js/* $DES/js/
|
||||||
cd $TMPDIR
|
cp platform/mv3/extension/img/* $DES/img/
|
||||||
node --no-warnings make-rulesets.js output=$DES
|
|
||||||
cd - > /dev/null
|
if [ "$1" != "quick" ]; then
|
||||||
rm -rf $TMPDIR
|
echo "*** uBlock0.mv3: Generating rulesets"
|
||||||
|
TMPDIR=$(mktemp -d)
|
||||||
|
mkdir -p $TMPDIR
|
||||||
|
cp platform/mv3/extension/manifest.json $DES/
|
||||||
|
./tools/make-nodejs.sh $TMPDIR
|
||||||
|
cp platform/mv3/package.json $TMPDIR/
|
||||||
|
cp platform/mv3/*.js $TMPDIR/
|
||||||
|
cd $TMPDIR
|
||||||
|
node --no-warnings make-rulesets.js output=$DES quick=$QUICK
|
||||||
|
cd - > /dev/null
|
||||||
|
rm -rf $TMPDIR
|
||||||
|
fi
|
||||||
|
|
||||||
echo "*** uBlock0.mv3: extension ready"
|
echo "*** uBlock0.mv3: extension ready"
|
||||||
echo "Extension location: $DES/"
|
echo "Extension location: $DES/"
|
||||||
|
|
||||||
if [ "$1" = all ]; then
|
echo "*** uBlock0.mv3: Creating webstore package..."
|
||||||
echo "*** uBlock0.mv3: Creating webstore package..."
|
PACKAGENAME=uBlock0_$(jq -r .version $DES/manifest.json).mv3.zip
|
||||||
pushd $(dirname $DES/) > /dev/null
|
TMPDIR=$(mktemp -d)
|
||||||
zip uBlock0.mv3.zip -qr $(basename $DES/)/*
|
mkdir -p $TMPDIR
|
||||||
echo "Package location: $(pwd)/uBlock0.mv3.zip"
|
cp -R $DES/* $TMPDIR/
|
||||||
popd > /dev/null
|
cd $TMPDIR > /dev/null
|
||||||
fi
|
rm log.txt
|
||||||
|
zip $PACKAGENAME -qr ./*
|
||||||
|
cp $PACKAGENAME $(dirname $DES/)/
|
||||||
|
cd - > /dev/null
|
||||||
|
rm -rf $TMPDIR
|
||||||
|
echo "Package location: $(pwd)/$PACKAGENAME"
|
||||||
|
Loading…
Reference in New Issue
Block a user