Index: include.postload.js |
=================================================================== |
--- a/include.postload.js |
+++ b/include.postload.js |
@@ -28,17 +28,17 @@ var highlightedElementsBGColors = null; |
var clickHideFiltersDialog = null; |
var lastRightClickEvent = null; |
// Highlight elements according to selector string. This would include |
// all elements that would be affected by proposed filters. |
function highlightElements(selectorString) { |
if(highlightedElementsSelector) |
unhighlightElements(); |
- |
+ |
var highlightedElements = document.querySelectorAll(selectorString); |
highlightedElementsSelector = selectorString; |
highlightedElementsBoxShadows = new Array(); |
highlightedElementsBGColors = new Array(); |
for(var i = 0; i < highlightedElements.length; i++) { |
highlightedElementsBoxShadows[i] = highlightedElements[i].style.getPropertyValue("-webkit-box-shadow"); |
highlightedElementsBGColors[i] = highlightedElements[i].style.backgroundColor; |
@@ -75,17 +75,17 @@ function getAbsolutePosition(elt) { |
return [l, t]; |
} |
// Adds an overlay to an element, which is probably a Flash object |
function addElementOverlay(elt) { |
// If this element is enclosed in an object tag, we prefer to block that instead |
if(!elt) |
return null; |
- |
+ |
// If element doesn't have at least one of class name, ID or URL, give up |
// because we don't know how to construct a filter rule for it |
var url = getElementURL(elt); |
if(!elt.className && !elt.id && !url) |
return; |
var thisStyle = getComputedStyle(elt, null); |
var overlay = document.createElement('div'); |
overlay.prisoner = elt; |
@@ -130,50 +130,50 @@ function clickHide_showDialog(left, top, |
{ |
if (clickHideFiltersDialog) |
clickHideFiltersDialog.style.setProperty("opacity", "0.7"); |
} |
clickHideFiltersDialog.onmouseover = function() |
{ |
if (clickHideFiltersDialog) |
clickHideFiltersDialog.style.setProperty("opacity", "1.0"); |
- } |
- |
+ } |
+ |
document.body.appendChild(clickHideFiltersDialog); |
} |
// Turn on the choose element to create filter thing |
function clickHide_activate() { |
if(document == null) |
return; |
- |
+ |
// If we are already selecting, abort now |
if (clickHide_activated || clickHideFiltersDialog) |
clickHide_deactivate(); |
// Add overlays for elements with URLs so user can easily click them |
var elts = document.querySelectorAll('object,embed,img,iframe'); |
for(var i=0; i<elts.length; i++) |
addElementOverlay(elts[i]); |
- |
+ |
clickHide_activated = true; |
document.addEventListener("mouseover", clickHide_mouseOver, false); |
document.addEventListener("mouseout", clickHide_mouseOut, false); |
document.addEventListener("click", clickHide_mouseClick, false); |
- document.addEventListener("keyup", clickHide_keyUp, false); |
+ document.addEventListener("keydown", clickHide_keyDown, false); |
} |
// Called when user has clicked on something and we are waiting for confirmation |
// on whether the user actually wants these filters |
function clickHide_rulesPending() { |
clickHide_activated = false; |
document.removeEventListener("mouseover", clickHide_mouseOver, false); |
document.removeEventListener("mouseout", clickHide_mouseOut, false); |
document.removeEventListener("click", clickHide_mouseClick, false); |
- document.removeEventListener("keyup", clickHide_keyUp, false); |
+ document.removeEventListener("keydown", clickHide_keyDown, false); |
} |
// Turn off click-to-hide |
function clickHide_deactivate() |
{ |
if (clickHideFiltersDialog) |
{ |
document.body.removeChild(clickHideFiltersDialog); |
@@ -192,129 +192,152 @@ function clickHide_deactivate() |
clickHide_activated = false; |
clickHide_filters = null; |
if(!document) |
return; // This can happen inside a nuked iframe...I think |
document.removeEventListener("mouseover", clickHide_mouseOver, false); |
document.removeEventListener("mouseout", clickHide_mouseOut, false); |
document.removeEventListener("click", clickHide_mouseClick, false); |
- document.removeEventListener("keyup", clickHide_keyUp, false); |
- |
+ document.removeEventListener("keydown", clickHide_keyDown, false); |
+ |
// Remove overlays |
// For some reason iterating over the array returend by getElementsByClassName() doesn't work |
var elt; |
while(elt = document.querySelector('.__adblockplus__overlay')) |
elt.parentNode.removeChild(elt); |
} |
function clickHide_elementClickHandler(ev) { |
ev.preventDefault(); |
ev.stopPropagation(); |
clickHide_mouseClick(ev); |
} |
// Hovering over an element so highlight it |
-function clickHide_mouseOver(e) { |
- if(clickHide_activated == false) |
+function clickHide_mouseOver(e) |
+{ |
+ if (clickHide_activated == false) |
return; |
- if(e.target.id || e.target.className || e.target.src) { |
- currentElement = e.target; |
- currentElement_boxShadow = e.target.style.getPropertyValue("-webkit-box-shadow"); |
- currentElement_backgroundColor = e.target.style.backgroundColor; |
- e.target.style.setProperty("-webkit-box-shadow", "inset 0px 0px 5px #d6d84b"); |
- e.target.style.backgroundColor = "#f8fa47"; |
+ var target = e.target; |
+ while (target.parentNode && !(target.id || target.className || target.src)) |
+ target = target.parentNode; |
+ if (target == document.documentElement || target == document.body) |
+ target = null; |
- // TODO: save old context menu |
- e.target.addEventListener("contextmenu", clickHide_elementClickHandler, false); |
+ if (target && target instanceof HTMLElement) |
+ { |
+ currentElement = target; |
+ currentElement_boxShadow = target.style.getPropertyValue("-webkit-box-shadow"); |
+ currentElement_backgroundColor = target.style.backgroundColor; |
+ target.style.setProperty("-webkit-box-shadow", "inset 0px 0px 5px #d6d84b"); |
+ target.style.backgroundColor = "#f8fa47"; |
+ |
+ target.addEventListener("contextmenu", clickHide_elementClickHandler, false); |
} |
} |
// No longer hovering over this element so unhighlight it |
-function clickHide_mouseOut(e) { |
- if(!clickHide_activated || !currentElement) |
+function clickHide_mouseOut(e) |
+{ |
+ if (!clickHide_activated || !currentElement) |
return; |
- |
+ |
currentElement.style.setProperty("-webkit-box-shadow", currentElement_boxShadow); |
currentElement.style.backgroundColor = currentElement_backgroundColor; |
- |
- // TODO: restore old context menu |
+ |
currentElement.removeEventListener("contextmenu", clickHide_elementClickHandler, false); |
} |
-// Selects the currently hovered-over filter |
-function clickHide_keyUp(e) { |
- // Ctrl+Shift+E |
- if(e.ctrlKey && e.shiftKey && e.keyCode == 69) |
- clickHide_mouseClick(e); |
+// Selects the currently hovered-over filter or cancels selection |
+function clickHide_keyDown(e) |
+{ |
+ if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 13 /*DOM_VK_ENTER*/) |
Thomas Greiner
2013/12/18 11:17:12
Different sources mention different codes. Does it
Wladimir Palant
2013/12/18 11:39:57
Sure. The comment is wrong however, I meant VK_RET
|
+ clickHide_mouseClick(e); |
+ else if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 27 /*DOM_VK_ESCAPE*/) |
+ { |
+ clickHide_deactivate(); |
+ e.preventDefault(); |
+ e.stopPropagation(); |
+ } |
} |
// When the user clicks, the currentElement is the one we want. |
// We should have ABP rules ready for when the |
// popup asks for them. |
-function clickHide_mouseClick(e) { |
- if(!currentElement || !clickHide_activated) |
+function clickHide_mouseClick(e) |
+{ |
+ if (!currentElement || !clickHide_activated) |
return; |
- |
+ |
var elt = currentElement; |
var url = null; |
- if(currentElement.className && currentElement.className == "__adblockplus__overlay") { |
+ if (currentElement.className && currentElement.className == "__adblockplus__overlay") |
+ { |
elt = currentElement.prisoner; |
url = currentElement.prisonerURL; |
- } else if(elt.src) { |
+ } |
+ else if (elt.src) |
url = elt.src; |
- } |
// Only normalize when the element contains a URL (issue 328.) |
// The URL is not always normalized, so do it here |
- if(url) |
+ if (url) |
url = normalizeURL(relativeToAbsoluteUrl(url)); |
- |
+ |
// Construct filters. The popup will retrieve these. |
// Only one ID |
var elementId = elt.id ? elt.id.split(' ').join('') : null; |
// Can have multiple classes, and there might be extraneous whitespace |
var elementClasses = null; |
- if(elt.className) { |
+ if (elt.className) |
elementClasses = elt.className.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '').split(' '); |
- } |
+ |
clickHideFilters = new Array(); |
selectorList = new Array(); |
- if(elementId) { |
+ if (elementId) |
+ { |
clickHideFilters.push(document.domain + "###" + elementId); |
selectorList.push("#" + elementId); |
} |
- if(elementClasses) { |
- for(var i = 0; i < elementClasses.length; i++) { |
+ if (elementClasses) |
+ { |
+ for(var i = 0; i < elementClasses.length; i++) |
+ { |
clickHideFilters.push(document.domain + "##." + elementClasses[i]); |
selectorList.push("." + elementClasses[i]); |
} |
} |
- if(url) { |
+ if (url) |
+ { |
clickHideFilters.push(relativeToAbsoluteUrl(url)); |
selectorList.push(elt.localName + '[src="' + url + '"]'); |
} |
- |
+ |
// Show popup |
clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); |
// Set background color in case it got selected using context menu |
if (typeof currentElement_backgroundColor == "undefined") |
currentElement_backgroundColor = currentElement.style.backgroundColor; |
// Highlight the unlucky elements |
// Restore currentElement's box-shadow and bgcolor so that highlightElements won't save those |
currentElement.style.setProperty("-webkit-box-shadow", currentElement_boxShadow); |
currentElement.style.backgroundColor = currentElement_backgroundColor; |
// Highlight the elements specified by selector in yellow |
highlightElements(selectorList.join(",")); |
// Now, actually highlight the element the user clicked on in red |
currentElement.style.setProperty("-webkit-box-shadow", "inset 0px 0px 5px #fd1708"); |
currentElement.style.backgroundColor = "#f6a1b5"; |
+ |
+ // Make sure the browser doesn't handle this click |
+ e.preventDefault(); |
+ e.stopPropagation(); |
} |
// Extracts source URL from an IMG, OBJECT, EMBED, or IFRAME |
function getElementURL(elt) { |
// Check children of object nodes for "param" nodes with name="movie" that specify a URL |
// in value attribute |
var url; |
if(elt.localName.toUpperCase() == "OBJECT" && !(url = elt.getAttribute("data"))) { |
@@ -324,17 +347,17 @@ function getElementURL(elt) { |
if(params[0]) |
url = params[0].getAttribute("value"); |
else { |
params = elt.querySelectorAll("param[name=\"src\"]"); |
if(params[0]) |
url = params[0].getAttribute("value"); |
} |
} else if(!url) { |
- url = elt.getAttribute("src") || elt.getAttribute("href"); |
+ url = elt.getAttribute("src") || elt.getAttribute("href"); |
} |
return url; |
} |
// Converts relative to absolute URL |
// e.g.: foo.swf on http://example.com/whatever/bar.html |
// -> http://example.com/whatever/foo.swf |
function relativeToAbsoluteUrl(url) |
@@ -472,17 +495,17 @@ if (document.documentElement instanceof |
return; |
ext.backgroundPage.sendMessage({ |
type: "add-subscription", |
title: title, |
url: url |
}); |
}, true); |
- |
+ |
ext.onMessage.addListener(function(msg, sender, sendResponse) |
{ |
switch (msg.type) |
{ |
case "get-clickhide-state": |
sendResponse({active: clickHide_activated}); |
break; |
case "clickhide-activate": |