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

Side by Side Diff: lib/elemHide.js

Issue 6201308310667264: Issue 521- Inject our stylesheet on per-site basis rather than globally (Closed)
Patch Set: Created May 20, 2014, 6:09 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 | no next file » | 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 <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH 3 * Copyright (C) 2006-2014 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 * @class 64 * @class
65 */ 65 */
66 let ElemHide = exports.ElemHide = 66 let ElemHide = exports.ElemHide =
67 { 67 {
68 /** 68 /**
69 * Indicates whether filters have been added or removed since the last apply() call. 69 * Indicates whether filters have been added or removed since the last apply() call.
70 * @type Boolean 70 * @type Boolean
71 */ 71 */
72 isDirty: false, 72 isDirty: false,
73 73
74 /** 74 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakRefer ence]),
75 * Inidicates whether the element hiding stylesheet is currently applied.
76 * @type Boolean
77 */
78 applied: false,
79 75
80 /** 76 /**
81 * Called on module startup. 77 * Called on module startup.
82 */ 78 */
83 init: function() 79 init: function()
84 { 80 {
85 TimeLine.enter("Entered ElemHide.init()"); 81 TimeLine.enter("Entered ElemHide.init()");
86 Prefs.addListener(function(name) 82 Prefs.addListener(function(name)
87 { 83 {
88 if (name == "enabled") 84 if (name == "enabled")
89 ElemHide.apply(); 85 ElemHide.apply();
90 }); 86 });
Wladimir Palant 2014/05/20 19:36:12 This code is no longer necessary.
91 onShutdown.add(function() 87 onShutdown.add(function()
92 { 88 {
93 ElemHide.unapply(); 89 Services.obs.removeObserver(this, "content-document-global-created");
94 }); 90 }.bind(this));
95 91
96 TimeLine.log("done adding prefs listener"); 92 TimeLine.log("done adding prefs listener");
97 93
98 let styleFile = IO.resolveFilePath(Prefs.data_directory); 94 let styleFile = IO.resolveFilePath(Prefs.data_directory);
99 styleFile.append("elemhide.css"); 95 styleFile.append("elemhide.css");
100 styleURL = Services.io.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL); 96 styleURL = Services.io.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL);
101 TimeLine.log("done determining stylesheet URL"); 97 TimeLine.log("done determining stylesheet URL");
102 98
99 Services.obs.addObserver(this, "content-document-global-created", true);
100
103 TimeLine.leave("ElemHide.init() done"); 101 TimeLine.leave("ElemHide.init() done");
104 }, 102 },
105 103
106 /** 104 /**
107 * Removes all known filters 105 * Removes all known filters
108 */ 106 */
109 clear: function() 107 clear: function()
110 { 108 {
111 filterByKey = {__proto__: null}; 109 filterByKey = {__proto__: null};
112 keyByFilter = {__proto__: null}; 110 keyByFilter = {__proto__: null};
113 knownExceptions = {__proto__: null}; 111 knownExceptions = {__proto__: null};
114 exceptions = {__proto__: null}; 112 exceptions = {__proto__: null};
115 ElemHide.isDirty = false; 113 ElemHide.isDirty = false;
116 ElemHide.unapply(); 114 },
115
116 observe: function (subject, topic, data, additional)
117 {
118 if (topic != "content-document-global-created")
119 return;
120
121 if (!Prefs.enabled)
122 return;
123
124 let uri = subject.document.documentURIObject;
125 if (!uri)
126 return;
127
128 switch(uri.scheme)
129 {
130 case "http":
131 case "https":
132 case "mailbox":
133 case "imap":
134 case "news":
135 case "snews":
136 break;
137 default:
138 // Avoid injecting in chrome documents
139 return;
140 }
Wladimir Palant 2014/05/20 19:36:12 Please use Policy.isBlockableScheme() here (from c
141
142 // XXX is there some better way to test if it's disabled on that domain that we should do before?
143 if (!ElemHide.anySelectorForDomain(uri.host))
144 return;
Wladimir Palant 2014/05/20 19:36:12 Wow, performance will go down the drain here. We c
145
146 var windowUtils = subject.QueryInterface(Ci.nsIInterfaceRequestor).getInterf ace(Ci.nsIDOMWindowUtils);
147 windowUtils.loadSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
117 }, 148 },
118 149
119 /** 150 /**
120 * Add a new element hiding filter 151 * Add a new element hiding filter
121 * @param {ElemHideFilter} filter 152 * @param {ElemHideFilter} filter
122 */ 153 */
123 add: function(filter) 154 add: function(filter)
124 { 155 {
125 if (filter instanceof ElemHideException) 156 if (filter instanceof ElemHideException)
126 { 157 {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 _applying: false, 234 _applying: false,
204 235
205 /** 236 /**
206 * Will be set to true if an apply() call arrives while apply() is already 237 * Will be set to true if an apply() call arrives while apply() is already
207 * running (delayed execution). 238 * running (delayed execution).
208 * @type Boolean 239 * @type Boolean
209 */ 240 */
210 _needsApply: false, 241 _needsApply: false,
211 242
212 /** 243 /**
213 * Generates stylesheet URL and applies it globally 244 * Generates stylesheet URL.
214 */ 245 */
246 // XXX Rename
215 apply: function() 247 apply: function()
Wladimir Palant 2014/05/20 19:36:12 saveStylesheet()?
216 { 248 {
217 if (this._applying) 249 if (this._applying)
218 { 250 {
219 this._needsApply = true; 251 this._needsApply = true;
220 return; 252 return;
221 } 253 }
222 254
223 TimeLine.enter("Entered ElemHide.apply()"); 255 TimeLine.enter("Entered ElemHide.apply()");
224 256
225 if (!ElemHide.isDirty || !Prefs.enabled)
226 {
227 // Nothing changed, looks like we merely got enabled/disabled
228 if (Prefs.enabled && !ElemHide.applied)
229 {
230 try
231 {
232 Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetServ ice.USER_SHEET);
233 ElemHide.applied = true;
234 }
235 catch (e)
236 {
237 Cu.reportError(e);
238 }
239 TimeLine.log("Applying existing stylesheet finished");
240 }
241 else if (!Prefs.enabled && ElemHide.applied)
242 {
243 ElemHide.unapply();
244 TimeLine.log("ElemHide.unapply() finished");
245 }
246
247 TimeLine.leave("ElemHide.apply() done (no file changes)");
248 return;
249 }
250
251 IO.writeToFile(styleURL.file, this._generateCSSContent(), function(e) 257 IO.writeToFile(styleURL.file, this._generateCSSContent(), function(e)
252 { 258 {
253 TimeLine.enter("ElemHide.apply() write callback"); 259 TimeLine.enter("ElemHide.apply() write callback");
254 this._applying = false; 260 this._applying = false;
255 261
256 // _generateCSSContent is throwing NS_ERROR_NOT_AVAILABLE to indicate that 262 // _generateCSSContent is throwing NS_ERROR_NOT_AVAILABLE to indicate that
257 // there are no filters. If that exception is passed through XPCOM we will 263 // there are no filters. If that exception is passed through XPCOM we will
258 // see a proper exception here, otherwise a number. 264 // see a proper exception here, otherwise a number.
259 let noFilters = (e == Cr.NS_ERROR_NOT_AVAILABLE || (e && e.result == Cr.NS _ERROR_NOT_AVAILABLE)); 265 let noFilters = (e == Cr.NS_ERROR_NOT_AVAILABLE || (e && e.result == Cr.NS _ERROR_NOT_AVAILABLE));
260 if (noFilters) 266 if (noFilters)
261 { 267 {
262 e = null; 268 e = null;
263 IO.removeFile(styleURL.file, function(e) {}); 269 IO.removeFile(styleURL.file, function(e) {});
264 } 270 }
265 else if (e) 271 else if (e)
266 Cu.reportError(e); 272 Cu.reportError(e);
267 273
268 if (this._needsApply) 274 if (this._needsApply)
269 { 275 {
270 this._needsApply = false; 276 this._needsApply = false;
271 this.apply(); 277 this.apply();
272 } 278 }
273 else if (!e) 279 else if (!e)
274 { 280 {
275 ElemHide.isDirty = false; 281 ElemHide.isDirty = false;
276 282
277 ElemHide.unapply();
278 TimeLine.log("ElemHide.unapply() finished");
279
280 if (!noFilters)
281 {
282 try
283 {
284 Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetSe rvice.USER_SHEET);
285 ElemHide.applied = true;
286 }
287 catch (e)
288 {
289 Cu.reportError(e);
290 }
291 TimeLine.log("Applying stylesheet finished");
292 }
293
294 FilterNotifier.triggerListeners("elemhideupdate"); 283 FilterNotifier.triggerListeners("elemhideupdate");
Wladimir Palant 2014/05/20 19:36:12 Apparently, this is dead code. This notification h
295 } 284 }
296 TimeLine.leave("ElemHide.apply() write callback done"); 285 TimeLine.leave("ElemHide.apply() write callback done");
297 }.bind(this), "ElemHideWrite"); 286 }.bind(this), "ElemHideWrite");
298 287
299 this._applying = true; 288 this._applying = true;
300 289
301 TimeLine.leave("ElemHide.apply() done", "ElemHideWrite"); 290 TimeLine.leave("ElemHide.apply() done", "ElemHideWrite");
302 }, 291 },
303 292
304 _generateCSSContent: function() 293 _generateCSSContent: function()
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 yield selector.replace(/[^\x01-\x7F]/g, escapeChar) + "{" + cssTemplate. replace("%ID%", list[selector]) + "}"; 343 yield selector.replace(/[^\x01-\x7F]/g, escapeChar) + "{" + cssTemplate. replace("%ID%", list[selector]) + "}";
355 yield '}'; 344 yield '}';
356 } 345 }
357 }, 346 },
358 347
359 /** 348 /**
360 * Unapplies current stylesheet URL 349 * Unapplies current stylesheet URL
361 */ 350 */
362 unapply: function() 351 unapply: function()
363 { 352 {
364 if (ElemHide.applied)
365 {
366 try
367 {
368 Utils.styleService.unregisterSheet(styleURL, Ci.nsIStyleSheetService.USE R_SHEET);
369 }
370 catch (e)
371 {
372 Cu.reportError(e);
373 }
374 ElemHide.applied = false;
375 }
376 }, 353 },
Wladimir Palant 2014/05/20 19:36:12 This function should be removed.
377 354
378 /** 355 /**
379 * Retrieves the currently applied stylesheet URL 356 * Retrieves the currently applied stylesheet URL
380 * @type String 357 * @type String
381 */ 358 */
382 get styleURL() ElemHide.applied ? styleURL.spec : null, 359 get styleURL() styleURL.spec,
Wladimir Palant 2014/05/20 19:36:12 This getter was also introduced in https://hg.adbl
383 360
384 /** 361 /**
385 * Retrieves an element hiding filter by the corresponding protocol key 362 * Retrieves an element hiding filter by the corresponding protocol key
386 */ 363 */
387 getFilterByKey: function(/**String*/ key) /**Filter*/ 364 getFilterByKey: function(/**String*/ key) /**Filter*/
388 { 365 {
389 return (key in filterByKey ? filterByKey[key] : null); 366 return (key in filterByKey ? filterByKey[key] : null);
390 }, 367 },
391 368
392 /** 369 /**
(...skipping 12 matching lines...) Expand all
405 // workaround WebKit bug 132872, also see #419 382 // workaround WebKit bug 132872, also see #419
406 let domains = filter.domains; 383 let domains = filter.domains;
407 384
408 if (specificOnly && (!domains || domains[""])) 385 if (specificOnly && (!domains || domains[""]))
409 continue; 386 continue;
410 387
411 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain)) 388 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain))
412 result.push(filter.selector); 389 result.push(filter.selector);
413 } 390 }
414 return result; 391 return result;
392 },
393
394 anySelectorForDomain: function(/**String*/ domain)
395 {
396 for (let key in filterByKey)
397 {
398 let filter = filterByKey[key];
399
400 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain))
401 return true;
402 }
403
404 return false;
415 } 405 }
416 }; 406 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld