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

Delta Between Two Patch Sets: lib/elemHide.js

Issue 6266581101314048: WIP: Have one global element hide stylesheet and inject the other ones per site (Closed)
Left Patch Set: Created July 27, 2014, 11:45 a.m.
Right Patch Set: rebased Created Aug. 19, 2014, 12:15 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | lib/elemHideHitRegistration.js » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 * @type nsIURI 59 * @type nsIURI
60 */ 60 */
61 let styleURL = null; 61 let styleURL = null;
62 62
63 /** 63 /**
64 * Global stylesheet that should be loaded into content windows. 64 * Global stylesheet that should be loaded into content windows.
65 * @type nsIStyleSheet 65 * @type nsIStyleSheet
66 */ 66 */
67 let styleSheet = null; 67 let styleSheet = null;
68 68
69 // fixme 69 /**
70 let filterByDomain = Object.create(null); 70 * Use the new way of injecting styles per window that exists since Firefox 33.
71
72 /**
73 * Use new way of injecting styles per Window that exists since Firefox 33.
74 * @type boolean 71 * @type boolean
75 */ 72 */
76 let useNew = ('preloadSheet' in Utils.styleService); 73 let useNew = ('preloadSheet' in Utils.styleService);
77 74
78 /** 75 /**
79 * Element hiding component 76 * Element hiding component
80 * @class 77 * @class
81 */ 78 */
82 let ElemHide = exports.ElemHide = 79 let ElemHide = exports.ElemHide =
83 { 80 {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 { 134 {
138 if (topic != "content-document-global-created") 135 if (topic != "content-document-global-created")
139 return; 136 return;
140 137
141 if (!Prefs.enabled) 138 if (!Prefs.enabled)
142 return; 139 return;
143 140
144 if (Policy.shouldNeverBlockWindow(subject)) 141 if (Policy.shouldNeverBlockWindow(subject))
145 return; 142 return;
146 143
147 dump(subject.document.documentURIObject.spec + "\n"); 144 let domain = null;
148 let domain = subject.document.documentURIObject.host; 145 let filters = null;
149 if (domain.startsWith("www.")) 146 try
150 domain = domain.substring(4); 147 {
151 148 domain = subject.document.documentURIObject.host;
152 dump("domain: " + domain + "\n"); // xxx is elemhide port or subdomain inses itive? 149 if (domain)
153 150 filters = ElemHide.getFiltersWithKeyForDomain(domain, true);
154 let list = Object.create(null); 151 } catch (e) {}
155 for (let filter of filterByDomain[domain]) 152
156 { 153 if (filters)
157 dump("filter: " + filter.text + "\n") 154 {
158 dump("key: " + keyByFilter[filter.text] + "\n") 155 let list = Object.create(null);
159 list[keyByFilter[filter.text]] = filter; 156 for (let {key, filter} of filters)
160 } 157 list[key] = filter;
161 158
162 if (filterByDomain[domain]) { 159 let css = "";
163 // XXX seems to stupid to use a file for this. 160 for (let line in this._generateCSSContent(list, false))
164 // Somehow get this to use a data url or similar 161 css += line + "\n";
165 let styleFile = IO.resolveFilePath(Prefs.data_directory); 162
166 styleFile.append(domain + ".css"); 163 let uri = Services.io.newURI("data:text/css;base64," + btoa(css), null, nu ll);
167 styleURL = Services.io.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL) ; 164 try
168 165 {
169 IO.writeToFile(styleURL.file, this._generateCSSContent(list, false), funct ion(e) 166 let utils = subject.QueryInterface(Ci.nsIInterfaceRequestor)
170 { 167 .getInterface(Ci.nsIDOMWindowUtils);
171 try 168 utils.loadSheet(uri, Ci.nsIStyleSheetService.USER_SHEET);
172 { 169 }
173 let utils = subject.QueryInterface(Ci.nsIInterfaceRequestor) 170 catch (e)
174 .getInterface(Ci.nsIDOMWindowUtils); 171 {
175 utils.loadSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); 172 Cu.reportError(e);
176 } 173 }
177 catch (e) 174 }
178 { 175
179 Cu.reportError(e); 176 if (styleSheet)
180 } 177 {
181 }); 178 try
182 } 179 {
183 180 let utils = subject.QueryInterface(Ci.nsIInterfaceRequestor)
184 try 181 .getInterface(Ci.nsIDOMWindowUtils);
185 { 182 utils.addSheet(styleSheet, Ci.nsIStyleSheetService.USER_SHEET);
186 let utils = subject.QueryInterface(Ci.nsIInterfaceRequestor) 183 }
187 .getInterface(Ci.nsIDOMWindowUtils); 184 catch (e)
188 utils.addSheet(styleSheet, Ci.nsIStyleSheetService.USER_SHEET); 185 {
189 } 186 Cu.reportError(e);
190 catch (e) 187 }
191 {
192 Cu.reportError(e);
193 } 188 }
194 }, 189 },
195 190
196 /** 191 /**
197 * Removes all known filters 192 * Removes all known filters
198 */ 193 */
199 clear: function() 194 clear: function()
200 { 195 {
201 filterByKey = Object.create(null); 196 filterByKey = Object.create(null);
202 keyByFilter = Object.create(null); 197 keyByFilter = Object.create(null);
203 knownExceptions = Object.create(null); 198 knownExceptions = Object.create(null);
204 exceptions = Object.create(null); 199 exceptions = Object.create(null);
205 filterByDomain = Object.create(null);
206 ElemHide.isDirty = false; 200 ElemHide.isDirty = false;
207 ElemHide.unapply(); 201 ElemHide.unapply();
208 }, 202 },
209 203
210 /** 204 /**
211 * Add a new element hiding filter 205 * Add a new element hiding filter
212 * @param {ElemHideFilter} filter 206 * @param {ElemHideFilter} filter
213 */ 207 */
214 add: function(filter) 208 add: function(filter)
215 { 209 {
216 if (filter instanceof ElemHideException) 210 if (filter instanceof ElemHideException)
217 { 211 {
218 if (filter.text in knownExceptions) 212 if (filter.text in knownExceptions)
219 return; 213 return;
220 214
221 let selector = filter.selector; 215 let selector = filter.selector;
222 if (!(selector in exceptions)) 216 if (!(selector in exceptions))
223 exceptions[selector] = []; 217 exceptions[selector] = [];
224 exceptions[selector].push(filter); 218 exceptions[selector].push(filter);
225 knownExceptions[filter.text] = true; 219 knownExceptions[filter.text] = true;
226 } 220 }
227 else 221 else
228 { 222 {
229 if (filter.text in keyByFilter) 223 if (filter.text in keyByFilter)
230 return; 224 return;
231 225
232 if (filter.selectorDomain && useNew)
233 {
234 let domains = filter.selectorDomain.split(",");
235
236 for (let domain of domains)
237 {
238 dump(domain + "\n");
239 if (filterByDomain[domain])
240 filterByDomain[domain].push(filter);
241 else
242 filterByDomain[domain] = [filter];
243 }
244 }
245
246 let key; 226 let key;
247 do { 227 do {
248 key = Math.random().toFixed(15).substr(5); 228 key = Math.random().toFixed(15).substr(5);
249 } while (key in filterByKey); 229 } while (key in filterByKey);
250 230
251 filterByKey[key] = filter; 231 filterByKey[key] = filter;
252 keyByFilter[filter.text] = key; 232 keyByFilter[filter.text] = key;
253 ElemHide.isDirty = true; 233 ElemHide.isDirty = true;
254 } 234 }
255 }, 235 },
(...skipping 13 matching lines...) Expand all
269 let index = list.indexOf(filter); 249 let index = list.indexOf(filter);
270 if (index >= 0) 250 if (index >= 0)
271 list.splice(index, 1); 251 list.splice(index, 1);
272 delete knownExceptions[filter.text]; 252 delete knownExceptions[filter.text];
273 } 253 }
274 else 254 else
275 { 255 {
276 if (!(filter.text in keyByFilter)) 256 if (!(filter.text in keyByFilter))
277 return; 257 return;
278 258
279 // if (filter.selectorDomain && useNew)
280 // {
281 // let filters = filterByDomain[filter.selectorDomain];
282 // if (Array.isArray(filters))
283 // filters.splice(filters.indexOf(filter), 1);
284 // else
285 // delete filterByDomain[filter.selectorDomain];
286 // }
287
288 let key = keyByFilter[filter.text]; 259 let key = keyByFilter[filter.text];
289 delete filterByKey[key]; 260 delete filterByKey[key];
290 delete keyByFilter[filter.text]; 261 delete keyByFilter[filter.text];
291 ElemHide.isDirty = true; 262 ElemHide.isDirty = true;
292 } 263 }
293 }, 264 },
294 265
295 /** 266 /**
296 * Checks whether an exception rule is registered for a filter on a particular 267 * Checks whether an exception rule is registered for a filter on a particular
297 * domain. 268 * domain.
298 */ 269 */
299 getException: function(/**Filter*/ filter, /**String*/ docDomain) /**ElemHideE xception*/ 270 getException: function(/**Filter*/ filter, /**String*/ docDomain) /**ElemHideE xception*/
300 { 271 {
301 let selector = filter.selector;
302 if (!(filter.selector in exceptions)) 272 if (!(filter.selector in exceptions))
303 return null; 273 return null;
304 274
305 let list = exceptions[filter.selector]; 275 let list = exceptions[filter.selector];
306 for (let i = list.length - 1; i >= 0; i--) 276 for (let i = list.length - 1; i >= 0; i--)
307 if (list[i].isActiveOnDomain(docDomain)) 277 if (list[i].isActiveOnDomain(docDomain))
308 return list[i]; 278 return list[i];
309 279
310 return null; 280 return null;
311 }, 281 },
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 { 359 {
390 ElemHide.isDirty = false; 360 ElemHide.isDirty = false;
391 361
392 ElemHide.unapply(); 362 ElemHide.unapply();
393 TimeLine.log("ElemHide.unapply() finished"); 363 TimeLine.log("ElemHide.unapply() finished");
394 364
395 if (!noFilters) 365 if (!noFilters)
396 { 366 {
397 try 367 try
398 { 368 {
399 if (!useNew) { 369 if (!useNew)
400 Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheet Service.USER_SHEET); 370 Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheet Service.USER_SHEET);
401 } else { 371 else
402 styleSheet = Utils.styleService.preloadSheet(styleURL, Ci.nsIStyle SheetService.USER_SHEET); 372 styleSheet = Utils.styleService.preloadSheet(styleURL, Ci.nsIStyle SheetService.USER_SHEET);
403 }
404 ElemHide.applied = true; 373 ElemHide.applied = true;
405 } 374 }
406 catch (e) 375 catch (e)
407 { 376 {
408 Cu.reportError(e); 377 Cu.reportError(e);
409 } 378 }
410 TimeLine.log("Applying stylesheet finished"); 379 TimeLine.log("Applying stylesheet finished");
380 Cu.reportError("applying finished");
411 } 381 }
412 382
413 FilterNotifier.triggerListeners("elemhideupdate"); 383 FilterNotifier.triggerListeners("elemhideupdate");
414 } 384 }
415 TimeLine.leave("ElemHide.apply() write callback done"); 385 TimeLine.leave("ElemHide.apply() write callback done");
416 }.bind(this), "ElemHideWrite"); 386 }.bind(this), "ElemHideWrite");
417 387
418 this._applying = true; 388 this._applying = true;
419 389
420 TimeLine.leave("ElemHide.apply() done", "ElemHideWrite"); 390 TimeLine.leave("ElemHide.apply() done", "ElemHideWrite");
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 // workaround WebKit bug 132872, also see #419 492 // workaround WebKit bug 132872, also see #419
523 let domains = filter.domains; 493 let domains = filter.domains;
524 494
525 if (specificOnly && (!domains || domains[""])) 495 if (specificOnly && (!domains || domains[""]))
526 continue; 496 continue;
527 497
528 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain)) 498 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain))
529 result.push(filter.selector); 499 result.push(filter.selector);
530 } 500 }
531 return result; 501 return result;
502 },
503
504 getFiltersWithKeyForDomain: function(/**String*/ domain)
505 {
506 let result = [];
507 for (let key in filterByKey)
508 {
509 let filter = filterByKey[key];
510
511 if (!filter.domains)
512 continue
513
514 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain))
515 result.push({key, filter});
516 }
517 return result;
532 } 518 }
519
533 }; 520 };
LEFTRIGHT

Powered by Google App Engine
This is Rietveld