| OLD | NEW | 
|---|
| 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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 260 | 260 | 
| 261     case "video": | 261     case "video": | 
| 262     case "audio": | 262     case "audio": | 
| 263     case "picture": | 263     case "picture": | 
| 264       return getURLsFromMediaElement(element); | 264       return getURLsFromMediaElement(element); | 
| 265   } | 265   } | 
| 266 | 266 | 
| 267   return getURLsFromAttributes(element); | 267   return getURLsFromAttributes(element); | 
| 268 } | 268 } | 
| 269 | 269 | 
| 270 function isBlockable(element) |  | 
| 271 { |  | 
| 272   if (element.id) |  | 
| 273     return true; |  | 
| 274   if (element.classList.length > 0) |  | 
| 275     return true; |  | 
| 276   if (getURLsFromElement(element).length > 0) |  | 
| 277     return true; |  | 
| 278 |  | 
| 279   // We only generate filters based on the "style" attribute, |  | 
| 280   // if this is the only way we can generate a filter, and |  | 
| 281   // only if there are at least two CSS properties defined. |  | 
| 282   if (/:.+:/.test(getOriginalStyle(element))) |  | 
| 283     return true; |  | 
| 284 |  | 
| 285   return false; |  | 
| 286 } |  | 
| 287 |  | 
| 288 // Gets the absolute position of an element by walking up the DOM tree, | 270 // Gets the absolute position of an element by walking up the DOM tree, | 
| 289 // adding up offsets. | 271 // adding up offsets. | 
| 290 // I hope there's a better way because it just seems absolutely stupid | 272 // I hope there's a better way because it just seems absolutely stupid | 
| 291 // that the DOM wouldn't have a direct way to get this, given that it | 273 // that the DOM wouldn't have a direct way to get this, given that it | 
| 292 // has hundreds and hundreds of other methods that do random junk. | 274 // has hundreds and hundreds of other methods that do random junk. | 
| 293 function getAbsolutePosition(elt) { | 275 function getAbsolutePosition(elt) { | 
| 294   var l = 0; | 276   var l = 0; | 
| 295   var t = 0; | 277   var t = 0; | 
| 296   for(; elt; elt = elt.offsetParent) { | 278   for(; elt; elt = elt.offsetParent) { | 
| 297     l += elt.offsetLeft; | 279     l += elt.offsetLeft; | 
| 298     t += elt.offsetTop; | 280     t += elt.offsetTop; | 
| 299   } | 281   } | 
| 300   return [l, t]; | 282   return [l, t]; | 
| 301 } | 283 } | 
| 302 | 284 | 
| 303 // Adds an overlay to an element, which is probably a Flash object | 285 // Adds an overlay to an element, which is probably a Flash object | 
| 304 function addElementOverlay(elt) { | 286 function addElementOverlay(elt, callback) { | 
| 305   // If this element is enclosed in an object tag, we prefer to block that inste
     ad | 287   // If this element is enclosed in an object tag, we prefer to block that inste
     ad | 
| 306   if(!elt) | 288   if(!elt) | 
| 307     return null; |  | 
| 308 |  | 
| 309   // If element doesn't have at least one of class name, ID or URL, give up |  | 
| 310   // because we don't know how to construct a filter rule for it |  | 
| 311   if(!isBlockable(elt)) |  | 
| 312     return; | 289     return; | 
| 313 | 290 | 
| 314   // If the element isn't rendered (since its or one of its ancestor's | 291   // If the element isn't rendered (since its or one of its ancestor's | 
| 315   // "display" property is "none"), the overlay wouldn't match the element. | 292   // "display" property is "none"), the overlay wouldn't match the element. | 
| 316   if (!elt.offsetParent) | 293   if (!elt.offsetParent) | 
| 317     return; | 294     return; | 
| 318 | 295 | 
| 319   var thisStyle = getComputedStyle(elt, null); | 296   generateFilters(elt, function(filters) | 
| 320   var overlay = document.createElement('div'); | 297   { | 
| 321   overlay.prisoner = elt; | 298     if (filters.length == 0) | 
| 322   overlay.className = "__adblockplus__overlay"; | 299       return; | 
| 323   overlay.setAttribute('style', 'opacity:0.4; background-color:#ffffff; display:
     inline-box; ' + 'width:' + thisStyle.width + '; height:' + thisStyle.height + ';
      position:absolute; overflow:hidden; -webkit-box-sizing:border-box;'); |  | 
| 324   var pos = getAbsolutePosition(elt); |  | 
| 325   overlay.style.left = pos[0] + "px"; |  | 
| 326   overlay.style.top = pos[1] + "px"; |  | 
| 327 | 300 | 
| 328   if (thisStyle.position != "static") | 301     var thisStyle = getComputedStyle(elt, null); | 
| 329     overlay.style.zIndex = thisStyle.zIndex; | 302     var overlay = document.createElement('div'); | 
| 330   else | 303     overlay.prisoner = elt; | 
| 331     overlay.style.zIndex = getComputedStyle(elt.offsetParent).zIndex; | 304     overlay.className = "__adblockplus__overlay"; | 
|  | 305     overlay.setAttribute('style', 'opacity:0.4; background-color:#ffffff; displa
     y:inline-box; ' + 'width:' + thisStyle.width + '; height:' + thisStyle.height + 
     '; position:absolute; overflow:hidden; -webkit-box-sizing:border-box;'); | 
|  | 306     var pos = getAbsolutePosition(elt); | 
|  | 307     overlay.style.left = pos[0] + "px"; | 
|  | 308     overlay.style.top = pos[1] + "px"; | 
| 332 | 309 | 
| 333   // elt.parentNode.appendChild(overlay, elt); | 310     if (thisStyle.position != "static") | 
| 334   document.body.appendChild(overlay); | 311       overlay.style.zIndex = thisStyle.zIndex; | 
| 335   return overlay; | 312     else | 
|  | 313       overlay.style.zIndex = getComputedStyle(elt.offsetParent).zIndex; | 
|  | 314 | 
|  | 315     document.body.appendChild(overlay); | 
|  | 316 | 
|  | 317     if (callback) | 
|  | 318       callback(overlay); | 
|  | 319   }); | 
| 336 } | 320 } | 
| 337 | 321 | 
| 338 // Show dialog asking user whether she wants to add the proposed filters derived | 322 // Show dialog asking user whether she wants to add the proposed filters derived | 
| 339 // from selected page element | 323 // from selected page element | 
| 340 function clickHide_showDialog(left, top, filters) | 324 function clickHide_showDialog(left, top, filters) | 
| 341 { | 325 { | 
| 342   // If we are already selecting, abort now | 326   // If we are already selecting, abort now | 
| 343   if (clickHide_activated || clickHideFiltersDialog) | 327   if (clickHide_activated || clickHideFiltersDialog) | 
| 344     clickHide_deactivate(true); | 328     clickHide_deactivate(true); | 
| 345 | 329 | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 436       overlays[0].parentNode.removeChild(overlays[0]); | 420       overlays[0].parentNode.removeChild(overlays[0]); | 
| 437   } | 421   } | 
| 438 } | 422 } | 
| 439 | 423 | 
| 440 function clickHide_elementClickHandler(ev) { | 424 function clickHide_elementClickHandler(ev) { | 
| 441   ev.preventDefault(); | 425   ev.preventDefault(); | 
| 442   ev.stopPropagation(); | 426   ev.stopPropagation(); | 
| 443   clickHide_mouseClick(ev); | 427   clickHide_mouseClick(ev); | 
| 444 } | 428 } | 
| 445 | 429 | 
|  | 430 function getBlockableElementOrAncestor(element, callback) | 
|  | 431 { | 
|  | 432   if (element && element != document.documentElement | 
|  | 433               && element != document.body) | 
|  | 434   { | 
|  | 435     generateFilters(element, function(filters) | 
|  | 436     { | 
|  | 437       if (filters.length > 0) | 
|  | 438         callback(element); | 
|  | 439       else | 
|  | 440         getBlockableElementOrAncestor(element.parentElement, callback); | 
|  | 441     }); | 
|  | 442   } | 
|  | 443   else | 
|  | 444   { | 
|  | 445     callback(null); | 
|  | 446   } | 
|  | 447 } | 
|  | 448 | 
| 446 // Hovering over an element so highlight it | 449 // Hovering over an element so highlight it | 
| 447 function clickHide_mouseOver(e) | 450 function clickHide_mouseOver(e) | 
| 448 { | 451 { | 
| 449   if (clickHide_activated == false) | 452   if (clickHide_activated == false) | 
| 450     return; | 453     return; | 
| 451 | 454 | 
| 452   var target = e.target; | 455   getBlockableElementOrAncestor(e.target, function(element) | 
| 453   while (target.parentNode && !isBlockable(target)) | 456   { | 
| 454     target = target.parentNode; | 457     if (currentElement) | 
| 455   if (target == document.documentElement || target == document.body) | 458       unhighlightElement(currentElement); | 
| 456     target = null; |  | 
| 457 | 459 | 
| 458   if (target && target instanceof HTMLElement) | 460     if (element) | 
| 459   { | 461     { | 
| 460     currentElement = target; | 462       highlightElement(element, "#d6d84b", "#f8fa47"); | 
|  | 463       element.addEventListener("contextmenu", clickHide_elementClickHandler, tru
     e); | 
|  | 464     } | 
| 461 | 465 | 
| 462     highlightElement(target, "#d6d84b", "#f8fa47"); | 466     currentElement = element; | 
| 463     target.addEventListener("contextmenu", clickHide_elementClickHandler, true); | 467   }); | 
| 464   } |  | 
| 465 } | 468 } | 
| 466 | 469 | 
| 467 // No longer hovering over this element so unhighlight it | 470 // No longer hovering over this element so unhighlight it | 
| 468 function clickHide_mouseOut(e) | 471 function clickHide_mouseOut(e) | 
| 469 { | 472 { | 
| 470   if (!clickHide_activated || !currentElement) | 473   if (!clickHide_activated || currentElement != e.target) | 
| 471     return; | 474     return; | 
| 472 | 475 | 
| 473   unhighlightElement(currentElement); | 476   unhighlightElement(currentElement); | 
| 474   currentElement.removeEventListener("contextmenu", clickHide_elementClickHandle
     r, true); | 477   currentElement.removeEventListener("contextmenu", clickHide_elementClickHandle
     r, true); | 
| 475 } | 478 } | 
| 476 | 479 | 
| 477 // Selects the currently hovered-over filter or cancels selection | 480 // Selects the currently hovered-over filter or cancels selection | 
| 478 function clickHide_keyDown(e) | 481 function clickHide_keyDown(e) | 
| 479 { | 482 { | 
| 480   if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 13 /*DOM_VK_RETURN*
     /) | 483   if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 13 /*DOM_VK_RETURN*
     /) | 
| 481      clickHide_mouseClick(e); | 484      clickHide_mouseClick(e); | 
| 482   else if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 27 /*DOM_VK_ES
     CAPE*/) | 485   else if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 27 /*DOM_VK_ES
     CAPE*/) | 
| 483   { | 486   { | 
| 484     ext.backgroundPage.sendMessage( | 487     ext.backgroundPage.sendMessage( | 
| 485     { | 488     { | 
| 486       type: "forward", | 489       type: "forward", | 
| 487       payload: | 490       payload: | 
| 488       { | 491       { | 
| 489         type: "clickhide-deactivate" | 492         type: "clickhide-deactivate" | 
| 490       } | 493       } | 
| 491     }); | 494     }); | 
| 492     e.preventDefault(); | 495     e.preventDefault(); | 
| 493     e.stopPropagation(); | 496     e.stopPropagation(); | 
| 494   } | 497   } | 
| 495 } | 498 } | 
| 496 | 499 | 
|  | 500 function generateFilters(element, callback) | 
|  | 501 { | 
|  | 502   function addStyleAttributeFilter(filters, selectors) | 
|  | 503   { | 
|  | 504     var style = getOriginalStyle(element); | 
|  | 505     if (style && filters.length == 0) | 
|  | 506     { | 
|  | 507       ext.backgroundPage.sendMessage( | 
|  | 508         { | 
|  | 509           type: "get-filters-from-selectors", | 
|  | 510           selectors: [escapeCSS(element.localName) + '[style=' + quote(style) + 
     ']'] | 
|  | 511         }, | 
|  | 512 | 
|  | 513         function(response) | 
|  | 514         { | 
|  | 515           callback(response.filters, response.selectors); | 
|  | 516         } | 
|  | 517       ); | 
|  | 518     } | 
|  | 519     else | 
|  | 520       callback(filters, selectors); | 
|  | 521   } | 
|  | 522 | 
|  | 523   function addElemHideFilters(filters, selectors) | 
|  | 524   { | 
|  | 525     if (selectors.length > 0) | 
|  | 526     { | 
|  | 527       ext.backgroundPage.sendMessage( | 
|  | 528         { | 
|  | 529           type: "get-filters-from-selectors", | 
|  | 530           selectors: selectors | 
|  | 531         }, | 
|  | 532 | 
|  | 533         function(response) | 
|  | 534         { | 
|  | 535           addStyleAttributeFilter(filters.concat(response.filters), response.sel
     ectors); | 
|  | 536         } | 
|  | 537       ); | 
|  | 538     } | 
|  | 539     else | 
|  | 540       addStyleAttributeFilter(filters, selectors); | 
|  | 541   } | 
|  | 542 | 
|  | 543   var filters = []; | 
|  | 544   var selectors = []; | 
|  | 545 | 
|  | 546   if (element.id) | 
|  | 547     selectors.push("#" + escapeCSS(element.id)); | 
|  | 548 | 
|  | 549   if (element.classList.length > 0) | 
|  | 550   { | 
|  | 551     var selector = ""; | 
|  | 552 | 
|  | 553     for (var i = 0; i < element.classList.length; i++) | 
|  | 554       selector += "." + escapeCSS(element.classList[i]); | 
|  | 555 | 
|  | 556     selectors.push(selector); | 
|  | 557   } | 
|  | 558 | 
|  | 559   var urls = getURLsFromElement(element); | 
|  | 560   if (urls.length > 0) | 
|  | 561   { | 
|  | 562     ext.backgroundPage.sendMessage( | 
|  | 563       { | 
|  | 564         type: "check-whitelisted-urls", | 
|  | 565         mediatype: typeMap[element.localName], | 
|  | 566         urls: urls | 
|  | 567       }, | 
|  | 568 | 
|  | 569       function(whitelisted) | 
|  | 570       { | 
|  | 571         for (var i = 0; i < urls.length; i++) | 
|  | 572         { | 
|  | 573           var url = urls[i]; | 
|  | 574 | 
|  | 575           if (!whitelisted[url] && /^https?:/i.test(url)) | 
|  | 576           { | 
|  | 577             var filter = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"); | 
|  | 578 | 
|  | 579             if (filters.indexOf(filter) == -1) | 
|  | 580               filters.push(filter); | 
|  | 581 | 
|  | 582             continue; | 
|  | 583           } | 
|  | 584 | 
|  | 585           if (url == element.src) | 
|  | 586           { | 
|  | 587             var selector = escapeCSS(element.localName) + '[src=' + quote(elemen
     t.getAttribute("src")) + ']'; | 
|  | 588 | 
|  | 589             if (selectors.indexOf(selector) == -1) | 
|  | 590               selectors.push(selector); | 
|  | 591           } | 
|  | 592         } | 
|  | 593 | 
|  | 594         addElemHideFilters(filters, selectors); | 
|  | 595       } | 
|  | 596     ); | 
|  | 597   } | 
|  | 598   else | 
|  | 599     addElemHideFilters(filters, selectors); | 
|  | 600 } | 
|  | 601 | 
| 497 // When the user clicks, the currentElement is the one we want. | 602 // When the user clicks, the currentElement is the one we want. | 
| 498 // We should have ABP rules ready for when the | 603 // We should have ABP rules ready for when the | 
| 499 // popup asks for them. | 604 // popup asks for them. | 
| 500 function clickHide_mouseClick(e) | 605 function clickHide_mouseClick(e) | 
| 501 { | 606 { | 
| 502   if (!currentElement || !clickHide_activated) | 607   if (!currentElement || !clickHide_activated) | 
| 503     return; | 608     return; | 
| 504 | 609 | 
| 505   var elt = currentElement; | 610   var elt = currentElement; | 
| 506   if (currentElement.classList.contains("__adblockplus__overlay")) | 611   if (currentElement.classList.contains("__adblockplus__overlay")) | 
| 507     elt = currentElement.prisoner; | 612     elt = currentElement.prisoner; | 
| 508 | 613 | 
| 509   clickHideFilters = new Array(); | 614   generateFilters(elt, function(filters, selectors) | 
| 510   selectorList = new Array(); | 615   { | 
|  | 616     clickHide_showDialog(e.clientX, e.clientY, filters); | 
| 511 | 617 | 
| 512   var addSelector = function(selector) | 618     // Highlight the elements specified by selector in yellow | 
| 513   { | 619     if (selectors.length > 0) | 
| 514     if (selectorList.indexOf(selector) != -1) | 620       highlightElements(selectors.join(",")); | 
| 515       return; |  | 
| 516 | 621 | 
| 517     clickHideFilters.push(document.domain + "##" + selector); | 622     // Now, actually highlight the element the user clicked on in red | 
| 518     selectorList.push(selector); | 623     highlightElement(currentElement, "#fd1708", "#f6a1b5"); | 
| 519   }; | 624   }); | 
| 520 |  | 
| 521   if (elt.id) |  | 
| 522     addSelector("#" + escapeCSS(elt.id)); |  | 
| 523 |  | 
| 524   if (elt.classList.length > 0) |  | 
| 525   { |  | 
| 526     var selector = ""; |  | 
| 527 |  | 
| 528     for (var i = 0; i < elt.classList.length; i++) |  | 
| 529       selector += "." + escapeCSS(elt.classList[i]); |  | 
| 530 |  | 
| 531     addSelector(selector); |  | 
| 532   } |  | 
| 533 |  | 
| 534   var urls = getURLsFromElement(elt); |  | 
| 535   for (var i = 0; i < urls.length; i++) |  | 
| 536   { |  | 
| 537     var url = urls[i]; |  | 
| 538 |  | 
| 539     if (/^https?:/i.test(url)) |  | 
| 540     { |  | 
| 541       var filter = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"); |  | 
| 542 |  | 
| 543       if (clickHideFilters.indexOf(filter) == -1) |  | 
| 544         clickHideFilters.push(filter); |  | 
| 545 |  | 
| 546       continue; |  | 
| 547     } |  | 
| 548 |  | 
| 549     if (url == elt.src) |  | 
| 550       addSelector(escapeCSS(elt.localName) + '[src=' + quote(elt.getAttribute("s
     rc")) + ']'); |  | 
| 551   } |  | 
| 552 |  | 
| 553   // as last resort, create a filter based on inline styles |  | 
| 554   if (clickHideFilters.length == 0) |  | 
| 555   { |  | 
| 556     var style = getOriginalStyle(elt); |  | 
| 557     if (style) |  | 
| 558       addSelector(escapeCSS(elt.localName) + '[style=' + quote(style) + ']'); |  | 
| 559   } |  | 
| 560 |  | 
| 561   // Show popup |  | 
| 562   clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); |  | 
| 563 |  | 
| 564   // Highlight the elements specified by selector in yellow |  | 
| 565   if (selectorList.length > 0) |  | 
| 566     highlightElements(selectorList.join(",")); |  | 
| 567   // Now, actually highlight the element the user clicked on in red |  | 
| 568   highlightElement(currentElement, "#fd1708", "#f6a1b5"); |  | 
| 569 | 625 | 
| 570   // Make sure the browser doesn't handle this click | 626   // Make sure the browser doesn't handle this click | 
| 571   e.preventDefault(); | 627   e.preventDefault(); | 
| 572   e.stopPropagation(); | 628   e.stopPropagation(); | 
| 573 } | 629 } | 
| 574 | 630 | 
| 575 // This function Copyright (c) 2008 Jeni Tennison, from jquery.uri.js | 631 // This function Copyright (c) 2008 Jeni Tennison, from jquery.uri.js | 
| 576 // and licensed under the MIT license. See jquery-*.min.js for details. | 632 // and licensed under the MIT license. See jquery-*.min.js for details. | 
| 577 function removeDotSegments(u) { | 633 function removeDotSegments(u) { | 
| 578   var r = '', m = []; | 634   var r = '', m = []; | 
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 685         break; | 741         break; | 
| 686       case "clickhide-activate": | 742       case "clickhide-activate": | 
| 687         clickHide_activate(); | 743         clickHide_activate(); | 
| 688         break; | 744         break; | 
| 689       case "clickhide-deactivate": | 745       case "clickhide-deactivate": | 
| 690         clickHide_deactivate(); | 746         clickHide_deactivate(); | 
| 691         break; | 747         break; | 
| 692       case "clickhide-new-filter": | 748       case "clickhide-new-filter": | 
| 693         if(lastRightClickEvent) | 749         if(lastRightClickEvent) | 
| 694         { | 750         { | 
| 695           clickHide_activated = true; | 751           var event = lastRightClickEvent; | 
| 696           currentElement = addElementOverlay(lastRightClickEvent.target); | 752 | 
| 697           clickHide_mouseClick(lastRightClickEvent); | 753           addElementOverlay(event.target, function(overlay) | 
|  | 754           { | 
|  | 755             clickHide_activated = true; | 
|  | 756             currentElement = overlay; | 
|  | 757             clickHide_mouseClick(event); | 
|  | 758           }); | 
| 698         } | 759         } | 
| 699         break; | 760         break; | 
| 700       case "clickhide-init": | 761       case "clickhide-init": | 
| 701         if (clickHideFiltersDialog) | 762         if (clickHideFiltersDialog) | 
| 702         { | 763         { | 
| 703           sendResponse({filters: clickHide_filters}); | 764           sendResponse({filters: clickHide_filters}); | 
| 704 | 765 | 
| 705           clickHideFiltersDialog.style.width = msg.width + "px"; | 766           clickHideFiltersDialog.style.width = msg.width + "px"; | 
| 706           clickHideFiltersDialog.style.height = msg.height + "px"; | 767           clickHideFiltersDialog.style.height = msg.height + "px"; | 
| 707           clickHideFiltersDialog.style.visibility = "visible"; | 768           clickHideFiltersDialog.style.visibility = "visible"; | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 726         break; | 787         break; | 
| 727       default: | 788       default: | 
| 728         sendResponse({}); | 789         sendResponse({}); | 
| 729         break; | 790         break; | 
| 730     } | 791     } | 
| 731   }); | 792   }); | 
| 732 | 793 | 
| 733   if (window == window.top) | 794   if (window == window.top) | 
| 734     ext.backgroundPage.sendMessage({type: "report-html-page"}); | 795     ext.backgroundPage.sendMessage({type: "report-html-page"}); | 
| 735 } | 796 } | 
| OLD | NEW | 
|---|