 Issue 29356078:
  Issue 524 - Stop using @-moz-document  (Closed) 
  Base URL: https://hg.adblockplus.org/adblockplus
    
  
    Issue 29356078:
  Issue 524 - Stop using @-moz-document  (Closed) 
  Base URL: https://hg.adblockplus.org/adblockplus| Index: lib/child/elemHide.js | 
| =================================================================== | 
| --- a/lib/child/elemHide.js | 
| +++ b/lib/child/elemHide.js | 
| @@ -11,17 +11,17 @@ | 
| * 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 Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 
| */ | 
| /** | 
| - * @fileOverview Hit counts for element hiding. | 
| + * @fileOverview Serves CSS for element hiding and processes hits. | 
| */ | 
| try | 
| { | 
| // Hack: SDK loader masks our Components object with a getter. | 
| let proto = Object.getPrototypeOf(this); | 
| let property = Object.getOwnPropertyDescriptor(proto, "Components"); | 
| if (property && property.get) | 
| @@ -36,22 +36,16 @@ let {XPCOMUtils} = Cu.import("resource:/ | 
| let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); | 
| let {shouldAllowAsync} = require("child/contentPolicy"); | 
| let {getFrames, isPrivate} = require("child/utils"); | 
| let {RequestNotifier} = require("child/requestNotifier"); | 
| let {port} = require("messaging"); | 
| let {Utils} = require("utils"); | 
| -// The allowXBL binding below won't have any effect on the element. For elements | 
| -// that should be hidden however we don't return any binding at all, this makes | 
| -// Gecko stop constructing the node - it cannot be shown. | 
| -const allowXBL = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dummy' bindToUntrustedContent='true'/></bindings>"; | 
| -const hideXBL = "<bindings xmlns='http://www.mozilla.org/xbl'/>"; | 
| - | 
| const notImplemented = () => Cr.NS_ERROR_NOT_IMPLEMENTED; | 
| /** | 
| * about: URL module used to count hits. | 
| * @class | 
| */ | 
| let AboutHandler = | 
| { | 
| @@ -91,24 +85,28 @@ let AboutHandler = | 
| getURIFlags: function(uri) | 
| { | 
| return Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT; | 
| }, | 
| newChannel: function(uri, loadInfo) | 
| { | 
| - let match = /\?(?:hit(\d+)|css)$/.exec(uri.path); | 
| - if (!match) | 
| - throw Cr.NS_ERROR_FAILURE; | 
| + let match = /\?hit(\d+)$/.exec(uri.path); | 
| + if (match) | 
| + return new HitRegistrationChannel(uri, loadInfo, match[1]); | 
| - if (match[1]) | 
| - return new HitRegistrationChannel(uri, loadInfo, match[1]); | 
| - else | 
| - return new StyleDataChannel(uri, loadInfo); | 
| + match = /\?css(?:=(.*?))?$/.exec(uri.path); | 
| + if (match) | 
| + { | 
| + return new StyleDataChannel(uri, loadInfo, | 
| + match[1] ? decodeURIComponent(match[1]) : null); | 
| + } | 
| + | 
| + throw Cr.NS_ERROR_FAILURE; | 
| }, | 
| QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule]) | 
| }; | 
| AboutHandler.init(); | 
| /** | 
| * Base class for channel implementations, subclasses usually only need to | 
| @@ -207,68 +205,52 @@ BaseChannel.prototype = { | 
| cancel: notImplemented, | 
| suspend: notImplemented, | 
| resume: notImplemented, | 
| QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest]) | 
| }; | 
| /** | 
| - * Channel returning CSS data for the global stylesheet. | 
| + * Channel returning CSS data for the global as well as site-specific stylesheet. | 
| * @constructor | 
| */ | 
| -function StyleDataChannel(uri, loadInfo) | 
| +function StyleDataChannel(uri, loadInfo, domain) | 
| { | 
| BaseChannel.call(this, uri, loadInfo); | 
| + this._domain = domain; | 
| } | 
| StyleDataChannel.prototype = { | 
| __proto__: BaseChannel.prototype, | 
| contentType: "text/css", | 
| + _domain: null, | 
| _getResponse: function() | 
| { | 
| function escapeChar(match) | 
| { | 
| return "\\" + match.charCodeAt(0).toString(16) + " "; | 
| } | 
| // Would be great to avoid sync messaging here but nsIStyleSheetService | 
| // insists on opening channels synchronously. | 
| - let domains = port.emitSync("getSelectors"); | 
| + let [selectors, keys] = (this._domain ? | 
| + port.emitSync("getSelectorsForDomain", this._domain) : | 
| + port.emitSync("getUnconditionalSelectors")); | 
| let cssPrefix = "{-moz-binding: url(about:abp-elemhide?hit"; | 
| let cssSuffix = "#dummy) !important;}\n"; | 
| let result = []; | 
| - for (let [domain, selectors] of domains) | 
| + for (let i = 0; i < selectors.length; i++) | 
| { | 
| - if (domain) | 
| - { | 
| - result.push('@-moz-document domain("', | 
| - domain.replace(/[^\x01-\x7F]/g, escapeChar) | 
| - .split(",").join('"),domain("'), | 
| - '"){\n'); | 
| - } | 
| - else | 
| - { | 
| - // Only allow unqualified rules on a few protocols to prevent them | 
| - // from blocking chrome content | 
| - result.push('@-moz-document url-prefix("http://"),', | 
| - 'url-prefix("https://"),url-prefix("mailbox://"),', | 
| - 'url-prefix("imap://"),url-prefix("news://"),', | 
| - 'url-prefix("snews://"){\n'); | 
| - } | 
| - | 
| - for (let [selector, key] of selectors) | 
| - { | 
| - result.push(selector.replace(/[^\x01-\x7F]/g, escapeChar), | 
| - cssPrefix, key, cssSuffix); | 
| - } | 
| - | 
| - result.push("}\n"); | 
| + let selector = selectors[i]; | 
| + let key = keys[i]; | 
| + result.push(selector.replace(/[^\x01-\x7F]/g, escapeChar), | 
| + cssPrefix, key, cssSuffix); | 
| } | 
| return result.join(""); | 
| } | 
| }; | 
| /** | 
| * Channel returning data for element hiding hits. | 
| @@ -281,24 +263,27 @@ function HitRegistrationChannel(uri, loa | 
| } | 
| HitRegistrationChannel.prototype = { | 
| __proto__: BaseChannel.prototype, | 
| key: null, | 
| contentType: "text/xml", | 
| _getResponse: function() | 
| { | 
| - return new Promise((resolve, reject) => | 
| + let window = Utils.getRequestWindow(this); | 
| + port.emitWithResponse("registerElemHideHit", { | 
| + key: this.key, | 
| + frames: getFrames(window), | 
| + isPrivate: isPrivate(window) | 
| + }).then(hit => | 
| { | 
| - let window = Utils.getRequestWindow(this); | 
| - shouldAllowAsync(window, window.document, "ELEMHIDE", this.key, allow => | 
| - { | 
| - resolve(allow ? allowXBL : hideXBL); | 
| - }); | 
| + if (hit) | 
| + RequestNotifier.addNodeData(window.document, window.top, hit); | 
| 
kzar
2016/10/06 13:02:32
(Doesn't storing all the details returned by regis
 
Wladimir Palant
2016/10/06 13:08:48
That's how the list of blockable items works - it
 | 
| }); | 
| + return "<bindings xmlns='http://www.mozilla.org/xbl'/>"; | 
| } | 
| }; | 
| let observer = { | 
| QueryInterface: XPCOMUtils.generateQI([ | 
| Ci.nsIObserver, Ci.nsISupportsWeakReference | 
| ]), | 
| @@ -370,16 +355,34 @@ let observer = { | 
| catch (e) | 
| { | 
| // Ignore NS_ERROR_ILLEGAL_VALUE - it will be thrown if we try to add | 
| // the stylesheet multiple times to the same document (the observer | 
| // will be notified twice for some documents). | 
| if (e.result != Cr.NS_ERROR_ILLEGAL_VALUE) | 
| throw e; | 
| } | 
| + | 
| + let host = subject.location.hostname; | 
| + if (host) | 
| + { | 
| + try | 
| + { | 
| + utils.loadSheetUsingURIString(this.styleURL.spec + "=" + | 
| + encodeURIComponent(host), Ci.nsIStyleSheetService.USER_SHEET); | 
| + } | 
| + catch (e) | 
| + { | 
| + // Ignore NS_ERROR_ILLEGAL_VALUE - it will be thrown if we try to add | 
| + // the stylesheet multiple times to the same document (the observer | 
| + // will be notified twice for some documents). | 
| + if (e.result != Cr.NS_ERROR_ILLEGAL_VALUE) | 
| + throw e; | 
| + } | 
| + } | 
| } | 
| else if (filter) | 
| { | 
| RequestNotifier.addNodeData(window.document, window.top, { | 
| contentType, docDomain, thirdParty, location, filter, filterType | 
| }); | 
| } | 
| }); |