| 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-2013 Eyeo GmbH | 3 * Copyright (C) 2006-2013 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 15 matching lines...) Expand all Loading... |
| 26 var highlightedElementsBoxShadows = null; | 26 var highlightedElementsBoxShadows = null; |
| 27 var highlightedElementsBGColors = null; | 27 var highlightedElementsBGColors = null; |
| 28 var clickHideFiltersDialog = null; | 28 var clickHideFiltersDialog = null; |
| 29 var lastRightClickEvent = null; | 29 var lastRightClickEvent = null; |
| 30 | 30 |
| 31 // Highlight elements according to selector string. This would include | 31 // Highlight elements according to selector string. This would include |
| 32 // all elements that would be affected by proposed filters. | 32 // all elements that would be affected by proposed filters. |
| 33 function highlightElements(selectorString) { | 33 function highlightElements(selectorString) { |
| 34 if(highlightedElementsSelector) | 34 if(highlightedElementsSelector) |
| 35 unhighlightElements(); | 35 unhighlightElements(); |
| 36 | 36 |
| 37 var highlightedElements = document.querySelectorAll(selectorString); | 37 var highlightedElements = document.querySelectorAll(selectorString); |
| 38 highlightedElementsSelector = selectorString; | 38 highlightedElementsSelector = selectorString; |
| 39 highlightedElementsBoxShadows = new Array(); | 39 highlightedElementsBoxShadows = new Array(); |
| 40 highlightedElementsBGColors = new Array(); | 40 highlightedElementsBGColors = new Array(); |
| 41 | 41 |
| 42 for(var i = 0; i < highlightedElements.length; i++) { | 42 for(var i = 0; i < highlightedElements.length; i++) { |
| 43 highlightedElementsBoxShadows[i] = highlightedElements[i].style.getPropertyV
alue("-webkit-box-shadow"); | 43 highlightedElementsBoxShadows[i] = highlightedElements[i].style.getPropertyV
alue("-webkit-box-shadow"); |
| 44 highlightedElementsBGColors[i] = highlightedElements[i].style.backgroundColo
r; | 44 highlightedElementsBGColors[i] = highlightedElements[i].style.backgroundColo
r; |
| 45 highlightedElements[i].style.setProperty("-webkit-box-shadow", "inset 0px 0p
x 5px #fd6738"); | 45 highlightedElements[i].style.setProperty("-webkit-box-shadow", "inset 0px 0p
x 5px #fd6738"); |
| 46 highlightedElements[i].style.backgroundColor = "#f6e1e5"; | 46 highlightedElements[i].style.backgroundColor = "#f6e1e5"; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 73 t += elt.offsetTop; | 73 t += elt.offsetTop; |
| 74 } | 74 } |
| 75 return [l, t]; | 75 return [l, t]; |
| 76 } | 76 } |
| 77 | 77 |
| 78 // Adds an overlay to an element, which is probably a Flash object | 78 // Adds an overlay to an element, which is probably a Flash object |
| 79 function addElementOverlay(elt) { | 79 function addElementOverlay(elt) { |
| 80 // If this element is enclosed in an object tag, we prefer to block that inste
ad | 80 // If this element is enclosed in an object tag, we prefer to block that inste
ad |
| 81 if(!elt) | 81 if(!elt) |
| 82 return null; | 82 return null; |
| 83 | 83 |
| 84 // If element doesn't have at least one of class name, ID or URL, give up | 84 // If element doesn't have at least one of class name, ID or URL, give up |
| 85 // because we don't know how to construct a filter rule for it | 85 // because we don't know how to construct a filter rule for it |
| 86 var url = getElementURL(elt); | 86 var url = getElementURL(elt); |
| 87 if(!elt.className && !elt.id && !url) | 87 if(!elt.className && !elt.id && !url) |
| 88 return; | 88 return; |
| 89 var thisStyle = getComputedStyle(elt, null); | 89 var thisStyle = getComputedStyle(elt, null); |
| 90 var overlay = document.createElement('div'); | 90 var overlay = document.createElement('div'); |
| 91 overlay.prisoner = elt; | 91 overlay.prisoner = elt; |
| 92 overlay.prisonerURL = url; | 92 overlay.prisonerURL = url; |
| 93 overlay.className = "__adblockplus__overlay"; | 93 overlay.className = "__adblockplus__overlay"; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 // view of what's going to be blocked | 128 // view of what's going to be blocked |
| 129 clickHideFiltersDialog.onmouseout = function() | 129 clickHideFiltersDialog.onmouseout = function() |
| 130 { | 130 { |
| 131 if (clickHideFiltersDialog) | 131 if (clickHideFiltersDialog) |
| 132 clickHideFiltersDialog.style.setProperty("opacity", "0.7"); | 132 clickHideFiltersDialog.style.setProperty("opacity", "0.7"); |
| 133 } | 133 } |
| 134 clickHideFiltersDialog.onmouseover = function() | 134 clickHideFiltersDialog.onmouseover = function() |
| 135 { | 135 { |
| 136 if (clickHideFiltersDialog) | 136 if (clickHideFiltersDialog) |
| 137 clickHideFiltersDialog.style.setProperty("opacity", "1.0"); | 137 clickHideFiltersDialog.style.setProperty("opacity", "1.0"); |
| 138 } | 138 } |
| 139 | 139 |
| 140 document.body.appendChild(clickHideFiltersDialog); | 140 document.body.appendChild(clickHideFiltersDialog); |
| 141 } | 141 } |
| 142 | 142 |
| 143 // Turn on the choose element to create filter thing | 143 // Turn on the choose element to create filter thing |
| 144 function clickHide_activate() { | 144 function clickHide_activate() { |
| 145 if(document == null) | 145 if(document == null) |
| 146 return; | 146 return; |
| 147 | 147 |
| 148 // If we are already selecting, abort now | 148 // If we are already selecting, abort now |
| 149 if (clickHide_activated || clickHideFiltersDialog) | 149 if (clickHide_activated || clickHideFiltersDialog) |
| 150 clickHide_deactivate(); | 150 clickHide_deactivate(); |
| 151 | 151 |
| 152 // Add overlays for elements with URLs so user can easily click them | 152 // Add overlays for elements with URLs so user can easily click them |
| 153 var elts = document.querySelectorAll('object,embed,img,iframe'); | 153 var elts = document.querySelectorAll('object,embed,img,iframe'); |
| 154 for(var i=0; i<elts.length; i++) | 154 for(var i=0; i<elts.length; i++) |
| 155 addElementOverlay(elts[i]); | 155 addElementOverlay(elts[i]); |
| 156 | 156 |
| 157 clickHide_activated = true; | 157 clickHide_activated = true; |
| 158 document.addEventListener("mouseover", clickHide_mouseOver, false); | 158 document.addEventListener("mouseover", clickHide_mouseOver, false); |
| 159 document.addEventListener("mouseout", clickHide_mouseOut, false); | 159 document.addEventListener("mouseout", clickHide_mouseOut, false); |
| 160 document.addEventListener("click", clickHide_mouseClick, false); | 160 document.addEventListener("click", clickHide_mouseClick, false); |
| 161 document.addEventListener("keyup", clickHide_keyUp, false); | 161 document.addEventListener("keyup", clickHide_keyUp, false); |
| 162 } | 162 } |
| 163 | 163 |
| 164 // Called when user has clicked on something and we are waiting for confirmation | 164 // Called when user has clicked on something and we are waiting for confirmation |
| 165 // on whether the user actually wants these filters | 165 // on whether the user actually wants these filters |
| 166 function clickHide_rulesPending() { | 166 function clickHide_rulesPending() { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 191 unhighlightElements(); | 191 unhighlightElements(); |
| 192 | 192 |
| 193 clickHide_activated = false; | 193 clickHide_activated = false; |
| 194 clickHide_filters = null; | 194 clickHide_filters = null; |
| 195 if(!document) | 195 if(!document) |
| 196 return; // This can happen inside a nuked iframe...I think | 196 return; // This can happen inside a nuked iframe...I think |
| 197 document.removeEventListener("mouseover", clickHide_mouseOver, false); | 197 document.removeEventListener("mouseover", clickHide_mouseOver, false); |
| 198 document.removeEventListener("mouseout", clickHide_mouseOut, false); | 198 document.removeEventListener("mouseout", clickHide_mouseOut, false); |
| 199 document.removeEventListener("click", clickHide_mouseClick, false); | 199 document.removeEventListener("click", clickHide_mouseClick, false); |
| 200 document.removeEventListener("keyup", clickHide_keyUp, false); | 200 document.removeEventListener("keyup", clickHide_keyUp, false); |
| 201 | 201 |
| 202 // Remove overlays | 202 // Remove overlays |
| 203 // For some reason iterating over the array returend by getElementsByClassName
() doesn't work | 203 // For some reason iterating over the array returend by getElementsByClassName
() doesn't work |
| 204 var elt; | 204 var elt; |
| 205 while(elt = document.querySelector('.__adblockplus__overlay')) | 205 while(elt = document.querySelector('.__adblockplus__overlay')) |
| 206 elt.parentNode.removeChild(elt); | 206 elt.parentNode.removeChild(elt); |
| 207 } | 207 } |
| 208 | 208 |
| 209 function clickHide_elementClickHandler(ev) { | 209 function clickHide_elementClickHandler(ev) { |
| 210 ev.preventDefault(); | 210 ev.preventDefault(); |
| 211 ev.stopPropagation(); | 211 ev.stopPropagation(); |
| 212 clickHide_mouseClick(ev); | 212 clickHide_mouseClick(ev); |
| 213 } | 213 } |
| 214 | 214 |
| 215 // Hovering over an element so highlight it | 215 // Hovering over an element so highlight it |
| 216 function clickHide_mouseOver(e) { | 216 function clickHide_mouseOver(e) |
| 217 if(clickHide_activated == false) | 217 { |
| 218 if (clickHide_activated == false) |
| 218 return; | 219 return; |
| 219 | 220 |
| 220 if(e.target.id || e.target.className || e.target.src) { | 221 var target = e.target; |
| 221 currentElement = e.target; | 222 while (target.parentNode && !(target.id || target.className || target.src)) |
| 222 currentElement_boxShadow = e.target.style.getPropertyValue("-webkit-box-shad
ow"); | 223 target = target.parentNode; |
| 223 currentElement_backgroundColor = e.target.style.backgroundColor; | |
| 224 e.target.style.setProperty("-webkit-box-shadow", "inset 0px 0px 5px #d6d84b"
); | |
| 225 e.target.style.backgroundColor = "#f8fa47"; | |
| 226 | 224 |
| 227 // TODO: save old context menu | 225 if (target && target instanceof HTMLElement) |
| 228 e.target.addEventListener("contextmenu", clickHide_elementClickHandler, fals
e); | 226 { |
| 227 currentElement = target; |
| 228 currentElement_boxShadow = target.style.getPropertyValue("-webkit-box-shadow
"); |
| 229 currentElement_backgroundColor = target.style.backgroundColor; |
| 230 target.style.setProperty("-webkit-box-shadow", "inset 0px 0px 5px #d6d84b"); |
| 231 target.style.backgroundColor = "#f8fa47"; |
| 232 |
| 233 target.addEventListener("contextmenu", clickHide_elementClickHandler, false)
; |
| 229 } | 234 } |
| 230 } | 235 } |
| 231 | 236 |
| 232 // No longer hovering over this element so unhighlight it | 237 // No longer hovering over this element so unhighlight it |
| 233 function clickHide_mouseOut(e) { | 238 function clickHide_mouseOut(e) |
| 234 if(!clickHide_activated || !currentElement) | 239 { |
| 240 if (!clickHide_activated || !currentElement) |
| 235 return; | 241 return; |
| 236 | 242 |
| 237 currentElement.style.setProperty("-webkit-box-shadow", currentElement_boxShado
w); | 243 currentElement.style.setProperty("-webkit-box-shadow", currentElement_boxShado
w); |
| 238 currentElement.style.backgroundColor = currentElement_backgroundColor; | 244 currentElement.style.backgroundColor = currentElement_backgroundColor; |
| 239 | 245 |
| 240 // TODO: restore old context menu | |
| 241 currentElement.removeEventListener("contextmenu", clickHide_elementClickHandle
r, false); | 246 currentElement.removeEventListener("contextmenu", clickHide_elementClickHandle
r, false); |
| 242 } | 247 } |
| 243 | 248 |
| 244 // Selects the currently hovered-over filter | 249 // Selects the currently hovered-over filter |
| 245 function clickHide_keyUp(e) { | 250 function clickHide_keyUp(e) { |
| 246 // Ctrl+Shift+E | 251 // Ctrl+Shift+E |
| 247 if(e.ctrlKey && e.shiftKey && e.keyCode == 69) | 252 if(e.ctrlKey && e.shiftKey && e.keyCode == 69) |
| 248 clickHide_mouseClick(e); | 253 clickHide_mouseClick(e); |
| 249 } | 254 } |
| 250 | 255 |
| 251 // When the user clicks, the currentElement is the one we want. | 256 // When the user clicks, the currentElement is the one we want. |
| 252 // We should have ABP rules ready for when the | 257 // We should have ABP rules ready for when the |
| 253 // popup asks for them. | 258 // popup asks for them. |
| 254 function clickHide_mouseClick(e) { | 259 function clickHide_mouseClick(e) |
| 255 if(!currentElement || !clickHide_activated) | 260 { |
| 261 if (!currentElement || !clickHide_activated) |
| 256 return; | 262 return; |
| 257 | 263 |
| 258 var elt = currentElement; | 264 var elt = currentElement; |
| 259 var url = null; | 265 var url = null; |
| 260 if(currentElement.className && currentElement.className == "__adblockplus__ove
rlay") { | 266 if (currentElement.className && currentElement.className == "__adblockplus__ov
erlay") |
| 267 { |
| 261 elt = currentElement.prisoner; | 268 elt = currentElement.prisoner; |
| 262 url = currentElement.prisonerURL; | 269 url = currentElement.prisonerURL; |
| 263 } else if(elt.src) { | 270 } |
| 271 else if (elt.src) |
| 264 url = elt.src; | 272 url = elt.src; |
| 265 } | |
| 266 | 273 |
| 267 // Only normalize when the element contains a URL (issue 328.) | 274 // Only normalize when the element contains a URL (issue 328.) |
| 268 // The URL is not always normalized, so do it here | 275 // The URL is not always normalized, so do it here |
| 269 if(url) | 276 if (url) |
| 270 url = normalizeURL(relativeToAbsoluteUrl(url)); | 277 url = normalizeURL(relativeToAbsoluteUrl(url)); |
| 271 | 278 |
| 272 // Construct filters. The popup will retrieve these. | 279 // Construct filters. The popup will retrieve these. |
| 273 // Only one ID | 280 // Only one ID |
| 274 var elementId = elt.id ? elt.id.split(' ').join('') : null; | 281 var elementId = elt.id ? elt.id.split(' ').join('') : null; |
| 275 // Can have multiple classes, and there might be extraneous whitespace | 282 // Can have multiple classes, and there might be extraneous whitespace |
| 276 var elementClasses = null; | 283 var elementClasses = null; |
| 277 if(elt.className) { | 284 if (elt.className) |
| 278 elementClasses = elt.className.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, ''
).split(' '); | 285 elementClasses = elt.className.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, ''
).split(' '); |
| 279 } | 286 |
| 280 clickHideFilters = new Array(); | 287 clickHideFilters = new Array(); |
| 281 selectorList = new Array(); | 288 selectorList = new Array(); |
| 282 if(elementId) { | 289 if (elementId) |
| 290 { |
| 283 clickHideFilters.push(document.domain + "###" + elementId); | 291 clickHideFilters.push(document.domain + "###" + elementId); |
| 284 selectorList.push("#" + elementId); | 292 selectorList.push("#" + elementId); |
| 285 } | 293 } |
| 286 if(elementClasses) { | 294 if (elementClasses) |
| 287 for(var i = 0; i < elementClasses.length; i++) { | 295 { |
| 296 for(var i = 0; i < elementClasses.length; i++) |
| 297 { |
| 288 clickHideFilters.push(document.domain + "##." + elementClasses[i]); | 298 clickHideFilters.push(document.domain + "##." + elementClasses[i]); |
| 289 selectorList.push("." + elementClasses[i]); | 299 selectorList.push("." + elementClasses[i]); |
| 290 } | 300 } |
| 291 } | 301 } |
| 292 if(url) { | 302 if (url) |
| 303 { |
| 293 clickHideFilters.push(relativeToAbsoluteUrl(url)); | 304 clickHideFilters.push(relativeToAbsoluteUrl(url)); |
| 294 selectorList.push(elt.localName + '[src="' + url + '"]'); | 305 selectorList.push(elt.localName + '[src="' + url + '"]'); |
| 295 } | 306 } |
| 296 | 307 |
| 297 // Show popup | 308 // Show popup |
| 298 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); | 309 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); |
| 299 | 310 |
| 300 // Set background color in case it got selected using context menu | 311 // Set background color in case it got selected using context menu |
| 301 if (typeof currentElement_backgroundColor == "undefined") | 312 if (typeof currentElement_backgroundColor == "undefined") |
| 302 currentElement_backgroundColor = currentElement.style.backgroundColor; | 313 currentElement_backgroundColor = currentElement.style.backgroundColor; |
| 303 | 314 |
| 304 // Highlight the unlucky elements | 315 // Highlight the unlucky elements |
| 305 // Restore currentElement's box-shadow and bgcolor so that highlightElements w
on't save those | 316 // Restore currentElement's box-shadow and bgcolor so that highlightElements w
on't save those |
| 306 currentElement.style.setProperty("-webkit-box-shadow", currentElement_boxShado
w); | 317 currentElement.style.setProperty("-webkit-box-shadow", currentElement_boxShado
w); |
| 307 currentElement.style.backgroundColor = currentElement_backgroundColor; | 318 currentElement.style.backgroundColor = currentElement_backgroundColor; |
| 308 // Highlight the elements specified by selector in yellow | 319 // Highlight the elements specified by selector in yellow |
| 309 highlightElements(selectorList.join(",")); | 320 highlightElements(selectorList.join(",")); |
| 310 // Now, actually highlight the element the user clicked on in red | 321 // Now, actually highlight the element the user clicked on in red |
| 311 currentElement.style.setProperty("-webkit-box-shadow", "inset 0px 0px 5px #fd1
708"); | 322 currentElement.style.setProperty("-webkit-box-shadow", "inset 0px 0px 5px #fd1
708"); |
| 312 currentElement.style.backgroundColor = "#f6a1b5"; | 323 currentElement.style.backgroundColor = "#f6a1b5"; |
| 324 |
| 325 // Make sure the browser doesn't handle this click |
| 326 e.preventDefault(); |
| 327 e.stopPropagation(); |
| 313 } | 328 } |
| 314 | 329 |
| 315 // Extracts source URL from an IMG, OBJECT, EMBED, or IFRAME | 330 // Extracts source URL from an IMG, OBJECT, EMBED, or IFRAME |
| 316 function getElementURL(elt) { | 331 function getElementURL(elt) { |
| 317 // Check children of object nodes for "param" nodes with name="movie" that spe
cify a URL | 332 // Check children of object nodes for "param" nodes with name="movie" that spe
cify a URL |
| 318 // in value attribute | 333 // in value attribute |
| 319 var url; | 334 var url; |
| 320 if(elt.localName.toUpperCase() == "OBJECT" && !(url = elt.getAttribute("data")
)) { | 335 if(elt.localName.toUpperCase() == "OBJECT" && !(url = elt.getAttribute("data")
)) { |
| 321 // No data attribute, look in PARAM child tags for a URL for the swf file | 336 // No data attribute, look in PARAM child tags for a URL for the swf file |
| 322 var params = elt.querySelectorAll("param[name=\"movie\"]"); | 337 var params = elt.querySelectorAll("param[name=\"movie\"]"); |
| 323 // This OBJECT could contain an EMBED we already nuked, in which case there'
s no URL | 338 // This OBJECT could contain an EMBED we already nuked, in which case there'
s no URL |
| 324 if(params[0]) | 339 if(params[0]) |
| 325 url = params[0].getAttribute("value"); | 340 url = params[0].getAttribute("value"); |
| 326 else { | 341 else { |
| 327 params = elt.querySelectorAll("param[name=\"src\"]"); | 342 params = elt.querySelectorAll("param[name=\"src\"]"); |
| 328 if(params[0]) | 343 if(params[0]) |
| 329 url = params[0].getAttribute("value"); | 344 url = params[0].getAttribute("value"); |
| 330 } | 345 } |
| 331 } else if(!url) { | 346 } else if(!url) { |
| 332 url = elt.getAttribute("src") || elt.getAttribute("href"); | 347 url = elt.getAttribute("src") || elt.getAttribute("href"); |
| 333 } | 348 } |
| 334 return url; | 349 return url; |
| 335 } | 350 } |
| 336 | 351 |
| 337 // Converts relative to absolute URL | 352 // Converts relative to absolute URL |
| 338 // e.g.: foo.swf on http://example.com/whatever/bar.html | 353 // e.g.: foo.swf on http://example.com/whatever/bar.html |
| 339 // -> http://example.com/whatever/foo.swf | 354 // -> http://example.com/whatever/foo.swf |
| 340 function relativeToAbsoluteUrl(url) | 355 function relativeToAbsoluteUrl(url) |
| 341 { | 356 { |
| 342 // If URL is already absolute, don't mess with it | 357 // If URL is already absolute, don't mess with it |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 url = url.replace(/^\s+/, "").replace(/\s+$/, ""); | 485 url = url.replace(/^\s+/, "").replace(/\s+$/, ""); |
| 471 if (!/^(https?|ftp):/.test(url)) | 486 if (!/^(https?|ftp):/.test(url)) |
| 472 return; | 487 return; |
| 473 | 488 |
| 474 ext.backgroundPage.sendMessage({ | 489 ext.backgroundPage.sendMessage({ |
| 475 type: "add-subscription", | 490 type: "add-subscription", |
| 476 title: title, | 491 title: title, |
| 477 url: url | 492 url: url |
| 478 }); | 493 }); |
| 479 }, true); | 494 }, true); |
| 480 | 495 |
| 481 ext.onMessage.addListener(function(msg, sender, sendResponse) | 496 ext.onMessage.addListener(function(msg, sender, sendResponse) |
| 482 { | 497 { |
| 483 switch (msg.type) | 498 switch (msg.type) |
| 484 { | 499 { |
| 485 case "get-clickhide-state": | 500 case "get-clickhide-state": |
| 486 sendResponse({active: clickHide_activated}); | 501 sendResponse({active: clickHide_activated}); |
| 487 break; | 502 break; |
| 488 case "clickhide-activate": | 503 case "clickhide-activate": |
| 489 clickHide_activate(); | 504 clickHide_activate(); |
| 490 break; | 505 break; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 | 578 |
| 564 clickHide_deactivate(); | 579 clickHide_deactivate(); |
| 565 } | 580 } |
| 566 break; | 581 break; |
| 567 default: | 582 default: |
| 568 sendResponse({}); | 583 sendResponse({}); |
| 569 break; | 584 break; |
| 570 } | 585 } |
| 571 }); | 586 }); |
| 572 } | 587 } |
| OLD | NEW |