gorhill 2016-12-15 10:47:32 -05:00
parent 66de9a3b5c
commit 94637ee4ff
3 changed files with 110 additions and 71 deletions

View File

@ -384,23 +384,34 @@ var contentObserver = {
svc.scriptloader.loadSubScript(script, sandbox);
};
sandbox.injectCSS = function(sheetURI) {
let canUserStyles = (function() {
try {
let wu = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
wu.loadSheetUsingURIString(sheetURI, wu.USER_SHEET);
return win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.loadSheetUsingURIString instanceof Function;
} catch(ex) {
}
};
return false;
})();
sandbox.removeCSS = function(sheetURI) {
try {
let wu = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
wu.removeSheetUsingURIString(sheetURI, wu.USER_SHEET);
} catch (ex) {
}
};
if ( canUserStyles ) {
sandbox.injectCSS = function(sheetURI) {
try {
let wu = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
wu.loadSheetUsingURIString(sheetURI, wu.USER_SHEET);
} catch(ex) {
}
};
sandbox.removeCSS = function(sheetURI) {
try {
let wu = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
wu.removeSheetUsingURIString(sheetURI, wu.USER_SHEET);
} catch (ex) {
}
};
}
sandbox.topContentScript = win === win.top;

View File

@ -505,6 +505,7 @@ if ( self.injectCSS ) {
return state ? this._load() : this._unload();
}
};
vAPI.hideNode = vAPI.unhideNode = function(){};
}
/******************************************************************************/

View File

@ -126,10 +126,6 @@ vAPI.domFilterer = (function() {
/******************************************************************************/
var shadowId = document.documentElement.shadowRoot !== undefined ?
vAPI.randomToken():
undefined;
var jobQueue = [
{ t: 'css-hide', _0: [] }, // to inject in style tag
{ t: 'css-style', _0: [] }, // to inject in style tag
@ -165,6 +161,87 @@ var cosmeticFiltersActivated = function() {
/******************************************************************************/
// If a platform does not provide its own (improved) vAPI.hideNode, we assign
// a default one to try to override author styles as best as can be.
var platformHideNode = vAPI.hideNode,
platformUnhideNode = vAPI.unhideNode;
(function() {
if ( platformHideNode instanceof Function ) {
return;
}
var uid,
timerId,
observer,
changedNodes = [];
var observerOptions = {
attributes: true,
attributeFilter: [ 'style' ]
};
var overrideInlineStyle = function(node) {
var style = window.getComputedStyle(node),
display = style.getPropertyValue('display'),
attr = node.getAttribute('style') || '';
if ( node[uid] === undefined ) {
node[uid] = node.hasAttribute('style') && attr;
}
if ( display !== '' && display !== 'none' ) {
if ( attr !== '' ) { attr += '; '; }
node.setAttribute('style', attr + 'display: none !important;');
}
};
var timerHandler = function() {
timerId = undefined;
var nodes = changedNodes,
i = nodes.length, node;
while ( i-- ) {
node = nodes[i];
if ( node[uid] !== undefined ) {
overrideInlineStyle(node);
}
}
nodes.length = 0;
};
var observerHandler = function(mutations) {
var i = mutations.length;
while ( i-- ) {
changedNodes.push(mutations[i].target);
}
if ( timerId === undefined ) {
timerId = vAPI.setTimeout(timerHandler, 1);
}
};
platformHideNode = function(node) {
if ( uid === undefined ) {
uid = vAPI.randomToken();
}
overrideInlineStyle(node);
if ( observer === undefined ) {
observer = new MutationObserver(observerHandler);
}
observer.observe(node, observerOptions);
};
platformUnhideNode = function(node) {
if ( uid === undefined ) { return; }
var attr = node[uid];
if ( attr === false ) {
node.removeAttribute('style');
} else if ( typeof attr === 'string' ) {
node.setAttribute('style', attr);
}
delete node[uid];
};
})();
/******************************************************************************/
var runSimpleSelectorJob = function(job, root, fn) {
if ( job._1 === undefined ) {
job._1 = job._0.join(cssNotHiddenId + ',');
@ -515,30 +592,7 @@ var domFilterer = {
this.hiddenNodeCount += 1;
node.hidden = true;
node[this.hiddenId] = null;
var style = window.getComputedStyle(node),
display = style.getPropertyValue('display');
if ( display !== '' && display !== 'none' ) {
var styleAttr = node.getAttribute('style') || '';
node[this.hiddenId] = node.hasAttribute('style') && styleAttr;
if ( styleAttr !== '' ) { styleAttr += '; '; }
node.setAttribute('style', styleAttr + 'display: none !important;');
}
if ( shadowId === undefined ) { return; }
var shadow = node.shadowRoot;
if ( shadow ) {
if ( shadow[shadowId] && shadow.firstElementChild !== null ) {
shadow.removeChild(shadow.firstElementChild);
}
return;
}
// https://github.com/gorhill/uBlock/pull/555
// Not all nodes can be shadowed:
// https://github.com/w3c/webcomponents/issues/102
try {
shadow = node.createShadowRoot();
shadow[shadowId] = true;
} catch (ex) {
}
platformHideNode(node);
},
init: function() {
@ -561,19 +615,7 @@ var domFilterer = {
showNode: function(node) {
node.hidden = false;
var styleAttr = node[this.hiddenId];
if ( styleAttr === false ) {
node.removeAttribute('style');
} else if ( typeof styleAttr === 'string' ) {
node.setAttribute('style', node[this.hiddenId]);
}
var shadow = node.shadowRoot;
if ( shadow && shadow[shadowId] ) {
if ( shadow.firstElementChild !== null ) {
shadow.removeChild(shadow.firstElementChild);
}
shadow.appendChild(document.createElement('content'));
}
platformUnhideNode(node);
},
toggleLogging: function(state) {
@ -601,27 +643,12 @@ var domFilterer = {
node.removeAttribute(this.hiddenId);
node[this.hiddenId] = undefined;
node.hidden = false;
var shadow = node.shadowRoot;
if ( shadow && shadow[shadowId] ) {
if ( shadow.firstElementChild !== null ) {
shadow.removeChild(shadow.firstElementChild);
}
shadow.appendChild(document.createElement('content'));
}
platformUnhideNode(node);
},
unshowNode: function(node) {
node.hidden = true;
var styleAttr = node[this.hiddenId];
if ( styleAttr === false ) {
node.setAttribute('style', 'display: none !important;');
} else if ( typeof styleAttr === 'string' ) {
node.setAttribute('style', node[this.hiddenId] + '; display: none !important;');
}
var shadow = node.shadowRoot;
if ( shadow && shadow[shadowId] && shadow.firstElementChild !== null ) {
shadow.removeChild(shadow.firstElementChild);
}
platformHideNode(node);
},
domChangedHandler: function(addedNodes, removedNodes) {