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

Delta Between Two Patch Sets: include.preload.js

Issue 29349024: Issue 4298 - Enforce 'display: none' for ElemHide (Closed)
Left Patch Set: Created Aug. 4, 2016, 3:23 p.m.
Right Patch Set: Block access to rules instead of attempting to enforce rule styles Created Aug. 5, 2016, 10:59 a.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 | no next file » | 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 <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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 }, 327 },
328 328
329 disconnect: function() 329 disconnect: function()
330 { 330 {
331 this.document.removeEventListener("DOMContentLoaded", this.trace); 331 this.document.removeEventListener("DOMContentLoaded", this.trace);
332 this.observer.disconnect(); 332 this.observer.disconnect();
333 clearTimeout(this.timeout); 333 clearTimeout(this.timeout);
334 } 334 }
335 }; 335 };
336 336
337 function enforceStyleSheetRules(style)
338 {
339 style.id = id;
340 injectJS(
341 function(id)
342 {
343 var style = document.getElementById(id) ||
344 document.documentElement.shadowRoot.getElementById(id);
345 style.removeAttribute("id");
346
347 Object.defineProperty(style.sheet, "disabled",
Sebastian Noack 2016/08/04 20:44:23 Where did the code go, that addressed deleteRule a
kzar 2016/08/05 11:01:57 This review is based upon the changes in a couple
348 {value: false, enumerable: true});
349
350 for (var i = 0; i < style.sheet.rules.length; i += 1)
351 Object.defineProperty(style.sheet.rules[i].style, "display",
Sebastian Noack 2016/08/04 20:44:23 How about overriding style.sheet.rules (and sheet.
kzar 2016/08/05 11:01:57 Cool idea, but I actually had to overwrite the get
352 {value: "none", enumerable: true});
353 }, id
354 );
355 }
356
357 function reinjectStyleSheetWhenRemoved(document, style) 337 function reinjectStyleSheetWhenRemoved(document, style)
358 { 338 {
359 if (!MutationObserver) 339 if (!MutationObserver)
360 return null; 340 return null;
361 341
362 var rules = style.sheet.rules; 342 var rules = style.sheet.rules;
363 var parentNode = style.parentNode; 343 var parentNode = style.parentNode;
364 var observer = new MutationObserver(function() 344 var observer = new MutationObserver(function()
365 { 345 {
366 if (style.parentNode != parentNode) 346 if (style.parentNode != parentNode)
367 { 347 {
368 parentNode.appendChild(style); 348 parentNode.appendChild(style);
369 349
350 // Our style element's sheet is sometimes lost when the element is removed
351 // from the DOM. A new empty sheet is then created in its place so we have
352 // to restore the rules ourselves.
370 if (style.sheet.rules.length == 0) 353 if (style.sheet.rules.length == 0)
371 { 354 {
372 for (var i = 0; i < rules.length; i += 1) 355 for (var i = 0; i < rules.length; i += 1)
373 style.sheet.addRule(rules[i].selectorText); 356 style.sheet.addRule(rules[i].selectorText, "display: none !important;" );
374 357
375 enforceStyleSheetRules(style); 358 style.id = id;
359 injectJS(
360 function(id)
361 {
362 var style = document.getElementById(id) ||
363 document.documentElement.shadowRoot.getElementById(id);
364 style.removeAttribute("id");
365
366 Object.defineProperty(style.sheet, "disabled",
367 {value: false, enumerable: true});
368 }, id
369 );
376 } 370 }
377 } 371 }
378 }); 372 });
379 373
380 observer.observe(parentNode, {childList: true}); 374 observer.observe(parentNode, {childList: true});
381 return observer; 375 return observer;
382 } 376 }
383 377
384 function injectJS(f) 378 function injectJS(f)
385 { 379 {
(...skipping 11 matching lines...) Expand all
397 function protectStyleSheet(document, style) 391 function protectStyleSheet(document, style)
398 { 392 {
399 style.id = id; 393 style.id = id;
400 394
401 var protector = function(id) 395 var protector = function(id)
402 { 396 {
403 var style = document.getElementById(id) || 397 var style = document.getElementById(id) ||
404 document.documentElement.shadowRoot.getElementById(id); 398 document.documentElement.shadowRoot.getElementById(id);
405 style.removeAttribute("id"); 399 style.removeAttribute("id");
406 400
407 var i; 401 Object.defineProperty(style, "disabled",
408 var disableables = [style, style.sheet]; 402 {value: false, enumerable: true});
409 for (i = 0; i < disableables.length; i += 1) 403 Object.defineProperty(style.sheet, "disabled",
410 Object.defineProperty(disableables[i], "disabled", 404 {value: false, enumerable: true});
411 {value: false, enumerable: true}); 405
412 406 function wrapMethods(methodNames, descKey, defaultReturnValue)
413 var methods = ["deleteRule", "removeRule"]; 407 {
414 for (i = 0; i < methods.length; i += 1) 408 for (var i = 0; i < methodNames.length; i += 1)
415 { 409 {
416 if (methods[i] in CSSStyleSheet.prototype) 410 if (methodNames[i] in CSSStyleSheet.prototype)
417 {
418 (function(method)
419 { 411 {
420 var original = CSSStyleSheet.prototype[method]; 412 (function(method)
421 CSSStyleSheet.prototype[method] = function(index)
422 { 413 {
423 if (this != style.sheet) 414 var desc = Object.getOwnPropertyDescriptor(CSSStyleSheet.prototype,
424 original.call(this, index); 415 method);
425 }; 416 var original = desc[descKey];
426 }(methods[i])); 417 desc[descKey] = function()
427 } 418 {
428 } 419 if (this != style.sheet)
420 return original.apply(this, arguments);
421 return defaultReturnValue;
422 };
423 Object.defineProperty(CSSStyleSheet.prototype, method, desc);
424 }(methodNames[i]));
425 }
426 }
427 }
428
429 wrapMethods(["deleteRule", "removeRule"], "value");
430 wrapMethods(["rules", "cssRules"], "get", []);
429 }; 431 };
430 432
431 injectJS(protector, id); 433 injectJS(protector, id);
432 } 434 }
433 435
434 // Neither Chrome[1] nor Safari allow us to intercept WebSockets, and therefore 436 // Neither Chrome[1] nor Safari allow us to intercept WebSockets, and therefore
435 // some ad networks are misusing them as a way to serve adverts and circumvent 437 // some ad networks are misusing them as a way to serve adverts and circumvent
436 // us. As a workaround we wrap WebSocket, preventing blocked WebSocket 438 // us. As a workaround we wrap WebSocket, preventing blocked WebSocket
437 // connections from being opened. 439 // connections from being opened.
438 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353 440 // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=129353
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 } 600 }
599 601
600 // Safari only allows 8192 primitive selectors to be injected at once[1], we 602 // Safari only allows 8192 primitive selectors to be injected at once[1], we
601 // therefore chunk the inserted selectors into groups of 200 to be safe. 603 // therefore chunk the inserted selectors into groups of 200 to be safe.
602 // (Chrome also has a limit, larger... but we're not certain exactly what it 604 // (Chrome also has a limit, larger... but we're not certain exactly what it
603 // is! Edge apparently has no such limit.) 605 // is! Edge apparently has no such limit.)
604 // [1] - https://github.com/WebKit/webkit/blob/1cb2227f6b2a1035f7bdc46e5ab69 debb75fc1de/Source/WebCore/css/RuleSet.h#L68 606 // [1] - https://github.com/WebKit/webkit/blob/1cb2227f6b2a1035f7bdc46e5ab69 debb75fc1de/Source/WebCore/css/RuleSet.h#L68
605 for (var i = 0; i < selectors.length; i += SELECTOR_GROUP_SIZE) 607 for (var i = 0; i < selectors.length; i += SELECTOR_GROUP_SIZE)
606 { 608 {
607 var selector = selectors.slice(i, i + SELECTOR_GROUP_SIZE).join(", "); 609 var selector = selectors.slice(i, i + SELECTOR_GROUP_SIZE).join(", ");
608 style.sheet.addRule(selector); 610 style.sheet.addRule(selector, "display: none !important;");
609 } 611 }
610 enforceStyleSheetRules(style);
611 }; 612 };
612 613
613 var updateStylesheet = function() 614 var updateStylesheet = function()
614 { 615 {
615 var selectors = null; 616 var selectors = null;
616 var CSSPropertyFiltersLoaded = false; 617 var CSSPropertyFiltersLoaded = false;
617 618
618 var checkLoaded = function() 619 var checkLoaded = function()
619 { 620 {
620 if (!selectors || !CSSPropertyFiltersLoaded) 621 if (!selectors || !CSSPropertyFiltersLoaded)
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 }, true); 697 }, true);
697 698
698 return updateStylesheet; 699 return updateStylesheet;
699 } 700 }
700 701
701 if (document instanceof HTMLDocument) 702 if (document instanceof HTMLDocument)
702 { 703 {
703 checkSitekey(); 704 checkSitekey();
704 window.updateStylesheet = init(document); 705 window.updateStylesheet = init(document);
705 } 706 }
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
This is Rietveld