mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-13 02:14:17 +01:00
Deprecate pseudo user styles code
The pseudo user styles code served only browsers based on Chromium 65 and earlier -- Chromium 66 supports native user styles and was first released more than two years ago. In Chromium-based browsers, the pseudo user styles code is being unconditionally injected in every page/frame just in case the browser is version 65 or earlier. Removing pseudo user styles reduce uBO's main content script in Chromium-based browsers by more than 20K. Related thread: - https://github.com/NanoAdblocker/NanoCore/issues/348#issuecomment-653646507
This commit is contained in:
parent
603bd2da8b
commit
5c68867b92
10 changed files with 261 additions and 1107 deletions
|
@ -1,54 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2018 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';
|
|
||||||
|
|
||||||
// This file can be replaced by platform-specific code. If a platform is
|
|
||||||
// known to NOT support user stylsheets, vAPI.supportsUserStylesheets can be
|
|
||||||
// set to `false`.
|
|
||||||
|
|
||||||
// Chromium 66 and above supports user stylesheets:
|
|
||||||
// https://github.com/gorhill/uBlock/issues/3588
|
|
||||||
|
|
||||||
if ( typeof vAPI === 'object' ) {
|
|
||||||
vAPI.supportsUserStylesheets =
|
|
||||||
/\bChrom(?:e|ium)\/(?:5\d|6[012345])\b/.test(navigator.userAgent) === false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
DO NOT:
|
|
||||||
- Remove the following code
|
|
||||||
- Add code beyond the following code
|
|
||||||
Reason:
|
|
||||||
- https://github.com/gorhill/uBlock/pull/3721
|
|
||||||
- uBO never uses the return value from injected content scripts
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
void 0;
|
|
|
@ -1,562 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2017-2018 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';
|
|
||||||
|
|
||||||
// Packaging this file is optional: it is not necessary to package it if the
|
|
||||||
// platform is known to support user stylesheets.
|
|
||||||
|
|
||||||
// >>>>>>>> start of HUGE-IF-BLOCK
|
|
||||||
if ( typeof vAPI === 'object' && vAPI.userStylesheet === undefined ) {
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
vAPI.userStylesheet = {
|
|
||||||
style: null,
|
|
||||||
styleFixCount: 0,
|
|
||||||
css: new Map(),
|
|
||||||
disabled: false,
|
|
||||||
apply: function() {
|
|
||||||
},
|
|
||||||
inject: function() {
|
|
||||||
this.style = document.createElement('style');
|
|
||||||
this.style.disabled = this.disabled;
|
|
||||||
const parent = document.head || document.documentElement;
|
|
||||||
if ( parent === null ) { return; }
|
|
||||||
parent.appendChild(this.style);
|
|
||||||
const observer = new MutationObserver(function() {
|
|
||||||
if ( this.style === null ) { return; }
|
|
||||||
if ( this.style.sheet !== null ) { return; }
|
|
||||||
this.styleFixCount += 1;
|
|
||||||
if ( this.styleFixCount < 32 ) {
|
|
||||||
parent.appendChild(this.style);
|
|
||||||
} else {
|
|
||||||
observer.disconnect();
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
observer.observe(parent, { childList: true });
|
|
||||||
},
|
|
||||||
add: function(cssText) {
|
|
||||||
if ( cssText === '' || this.css.has(cssText) ) { return; }
|
|
||||||
if ( this.style === null ) { this.inject(); }
|
|
||||||
const sheet = this.style.sheet;
|
|
||||||
if ( !sheet ) { return; }
|
|
||||||
const i = sheet.cssRules.length;
|
|
||||||
sheet.insertRule(cssText, i);
|
|
||||||
this.css.set(cssText, sheet.cssRules[i]);
|
|
||||||
},
|
|
||||||
remove: function(cssText) {
|
|
||||||
if ( cssText === '' ) { return; }
|
|
||||||
const cssRule = this.css.get(cssText);
|
|
||||||
if ( cssRule === undefined ) { return; }
|
|
||||||
this.css.delete(cssText);
|
|
||||||
if ( this.style === null ) { return; }
|
|
||||||
const sheet = this.style.sheet;
|
|
||||||
if ( !sheet ) { return; }
|
|
||||||
const rules = sheet.cssRules;
|
|
||||||
let i = rules.length;
|
|
||||||
while ( i-- ) {
|
|
||||||
if ( rules[i] !== cssRule ) { continue; }
|
|
||||||
sheet.deleteRule(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ( rules.length !== 0 ) { return; }
|
|
||||||
const style = this.style;
|
|
||||||
this.style = null;
|
|
||||||
const parent = style.parentNode;
|
|
||||||
if ( parent !== null ) {
|
|
||||||
parent.removeChild(style);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toggle: function(state) {
|
|
||||||
if ( state === undefined ) { state = this.disabled; }
|
|
||||||
if ( state !== this.disabled ) { return; }
|
|
||||||
this.disabled = !state;
|
|
||||||
if ( this.style !== null ) {
|
|
||||||
this.style.disabled = this.disabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
vAPI.DOMFilterer = class {
|
|
||||||
constructor() {
|
|
||||||
this.commitTimer = new vAPI.SafeAnimationFrame(this.commitNow.bind(this));
|
|
||||||
this.domIsReady = document.readyState !== 'loading';
|
|
||||||
this.listeners = [];
|
|
||||||
this.excludedNodeSet = new WeakSet();
|
|
||||||
this.addedNodes = new Set();
|
|
||||||
this.removedNodes = false;
|
|
||||||
|
|
||||||
this.specificSimpleHide = new Set();
|
|
||||||
this.specificSimpleHideAggregated = undefined;
|
|
||||||
this.addedSpecificSimpleHide = [];
|
|
||||||
this.specificComplexHide = new Set();
|
|
||||||
this.specificComplexHideAggregated = undefined;
|
|
||||||
this.addedSpecificComplexHide = [];
|
|
||||||
this.specificOthers = [];
|
|
||||||
this.genericSimpleHide = new Set();
|
|
||||||
this.genericComplexHide = new Set();
|
|
||||||
this.exceptedCSSRules = [];
|
|
||||||
|
|
||||||
this.hideNodeExpando = undefined;
|
|
||||||
this.hideNodeBatchProcessTimer = undefined;
|
|
||||||
this.hiddenNodeObserver = undefined;
|
|
||||||
this.hiddenNodesetToProcess = new Set();
|
|
||||||
this.hiddenNodeset = new WeakSet();
|
|
||||||
|
|
||||||
if ( vAPI.domWatcher instanceof Object ) {
|
|
||||||
vAPI.domWatcher.addListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://www.w3.org/community/webed/wiki/CSS/Selectors#Combinators
|
|
||||||
this.reCSSCombinators = /[ >+~]/;
|
|
||||||
}
|
|
||||||
|
|
||||||
commitNow() {
|
|
||||||
this.commitTimer.clear();
|
|
||||||
|
|
||||||
if ( this.domIsReady !== true || vAPI.userStylesheet.disabled ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filterset changed.
|
|
||||||
|
|
||||||
if ( this.addedSpecificSimpleHide.length !== 0 ) {
|
|
||||||
//console.time('specific simple filterset changed');
|
|
||||||
//console.log('added %d specific simple selectors', this.addedSpecificSimpleHide.length);
|
|
||||||
const nodes = document.querySelectorAll(this.addedSpecificSimpleHide.join(','));
|
|
||||||
for ( const node of nodes ) {
|
|
||||||
this.hideNode(node);
|
|
||||||
}
|
|
||||||
this.addedSpecificSimpleHide = [];
|
|
||||||
this.specificSimpleHideAggregated = undefined;
|
|
||||||
//console.timeEnd('specific simple filterset changed');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( this.addedSpecificComplexHide.length !== 0 ) {
|
|
||||||
//console.time('specific complex filterset changed');
|
|
||||||
//console.log('added %d specific complex selectors', this.addedSpecificComplexHide.length);
|
|
||||||
const nodes = document.querySelectorAll(this.addedSpecificComplexHide.join(','));
|
|
||||||
for ( const node of nodes ) {
|
|
||||||
this.hideNode(node);
|
|
||||||
}
|
|
||||||
this.addedSpecificComplexHide = [];
|
|
||||||
this.specificComplexHideAggregated = undefined;
|
|
||||||
//console.timeEnd('specific complex filterset changed');
|
|
||||||
}
|
|
||||||
|
|
||||||
// DOM layout changed.
|
|
||||||
|
|
||||||
const domNodesAdded = this.addedNodes.size !== 0;
|
|
||||||
const domLayoutChanged = domNodesAdded || this.removedNodes;
|
|
||||||
|
|
||||||
if ( domNodesAdded === false || domLayoutChanged === false ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.log('%d nodes added', this.addedNodes.size);
|
|
||||||
|
|
||||||
if ( this.specificSimpleHide.size !== 0 && domNodesAdded ) {
|
|
||||||
//console.time('dom layout changed/specific simple selectors');
|
|
||||||
if ( this.specificSimpleHideAggregated === undefined ) {
|
|
||||||
this.specificSimpleHideAggregated =
|
|
||||||
Array.from(this.specificSimpleHide).join(',\n');
|
|
||||||
}
|
|
||||||
for ( const node of this.addedNodes ) {
|
|
||||||
if ( node.matches(this.specificSimpleHideAggregated) ) {
|
|
||||||
this.hideNode(node);
|
|
||||||
}
|
|
||||||
const nodes = node.querySelectorAll(this.specificSimpleHideAggregated);
|
|
||||||
for ( const node of nodes ) {
|
|
||||||
this.hideNode(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//console.timeEnd('dom layout changed/specific simple selectors');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( this.specificComplexHide.size !== 0 && domLayoutChanged ) {
|
|
||||||
//console.time('dom layout changed/specific complex selectors');
|
|
||||||
if ( this.specificComplexHideAggregated === undefined ) {
|
|
||||||
this.specificComplexHideAggregated =
|
|
||||||
Array.from(this.specificComplexHide).join(',\n');
|
|
||||||
}
|
|
||||||
const nodes = document.querySelectorAll(this.specificComplexHideAggregated);
|
|
||||||
for ( const node of nodes ) {
|
|
||||||
this.hideNode(node);
|
|
||||||
}
|
|
||||||
//console.timeEnd('dom layout changed/specific complex selectors');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.addedNodes.clear();
|
|
||||||
this.removedNodes = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
commit(now) {
|
|
||||||
if ( now ) {
|
|
||||||
this.commitTimer.clear();
|
|
||||||
this.commitNow();
|
|
||||||
} else {
|
|
||||||
this.commitTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addCSSRule(selectors, declarations, details = {}) {
|
|
||||||
if ( selectors === undefined ) { return; }
|
|
||||||
|
|
||||||
const selectorsStr = Array.isArray(selectors) ?
|
|
||||||
selectors.join(',\n') :
|
|
||||||
selectors;
|
|
||||||
if ( selectorsStr.length === 0 ) { return; }
|
|
||||||
|
|
||||||
vAPI.userStylesheet.add(selectorsStr + '\n{' + declarations + '}');
|
|
||||||
this.commit();
|
|
||||||
if ( details.silent !== true && this.hasListeners() ) {
|
|
||||||
this.triggerListeners({
|
|
||||||
declarative: [ [ selectorsStr, declarations ] ]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( declarations !== 'display:none!important;' ) {
|
|
||||||
this.specificOthers.push({
|
|
||||||
selectors: selectorsStr,
|
|
||||||
declarations: declarations
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isGeneric= details.lazy === true;
|
|
||||||
const isSimple = details.type === 'simple';
|
|
||||||
const isComplex = details.type === 'complex';
|
|
||||||
|
|
||||||
if ( isGeneric ) {
|
|
||||||
if ( isSimple ) {
|
|
||||||
this.genericSimpleHide.add(selectorsStr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( isComplex ) {
|
|
||||||
this.genericComplexHide.add(selectorsStr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectorsArr = Array.isArray(selectors) ?
|
|
||||||
selectors :
|
|
||||||
selectors.split(',\n');
|
|
||||||
|
|
||||||
if ( isGeneric ) {
|
|
||||||
for ( const selector of selectorsArr ) {
|
|
||||||
if ( this.reCSSCombinators.test(selector) ) {
|
|
||||||
this.genericComplexHide.add(selector);
|
|
||||||
} else {
|
|
||||||
this.genericSimpleHide.add(selector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific cosmetic filters.
|
|
||||||
for ( const selector of selectorsArr ) {
|
|
||||||
if (
|
|
||||||
isComplex ||
|
|
||||||
isSimple === false && this.reCSSCombinators.test(selector)
|
|
||||||
) {
|
|
||||||
if ( this.specificComplexHide.has(selector) === false ) {
|
|
||||||
this.specificComplexHide.add(selector);
|
|
||||||
this.addedSpecificComplexHide.push(selector);
|
|
||||||
}
|
|
||||||
} else if ( this.specificSimpleHide.has(selector) === false ) {
|
|
||||||
this.specificSimpleHide.add(selector);
|
|
||||||
this.addedSpecificSimpleHide.push(selector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exceptCSSRules(exceptions) {
|
|
||||||
if ( exceptions.length === 0 ) { return; }
|
|
||||||
this.exceptedCSSRules.push(...exceptions);
|
|
||||||
if ( this.hasListeners() ) {
|
|
||||||
this.triggerListeners({ exceptions });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onDOMCreated() {
|
|
||||||
this.domIsReady = true;
|
|
||||||
this.addedNodes.clear();
|
|
||||||
this.removedNodes = false;
|
|
||||||
this.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
onDOMChanged(addedNodes, removedNodes) {
|
|
||||||
for ( const node of addedNodes ) {
|
|
||||||
this.addedNodes.add(node);
|
|
||||||
}
|
|
||||||
this.removedNodes = this.removedNodes || removedNodes;
|
|
||||||
this.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
addListener(listener) {
|
|
||||||
if ( this.listeners.indexOf(listener) !== -1 ) { return; }
|
|
||||||
this.listeners.push(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeListener(listener) {
|
|
||||||
const pos = this.listeners.indexOf(listener);
|
|
||||||
if ( pos === -1 ) { return; }
|
|
||||||
this.listeners.splice(pos, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
hasListeners() {
|
|
||||||
return this.listeners.length !== 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerListeners(changes) {
|
|
||||||
for ( const listener of this.listeners ) {
|
|
||||||
listener.onFiltersetChanged(changes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://jsperf.com/clientheight-and-clientwidth-vs-getcomputedstyle
|
|
||||||
// Avoid getComputedStyle(), detecting whether a node is visible can be
|
|
||||||
// achieved with clientWidth/clientHeight.
|
|
||||||
// https://gist.github.com/paulirish/5d52fb081b3570c81e3a
|
|
||||||
// Do not interleave read-from/write-to the DOM. Write-to DOM
|
|
||||||
// operations would cause the first read-from to be expensive, and
|
|
||||||
// interleaving means that potentially all single read-from operation
|
|
||||||
// would be expensive rather than just the 1st one.
|
|
||||||
// Benchmarking toggling off/on cosmetic filtering confirms quite an
|
|
||||||
// improvement when:
|
|
||||||
// - batching as much as possible handling of all nodes;
|
|
||||||
// - avoiding to interleave read-from/write-to operations.
|
|
||||||
// However, toggling off/on cosmetic filtering repeatedly is not
|
|
||||||
// a real use case, but this shows this will help performance
|
|
||||||
// on sites which try to use inline styles to bypass blockers.
|
|
||||||
hideNodeBatchProcess() {
|
|
||||||
this.hideNodeBatchProcessTimer.clear();
|
|
||||||
const expando = this.hideNodeExpando;
|
|
||||||
for ( const node of this.hiddenNodesetToProcess ) {
|
|
||||||
if (
|
|
||||||
this.hiddenNodeset.has(node) === false ||
|
|
||||||
node[expando] === undefined ||
|
|
||||||
node.clientHeight === 0 || node.clientWidth === 0
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let attr = node.getAttribute('style');
|
|
||||||
if ( attr === null ) {
|
|
||||||
attr = '';
|
|
||||||
} else if ( attr.length !== 0 ) {
|
|
||||||
if ( attr.endsWith('display:none!important;') ) { continue; }
|
|
||||||
if ( attr.charCodeAt(attr.length - 1) !== 0x3B /* ';' */ ) {
|
|
||||||
attr += ';';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node.setAttribute('style', attr + 'display:none!important;');
|
|
||||||
}
|
|
||||||
this.hiddenNodesetToProcess.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
hideNodeObserverHandler(mutations) {
|
|
||||||
if ( vAPI.userStylesheet.disabled ) { return; }
|
|
||||||
const stagedNodes = this.hiddenNodesetToProcess;
|
|
||||||
for ( const mutation of mutations ) {
|
|
||||||
stagedNodes.add(mutation.target);
|
|
||||||
}
|
|
||||||
this.hideNodeBatchProcessTimer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
hideNodeInit() {
|
|
||||||
this.hideNodeExpando = vAPI.randomToken();
|
|
||||||
this.hideNodeBatchProcessTimer =
|
|
||||||
new vAPI.SafeAnimationFrame(this.hideNodeBatchProcess.bind(this));
|
|
||||||
this.hiddenNodeObserver =
|
|
||||||
new MutationObserver(this.hideNodeObserverHandler.bind(this));
|
|
||||||
if ( this.hideNodeStyleSheetInjected === false ) {
|
|
||||||
this.hideNodeStyleSheetInjected = true;
|
|
||||||
vAPI.userStylesheet.add(
|
|
||||||
`[${this.hideNodeAttr}]\n{display:none!important;}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
excludeNode(node) {
|
|
||||||
this.excludedNodeSet.add(node);
|
|
||||||
this.unhideNode(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
unexcludeNode(node) {
|
|
||||||
this.excludedNodeSet.delete(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
hideNode(node) {
|
|
||||||
if ( this.excludedNodeSet.has(node) ) { return; }
|
|
||||||
if ( this.hideNodeAttr === undefined ) { return; }
|
|
||||||
if ( this.hiddenNodeset.has(node) ) { return; }
|
|
||||||
node.hidden = true;
|
|
||||||
this.hiddenNodeset.add(node);
|
|
||||||
if ( this.hideNodeExpando === undefined ) { this.hideNodeInit(); }
|
|
||||||
node.setAttribute(this.hideNodeAttr, '');
|
|
||||||
if ( node[this.hideNodeExpando] === undefined ) {
|
|
||||||
node[this.hideNodeExpando] =
|
|
||||||
node.hasAttribute('style') &&
|
|
||||||
(node.getAttribute('style') || '');
|
|
||||||
}
|
|
||||||
this.hiddenNodesetToProcess.add(node);
|
|
||||||
this.hideNodeBatchProcessTimer.start();
|
|
||||||
this.hiddenNodeObserver.observe(node, this.hiddenNodeObserverOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
unhideNode(node) {
|
|
||||||
if ( this.hiddenNodeset.has(node) === false ) { return; }
|
|
||||||
node.hidden = false;
|
|
||||||
node.removeAttribute(this.hideNodeAttr);
|
|
||||||
this.hiddenNodesetToProcess.delete(node);
|
|
||||||
if ( this.hideNodeExpando === undefined ) { return; }
|
|
||||||
const attr = node[this.hideNodeExpando];
|
|
||||||
if ( attr === false ) {
|
|
||||||
node.removeAttribute('style');
|
|
||||||
} else if ( typeof attr === 'string' ) {
|
|
||||||
node.setAttribute('style', attr);
|
|
||||||
}
|
|
||||||
node[this.hideNodeExpando] = undefined;
|
|
||||||
this.hiddenNodeset.delete(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
showNode(node) {
|
|
||||||
node.hidden = false;
|
|
||||||
const attr = node[this.hideNodeExpando];
|
|
||||||
if ( attr === false ) {
|
|
||||||
node.removeAttribute('style');
|
|
||||||
} else if ( typeof attr === 'string' ) {
|
|
||||||
node.setAttribute('style', attr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unshowNode(node) {
|
|
||||||
node.hidden = true;
|
|
||||||
this.hiddenNodesetToProcess.add(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle(state, callback) {
|
|
||||||
vAPI.userStylesheet.toggle(state);
|
|
||||||
const disabled = vAPI.userStylesheet.disabled;
|
|
||||||
const nodes = document.querySelectorAll(`[${this.hideNodeAttr}]`);
|
|
||||||
for ( const node of nodes ) {
|
|
||||||
if ( disabled ) {
|
|
||||||
this.showNode(node);
|
|
||||||
} else {
|
|
||||||
this.unshowNode(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( disabled === false && this.hideNodeExpando !== undefined ) {
|
|
||||||
this.hideNodeBatchProcessTimer.start();
|
|
||||||
}
|
|
||||||
if ( typeof callback === 'function' ) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllSelectors_(all) {
|
|
||||||
const out = {
|
|
||||||
declarative: [],
|
|
||||||
exceptions: this.exceptedCSSRules,
|
|
||||||
};
|
|
||||||
if ( this.specificSimpleHide.size !== 0 ) {
|
|
||||||
out.declarative.push([
|
|
||||||
Array.from(this.specificSimpleHide).join(',\n'),
|
|
||||||
'display:none!important;'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
if ( this.specificComplexHide.size !== 0 ) {
|
|
||||||
out.declarative.push([
|
|
||||||
Array.from(this.specificComplexHide).join(',\n'),
|
|
||||||
'display:none!important;'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
if ( this.genericSimpleHide.size !== 0 ) {
|
|
||||||
out.declarative.push([
|
|
||||||
Array.from(this.genericSimpleHide).join(',\n'),
|
|
||||||
'display:none!important;'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
if ( this.genericComplexHide.size !== 0 ) {
|
|
||||||
out.declarative.push([
|
|
||||||
Array.from(this.genericComplexHide).join(',\n'),
|
|
||||||
'display:none!important;'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
if ( all ) {
|
|
||||||
out.declarative.push([
|
|
||||||
'[' + this.hideNodeAttr + ']',
|
|
||||||
'display:none!important;'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
for ( const entry of this.specificOthers ) {
|
|
||||||
out.declarative.push([ entry.selectors, entry.declarations ]);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
getFilteredElementCount() {
|
|
||||||
const details = this.getAllSelectors_(true);
|
|
||||||
if ( Array.isArray(details.declarative) === false ) { return 0; }
|
|
||||||
const selectors = details.declarative.map(entry => entry[0]);
|
|
||||||
if ( selectors.length === 0 ) { return 0; }
|
|
||||||
return document.querySelectorAll(selectors.join(',\n')).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllSelectors() {
|
|
||||||
return this.getAllSelectors_(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
vAPI.DOMFilterer.prototype.hiddenNodeObserverOptions = {
|
|
||||||
attributes: true,
|
|
||||||
attributeFilter: [ 'style' ]
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
}
|
|
||||||
// <<<<<<<< end of HUGE-IF-BLOCK
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
DO NOT:
|
|
||||||
- Remove the following code
|
|
||||||
- Add code beyond the following code
|
|
||||||
Reason:
|
|
||||||
- https://github.com/gorhill/uBlock/pull/3721
|
|
||||||
- uBO never uses the return value from injected content scripts
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
void 0;
|
|
|
@ -1,282 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2017-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';
|
|
||||||
|
|
||||||
// Packaging this file is optional: it is not necessary to package it if the
|
|
||||||
// platform is known to not support user stylesheets.
|
|
||||||
|
|
||||||
// >>>>>>>> start of HUGE-IF-BLOCK
|
|
||||||
if ( typeof vAPI === 'object' && vAPI.supportsUserStylesheets ) {
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
vAPI.userStylesheet = {
|
|
||||||
added: new Set(),
|
|
||||||
removed: new Set(),
|
|
||||||
apply: function(callback) {
|
|
||||||
if ( this.added.size === 0 && this.removed.size === 0 ) { return; }
|
|
||||||
vAPI.messaging.send('vapi', {
|
|
||||||
what: 'userCSS',
|
|
||||||
add: Array.from(this.added),
|
|
||||||
remove: Array.from(this.removed),
|
|
||||||
}).then(( ) => {
|
|
||||||
if ( callback instanceof Function === false ) { return; }
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
this.added.clear();
|
|
||||||
this.removed.clear();
|
|
||||||
},
|
|
||||||
add: function(cssText, now) {
|
|
||||||
if ( cssText === '' ) { return; }
|
|
||||||
this.added.add(cssText);
|
|
||||||
if ( now ) { this.apply(); }
|
|
||||||
},
|
|
||||||
remove: function(cssText, now) {
|
|
||||||
if ( cssText === '' ) { return; }
|
|
||||||
this.removed.add(cssText);
|
|
||||||
if ( now ) { this.apply(); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
vAPI.DOMFilterer = class {
|
|
||||||
constructor() {
|
|
||||||
this.commitTimer = new vAPI.SafeAnimationFrame(this.commitNow.bind(this));
|
|
||||||
this.domIsReady = document.readyState !== 'loading';
|
|
||||||
this.disabled = false;
|
|
||||||
this.listeners = [];
|
|
||||||
this.filterset = new Set();
|
|
||||||
this.excludedNodeSet = new WeakSet();
|
|
||||||
this.addedCSSRules = new Set();
|
|
||||||
this.exceptedCSSRules = [];
|
|
||||||
this.reOnlySelectors = /\n\{[^\n]+/g;
|
|
||||||
|
|
||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/167
|
|
||||||
// By the time the DOMContentLoaded is fired, the content script might
|
|
||||||
// have been disconnected from the background page. Unclear why this
|
|
||||||
// would happen, so far seems to be a Chromium-specific behavior at
|
|
||||||
// launch time.
|
|
||||||
if ( this.domIsReady !== true ) {
|
|
||||||
document.addEventListener('DOMContentLoaded', ( ) => {
|
|
||||||
if ( vAPI instanceof Object === false ) { return; }
|
|
||||||
this.domIsReady = true;
|
|
||||||
this.commit();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Here we will deal with:
|
|
||||||
// - Injecting low priority user styles;
|
|
||||||
// - Notifying listeners about changed filterset.
|
|
||||||
// https://www.reddit.com/r/uBlockOrigin/comments/9jj0y1/no_longer_blocking_ads/
|
|
||||||
// Ensure vAPI is still valid -- it can go away by the time we are
|
|
||||||
// called, since the port could be force-disconnected from the main
|
|
||||||
// process. Another approach would be to have vAPI.SafeAnimationFrame
|
|
||||||
// register a shutdown job: to evaluate. For now I will keep the fix
|
|
||||||
// trivial.
|
|
||||||
commitNow() {
|
|
||||||
this.commitTimer.clear();
|
|
||||||
if ( vAPI instanceof Object === false ) { return; }
|
|
||||||
const userStylesheet = vAPI.userStylesheet;
|
|
||||||
for ( const entry of this.addedCSSRules ) {
|
|
||||||
if (
|
|
||||||
this.disabled === false &&
|
|
||||||
entry.lazy &&
|
|
||||||
entry.injected === false
|
|
||||||
) {
|
|
||||||
userStylesheet.add(
|
|
||||||
entry.selectors + '\n{' + entry.declarations + '}'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.addedCSSRules.clear();
|
|
||||||
userStylesheet.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
commit(commitNow) {
|
|
||||||
if ( commitNow ) {
|
|
||||||
this.commitTimer.clear();
|
|
||||||
this.commitNow();
|
|
||||||
} else {
|
|
||||||
this.commitTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addCSSRule(selectors, declarations, details = {}) {
|
|
||||||
if ( selectors === undefined ) { return; }
|
|
||||||
const selectorsStr = Array.isArray(selectors)
|
|
||||||
? selectors.join(',\n')
|
|
||||||
: selectors;
|
|
||||||
if ( selectorsStr.length === 0 ) { return; }
|
|
||||||
const entry = {
|
|
||||||
selectors: selectorsStr,
|
|
||||||
declarations,
|
|
||||||
lazy: details.lazy === true,
|
|
||||||
injected: details.injected === true
|
|
||||||
};
|
|
||||||
this.addedCSSRules.add(entry);
|
|
||||||
this.filterset.add(entry);
|
|
||||||
if (
|
|
||||||
this.disabled === false &&
|
|
||||||
entry.lazy !== true &&
|
|
||||||
entry.injected !== true
|
|
||||||
) {
|
|
||||||
vAPI.userStylesheet.add(selectorsStr + '\n{' + declarations + '}');
|
|
||||||
}
|
|
||||||
this.commit();
|
|
||||||
if ( details.silent !== true && this.hasListeners() ) {
|
|
||||||
this.triggerListeners({
|
|
||||||
declarative: [ [ selectorsStr, declarations ] ]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exceptCSSRules(exceptions) {
|
|
||||||
if ( exceptions.length === 0 ) { return; }
|
|
||||||
this.exceptedCSSRules.push(...exceptions);
|
|
||||||
if ( this.hasListeners() ) {
|
|
||||||
this.triggerListeners({ exceptions });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addListener(listener) {
|
|
||||||
if ( this.listeners.indexOf(listener) !== -1 ) { return; }
|
|
||||||
this.listeners.push(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeListener(listener) {
|
|
||||||
const pos = this.listeners.indexOf(listener);
|
|
||||||
if ( pos === -1 ) { return; }
|
|
||||||
this.listeners.splice(pos, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
hasListeners() {
|
|
||||||
return this.listeners.length !== 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerListeners(changes) {
|
|
||||||
for ( const listener of this.listeners ) {
|
|
||||||
listener.onFiltersetChanged(changes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
excludeNode(node) {
|
|
||||||
this.excludedNodeSet.add(node);
|
|
||||||
this.unhideNode(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
unexcludeNode(node) {
|
|
||||||
this.excludedNodeSet.delete(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
hideNode(node) {
|
|
||||||
if ( this.excludedNodeSet.has(node) ) { return; }
|
|
||||||
if ( this.hideNodeAttr === undefined ) { return; }
|
|
||||||
node.setAttribute(this.hideNodeAttr, '');
|
|
||||||
if ( this.hideNodeStyleSheetInjected ) { return; }
|
|
||||||
this.hideNodeStyleSheetInjected = true;
|
|
||||||
this.addCSSRule(
|
|
||||||
`[${this.hideNodeAttr}]`,
|
|
||||||
'display:none!important;',
|
|
||||||
{ silent: true }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
unhideNode(node) {
|
|
||||||
if ( this.hideNodeAttr === undefined ) { return; }
|
|
||||||
node.removeAttribute(this.hideNodeAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle(state, callback) {
|
|
||||||
if ( state === undefined ) { state = this.disabled; }
|
|
||||||
if ( state !== this.disabled ) { return; }
|
|
||||||
this.disabled = !state;
|
|
||||||
const userStylesheet = vAPI.userStylesheet;
|
|
||||||
for ( const entry of this.filterset ) {
|
|
||||||
const rule = `${entry.selectors}\n{${entry.declarations}}`;
|
|
||||||
if ( this.disabled ) {
|
|
||||||
userStylesheet.remove(rule);
|
|
||||||
} else {
|
|
||||||
userStylesheet.add(rule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
userStylesheet.apply(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllSelectors_(all) {
|
|
||||||
const out = {
|
|
||||||
declarative: [],
|
|
||||||
exceptions: this.exceptedCSSRules,
|
|
||||||
};
|
|
||||||
for ( const entry of this.filterset ) {
|
|
||||||
let selectors = entry.selectors;
|
|
||||||
if ( all !== true && this.hideNodeAttr !== undefined ) {
|
|
||||||
selectors = selectors
|
|
||||||
.replace(`[${this.hideNodeAttr}]`, '')
|
|
||||||
.replace(/^,\n|,\n$/gm, '');
|
|
||||||
if ( selectors === '' ) { continue; }
|
|
||||||
}
|
|
||||||
out.declarative.push([ selectors, entry.declarations ]);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
getFilteredElementCount() {
|
|
||||||
const details = this.getAllSelectors_(true);
|
|
||||||
if ( Array.isArray(details.declarative) === false ) { return 0; }
|
|
||||||
const selectors = details.declarative.map(entry => entry[0]);
|
|
||||||
if ( selectors.length === 0 ) { return 0; }
|
|
||||||
return document.querySelectorAll(selectors.join(',\n')).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAllSelectors() {
|
|
||||||
return this.getAllSelectors_(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
}
|
|
||||||
// <<<<<<<< end of HUGE-IF-BLOCK
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
DO NOT:
|
|
||||||
- Remove the following code
|
|
||||||
- Add code beyond the following code
|
|
||||||
Reason:
|
|
||||||
- https://github.com/gorhill/uBlock/pull/3721
|
|
||||||
- uBO never uses the return value from injected content scripts
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
void 0;
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2018 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';
|
|
||||||
|
|
||||||
// User stylesheets are always supported with Firefox/webext .
|
|
||||||
|
|
||||||
if ( typeof vAPI === 'object' ) {
|
|
||||||
vAPI.supportsUserStylesheets = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
DO NOT:
|
|
||||||
- Remove the following code
|
|
||||||
- Add code beyond the following code
|
|
||||||
Reason:
|
|
||||||
- https://github.com/gorhill/uBlock/pull/3721
|
|
||||||
- uBO never uses the return value from injected content scripts
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
void 0;
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
uBlock Origin - a browser extension to block requests.
|
|
||||||
Copyright (C) 2018 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';
|
|
||||||
|
|
||||||
// This file can be replaced by platform-specific code. If a platform is
|
|
||||||
// known to NOT support user stylsheets, vAPI.supportsUserStylesheets can be
|
|
||||||
// set to `false`.
|
|
||||||
|
|
||||||
// Chromium 66 and above supports user stylesheets:
|
|
||||||
// https://github.com/gorhill/uBlock/issues/3588
|
|
||||||
|
|
||||||
if ( typeof vAPI === 'object' ) {
|
|
||||||
vAPI.supportsUserStylesheets =
|
|
||||||
/\bChrom(?:e|ium)\/(?:6[6789]|[789]|1\d\d)|\bFirefox\/\d/.test(navigator.userAgent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
|
|
||||||
DO NOT:
|
|
||||||
- Remove the following code
|
|
||||||
- Add code beyond the following code
|
|
||||||
Reason:
|
|
||||||
- https://github.com/gorhill/uBlock/pull/3721
|
|
||||||
- uBO never uses the return value from injected content scripts
|
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
void 0;
|
|
|
@ -114,6 +114,38 @@ if ( typeof vAPI === 'object' && !vAPI.contentScript ) {
|
||||||
|
|
||||||
vAPI.contentScript = true;
|
vAPI.contentScript = true;
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/******************************************************************************/
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
vAPI.userStylesheet = {
|
||||||
|
added: new Set(),
|
||||||
|
removed: new Set(),
|
||||||
|
apply: function(callback) {
|
||||||
|
if ( this.added.size === 0 && this.removed.size === 0 ) { return; }
|
||||||
|
vAPI.messaging.send('vapi', {
|
||||||
|
what: 'userCSS',
|
||||||
|
add: Array.from(this.added),
|
||||||
|
remove: Array.from(this.removed),
|
||||||
|
}).then(( ) => {
|
||||||
|
if ( callback instanceof Function === false ) { return; }
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
this.added.clear();
|
||||||
|
this.removed.clear();
|
||||||
|
},
|
||||||
|
add: function(cssText, now) {
|
||||||
|
if ( cssText === '' ) { return; }
|
||||||
|
this.added.add(cssText);
|
||||||
|
if ( now ) { this.apply(); }
|
||||||
|
},
|
||||||
|
remove: function(cssText, now) {
|
||||||
|
if ( cssText === '' ) { return; }
|
||||||
|
this.removed.add(cssText);
|
||||||
|
if ( now ) { this.apply(); }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -141,13 +173,12 @@ vAPI.contentScript = true;
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/2147
|
// https://github.com/gorhill/uBlock/issues/2147
|
||||||
|
|
||||||
vAPI.SafeAnimationFrame = function(callback) {
|
vAPI.SafeAnimationFrame = class {
|
||||||
this.fid = this.tid = undefined;
|
constructor(callback) {
|
||||||
this.callback = callback;
|
this.fid = this.tid = undefined;
|
||||||
};
|
this.callback = callback;
|
||||||
|
}
|
||||||
vAPI.SafeAnimationFrame.prototype = {
|
start(delay) {
|
||||||
start: function(delay) {
|
|
||||||
if ( self.vAPI instanceof Object === false ) { return; }
|
if ( self.vAPI instanceof Object === false ) { return; }
|
||||||
if ( delay === undefined ) {
|
if ( delay === undefined ) {
|
||||||
if ( this.fid === undefined ) {
|
if ( this.fid === undefined ) {
|
||||||
|
@ -161,8 +192,8 @@ vAPI.SafeAnimationFrame.prototype = {
|
||||||
if ( this.fid === undefined && this.tid === undefined ) {
|
if ( this.fid === undefined && this.tid === undefined ) {
|
||||||
this.tid = vAPI.setTimeout(( ) => { this.macroToMicro(); }, delay);
|
this.tid = vAPI.setTimeout(( ) => { this.macroToMicro(); }, delay);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
clear: function() {
|
clear() {
|
||||||
if ( this.fid !== undefined ) {
|
if ( this.fid !== undefined ) {
|
||||||
cancelAnimationFrame(this.fid);
|
cancelAnimationFrame(this.fid);
|
||||||
this.fid = undefined;
|
this.fid = undefined;
|
||||||
|
@ -171,27 +202,27 @@ vAPI.SafeAnimationFrame.prototype = {
|
||||||
clearTimeout(this.tid);
|
clearTimeout(this.tid);
|
||||||
this.tid = undefined;
|
this.tid = undefined;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
macroToMicro: function() {
|
macroToMicro() {
|
||||||
this.tid = undefined;
|
this.tid = undefined;
|
||||||
this.start();
|
this.start();
|
||||||
},
|
}
|
||||||
onRAF: function() {
|
onRAF() {
|
||||||
if ( this.tid !== undefined ) {
|
if ( this.tid !== undefined ) {
|
||||||
clearTimeout(this.tid);
|
clearTimeout(this.tid);
|
||||||
this.tid = undefined;
|
this.tid = undefined;
|
||||||
}
|
}
|
||||||
this.fid = undefined;
|
this.fid = undefined;
|
||||||
this.callback();
|
this.callback();
|
||||||
},
|
}
|
||||||
onSTO: function() {
|
onSTO() {
|
||||||
if ( this.fid !== undefined ) {
|
if ( this.fid !== undefined ) {
|
||||||
cancelAnimationFrame(this.fid);
|
cancelAnimationFrame(this.fid);
|
||||||
this.fid = undefined;
|
this.fid = undefined;
|
||||||
}
|
}
|
||||||
this.tid = undefined;
|
this.tid = undefined;
|
||||||
this.callback();
|
this.callback();
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -267,7 +298,9 @@ vAPI.SafeAnimationFrame.prototype = {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.domWatcher = (( ) => {
|
// vAPI.domWatcher
|
||||||
|
|
||||||
|
{
|
||||||
vAPI.domMutationTime = Date.now();
|
vAPI.domMutationTime = Date.now();
|
||||||
|
|
||||||
const addedNodeLists = [];
|
const addedNodeLists = [];
|
||||||
|
@ -406,8 +439,8 @@ vAPI.domWatcher = (( ) => {
|
||||||
startMutationObserver();
|
startMutationObserver();
|
||||||
};
|
};
|
||||||
|
|
||||||
return { start, addListener, removeListener };
|
vAPI.domWatcher = { start, addListener, removeListener };
|
||||||
})();
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -436,15 +469,11 @@ vAPI.injectScriptlet = function(doc, text) {
|
||||||
|
|
||||||
The DOM filterer is the heart of uBO's cosmetic filtering.
|
The DOM filterer is the heart of uBO's cosmetic filtering.
|
||||||
|
|
||||||
DOMBaseFilterer: platform-specific
|
DOMFilterer: adds procedural cosmetic filtering
|
||||||
|
|
|
||||||
|
|
|
||||||
+---- DOMFilterer: adds procedural cosmetic filtering
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vAPI.DOMFilterer = (function() {
|
{
|
||||||
|
|
||||||
// 'P' stands for 'Procedural'
|
// 'P' stands for 'Procedural'
|
||||||
|
|
||||||
const PSelectorHasTextTask = class {
|
const PSelectorHasTextTask = class {
|
||||||
|
@ -837,9 +866,19 @@ vAPI.DOMFilterer = (function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const DOMFilterer = class extends vAPI.DOMFilterer {
|
vAPI.DOMFilterer = class {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
this.commitTimer = new vAPI.SafeAnimationFrame(
|
||||||
|
( ) => { this.commitNow(); }
|
||||||
|
);
|
||||||
|
this.domIsReady = document.readyState !== 'loading';
|
||||||
|
this.disabled = false;
|
||||||
|
this.listeners = [];
|
||||||
|
this.filterset = new Set();
|
||||||
|
this.excludedNodeSet = new WeakSet();
|
||||||
|
this.addedCSSRules = new Set();
|
||||||
|
this.exceptedCSSRules = [];
|
||||||
|
this.reOnlySelectors = /\n\{[^\n]+/g;
|
||||||
this.exceptions = [];
|
this.exceptions = [];
|
||||||
this.proceduralFilterer = new DOMProceduralFilterer(this);
|
this.proceduralFilterer = new DOMProceduralFilterer(this);
|
||||||
this.hideNodeAttr = undefined;
|
this.hideNodeAttr = undefined;
|
||||||
|
@ -847,13 +886,177 @@ vAPI.DOMFilterer = (function() {
|
||||||
if ( vAPI.domWatcher instanceof Object ) {
|
if ( vAPI.domWatcher instanceof Object ) {
|
||||||
vAPI.domWatcher.addListener(this);
|
vAPI.domWatcher.addListener(this);
|
||||||
}
|
}
|
||||||
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/167
|
||||||
|
// By the time the DOMContentLoaded is fired, the content script might
|
||||||
|
// have been disconnected from the background page. Unclear why this
|
||||||
|
// would happen, so far seems to be a Chromium-specific behavior at
|
||||||
|
// launch time.
|
||||||
|
if ( this.domIsReady !== true ) {
|
||||||
|
document.addEventListener('DOMContentLoaded', ( ) => {
|
||||||
|
if ( vAPI instanceof Object === false ) { return; }
|
||||||
|
this.domIsReady = true;
|
||||||
|
this.commit();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addCSSRule(selectors, declarations, details = {}) {
|
||||||
|
if ( selectors === undefined ) { return; }
|
||||||
|
const selectorsStr = Array.isArray(selectors)
|
||||||
|
? selectors.join(',\n')
|
||||||
|
: selectors;
|
||||||
|
if ( selectorsStr.length === 0 ) { return; }
|
||||||
|
const entry = {
|
||||||
|
selectors: selectorsStr,
|
||||||
|
declarations,
|
||||||
|
lazy: details.lazy === true,
|
||||||
|
injected: details.injected === true
|
||||||
|
};
|
||||||
|
this.addedCSSRules.add(entry);
|
||||||
|
this.filterset.add(entry);
|
||||||
|
if (
|
||||||
|
this.disabled === false &&
|
||||||
|
entry.lazy !== true &&
|
||||||
|
entry.injected !== true
|
||||||
|
) {
|
||||||
|
vAPI.userStylesheet.add(`${selectorsStr}\n{${declarations}}`);
|
||||||
|
}
|
||||||
|
this.commit();
|
||||||
|
if ( details.silent !== true && this.hasListeners() ) {
|
||||||
|
this.triggerListeners({
|
||||||
|
declarative: [ [ selectorsStr, declarations ] ]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exceptCSSRules(exceptions) {
|
||||||
|
if ( exceptions.length === 0 ) { return; }
|
||||||
|
this.exceptedCSSRules.push(...exceptions);
|
||||||
|
if ( this.hasListeners() ) {
|
||||||
|
this.triggerListeners({ exceptions });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addListener(listener) {
|
||||||
|
if ( this.listeners.indexOf(listener) !== -1 ) { return; }
|
||||||
|
this.listeners.push(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeListener(listener) {
|
||||||
|
const pos = this.listeners.indexOf(listener);
|
||||||
|
if ( pos === -1 ) { return; }
|
||||||
|
this.listeners.splice(pos, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasListeners() {
|
||||||
|
return this.listeners.length !== 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerListeners(changes) {
|
||||||
|
for ( const listener of this.listeners ) {
|
||||||
|
listener.onFiltersetChanged(changes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
excludeNode(node) {
|
||||||
|
this.excludedNodeSet.add(node);
|
||||||
|
this.unhideNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
unexcludeNode(node) {
|
||||||
|
this.excludedNodeSet.delete(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
hideNode(node) {
|
||||||
|
if ( this.excludedNodeSet.has(node) ) { return; }
|
||||||
|
if ( this.hideNodeAttr === undefined ) { return; }
|
||||||
|
node.setAttribute(this.hideNodeAttr, '');
|
||||||
|
if ( this.hideNodeStyleSheetInjected ) { return; }
|
||||||
|
this.hideNodeStyleSheetInjected = true;
|
||||||
|
this.addCSSRule(
|
||||||
|
`[${this.hideNodeAttr}]`,
|
||||||
|
'display:none!important;',
|
||||||
|
{ silent: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
unhideNode(node) {
|
||||||
|
if ( this.hideNodeAttr === undefined ) { return; }
|
||||||
|
node.removeAttribute(this.hideNodeAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle(state, callback) {
|
||||||
|
if ( state === undefined ) { state = this.disabled; }
|
||||||
|
if ( state !== this.disabled ) { return; }
|
||||||
|
this.disabled = !state;
|
||||||
|
const userStylesheet = vAPI.userStylesheet;
|
||||||
|
for ( const entry of this.filterset ) {
|
||||||
|
const rule = `${entry.selectors}\n{${entry.declarations}}`;
|
||||||
|
if ( this.disabled ) {
|
||||||
|
userStylesheet.remove(rule);
|
||||||
|
} else {
|
||||||
|
userStylesheet.add(rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userStylesheet.apply(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllSelectors_(all) {
|
||||||
|
const out = {
|
||||||
|
declarative: [],
|
||||||
|
exceptions: this.exceptedCSSRules,
|
||||||
|
};
|
||||||
|
for ( const entry of this.filterset ) {
|
||||||
|
let selectors = entry.selectors;
|
||||||
|
if ( all !== true && this.hideNodeAttr !== undefined ) {
|
||||||
|
selectors = selectors
|
||||||
|
.replace(`[${this.hideNodeAttr}]`, '')
|
||||||
|
.replace(/^,\n|,\n$/gm, '');
|
||||||
|
if ( selectors === '' ) { continue; }
|
||||||
|
}
|
||||||
|
out.declarative.push([ selectors, entry.declarations ]);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here we will deal with:
|
||||||
|
// - Injecting low priority user styles;
|
||||||
|
// - Notifying listeners about changed filterset.
|
||||||
|
// https://www.reddit.com/r/uBlockOrigin/comments/9jj0y1/no_longer_blocking_ads/
|
||||||
|
// Ensure vAPI is still valid -- it can go away by the time we are
|
||||||
|
// called, since the port could be force-disconnected from the main
|
||||||
|
// process. Another approach would be to have vAPI.SafeAnimationFrame
|
||||||
|
// register a shutdown job: to evaluate. For now I will keep the fix
|
||||||
|
// trivial.
|
||||||
commitNow() {
|
commitNow() {
|
||||||
super.commitNow();
|
this.commitTimer.clear();
|
||||||
|
if ( vAPI instanceof Object === false ) { return; }
|
||||||
|
const userStylesheet = vAPI.userStylesheet;
|
||||||
|
for ( const entry of this.addedCSSRules ) {
|
||||||
|
if (
|
||||||
|
this.disabled === false &&
|
||||||
|
entry.lazy &&
|
||||||
|
entry.injected === false
|
||||||
|
) {
|
||||||
|
userStylesheet.add(
|
||||||
|
entry.selectors + '\n{' + entry.declarations + '}'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.addedCSSRules.clear();
|
||||||
|
userStylesheet.apply();
|
||||||
this.proceduralFilterer.commitNow();
|
this.proceduralFilterer.commitNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commit(commitNow) {
|
||||||
|
if ( commitNow ) {
|
||||||
|
this.commitTimer.clear();
|
||||||
|
this.commitNow();
|
||||||
|
} else {
|
||||||
|
this.commitTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addProceduralSelectors(aa) {
|
addProceduralSelectors(aa) {
|
||||||
this.proceduralFilterer.addProceduralSelectors(aa);
|
this.proceduralFilterer.addProceduralSelectors(aa);
|
||||||
}
|
}
|
||||||
|
@ -863,8 +1066,10 @@ vAPI.DOMFilterer = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllSelectors() {
|
getAllSelectors() {
|
||||||
const out = super.getAllSelectors();
|
const out = this.getAllSelectors_(false);
|
||||||
out.procedural = Array.from(this.proceduralFilterer.selectors.values());
|
out.procedural = Array.from(
|
||||||
|
this.proceduralFilterer.selectors.values()
|
||||||
|
);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -872,34 +1077,34 @@ vAPI.DOMFilterer = (function() {
|
||||||
return this.exceptions.join(',\n');
|
return this.exceptions.join(',\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFilteredElementCount() {
|
||||||
|
const details = this.getAllSelectors_(true);
|
||||||
|
if ( Array.isArray(details.declarative) === false ) { return 0; }
|
||||||
|
const selectors = details.declarative.map(entry => entry[0]);
|
||||||
|
if ( selectors.length === 0 ) { return 0; }
|
||||||
|
return document.querySelectorAll(selectors.join(',\n')).length;
|
||||||
|
}
|
||||||
|
|
||||||
onDOMCreated() {
|
onDOMCreated() {
|
||||||
if ( super.onDOMCreated instanceof Function ) {
|
|
||||||
super.onDOMCreated();
|
|
||||||
}
|
|
||||||
this.proceduralFilterer.onDOMCreated();
|
this.proceduralFilterer.onDOMCreated();
|
||||||
}
|
}
|
||||||
|
|
||||||
onDOMChanged() {
|
onDOMChanged() {
|
||||||
if ( super.onDOMChanged instanceof Function ) {
|
|
||||||
super.onDOMChanged.apply(this, arguments);
|
|
||||||
}
|
|
||||||
this.proceduralFilterer.onDOMChanged.apply(
|
this.proceduralFilterer.onDOMChanged.apply(
|
||||||
this.proceduralFilterer,
|
this.proceduralFilterer,
|
||||||
arguments
|
arguments
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
return DOMFilterer;
|
|
||||||
})();
|
|
||||||
|
|
||||||
vAPI.domFilterer = new vAPI.DOMFilterer();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.domCollapser = (function() {
|
// vAPI.domCollapser
|
||||||
|
|
||||||
|
{
|
||||||
const messaging = vAPI.messaging;
|
const messaging = vAPI.messaging;
|
||||||
const toCollapse = new Map();
|
const toCollapse = new Map();
|
||||||
const src1stProps = {
|
const src1stProps = {
|
||||||
|
@ -1136,14 +1341,16 @@ vAPI.domCollapser = (function() {
|
||||||
vAPI.domWatcher.addListener(domWatcherInterface);
|
vAPI.domWatcher.addListener(domWatcherInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { add, addMany, addIFrame, addIFrames, process };
|
vAPI.domCollapser = { add, addMany, addIFrame, addIFrames, process };
|
||||||
})();
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.domSurveyor = (function() {
|
// vAPI.domSurveyor
|
||||||
|
|
||||||
|
{
|
||||||
const messaging = vAPI.messaging;
|
const messaging = vAPI.messaging;
|
||||||
const queriedIds = new Set();
|
const queriedIds = new Set();
|
||||||
const queriedClasses = new Set();
|
const queriedClasses = new Set();
|
||||||
|
@ -1402,18 +1609,18 @@ vAPI.domSurveyor = (function() {
|
||||||
vAPI.domWatcher.addListener(domWatcherInterface);
|
vAPI.domWatcher.addListener(domWatcherInterface);
|
||||||
};
|
};
|
||||||
|
|
||||||
return { start };
|
vAPI.domSurveyor = { start };
|
||||||
})();
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// Bootstrapping allows all components of the content script to be launched
|
// vAPI.bootstrap:
|
||||||
// if/when needed.
|
// Bootstrapping allows all components of the content script
|
||||||
|
// to be launched if/when needed.
|
||||||
vAPI.bootstrap = (function() {
|
|
||||||
|
|
||||||
|
{
|
||||||
const bootstrapPhase2 = function() {
|
const bootstrapPhase2 = function() {
|
||||||
// This can happen on Firefox. For instance:
|
// This can happen on Firefox. For instance:
|
||||||
// https://github.com/gorhill/uBlock/issues/1893
|
// https://github.com/gorhill/uBlock/issues/1893
|
||||||
|
@ -1488,7 +1695,7 @@ vAPI.bootstrap = (function() {
|
||||||
vAPI.domFilterer = null;
|
vAPI.domFilterer = null;
|
||||||
vAPI.domSurveyor = null;
|
vAPI.domSurveyor = null;
|
||||||
} else {
|
} else {
|
||||||
const domFilterer = vAPI.domFilterer;
|
const domFilterer = vAPI.domFilterer = new vAPI.DOMFilterer();
|
||||||
if ( response.noGenericCosmeticFiltering || cfeDetails.noDOMSurveying ) {
|
if ( response.noGenericCosmeticFiltering || cfeDetails.noDOMSurveying ) {
|
||||||
vAPI.domSurveyor = null;
|
vAPI.domSurveyor = null;
|
||||||
}
|
}
|
||||||
|
@ -1555,7 +1762,7 @@ vAPI.bootstrap = (function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return function() {
|
vAPI.bootstrap = function() {
|
||||||
vAPI.messaging.send('contentscript', {
|
vAPI.messaging.send('contentscript', {
|
||||||
what: 'retrieveContentScriptParameters',
|
what: 'retrieveContentScriptParameters',
|
||||||
url: window.location.href,
|
url: window.location.href,
|
||||||
|
@ -1565,7 +1772,7 @@ vAPI.bootstrap = (function() {
|
||||||
bootstrapPhase1(response);
|
bootstrapPhase1(response);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
})();
|
}
|
||||||
|
|
||||||
// This starts bootstrap process.
|
// This starts bootstrap process.
|
||||||
vAPI.bootstrap();
|
vAPI.bootstrap();
|
||||||
|
|
|
@ -11,19 +11,6 @@ mkdir -p $DES
|
||||||
echo "*** uBlock0.chromium: copying common files"
|
echo "*** uBlock0.chromium: copying common files"
|
||||||
bash ./tools/copy-common-files.sh $DES
|
bash ./tools/copy-common-files.sh $DES
|
||||||
|
|
||||||
echo "*** uBlock0.chromium: concatenating content scripts"
|
|
||||||
cat $DES/js/vapi-usercss.js > /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/vapi-usercss.real.js >> /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/vapi-usercss.pseudo.js >> /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/contentscript.js >> /tmp/contentscript.js
|
|
||||||
mv /tmp/contentscript.js $DES/js/contentscript.js
|
|
||||||
rm $DES/js/vapi-usercss.js
|
|
||||||
rm $DES/js/vapi-usercss.real.js
|
|
||||||
rm $DES/js/vapi-usercss.pseudo.js
|
|
||||||
|
|
||||||
# Chrome store-specific
|
# Chrome store-specific
|
||||||
cp -R $DES/_locales/nb $DES/_locales/no
|
cp -R $DES/_locales/nb $DES/_locales/no
|
||||||
|
|
||||||
|
|
|
@ -16,20 +16,8 @@ cp -R $DES/_locales/nb $DES/_locales/no
|
||||||
|
|
||||||
cp platform/firefox/manifest.json $DES/
|
cp platform/firefox/manifest.json $DES/
|
||||||
cp platform/firefox/webext.js $DES/js/
|
cp platform/firefox/webext.js $DES/js/
|
||||||
cp platform/firefox/vapi-usercss.js $DES/js/
|
|
||||||
cp platform/firefox/vapi-webrequest.js $DES/js/
|
cp platform/firefox/vapi-webrequest.js $DES/js/
|
||||||
|
|
||||||
echo "*** uBlock0.firefox: concatenating content scripts"
|
|
||||||
cat $DES/js/vapi-usercss.js > /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/vapi-usercss.real.js >> /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/contentscript.js >> /tmp/contentscript.js
|
|
||||||
mv /tmp/contentscript.js $DES/js/contentscript.js
|
|
||||||
rm $DES/js/vapi-usercss.js
|
|
||||||
rm $DES/js/vapi-usercss.real.js
|
|
||||||
rm $DES/js/vapi-usercss.pseudo.js
|
|
||||||
|
|
||||||
# Firefox/webext-specific
|
# Firefox/webext-specific
|
||||||
rm $DES/img/icon_128.png
|
rm $DES/img/icon_128.png
|
||||||
|
|
||||||
|
|
|
@ -11,19 +11,6 @@ mkdir -p $DES
|
||||||
echo "*** uBlock0.opera: copying common files"
|
echo "*** uBlock0.opera: copying common files"
|
||||||
bash ./tools/copy-common-files.sh $DES
|
bash ./tools/copy-common-files.sh $DES
|
||||||
|
|
||||||
echo "*** uBlock0.opera: concatenating content scripts"
|
|
||||||
cat $DES/js/vapi-usercss.js > /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/vapi-usercss.real.js >> /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/vapi-usercss.pseudo.js >> /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/contentscript.js >> /tmp/contentscript.js
|
|
||||||
mv /tmp/contentscript.js $DES/js/contentscript.js
|
|
||||||
rm $DES/js/vapi-usercss.js
|
|
||||||
rm $DES/js/vapi-usercss.real.js
|
|
||||||
rm $DES/js/vapi-usercss.pseudo.js
|
|
||||||
|
|
||||||
# Opera-specific
|
# Opera-specific
|
||||||
cp platform/opera/manifest.json $DES/
|
cp platform/opera/manifest.json $DES/
|
||||||
rm -r $DES/_locales/az
|
rm -r $DES/_locales/az
|
||||||
|
|
|
@ -17,28 +17,13 @@ bash ./tools/copy-common-files.sh $DES
|
||||||
cp -R $DES/_locales/nb $DES/_locales/no
|
cp -R $DES/_locales/nb $DES/_locales/no
|
||||||
|
|
||||||
cp platform/webext/manifest.json $DES/
|
cp platform/webext/manifest.json $DES/
|
||||||
cp platform/webext/vapi-usercss.js $DES/js/
|
|
||||||
|
|
||||||
# https://github.com/uBlockOrigin/uBlock-issues/issues/407
|
# https://github.com/uBlockOrigin/uBlock-issues/issues/407
|
||||||
echo "*** uBlock0.webext: concatenating vapi-webrequest.js"
|
echo "*** uBlock0.webext: concatenating vapi-webrequest.js"
|
||||||
cat platform/chromium/vapi-webrequest.js > /tmp/vapi-webrequest.js
|
cat platform/chromium/vapi-webrequest.js > /tmp/vapi-webrequest.js
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" platform/firefox/vapi-webrequest.js >> /tmp/vapi-webrequest.js
|
grep -v "^'use strict';$" platform/firefox/vapi-webrequest.js >> /tmp/vapi-webrequest.js
|
||||||
mv /tmp/vapi-webrequest.js $DES/js/vapi-webrequest.js
|
mv /tmp/vapi-webrequest.js $DES/js/vapi-webrequest.js
|
||||||
|
|
||||||
echo "*** uBlock0.webext: concatenating content scripts"
|
|
||||||
cat $DES/js/vapi-usercss.js > /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/vapi-usercss.real.js >> /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/vapi-usercss.pseudo.js >> /tmp/contentscript.js
|
|
||||||
echo >> /tmp/contentscript.js
|
|
||||||
grep -v "^'use strict';$" $DES/js/contentscript.js >> /tmp/contentscript.js
|
|
||||||
mv /tmp/contentscript.js $DES/js/contentscript.js
|
|
||||||
rm $DES/js/vapi-usercss.js
|
|
||||||
rm $DES/js/vapi-usercss.real.js
|
|
||||||
rm $DES/js/vapi-usercss.pseudo.js
|
|
||||||
|
|
||||||
echo "*** uBlock0.webext: Generating meta..."
|
echo "*** uBlock0.webext: Generating meta..."
|
||||||
python3 tools/make-webext-meta.py $DES/
|
python3 tools/make-webext-meta.py $DES/
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue