| 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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 178   { | 178   { | 
| 179     Array.prototype.forEach.call( | 179     Array.prototype.forEach.call( | 
| 180       document.querySelectorAll(highlightedElementsSelector), | 180       document.querySelectorAll(highlightedElementsSelector), | 
| 181       unhighlightElement | 181       unhighlightElement | 
| 182     ); | 182     ); | 
| 183 | 183 | 
| 184     highlightedElementsSelector = null; | 184     highlightedElementsSelector = null; | 
| 185   } | 185   } | 
| 186 } | 186 } | 
| 187 | 187 | 
|  | 188 function getURLsFromObjectElement(element) | 
|  | 189 { | 
|  | 190   var url = element.getAttribute("data"); | 
|  | 191   if (url) | 
|  | 192     return [resolveURL(url)]; | 
|  | 193 | 
|  | 194   for (var i = 0; i < element.children.length; i++) | 
|  | 195   { | 
|  | 196     var child = element.children[i]; | 
|  | 197     if (child.localName != "param") | 
|  | 198       continue; | 
|  | 199 | 
|  | 200     var name = child.getAttribute("name"); | 
|  | 201     if (name != "movie"  && // Adobe Flash | 
|  | 202         name != "source" && // Silverlight | 
|  | 203         name != "src"    && // Real Media + Quicktime | 
|  | 204         name != "FileName") // Windows Media | 
|  | 205       continue; | 
|  | 206 | 
|  | 207     var value = child.getAttribute("value"); | 
|  | 208     if (!value) | 
|  | 209       continue; | 
|  | 210 | 
|  | 211     return [resolveURL(value)]; | 
|  | 212   } | 
|  | 213 | 
|  | 214   return []; | 
|  | 215 } | 
|  | 216 | 
|  | 217 function getURLsFromAttributes(element) | 
|  | 218 { | 
|  | 219   var urls = []; | 
|  | 220 | 
|  | 221   if (element.src) | 
|  | 222     urls.push(element.src); | 
|  | 223 | 
|  | 224   if (element.srcset) | 
|  | 225   { | 
|  | 226     var candidates = element.srcset.split(","); | 
|  | 227     for (var i = 0; i < candidates.length; i++) | 
|  | 228     { | 
|  | 229       var url = candidates[i].trim().replace(/\s+\S+$/, ""); | 
|  | 230       if (url) | 
|  | 231         urls.push(resolveURL(url)); | 
|  | 232     } | 
|  | 233   } | 
|  | 234 | 
|  | 235   return urls; | 
|  | 236 } | 
|  | 237 | 
|  | 238 function getURLsFromMediaElement(element) | 
|  | 239 { | 
|  | 240   var urls = getURLsFromAttributes(element); | 
|  | 241 | 
|  | 242   for (var i = 0; i < element.children.length; i++) | 
|  | 243   { | 
|  | 244     var child = element.children[i]; | 
|  | 245     if (child.localName == "source" || child.localName == "track") | 
|  | 246       urls.push.apply(urls, getURLsFromAttributes(child)); | 
|  | 247   } | 
|  | 248 | 
|  | 249   if (element.poster) | 
|  | 250     urls.push(element.poster); | 
|  | 251 | 
|  | 252   return urls; | 
|  | 253 } | 
|  | 254 | 
|  | 255 function getURLsFromElement(element) { | 
|  | 256   switch (element.localName) | 
|  | 257   { | 
|  | 258     case "object": | 
|  | 259       return getURLsFromObjectElement(element); | 
|  | 260 | 
|  | 261     case "video": | 
|  | 262     case "audio": | 
|  | 263     case "picture": | 
|  | 264       return getURLsFromMediaElement(element); | 
|  | 265   } | 
|  | 266 | 
|  | 267   return getURLsFromAttributes(element); | 
|  | 268 } | 
|  | 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 | 
| 188 // Gets the absolute position of an element by walking up the DOM tree, | 288 // Gets the absolute position of an element by walking up the DOM tree, | 
| 189 // adding up offsets. | 289 // adding up offsets. | 
| 190 // I hope there's a better way because it just seems absolutely stupid | 290 // I hope there's a better way because it just seems absolutely stupid | 
| 191 // that the DOM wouldn't have a direct way to get this, given that it | 291 // that the DOM wouldn't have a direct way to get this, given that it | 
| 192 // has hundreds and hundreds of other methods that do random junk. | 292 // has hundreds and hundreds of other methods that do random junk. | 
| 193 function getAbsolutePosition(elt) { | 293 function getAbsolutePosition(elt) { | 
| 194   var l = 0; | 294   var l = 0; | 
| 195   var t = 0; | 295   var t = 0; | 
| 196   for(; elt; elt = elt.offsetParent) { | 296   for(; elt; elt = elt.offsetParent) { | 
| 197     l += elt.offsetLeft; | 297     l += elt.offsetLeft; | 
| 198     t += elt.offsetTop; | 298     t += elt.offsetTop; | 
| 199   } | 299   } | 
| 200   return [l, t]; | 300   return [l, t]; | 
| 201 } | 301 } | 
| 202 | 302 | 
| 203 // Adds an overlay to an element, which is probably a Flash object | 303 // Adds an overlay to an element, which is probably a Flash object | 
| 204 function addElementOverlay(elt) { | 304 function addElementOverlay(elt) { | 
| 205   // If this element is enclosed in an object tag, we prefer to block that inste
     ad | 305   // If this element is enclosed in an object tag, we prefer to block that inste
     ad | 
| 206   if(!elt) | 306   if(!elt) | 
| 207     return null; | 307     return null; | 
| 208 | 308 | 
| 209   // If element doesn't have at least one of class name, ID or URL, give up | 309   // If element doesn't have at least one of class name, ID or URL, give up | 
| 210   // because we don't know how to construct a filter rule for it | 310   // because we don't know how to construct a filter rule for it | 
| 211   var url = getElementURL(elt); | 311   if(!isBlockable(elt)) | 
| 212   if(!elt.className && !elt.id && !url) |  | 
| 213     return; | 312     return; | 
| 214 | 313 | 
| 215   // If the element isn't rendered (since its or one of its ancestor's | 314   // If the element isn't rendered (since its or one of its ancestor's | 
| 216   // "display" property is "none"), the overlay wouldn't match the element. | 315   // "display" property is "none"), the overlay wouldn't match the element. | 
| 217   if (!elt.offsetParent) | 316   if (!elt.offsetParent) | 
| 218     return; | 317     return; | 
| 219 | 318 | 
| 220   var thisStyle = getComputedStyle(elt, null); | 319   var thisStyle = getComputedStyle(elt, null); | 
| 221   var overlay = document.createElement('div'); | 320   var overlay = document.createElement('div'); | 
| 222   overlay.prisoner = elt; | 321   overlay.prisoner = elt; | 
| 223   overlay.prisonerURL = url; |  | 
| 224   overlay.className = "__adblockplus__overlay"; | 322   overlay.className = "__adblockplus__overlay"; | 
| 225   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;'); | 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;'); | 
| 226   var pos = getAbsolutePosition(elt); | 324   var pos = getAbsolutePosition(elt); | 
| 227   overlay.style.left = pos[0] + "px"; | 325   overlay.style.left = pos[0] + "px"; | 
| 228   overlay.style.top = pos[1] + "px"; | 326   overlay.style.top = pos[1] + "px"; | 
| 229 | 327 | 
| 230   if (thisStyle.position != "static") | 328   if (thisStyle.position != "static") | 
| 231     overlay.style.zIndex = thisStyle.zIndex; | 329     overlay.style.zIndex = thisStyle.zIndex; | 
| 232   else | 330   else | 
| 233     overlay.style.zIndex = getComputedStyle(elt.offsetParent).zIndex; | 331     overlay.style.zIndex = getComputedStyle(elt.offsetParent).zIndex; | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 276 // Turn on the choose element to create filter thing | 374 // Turn on the choose element to create filter thing | 
| 277 function clickHide_activate() { | 375 function clickHide_activate() { | 
| 278   if(document == null) | 376   if(document == null) | 
| 279     return; | 377     return; | 
| 280 | 378 | 
| 281   // If we are already selecting, abort now | 379   // If we are already selecting, abort now | 
| 282   if (clickHide_activated || clickHideFiltersDialog) | 380   if (clickHide_activated || clickHideFiltersDialog) | 
| 283     clickHide_deactivate(); | 381     clickHide_deactivate(); | 
| 284 | 382 | 
| 285   // Add overlays for elements with URLs so user can easily click them | 383   // Add overlays for elements with URLs so user can easily click them | 
| 286   var elts = document.querySelectorAll('object,embed,img,iframe'); | 384   var elts = document.querySelectorAll('object,embed,img,iframe,video,audio,pict
     ure'); | 
| 287   for(var i=0; i<elts.length; i++) | 385   for(var i=0; i<elts.length; i++) | 
| 288     addElementOverlay(elts[i]); | 386     addElementOverlay(elts[i]); | 
| 289 | 387 | 
| 290   clickHide_activated = true; | 388   clickHide_activated = true; | 
| 291   document.addEventListener("mouseover", clickHide_mouseOver, true); | 389   document.addEventListener("mouseover", clickHide_mouseOver, true); | 
| 292   document.addEventListener("mouseout", clickHide_mouseOut, true); | 390   document.addEventListener("mouseout", clickHide_mouseOut, true); | 
| 293   document.addEventListener("click", clickHide_mouseClick, true); | 391   document.addEventListener("click", clickHide_mouseClick, true); | 
| 294   document.addEventListener("keydown", clickHide_keyDown, true); | 392   document.addEventListener("keydown", clickHide_keyDown, true); | 
| 295 } | 393 } | 
| 296 | 394 | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 345   clickHide_mouseClick(ev); | 443   clickHide_mouseClick(ev); | 
| 346 } | 444 } | 
| 347 | 445 | 
| 348 // Hovering over an element so highlight it | 446 // Hovering over an element so highlight it | 
| 349 function clickHide_mouseOver(e) | 447 function clickHide_mouseOver(e) | 
| 350 { | 448 { | 
| 351   if (clickHide_activated == false) | 449   if (clickHide_activated == false) | 
| 352     return; | 450     return; | 
| 353 | 451 | 
| 354   var target = e.target; | 452   var target = e.target; | 
| 355   while (target.parentNode && !(target.id || target.className || target.src || /
     :.+:/.test(getOriginalStyle(target)))) | 453   while (target.parentNode && !isBlockable(target)) | 
| 356     target = target.parentNode; | 454     target = target.parentNode; | 
| 357   if (target == document.documentElement || target == document.body) | 455   if (target == document.documentElement || target == document.body) | 
| 358     target = null; | 456     target = null; | 
| 359 | 457 | 
| 360   if (target && target instanceof HTMLElement) | 458   if (target && target instanceof HTMLElement) | 
| 361   { | 459   { | 
| 362     currentElement = target; | 460     currentElement = target; | 
| 363 | 461 | 
| 364     highlightElement(target, "#d6d84b", "#f8fa47"); | 462     highlightElement(target, "#d6d84b", "#f8fa47"); | 
| 365     target.addEventListener("contextmenu", clickHide_elementClickHandler, true); | 463     target.addEventListener("contextmenu", clickHide_elementClickHandler, true); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 398 | 496 | 
| 399 // When the user clicks, the currentElement is the one we want. | 497 // When the user clicks, the currentElement is the one we want. | 
| 400 // We should have ABP rules ready for when the | 498 // We should have ABP rules ready for when the | 
| 401 // popup asks for them. | 499 // popup asks for them. | 
| 402 function clickHide_mouseClick(e) | 500 function clickHide_mouseClick(e) | 
| 403 { | 501 { | 
| 404   if (!currentElement || !clickHide_activated) | 502   if (!currentElement || !clickHide_activated) | 
| 405     return; | 503     return; | 
| 406 | 504 | 
| 407   var elt = currentElement; | 505   var elt = currentElement; | 
| 408   var url = null; |  | 
| 409   if (currentElement.classList.contains("__adblockplus__overlay")) | 506   if (currentElement.classList.contains("__adblockplus__overlay")) | 
| 410   { |  | 
| 411     elt = currentElement.prisoner; | 507     elt = currentElement.prisoner; | 
| 412     url = currentElement.prisonerURL; |  | 
| 413   } |  | 
| 414   else if (elt.src) |  | 
| 415     url = elt.src; |  | 
| 416 | 508 | 
| 417   clickHideFilters = new Array(); | 509   clickHideFilters = new Array(); | 
| 418   selectorList = new Array(); | 510   selectorList = new Array(); | 
| 419 | 511 | 
| 420   var addSelector = function(selector) | 512   var addSelector = function(selector) | 
| 421   { | 513   { | 
|  | 514     if (selectorList.indexOf(selector) != -1) | 
|  | 515       return; | 
|  | 516 | 
| 422     clickHideFilters.push(document.domain + "##" + selector); | 517     clickHideFilters.push(document.domain + "##" + selector); | 
| 423     selectorList.push(selector); | 518     selectorList.push(selector); | 
| 424   }; | 519   }; | 
| 425 | 520 | 
| 426   if (elt.id) | 521   if (elt.id) | 
| 427     addSelector("#" + escapeCSS(elt.id)); | 522     addSelector("#" + escapeCSS(elt.id)); | 
| 428 | 523 | 
| 429   if (elt.classList.length > 0) | 524   if (elt.classList.length > 0) | 
| 430   { | 525   { | 
| 431     var selector = ""; | 526     var selector = ""; | 
| 432 | 527 | 
| 433     for (var i = 0; i < elt.classList.length; i++) | 528     for (var i = 0; i < elt.classList.length; i++) | 
| 434       selector += "." + escapeCSS(elt.classList[i]); | 529       selector += "." + escapeCSS(elt.classList[i]); | 
| 435 | 530 | 
| 436     addSelector(selector); | 531     addSelector(selector); | 
| 437   } | 532   } | 
| 438 | 533 | 
| 439   if (url) | 534   var urls = getURLsFromElement(elt); | 
|  | 535   for (var i = 0; i < urls.length; i++) | 
| 440   { | 536   { | 
| 441     var src = elt.getAttribute("src"); | 537     var url = urls[i]; | 
| 442     var selector = src && escapeCSS(elt.localName) + '[src=' + quote(src) + ']'; |  | 
| 443 | 538 | 
| 444     if (/^https?:/i.test(url)) | 539     if (/^https?:/i.test(url)) | 
| 445     { | 540     { | 
| 446       clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||")); | 541       var filter = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"); | 
| 447 | 542 | 
| 448       if (selector) | 543       if (clickHideFilters.indexOf(filter) == -1) | 
| 449         selectorList.push(selector); | 544         clickHideFilters.push(filter); | 
|  | 545 | 
|  | 546       continue; | 
| 450     } | 547     } | 
| 451     else if (selector) | 548 | 
| 452       addSelector(selector); | 549     if (url == elt.src) | 
|  | 550       addSelector(escapeCSS(elt.localName) + '[src=' + quote(elt.getAttribute("s
     rc")) + ']'); | 
| 453   } | 551   } | 
| 454 | 552 | 
| 455   // as last resort, create a filter based on inline styles | 553   // as last resort, create a filter based on inline styles | 
| 456   if (clickHideFilters.length == 0) | 554   if (clickHideFilters.length == 0) | 
| 457   { | 555   { | 
| 458     var style = getOriginalStyle(elt); | 556     var style = getOriginalStyle(elt); | 
| 459     if (style) | 557     if (style) | 
| 460       addSelector(escapeCSS(elt.localName) + '[style=' + quote(style) + ']'); | 558       addSelector(escapeCSS(elt.localName) + '[style=' + quote(style) + ']'); | 
| 461   } | 559   } | 
| 462 | 560 | 
| 463   // Show popup | 561   // Show popup | 
| 464   clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); | 562   clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); | 
| 465 | 563 | 
| 466   // Highlight the elements specified by selector in yellow | 564   // Highlight the elements specified by selector in yellow | 
| 467   if (selectorList.length > 0) | 565   if (selectorList.length > 0) | 
| 468     highlightElements(selectorList.join(",")); | 566     highlightElements(selectorList.join(",")); | 
| 469   // Now, actually highlight the element the user clicked on in red | 567   // Now, actually highlight the element the user clicked on in red | 
| 470   highlightElement(currentElement, "#fd1708", "#f6a1b5"); | 568   highlightElement(currentElement, "#fd1708", "#f6a1b5"); | 
| 471 | 569 | 
| 472   // Make sure the browser doesn't handle this click | 570   // Make sure the browser doesn't handle this click | 
| 473   e.preventDefault(); | 571   e.preventDefault(); | 
| 474   e.stopPropagation(); | 572   e.stopPropagation(); | 
| 475 } | 573 } | 
| 476 | 574 | 
| 477 // Extracts source URL from an IMG, OBJECT, EMBED, or IFRAME |  | 
| 478 function getElementURL(elt) { |  | 
| 479   // Check children of object nodes for "param" nodes with name="movie" that spe
     cify a URL |  | 
| 480   // in value attribute |  | 
| 481   var url; |  | 
| 482   if(elt.localName.toUpperCase() == "OBJECT" && !(url = elt.getAttribute("data")
     )) { |  | 
| 483     // No data attribute, look in PARAM child tags for a URL for the swf file |  | 
| 484     var params = elt.querySelectorAll("param[name=\"movie\"]"); |  | 
| 485     // This OBJECT could contain an EMBED we already nuked, in which case there'
     s no URL |  | 
| 486     if(params[0]) |  | 
| 487       url = params[0].getAttribute("value"); |  | 
| 488     else { |  | 
| 489       params = elt.querySelectorAll("param[name=\"src\"]"); |  | 
| 490       if(params[0]) |  | 
| 491         url = params[0].getAttribute("value"); |  | 
| 492     } |  | 
| 493 |  | 
| 494     if (url) |  | 
| 495       url = resolveURL(url); |  | 
| 496   } else if(!url) { |  | 
| 497     url = elt.src || elt.href; |  | 
| 498   } |  | 
| 499   return url; |  | 
| 500 } |  | 
| 501 |  | 
| 502 // This function Copyright (c) 2008 Jeni Tennison, from jquery.uri.js | 575 // This function Copyright (c) 2008 Jeni Tennison, from jquery.uri.js | 
| 503 // and licensed under the MIT license. See jquery-*.min.js for details. | 576 // and licensed under the MIT license. See jquery-*.min.js for details. | 
| 504 function removeDotSegments(u) { | 577 function removeDotSegments(u) { | 
| 505   var r = '', m = []; | 578   var r = '', m = []; | 
| 506   if (/\./.test(u)) { | 579   if (/\./.test(u)) { | 
| 507     while (u !== undefined && u !== '') { | 580     while (u !== undefined && u !== '') { | 
| 508       if (u === '.' || u === '..') { | 581       if (u === '.' || u === '..') { | 
| 509         u = ''; | 582         u = ''; | 
| 510       } else if (/^\.\.\//.test(u)) { // starts with ../ | 583       } else if (/^\.\.\//.test(u)) { // starts with ../ | 
| 511         u = u.substring(3); | 584         u = u.substring(3); | 
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 691         break; | 764         break; | 
| 692       default: | 765       default: | 
| 693         sendResponse({}); | 766         sendResponse({}); | 
| 694         break; | 767         break; | 
| 695     } | 768     } | 
| 696   }); | 769   }); | 
| 697 | 770 | 
| 698   if (window == window.top) | 771   if (window == window.top) | 
| 699     ext.backgroundPage.sendMessage({type: "report-html-page"}); | 772     ext.backgroundPage.sendMessage({type: "report-html-page"}); | 
| 700 } | 773 } | 
| OLD | NEW | 
|---|