Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: include.postload.js

Issue 4998212691689472: Some click-hide improvements (Closed)
Patch Set: Also fixed key handler Created Dec. 18, 2013, 10:58 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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":
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld