diff --git a/js/abp-hide-filters.js b/js/abp-hide-filters.js index c90bb5178..746f961d2 100644 --- a/js/abp-hide-filters.js +++ b/js/abp-hide-filters.js @@ -667,8 +667,8 @@ FilterContainer.prototype.retrieveDomainSelectors = function(request) { donthide: [] }; - var bucket; - var hash = makeHash('#', r.domain, this.domainHashMask); + var hash, bucket; + hash = makeHash('#', r.domain, this.domainHashMask); if ( bucket = this.hostnameFilters[hash] ) { bucket.retrieve(hostname, r.hide); } diff --git a/js/contentscript-end.js b/js/contentscript-end.js index f3ad62b4c..c30c66827 100644 --- a/js/contentscript-end.js +++ b/js/contentscript-end.js @@ -139,7 +139,7 @@ var messaging = (function(name){ var style = document.getElementById('uBlock1ae7a5f130fc79b4fdb8a4272d9426b5'); var exceptions = style && style.getAttribute('uBlock1ae7a5f130fc79b4fdb8a4272d9426b5'); if ( exceptions ) { - exceptions = decodeURIComponent(exceptions).split(','); + exceptions = JSON.parse(exceptions); var i = exceptions.length; while ( i-- ) { injectedSelectors[exceptions[i]] = true; @@ -173,34 +173,27 @@ var messaging = (function(name){ if ( !selectors ) { return; } - var styleText = []; + filterLowGenerics(selectors, 'donthide'); + filterHighGenerics(selectors, 'donthide'); + if ( selectors.donthide.length ) { + var i = selectors.donthide.length; + while ( i-- ) { + injectedSelectors[selectors.donthide[i]] = true; + } + } filterLowGenerics(selectors, 'hide'); filterHighGenerics(selectors, 'hide'); reduce(selectors.hide, injectedSelectors); if ( selectors.hide.length ) { - var hideStyleText = '{{hideSelectors}} {display:none !important;}' - .replace('{{hideSelectors}}', selectors.hide.join(',')); - styleText.push(hideStyleText); applyCSS(selectors.hide, 'display', 'none'); - //console.debug('µBlock> generic cosmetic filters: injecting %d CSS rules:', selectors.hide.length, hideStyleText); - } - filterLowGenerics(selectors, 'donthide'); - filterHighGenerics(selectors, 'donthide'); - reduce(selectors.donthide, injectedSelectors); - if ( selectors.donthide.length ) { - var dontHideStyleText = '{{donthideSelectors}} {display:initial !important;}' - .replace('{{donthideSelectors}}', selectors.donthide.join(',')); - styleText.push(dontHideStyleText); - applyCSS(selectors.donthide, 'display', 'initial'); - //console.debug('µBlock> generic cosmetic filters: injecting %d CSS rules:', selectors.donthide.length, dontHideStyleText); - } - if ( styleText.length > 0 ) { var style = document.createElement('style'); - style.appendChild(document.createTextNode(styleText.join('\n'))); + var text = selectors.hide.join(',\n') + ' {display:none !important;}'; + style.appendChild(document.createTextNode(text)); var parent = document.body || document.documentElement; if ( parent ) { parent.appendChild(style); } + //console.debug('µBlock> generic cosmetic filters: injecting %d CSS rules:', selectors.hide.length, hideStyleText); } }; diff --git a/js/contentscript-start.js b/js/contentscript-start.js index ec68c86ed..77376f058 100644 --- a/js/contentscript-start.js +++ b/js/contentscript-start.js @@ -137,38 +137,43 @@ var domainCosmeticFilteringHandler = function(selectors) { if ( !selectors ) { return; } - var styleText = []; - if ( selectors.hide.length ) { - var hideStyleText = '{{hideSelectors}} {display:none !important;}' - .replace('{{hideSelectors}}', selectors.hide.join(',')); - styleText.push(hideStyleText); - domainCosmeticFilteringApplyCSS(selectors.hide, 'display', 'none'); + if ( selectors.hide.length === 0 && selectors.donthide.length === 0 ) { + return; + } + var style = document.createElement('style'); + var donthide = selectors.donthide; + var hide = selectors.hide; + if ( donthide.length !== 0 ) { + donthide = donthide.length !== 1 ? donthide.join(',') : donthide[0]; + donthide = donthide.split(','); + style.setAttribute('id', 'uBlock1ae7a5f130fc79b4fdb8a4272d9426b5'); + style.setAttribute('uBlock1ae7a5f130fc79b4fdb8a4272d9426b5', JSON.stringify(donthide)); + // https://github.com/gorhill/uBlock/issues/143 + if ( hide.length !== 0 ) { + // I chose to use Array.indexOf() instead of converting the array to + // a map, then deleting whitelisted selectors, and then converting + // back the map into an array, because there are typically very few + // exception filters, if any. + hide = hide.length !== 1 ? hide.join(',') : hide[0]; + hide = hide.split(','); + var i = donthide.length, j; + while ( i-- ) { + j = hide.indexOf(donthide[i]); + if ( j !== -1 ) { + hide.splice(j, 1); + } + } + } + } + if ( hide.length !== 0 ) { + var text = hide.join(','); + domainCosmeticFilteringApplyCSS(text, 'display', 'none'); + style.appendChild(document.createTextNode(text + ' {display:none !important;}')); //console.debug('µBlock> "%s" cosmetic filters: injecting %d CSS rules:', selectors.domain, selectors.hide.length, hideStyleText); } - if ( selectors.donthide.length ) { - var dontHideStyleText = '{{donthideSelectors}} {display:initial !important;}' - .replace('{{donthideSelectors}}', selectors.donthide.join(',')); - styleText.push(dontHideStyleText); - domainCosmeticFilteringApplyCSS(selectors.donthide, 'display', 'initial'); - //console.debug('µBlock> "%s" cosmetic filters: injecting %d CSS rules:', selectors.domain, selectors.donthide.length, dontHideStyleText); - } - if ( styleText.length > 0 ) { - var style = document.createElement('style'); - style.appendChild(document.createTextNode(styleText.join('\n'))); - if ( selectors.donthide.length > 0 ) { - style.setAttribute( - 'id', - 'uBlock1ae7a5f130fc79b4fdb8a4272d9426b5' - ); - style.setAttribute( - 'uBlock1ae7a5f130fc79b4fdb8a4272d9426b5', - encodeURIComponent(selectors.donthide.join(',')) - ); - } - var parent = document.head || document.documentElement; - if ( parent ) { - parent.appendChild(style); - } + var parent = document.head || document.documentElement; + if ( parent ) { + parent.appendChild(style); } };