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

Side by Side Diff: include.postload.js

Issue 5225119261655040: Issue 1282 - Don't generate filters conflicting with existing exception rules (Closed)
Patch Set: Rebased Created Feb. 28, 2015, 6:03 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
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-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 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 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 191
192 case "video": 192 case "video":
193 case "audio": 193 case "audio":
194 case "picture": 194 case "picture":
195 return getURLsFromMediaElement(element); 195 return getURLsFromMediaElement(element);
196 } 196 }
197 197
198 return getURLsFromAttributes(element); 198 return getURLsFromAttributes(element);
199 } 199 }
200 200
201 function isBlockable(element)
202 {
203 if (element.id)
204 return true;
205 if (element.classList.length > 0)
206 return true;
207 if (getURLsFromElement(element).length > 0)
208 return true;
209
210 // We only generate filters based on the "style" attribute,
211 // if this is the only way we can generate a filter, and
212 // only if there are at least two CSS properties defined.
213 if (/:.+:/.test(element.getAttribute("style")))
214 return true;
215
216 return false;
217 }
218
219 // Adds an overlay to an element, which is probably a Flash object 201 // Adds an overlay to an element, which is probably a Flash object
220 function addElementOverlay(elt) { 202 function addElementOverlay(elt) {
221 var zIndex = "auto"; 203 var zIndex = "auto";
222 var position = "absolute"; 204 var position = "absolute";
223 205
224 for (var e = elt; e; e = e.parentElement) 206 for (var e = elt; e; e = e.parentElement)
225 { 207 {
226 var style = getComputedStyle(e); 208 var style = getComputedStyle(e);
227 209
228 // If the element isn't rendered (since its or one of its ancestor's 210 // If the element isn't rendered (since its or one of its ancestor's
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 function clickHide_activate() { 287 function clickHide_activate() {
306 if(document == null) 288 if(document == null)
307 return; 289 return;
308 290
309 // If we are already selecting, abort now 291 // If we are already selecting, abort now
310 if (clickHide_activated || clickHideFiltersDialog) 292 if (clickHide_activated || clickHideFiltersDialog)
311 clickHide_deactivate(); 293 clickHide_deactivate();
312 294
313 // Add overlays for blockable elements that don't emit mouse events, 295 // Add overlays for blockable elements that don't emit mouse events,
314 // so that they can still be selected. 296 // so that they can still be selected.
315 var elts = document.querySelectorAll('object,embed,iframe,frame'); 297 [].forEach.call(
316 for(var i=0; i<elts.length; i++) 298 document.querySelectorAll('object,embed,iframe,frame'),
317 { 299 function(element)
318 var element = elts[i]; 300 {
319 if (isBlockable(element)) 301 getFiltersForElement(element, function(filters)
320 addElementOverlay(element); 302 {
321 } 303 if (filters.length > 0)
304 addElementOverlay(element);
305 });
306 }
307 );
322 308
323 clickHide_activated = true; 309 clickHide_activated = true;
324 document.addEventListener("mousedown", clickHide_stopPropagation, true); 310 document.addEventListener("mousedown", clickHide_stopPropagation, true);
325 document.addEventListener("mouseup", clickHide_stopPropagation, true); 311 document.addEventListener("mouseup", clickHide_stopPropagation, true);
326 document.addEventListener("mouseenter", clickHide_stopPropagation, true); 312 document.addEventListener("mouseenter", clickHide_stopPropagation, true);
327 document.addEventListener("mouseleave", clickHide_stopPropagation, true); 313 document.addEventListener("mouseleave", clickHide_stopPropagation, true);
328 document.addEventListener("mouseover", clickHide_mouseOver, true); 314 document.addEventListener("mouseover", clickHide_mouseOver, true);
329 document.addEventListener("mouseout", clickHide_mouseOut, true); 315 document.addEventListener("mouseout", clickHide_mouseOut, true);
330 document.addEventListener("click", clickHide_mouseClick, true); 316 document.addEventListener("click", clickHide_mouseClick, true);
331 document.addEventListener("keydown", clickHide_keyDown, true); 317 document.addEventListener("keydown", clickHide_keyDown, true);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 { 380 {
395 e.stopPropagation(); 381 e.stopPropagation();
396 } 382 }
397 383
398 function clickHide_elementClickHandler(e) { 384 function clickHide_elementClickHandler(e) {
399 e.preventDefault(); 385 e.preventDefault();
400 e.stopPropagation(); 386 e.stopPropagation();
401 clickHide_mouseClick(e); 387 clickHide_mouseClick(e);
402 } 388 }
403 389
404 function getBlockableElementOrAncestor(element) 390 function getBlockableElementOrAncestor(element, callback)
405 { 391 {
406 while (element && element != document.documentElement 392 // We reached the document root without finding a blockable element.
407 && element != document.body) 393 // We also assume that the user doesn't want to block the whole page.
394 // So we never consider the <html> or <body> element.
395 if (!element || element == document.documentElement || element == document.bod y)
396 callback(null);
397
398 // We can't handle non-HTML (like SVG) elements, as well as
399 // <area> elements (see below). So fall back to the parent element.
400 else if (!(element instanceof HTMLElement) || element.localName == "area")
401 getBlockableElementOrAncestor(element.parentElement, callback);
Wladimir Palant 2015/03/02 20:14:19 This seems to be the right recipe to error out wit
Sebastian Noack 2015/03/03 14:29:00 Done.
402
403 // If image maps are used mouse events occur for the <area> element.
404 // But we have to block the image associated with the <map> element.
405 else if (element.localName == "map")
408 { 406 {
409 if (element instanceof HTMLElement && element.localName != "area") 407 var images = document.querySelectorAll("img[usemap]");
408 var image = null;
409
410 for (var i = 0; i < images.length; i++)
410 { 411 {
411 // Handle <area> and their <map> elements specially, 412 var usemap = images[i].getAttribute("usemap");
412 // blocking the image they are associated with 413 var index = usemap.indexOf("#");
413 if (element.localName == "map") 414
415 if (index != -1 && usemap.substr(index + 1) == element.name)
414 { 416 {
415 var images = document.querySelectorAll("img[usemap]"); 417 image = images[i];
416 for (var i = 0; i < images.length; i++) 418 break;
417 {
418 var image = images[i];
419 var usemap = image.getAttribute("usemap");
420 var index = usemap.indexOf("#");
421
422 if (index != -1 && usemap.substr(index + 1) == element.name)
423 return getBlockableElementOrAncestor(image);
424 }
425
426 return null;
427 } 419 }
428
429 if (isBlockable(element))
430 return element;
431 } 420 }
432 421
433 element = element.parentElement; 422 getBlockableElementOrAncestor(image, callback);
434 } 423 }
435 424
436 return null; 425 // Finally, if none of the above is true, check whether we can generate
426 // any filters for this element. Otherwise fall back to its parent element.
427 else
428 {
429 getFiltersForElement(element, function(filters)
430 {
431 if (filters.length > 0)
432 callback(element);
433 else
434 getBlockableElementOrAncestor(element.parentElement, callback);
435 });
436 }
437 } 437 }
438 438
439 // Hovering over an element so highlight it 439 // Hovering over an element so highlight it
440 function clickHide_mouseOver(e) 440 function clickHide_mouseOver(e)
441 { 441 {
442 if (clickHide_activated == false) 442 if (clickHide_activated == false)
443 return; 443 return;
444 444
445 var target = getBlockableElementOrAncestor(e.target); 445 getBlockableElementOrAncestor(e.target, function(element)
446 {
447 if (currentElement)
448 unhighlightElement(currentElement);
Wladimir Palant 2015/03/02 20:14:19 I don't think it is that simple. Mouse events can
Sebastian Noack 2015/03/03 14:29:00 I have a hard time verifying that the suggested lo
446 449
447 if (target) 450 if (element)
448 { 451 {
449 currentElement = target; 452 highlightElement(element, "#d6d84b", "#f8fa47");
453 element.addEventListener("contextmenu", clickHide_elementClickHandler, tru e);
454 }
450 455
451 highlightElement(target, "#d6d84b", "#f8fa47"); 456 currentElement = element;
452 target.addEventListener("contextmenu", clickHide_elementClickHandler, true); 457 });
453 } 458
454 e.stopPropagation(); 459 e.stopPropagation();
455 } 460 }
456 461
457 // No longer hovering over this element so unhighlight it 462 // No longer hovering over this element so unhighlight it
458 function clickHide_mouseOut(e) 463 function clickHide_mouseOut(e)
459 { 464 {
460 if (!clickHide_activated || !currentElement) 465 if (!clickHide_activated || currentElement != e.target)
kzar 2015/03/02 18:30:08 Wouldn't e.target not match for image maps where t
Sebastian Noack 2015/03/02 18:40:48 currentElement is the element we are highlighting
kzar 2015/03/02 18:42:29 Whoops missed the return there, OK.
461 return; 466 return;
462 467
463 unhighlightElement(currentElement); 468 unhighlightElement(currentElement);
464 currentElement.removeEventListener("contextmenu", clickHide_elementClickHandle r, true); 469 currentElement.removeEventListener("contextmenu", clickHide_elementClickHandle r, true);
465 e.stopPropagation(); 470 e.stopPropagation();
466 } 471 }
467 472
468 // Selects the currently hovered-over filter or cancels selection 473 // Selects the currently hovered-over filter or cancels selection
469 function clickHide_keyDown(e) 474 function clickHide_keyDown(e)
470 { 475 {
(...skipping 18 matching lines...) Expand all
489 { 494 {
490 ext.backgroundPage.sendMessage( 495 ext.backgroundPage.sendMessage(
491 { 496 {
492 type: "compose-filters", 497 type: "compose-filters",
493 tagName: element.localName, 498 tagName: element.localName,
494 id: element.id, 499 id: element.id,
495 src: element.getAttribute("src"), 500 src: element.getAttribute("src"),
496 style: element.getAttribute("style"), 501 style: element.getAttribute("style"),
497 classes: [].slice.call(element.classList), 502 classes: [].slice.call(element.classList),
498 urls: getURLsFromElement(element), 503 urls: getURLsFromElement(element),
504 mediatype: typeMap[element.localName],
499 baseURL: document.location.href 505 baseURL: document.location.href
500 }, 506 },
501 function(response) 507 function(response)
502 { 508 {
503 callback(response.filters, response.selectors); 509 callback(response.filters, response.selectors);
504 } 510 }
505 ); 511 );
506 } 512 }
507 513
508 // When the user clicks, the currentElement is the one we want. 514 // When the user clicks, the currentElement is the one we want.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 break; 673 break;
668 case "clickhide-activate": 674 case "clickhide-activate":
669 clickHide_activate(); 675 clickHide_activate();
670 break; 676 break;
671 case "clickhide-deactivate": 677 case "clickhide-deactivate":
672 clickHide_deactivate(); 678 clickHide_deactivate();
673 break; 679 break;
674 case "clickhide-new-filter": 680 case "clickhide-new-filter":
675 if(lastRightClickEvent) 681 if(lastRightClickEvent)
676 { 682 {
677 clickHide_activated = true; 683 getBlockableElementOrAncestor(lastRightClickEvent.target, function(ele ment)
678 currentElement = getBlockableElementOrAncestor(lastRightClickEvent.tar get); 684 {
679 clickHide_mouseClick(lastRightClickEvent); 685 clickHide_activated = true;
686 currentElement = element;
687 clickHide_mouseClick(lastRightClickEvent);
688 });
680 } 689 }
681 break; 690 break;
682 case "clickhide-init": 691 case "clickhide-init":
683 if (clickHideFiltersDialog) 692 if (clickHideFiltersDialog)
684 { 693 {
685 sendResponse({filters: clickHide_filters}); 694 sendResponse({filters: clickHide_filters});
686 695
687 clickHideFiltersDialog.style.width = msg.width + "px"; 696 clickHideFiltersDialog.style.width = msg.width + "px";
688 clickHideFiltersDialog.style.height = msg.height + "px"; 697 clickHideFiltersDialog.style.height = msg.height + "px";
689 clickHideFiltersDialog.style.visibility = "visible"; 698 clickHideFiltersDialog.style.visibility = "visible";
(...skipping 27 matching lines...) Expand all
717 lastRightClickEventValid = false; 726 lastRightClickEventValid = false;
718 else 727 else
719 lastRightClickEvent = null; 728 lastRightClickEvent = null;
720 break; 729 break;
721 } 730 }
722 }); 731 });
723 732
724 if (window == window.top) 733 if (window == window.top)
725 ext.backgroundPage.sendMessage({type: "report-html-page"}); 734 ext.backgroundPage.sendMessage({type: "report-html-page"});
726 } 735 }
OLDNEW

Powered by Google App Engine
This is Rietveld