Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/child/elemHide.js

Issue 29345667: Issue 4139 - Don't save element hiding filters on disk (Closed)
Patch Set: Created June 8, 2016, 8:27 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | lib/elemHideStylesheet.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 17 matching lines...) Expand all
28 delete proto.Components; 28 delete proto.Components;
29 } 29 }
30 catch (e) 30 catch (e)
31 { 31 {
32 Cu.reportError(e); 32 Cu.reportError(e);
33 } 33 }
34 34
35 let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {}); 35 let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
36 36
37 let {shouldAllowAsync} = require("child/contentPolicy"); 37 let {shouldAllowAsync} = require("child/contentPolicy");
38 let {port} = require("messaging");
38 let {Utils} = require("utils"); 39 let {Utils} = require("utils");
39 40
40 // The allowXBL binding below won't have any effect on the element. For elements 41 // The allowXBL binding below won't have any effect on the element. For elements
41 // that should be hidden however we don't return any binding at all, this makes 42 // that should be hidden however we don't return any binding at all, this makes
42 // Gecko stop constructing the node - it cannot be shown. 43 // Gecko stop constructing the node - it cannot be shown.
43 const allowXBL = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dumm y' bindToUntrustedContent='true'/></bindings>"; 44 const allowXBL = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dumm y' bindToUntrustedContent='true'/></bindings>";
44 const hideXBL = "<bindings xmlns='http://www.mozilla.org/xbl'/>"; 45 const hideXBL = "<bindings xmlns='http://www.mozilla.org/xbl'/>";
45 46
47 const notImplemented = () => Cr.NS_ERROR_NOT_IMPLEMENTED;
48
46 /** 49 /**
47 * about: URL module used to count hits. 50 * about: URL module used to count hits.
48 * @class 51 * @class
49 */ 52 */
50 let AboutHandler = 53 let AboutHandler =
51 { 54 {
52 classID: Components.ID("{55fb7be0-1dd2-11b2-98e6-9e97caf8ba67}"), 55 classID: Components.ID("{55fb7be0-1dd2-11b2-98e6-9e97caf8ba67}"),
53 classDescription: "Element hiding hit registration protocol handler", 56 classDescription: "Element hiding hit registration protocol handler",
54 aboutPrefix: "abp-elemhidehit", 57 aboutPrefix: "abp-elemhidehit",
55 58
(...skipping 27 matching lines...) Expand all
83 // About module implementation 86 // About module implementation
84 // 87 //
85 88
86 getURIFlags: function(uri) 89 getURIFlags: function(uri)
87 { 90 {
88 return Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT; 91 return Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT;
89 }, 92 },
90 93
91 newChannel: function(uri, loadInfo) 94 newChannel: function(uri, loadInfo)
92 { 95 {
93 let match = /\?(\d+)/.exec(uri.path); 96 let match = /\?(\d+|css)$/.exec(uri.path);
94 if (!match) 97 if (!match)
95 throw Cr.NS_ERROR_FAILURE; 98 throw Cr.NS_ERROR_FAILURE;
96 99
97 return new HitRegistrationChannel(uri, loadInfo, match[1]); 100 if (match[1] == "css")
101 return new StyleDataChannel(uri, loadInfo);
102 else
103 return new HitRegistrationChannel(uri, loadInfo, match[1]);
98 }, 104 },
99 105
100 QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule]) 106 QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule])
101 }; 107 };
102 AboutHandler.init(); 108 AboutHandler.init();
103 109
104 /** 110 /**
105 * Channel returning data for element hiding hits. 111 * Base class for channel implementations, subclasses usually only need to
112 * override BaseChannel._getResponse() method.
106 * @constructor 113 * @constructor
107 */ 114 */
108 function HitRegistrationChannel(uri, loadInfo, key) 115 function BaseChannel(uri, loadInfo)
109 { 116 {
110 this.key = key;
111 this.URI = this.originalURI = uri; 117 this.URI = this.originalURI = uri;
112 this.loadInfo = loadInfo; 118 this.loadInfo = loadInfo;
113 } 119 }
114 HitRegistrationChannel.prototype = { 120 BaseChannel.prototype = {
115 key: null,
116 URI: null, 121 URI: null,
117 originalURI: null, 122 originalURI: null,
118 contentCharset: "utf-8", 123 contentCharset: "utf-8",
119 contentLength: 0, 124 contentLength: 0,
120 contentType: "text/xml", 125 contentType: null,
121 owner: Utils.systemPrincipal, 126 owner: Utils.systemPrincipal,
122 securityInfo: null, 127 securityInfo: null,
123 notificationCallbacks: null, 128 notificationCallbacks: null,
124 loadFlags: 0, 129 loadFlags: 0,
125 loadGroup: null, 130 loadGroup: null,
126 name: null, 131 name: null,
127 status: Cr.NS_OK, 132 status: Cr.NS_OK,
128 133
129 asyncOpen: function(listener, context) 134 _getResponse: notImplemented,
130 { 135
131 let processResponse = (allow) => 136 _checkSecurity: function()
132 {
133 let data = (allow ? allowXBL : hideXBL);
134 let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci .nsIStringInputStream);
135 stream.setData(data, data.length);
136
137 try {
138 listener.onStartRequest(this, context);
139 } catch(e) {}
140 try {
141 listener.onDataAvailable(this, context, stream, 0, stream.available());
142 } catch(e) {}
143 try {
144 listener.onStopRequest(this, context, Cr.NS_OK);
145 } catch(e) {}
146 };
147
148 let window = Utils.getRequestWindow(this);
149 shouldAllowAsync(window, window.document, "ELEMHIDE", this.key, processRespo nse);
150 },
151
152 asyncOpen2: function(listener)
153 { 137 {
154 if (!this.loadInfo.triggeringPrincipal.equals(Utils.systemPrincipal)) 138 if (!this.loadInfo.triggeringPrincipal.equals(Utils.systemPrincipal))
155 throw Cr.NS_ERROR_FAILURE; 139 throw Cr.NS_ERROR_FAILURE;
140 },
141
142 asyncOpen: function()
143 {
144 Promise.resolve(this._getResponse()).then(data =>
145 {
146 let stream = Cc["@mozilla.org/io/string-input-stream;1"]
147 .createInstance(Ci.nsIStringInputStream);
148 stream.setData(data, data.length);
149
150 try
151 {
152 listener.onStartRequest(this, context);
153 }
154 catch(e)
155 {
156 // Listener failing isn't our problem
157 }
158
159 try
160 {
161 listener.onDataAvailable(this, context, stream, 0, stream.available());
162 }
163 catch(e)
164 {
165 // Listener failing isn't our problem
166 }
167
168 try
169 {
170 listener.onStopRequest(this, context, Cr.NS_OK);
171 }
172 catch(e)
173 {
174 // Listener failing isn't our problem
175 }
176 });
177 },
178
179 asyncOpen2: function(listener)
180 {
181 this._checkSecurity();
156 this.asyncOpen(listener, null); 182 this.asyncOpen(listener, null);
157 }, 183 },
158 184
159 open: function() 185 open: function()
160 { 186 {
161 throw Cr.NS_ERROR_NOT_IMPLEMENTED; 187 let data = this._getResponse();
162 }, 188 if (typeof data.then == "function")
163 isPending: function() 189 throw Cr.NS_ERROR_NOT_IMPLEMENTED;
164 { 190
165 return false; 191 let stream = Cc["@mozilla.org/io/string-input-stream;1"]
166 }, 192 .createInstance(Ci.nsIStringInputStream);
167 cancel: function() 193 stream.setData(data, data.length);
168 { 194 return stream;
169 throw Cr.NS_ERROR_NOT_IMPLEMENTED; 195 },
170 }, 196
171 suspend: function() 197 open2: function()
172 { 198 {
173 throw Cr.NS_ERROR_NOT_IMPLEMENTED; 199 this._checkSecurity();
174 }, 200 return this.open();
175 resume: function() 201 },
176 { 202
177 throw Cr.NS_ERROR_NOT_IMPLEMENTED; 203 isPending: () => false,
178 }, 204 cancel: notImplemented,
205 suspend: notImplemented,
206 resume: notImplemented,
179 207
180 QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest]) 208 QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
181 }; 209 };
210
211 /**
212 * Channel returning CSS data for the global stylesheet.
213 * @constructor
214 */
215 function StyleDataChannel(uri, loadInfo)
216 {
217 BaseChannel.call(this, uri, loadInfo);
218 }
219 StyleDataChannel.prototype = {
220 __proto__: BaseChannel.prototype,
221 contentType: "text/css",
222
223 _getResponse: function()
224 {
225 function escapeChar(match)
226 {
227 return "\\" + match.charCodeAt(0).toString(16) + " ";
228 }
229
230 // Would be great to avoid sync messaging here but nsIStyleSheetService
231 // insists on opening channels synchronously.
232 let domains = port.emitSync("getSelectors");
233
234 let cssPrefix = "{-moz-binding: url(about:abp-elemhidehit?";
235 let cssSuffix = "#dummy) !important;}\n";
236 let result = [];
237
238 for (let [domain, selectors] of domains)
239 {
240 if (domain)
241 {
242 result.push('@-moz-document domain("',
243 domain.replace(/[^\x01-\x7F]/g, escapeChar)
244 .split(",").join('"),domain("'),
245 '"){\n');
246 }
247 else
248 {
249 // Only allow unqualified rules on a few protocols to prevent them
250 // from blocking chrome content
251 result.push('@-moz-document url-prefix("http://"),',
252 'url-prefix("https://"),url-prefix("mailbox://"),',
253 'url-prefix("imap://"),url-prefix("news://"),',
254 'url-prefix("snews://"){\n');
255 }
256
257 for (let [selector, key] of selectors)
258 {
259 result.push(selector.replace(/[^\x01-\x7F]/g, escapeChar),
260 cssPrefix, key, cssSuffix);
261 }
262
263 result.push("}\n");
264 }
265
266 return result.join("");
267 }
268 };
269
270 /**
271 * Channel returning data for element hiding hits.
272 * @constructor
273 */
274 function HitRegistrationChannel(uri, loadInfo, key)
275 {
276 BaseChannel.call(this, uri, loadInfo);
277 this.key = key;
278 }
279 HitRegistrationChannel.prototype = {
280 __proto__: BaseChannel.prototype,
281 key: null,
282 contentType: "text/xml",
283
284 _getResponse: function()
285 {
286 return new Promise((resolve, reject) =>
287 {
288 let window = Utils.getRequestWindow(this);
289 shouldAllowAsync(window, window.document, "ELEMHIDE", this.key, allow =>
290 {
291 resolve(allow ? allowXBL : hideXBL);
292 });
293 });
294 }
295 };
OLDNEW
« no previous file with comments | « no previous file | lib/elemHideStylesheet.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld