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

Side by Side Diff: include.postload.js

Issue 4998212691689472: Some click-hide improvements (Closed)
Patch Set: Created Dec. 18, 2013, 10:13 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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)
Thomas Greiner 2013/12/18 10:32:54 We don't want to hide the <body> element which can
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld