Index: include.postload.js |
=================================================================== |
--- a/include.postload.js |
+++ b/include.postload.js |
@@ -23,7 +23,6 @@ |
var clickHideFiltersDialog = null; |
var lastRightClickEvent = null; |
var lastRightClickEventValid = false; |
-var lastMouseOverEvent = null; |
function highlightElement(element, shadowColor, backgroundColor) |
{ |
@@ -199,6 +198,24 @@ |
return getURLsFromAttributes(element); |
} |
+function isBlockable(element) |
+{ |
+ if (element.id) |
+ return true; |
+ if (element.classList.length > 0) |
+ return true; |
+ if (getURLsFromElement(element).length > 0) |
+ return true; |
+ |
+ // We only generate filters based on the "style" attribute, |
+ // if this is the only way we can generate a filter, and |
+ // only if there are at least two CSS properties defined. |
+ if (/:.+:/.test(element.getAttribute("style"))) |
+ return true; |
+ |
+ return false; |
+} |
+ |
// Adds an overlay to an element, which is probably a Flash object |
function addElementOverlay(elt) { |
var zIndex = "auto"; |
@@ -295,17 +312,13 @@ |
// Add overlays for blockable elements that don't emit mouse events, |
// so that they can still be selected. |
- [].forEach.call( |
- document.querySelectorAll('object,embed,iframe,frame'), |
- function(element) |
- { |
- getFiltersForElement(element, function(filters) |
- { |
- if (filters.length > 0) |
- addElementOverlay(element); |
- }); |
- } |
- ); |
+ var elts = document.querySelectorAll('object,embed,iframe,frame'); |
+ for(var i=0; i<elts.length; i++) |
+ { |
+ var element = elts[i]; |
+ if (isBlockable(element)) |
+ addElementOverlay(element); |
+ } |
clickHide_activated = true; |
document.addEventListener("mousedown", clickHide_stopPropagation, true); |
@@ -388,94 +401,63 @@ |
clickHide_mouseClick(e); |
} |
-function getBlockableElementOrAncestor(element, callback) |
+function getBlockableElementOrAncestor(element) |
{ |
- // We assume that the user doesn't want to block the whole page. |
- // So we never consider the <html> or <body> element. |
while (element && element != document.documentElement |
&& element != document.body) |
{ |
- // We can't handle non-HTML (like SVG) elements, as well as |
- // <area> elements (see below). So fall back to the parent element. |
- if (!(element instanceof HTMLElement) || element.localName == "area") |
- element = element.parentElement; |
+ if (element instanceof HTMLElement && element.localName != "area") |
+ { |
+ // Handle <area> and their <map> elements specially, |
+ // blocking the image they are associated with |
+ if (element.localName == "map") |
+ { |
+ var images = document.querySelectorAll("img[usemap]"); |
+ for (var i = 0; i < images.length; i++) |
+ { |
+ var image = images[i]; |
+ var usemap = image.getAttribute("usemap"); |
+ var index = usemap.indexOf("#"); |
- // If image maps are used mouse events occur for the <area> element. |
- // But we have to block the image associated with the <map> element. |
- else if (element.localName == "map") |
- { |
- var images = document.querySelectorAll("img[usemap]"); |
- var image = null; |
+ if (index != -1 && usemap.substr(index + 1) == element.name) |
+ return getBlockableElementOrAncestor(image); |
+ } |
- for (var i = 0; i < images.length; i++) |
- { |
- var usemap = image.getAttribute("usemap"); |
- var index = usemap.indexOf("#"); |
- |
- if (index != -1 && usemap.substr(index + 1) == element.name) |
- { |
- image = images[i]; |
- break; |
- } |
+ return null; |
} |
- element = image; |
+ if (isBlockable(element)) |
+ return element; |
} |
- // Finally, if none of the above is true, check whether we can generate |
- // any filters for this element. Otherwise fall back to its parent element. |
- else |
- { |
- getFiltersForElement(element, function(filters) |
- { |
- if (filters.length > 0) |
- callback(element); |
- else |
- getBlockableElementOrAncestor(element.parentElement, callback); |
- }); |
- |
- return; |
- } |
+ element = element.parentElement; |
} |
- // We reached the document root without finding a blockable element. |
- callback(null); |
+ return null; |
} |
// Hovering over an element so highlight it |
function clickHide_mouseOver(e) |
{ |
- lastMouseOverEvent = e; |
+ if (clickHide_activated == false) |
+ return; |
- getBlockableElementOrAncestor(e.target, function(element) |
+ var target = getBlockableElementOrAncestor(e.target); |
+ |
+ if (target) |
{ |
- if (e == lastMouseOverEvent) |
- { |
- lastMouseOverEvent = null; |
+ currentElement = target; |
- if (clickHide_activated) |
- { |
- if (currentElement) |
- unhighlightElement(currentElement); |
- |
- if (element) |
- { |
- highlightElement(element, "#d6d84b", "#f8fa47"); |
- element.addEventListener("contextmenu", clickHide_elementClickHandler, true); |
- } |
- |
- currentElement = element; |
- } |
- } |
- }); |
- |
+ highlightElement(target, "#d6d84b", "#f8fa47"); |
+ target.addEventListener("contextmenu", clickHide_elementClickHandler, true); |
+ } |
e.stopPropagation(); |
} |
// No longer hovering over this element so unhighlight it |
function clickHide_mouseOut(e) |
{ |
- if (!clickHide_activated || currentElement != e.target) |
+ if (!clickHide_activated || !currentElement) |
return; |
unhighlightElement(currentElement); |
@@ -514,7 +496,6 @@ |
style: element.getAttribute("style"), |
classes: [].slice.call(element.classList), |
urls: getURLsFromElement(element), |
- mediatype: typeMap[element.localName], |
baseURL: document.location.href |
}, |
function(response) |
@@ -693,12 +674,9 @@ |
case "clickhide-new-filter": |
if(lastRightClickEvent) |
{ |
- getBlockableElementOrAncestor(lastRightClickEvent.target, function(element) |
- { |
- clickHide_activated = true; |
- currentElement = element; |
- clickHide_mouseClick(lastRightClickEvent); |
- }); |
+ clickHide_activated = true; |
+ currentElement = getBlockableElementOrAncestor(lastRightClickEvent.target); |
+ clickHide_mouseClick(lastRightClickEvent); |
} |
break; |
case "clickhide-init": |