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

Delta Between Two Patch Sets: include.postload.js

Issue 6174977720057856: Issue 1853 - Moved filter generation into background page (Closed)
Left Patch Set: Created Jan. 25, 2015, 1:21 p.m.
Right Patch Set: Rebased and fixed documentation mistakenly indicating arguments as optional Created Feb. 28, 2015, 5:59 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « background.js ('k') | include.preload.js » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 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 14 matching lines...) Expand all
25 var lastRightClickEventValid = false; 25 var lastRightClickEventValid = false;
26 26
27 function highlightElement(element, shadowColor, backgroundColor) 27 function highlightElement(element, shadowColor, backgroundColor)
28 { 28 {
29 unhighlightElement(element); 29 unhighlightElement(element);
30 30
31 var highlightWithOverlay = function() 31 var highlightWithOverlay = function()
32 { 32 {
33 var overlay = addElementOverlay(element); 33 var overlay = addElementOverlay(element);
34 34
35 // If the element isn't displayed no overlay will be added.
36 // Moreover, we don't need to highlight anything then.
37 if (!overlay)
38 return;
39
35 highlightElement(overlay, shadowColor, backgroundColor); 40 highlightElement(overlay, shadowColor, backgroundColor);
36 overlay.style.pointerEvents = "none"; 41 overlay.style.pointerEvents = "none";
37 42
38 element._unhighlight = function() 43 element._unhighlight = function()
39 { 44 {
40 overlay.parentNode.removeChild(overlay); 45 overlay.parentNode.removeChild(overlay);
41 }; 46 };
42 }; 47 };
43 48
44 var highlightWithStyleAttribute = function() 49 var highlightWithStyleAttribute = function()
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 209
205 // We only generate filters based on the "style" attribute, 210 // We only generate filters based on the "style" attribute,
206 // if this is the only way we can generate a filter, and 211 // if this is the only way we can generate a filter, and
207 // only if there are at least two CSS properties defined. 212 // only if there are at least two CSS properties defined.
208 if (/:.+:/.test(element.getAttribute("style"))) 213 if (/:.+:/.test(element.getAttribute("style")))
209 return true; 214 return true;
210 215
211 return false; 216 return false;
212 } 217 }
213 218
214 // Gets the absolute position of an element by walking up the DOM tree,
215 // adding up offsets.
216 // I hope there's a better way because it just seems absolutely stupid
217 // that the DOM wouldn't have a direct way to get this, given that it
218 // has hundreds and hundreds of other methods that do random junk.
219 function getAbsolutePosition(elt) {
220 var l = 0;
221 var t = 0;
222 for(; elt; elt = elt.offsetParent) {
223 l += elt.offsetLeft;
224 t += elt.offsetTop;
225 }
226 return [l, t];
227 }
228
229 // Adds an overlay to an element, which is probably a Flash object 219 // Adds an overlay to an element, which is probably a Flash object
230 function addElementOverlay(elt) { 220 function addElementOverlay(elt) {
231 var zIndex = "auto"; 221 var zIndex = "auto";
232 var position = "absolute"; 222 var position = "absolute";
233 223
234 for (var e = elt; e; e = e.parentElement) 224 for (var e = elt; e; e = e.parentElement)
235 { 225 {
236 var style = getComputedStyle(e); 226 var style = getComputedStyle(e);
237 227
238 // If the element isn't rendered (since its or one of its ancestor's 228 // If the element isn't rendered (since its or one of its ancestor's
239 // "display" property is "none"), the overlay wouldn't match the element. 229 // "display" property is "none"), the overlay wouldn't match the element.
240 if (style.display == "none") 230 if (style.display == "none")
241 return null; 231 return null;
242 232
243 // If the element or one of its ancestors uses fixed postioning, the overlay 233 // If the element or one of its ancestors uses fixed postioning, the overlay
244 // has to use fixed postioning too. Otherwise it might not match the element . 234 // has to use fixed postioning too. Otherwise it might not match the element .
245 if (style.position == "fixed") 235 if (style.position == "fixed")
246 position = "fixed"; 236 position = "fixed";
247 237
248 // Determine the effective z-index, which is the highest z-index used 238 // Determine the effective z-index, which is the highest z-index used
249 // by the element and its offset ancestors. When using a lower z-index 239 // by the element and its offset ancestors, and increase it by one.
250 // the element would cover the overlay. When using a higher z-index the 240 // When using a lower z-index the element would cover the overlay.
251 // overlay might also cover other elements. 241 // When using a higher z-index the overlay might also cover other elements.
252 if (style.position != "static" && style.zIndex != "auto") 242 if (style.position != "static" && style.zIndex != "auto")
253 { 243 {
254 if (zIndex == "auto") 244 var curZIndex = parseInt(style.zIndex, 10) + 1;
255 zIndex = style.zIndex; 245
256 else 246 if (zIndex == "auto" || curZIndex > zIndex)
257 zIndex = Math.max(zIndex, style.zIndex); 247 zIndex = curZIndex;
258 } 248 }
259 } 249 }
260 250
261 var overlay = document.createElement('div'); 251 var overlay = document.createElement('div');
262 overlay.prisoner = elt; 252 overlay.prisoner = elt;
263 overlay.className = "__adblockplus__overlay"; 253 overlay.className = "__adblockplus__overlay";
264 overlay.setAttribute('style', 'opacity:0.4; display:inline-box; overflow:hidde n; box-sizing:border-box;'); 254 overlay.setAttribute('style', 'opacity:0.4; display:inline-box; overflow:hidde n; box-sizing:border-box;');
265 var pos = getAbsolutePosition(elt); 255 var rect = elt.getBoundingClientRect();
266 overlay.style.width = elt.offsetWidth + "px"; 256 overlay.style.width = rect.width + "px";
267 overlay.style.height = elt.offsetHeight + "px"; 257 overlay.style.height = rect.height + "px";
268 overlay.style.left = pos[0] + "px"; 258 overlay.style.left = (rect.left + window.scrollX) + "px";
269 overlay.style.top = pos[1] + "px"; 259 overlay.style.top = (rect.top + window.scrollY) + "px";
270 overlay.style.position = position; 260 overlay.style.position = position;
271 overlay.style.zIndex = zIndex; 261 overlay.style.zIndex = zIndex;
272 262
273 // elt.parentNode.appendChild(overlay, elt); 263 // elt.parentNode.appendChild(overlay, elt);
274 document.body.appendChild(overlay); 264 document.documentElement.appendChild(overlay);
275 return overlay; 265 return overlay;
276 } 266 }
277 267
278 // Show dialog asking user whether she wants to add the proposed filters derived 268 // Show dialog asking user whether she wants to add the proposed filters derived
279 // from selected page element 269 // from selected page element
280 function clickHide_showDialog(left, top, filters) 270 function clickHide_showDialog(left, top, filters)
281 { 271 {
282 // If we are already selecting, abort now 272 // If we are already selecting, abort now
283 if (clickHide_activated || clickHideFiltersDialog) 273 if (clickHide_activated || clickHideFiltersDialog)
284 clickHide_deactivate(true); 274 clickHide_deactivate(true);
(...skipping 16 matching lines...) Expand all
301 { 291 {
302 if (clickHideFiltersDialog) 292 if (clickHideFiltersDialog)
303 clickHideFiltersDialog.style.setProperty("opacity", "0.7"); 293 clickHideFiltersDialog.style.setProperty("opacity", "0.7");
304 }; 294 };
305 clickHideFiltersDialog.onmouseover = function() 295 clickHideFiltersDialog.onmouseover = function()
306 { 296 {
307 if (clickHideFiltersDialog) 297 if (clickHideFiltersDialog)
308 clickHideFiltersDialog.style.setProperty("opacity", "1.0"); 298 clickHideFiltersDialog.style.setProperty("opacity", "1.0");
309 }; 299 };
310 300
311 document.body.appendChild(clickHideFiltersDialog); 301 document.documentElement.appendChild(clickHideFiltersDialog);
312 } 302 }
313 303
314 // Turn on the choose element to create filter thing 304 // Turn on the choose element to create filter thing
315 function clickHide_activate() { 305 function clickHide_activate() {
316 if(document == null) 306 if(document == null)
317 return; 307 return;
318 308
319 // If we are already selecting, abort now 309 // If we are already selecting, abort now
320 if (clickHide_activated || clickHideFiltersDialog) 310 if (clickHide_activated || clickHideFiltersDialog)
321 clickHide_deactivate(); 311 clickHide_deactivate();
322 312
323 // Add overlays for blockable elements that don't emit mouse events that they can still be selected 313 // Add overlays for blockable elements that don't emit mouse events,
324 var elts = document.querySelectorAll('object,embed,iframe'); 314 // so that they can still be selected.
315 var elts = document.querySelectorAll('object,embed,iframe,frame');
325 for(var i=0; i<elts.length; i++) 316 for(var i=0; i<elts.length; i++)
326 { 317 {
327 var element = elts[i]; 318 var element = elts[i];
328 if (isBlockable(element)) 319 if (isBlockable(element))
329 addElementOverlay(element); 320 addElementOverlay(element);
330 } 321 }
331 322
332 clickHide_activated = true; 323 clickHide_activated = true;
324 document.addEventListener("mousedown", clickHide_stopPropagation, true);
325 document.addEventListener("mouseup", clickHide_stopPropagation, true);
326 document.addEventListener("mouseenter", clickHide_stopPropagation, true);
327 document.addEventListener("mouseleave", clickHide_stopPropagation, true);
333 document.addEventListener("mouseover", clickHide_mouseOver, true); 328 document.addEventListener("mouseover", clickHide_mouseOver, true);
334 document.addEventListener("mouseout", clickHide_mouseOut, true); 329 document.addEventListener("mouseout", clickHide_mouseOut, true);
335 document.addEventListener("click", clickHide_mouseClick, true); 330 document.addEventListener("click", clickHide_mouseClick, true);
336 document.addEventListener("keydown", clickHide_keyDown, true); 331 document.addEventListener("keydown", clickHide_keyDown, true);
332
333 ext.onExtensionUnloaded.addListener(clickHide_deactivate);
337 } 334 }
338 335
339 // Called when user has clicked on something and we are waiting for confirmation 336 // Called when user has clicked on something and we are waiting for confirmation
340 // on whether the user actually wants these filters 337 // on whether the user actually wants these filters
341 function clickHide_rulesPending() { 338 function clickHide_rulesPending() {
342 clickHide_activated = false; 339 clickHide_activated = false;
340 document.removeEventListener("mousedown", clickHide_stopPropagation, true);
341 document.removeEventListener("mouseup", clickHide_stopPropagation, true);
342 document.removeEventListener("mouseenter", clickHide_stopPropagation, true);
343 document.removeEventListener("mouseleave", clickHide_stopPropagation, true);
343 document.removeEventListener("mouseover", clickHide_mouseOver, true); 344 document.removeEventListener("mouseover", clickHide_mouseOver, true);
344 document.removeEventListener("mouseout", clickHide_mouseOut, true); 345 document.removeEventListener("mouseout", clickHide_mouseOut, true);
345 document.removeEventListener("click", clickHide_mouseClick, true); 346 document.removeEventListener("click", clickHide_mouseClick, true);
346 document.removeEventListener("keydown", clickHide_keyDown, true); 347 document.removeEventListener("keydown", clickHide_keyDown, true);
347 } 348 }
348 349
349 // Turn off click-to-hide 350 // Turn off click-to-hide
350 function clickHide_deactivate(keepOverlays) 351 function clickHide_deactivate(keepOverlays)
351 { 352 {
352 if (clickHideFiltersDialog) 353 if (clickHideFiltersDialog)
353 { 354 {
354 document.body.removeChild(clickHideFiltersDialog); 355 document.documentElement.removeChild(clickHideFiltersDialog);
355 clickHideFiltersDialog = null; 356 clickHideFiltersDialog = null;
356 } 357 }
357 358
358 clickHide_activated = false; 359 clickHide_activated = false;
359 clickHide_filters = null; 360 clickHide_filters = null;
360 if(!document) 361 if(!document)
361 return; // This can happen inside a nuked iframe...I think 362 return; // This can happen inside a nuked iframe...I think
363
364 document.removeEventListener("mousedown", clickHide_stopPropagation, true);
365 document.removeEventListener("mouseup", clickHide_stopPropagation, true);
366 document.removeEventListener("mouseenter", clickHide_stopPropagation, true);
367 document.removeEventListener("mouseleave", clickHide_stopPropagation, true);
362 document.removeEventListener("mouseover", clickHide_mouseOver, true); 368 document.removeEventListener("mouseover", clickHide_mouseOver, true);
363 document.removeEventListener("mouseout", clickHide_mouseOut, true); 369 document.removeEventListener("mouseout", clickHide_mouseOut, true);
364 document.removeEventListener("click", clickHide_mouseClick, true); 370 document.removeEventListener("click", clickHide_mouseClick, true);
365 document.removeEventListener("keydown", clickHide_keyDown, true); 371 document.removeEventListener("keydown", clickHide_keyDown, true);
366 372
367 if (!keepOverlays) 373 if (keepOverlays !== true)
368 { 374 {
369 lastRightClickEvent = null; 375 lastRightClickEvent = null;
370 376
371 if (currentElement) { 377 if (currentElement) {
372 currentElement.removeEventListener("contextmenu", clickHide_elementClickH andler, true); 378 currentElement.removeEventListener("contextmenu", clickHide_elementClickH andler, true);
373 unhighlightElements(); 379 unhighlightElements();
374 unhighlightElement(currentElement); 380 unhighlightElement(currentElement);
375 currentElement = null; 381 currentElement = null;
376 } 382 }
377 unhighlightElements(); 383 unhighlightElements();
378 384
379 var overlays = document.getElementsByClassName("__adblockplus__overlay"); 385 var overlays = document.getElementsByClassName("__adblockplus__overlay");
380 while (overlays.length > 0) 386 while (overlays.length > 0)
381 overlays[0].parentNode.removeChild(overlays[0]); 387 overlays[0].parentNode.removeChild(overlays[0]);
382 } 388
383 } 389 ext.onExtensionUnloaded.removeListener(clickHide_deactivate);
384 390 }
385 function clickHide_elementClickHandler(ev) { 391 }
386 ev.preventDefault(); 392
387 ev.stopPropagation(); 393 function clickHide_stopPropagation(e)
388 clickHide_mouseClick(ev); 394 {
395 e.stopPropagation();
396 }
397
398 function clickHide_elementClickHandler(e) {
399 e.preventDefault();
400 e.stopPropagation();
401 clickHide_mouseClick(e);
402 }
403
404 function getBlockableElementOrAncestor(element)
405 {
406 while (element && element != document.documentElement
407 && element != document.body)
408 {
409 if (element instanceof HTMLElement && element.localName != "area")
410 {
411 // Handle <area> and their <map> elements specially,
412 // blocking the image they are associated with
413 if (element.localName == "map")
414 {
415 var images = document.querySelectorAll("img[usemap]");
416 for (var i = 0; i < images.length; i++)
417 {
418 var image = images[i];
419 var usemap = image.getAttribute("usemap");
420 var index = usemap.indexOf("#");
421
422 if (index != -1 && usemap.substr(index + 1) == element.name)
423 return getBlockableElementOrAncestor(image);
424 }
425
426 return null;
427 }
428
429 if (isBlockable(element))
430 return element;
431 }
432
433 element = element.parentElement;
434 }
435
436 return null;
389 } 437 }
390 438
391 // Hovering over an element so highlight it 439 // Hovering over an element so highlight it
392 function clickHide_mouseOver(e) 440 function clickHide_mouseOver(e)
393 { 441 {
394 if (clickHide_activated == false) 442 if (clickHide_activated == false)
395 return; 443 return;
396 444
397 var target = e.target; 445 var target = getBlockableElementOrAncestor(e.target);
398 while (target.parentNode && !isBlockable(target)) 446
399 target = target.parentNode; 447 if (target)
400 if (target == document.documentElement || target == document.body)
401 target = null;
402
403 if (target && target instanceof HTMLElement)
404 { 448 {
405 currentElement = target; 449 currentElement = target;
406 450
407 highlightElement(target, "#d6d84b", "#f8fa47"); 451 highlightElement(target, "#d6d84b", "#f8fa47");
408 target.addEventListener("contextmenu", clickHide_elementClickHandler, true); 452 target.addEventListener("contextmenu", clickHide_elementClickHandler, true);
409 } 453 }
454 e.stopPropagation();
410 } 455 }
411 456
412 // No longer hovering over this element so unhighlight it 457 // No longer hovering over this element so unhighlight it
413 function clickHide_mouseOut(e) 458 function clickHide_mouseOut(e)
414 { 459 {
415 if (!clickHide_activated || !currentElement) 460 if (!clickHide_activated || !currentElement)
416 return; 461 return;
417 462
418 unhighlightElement(currentElement); 463 unhighlightElement(currentElement);
419 currentElement.removeEventListener("contextmenu", clickHide_elementClickHandle r, true); 464 currentElement.removeEventListener("contextmenu", clickHide_elementClickHandle r, true);
465 e.stopPropagation();
420 } 466 }
421 467
422 // Selects the currently hovered-over filter or cancels selection 468 // Selects the currently hovered-over filter or cancels selection
423 function clickHide_keyDown(e) 469 function clickHide_keyDown(e)
424 { 470 {
425 if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 13 /*DOM_VK_RETURN* /) 471 if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 13 /*DOM_VK_RETURN* /)
426 clickHide_mouseClick(e); 472 clickHide_mouseClick(e);
427 else if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 27 /*DOM_VK_ES CAPE*/) 473 else if (!e.ctrlKey && !e.altKey && !e.shiftKey && e.keyCode == 27 /*DOM_VK_ES CAPE*/)
428 { 474 {
429 ext.backgroundPage.sendMessage( 475 ext.backgroundPage.sendMessage(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 { 523 {
478 type: "forward", 524 type: "forward",
479 payload: 525 payload:
480 { 526 {
481 type: "clickhide-show-dialog", 527 type: "clickhide-show-dialog",
482 screenX: e.screenX, 528 screenX: e.screenX,
483 screenY: e.screenY, 529 screenY: e.screenY,
484 clickHideFilters: filters 530 clickHideFilters: filters
485 } 531 }
486 }); 532 });
487 533
kzar 2015/01/26 10:35:16 Why remove the comments explaining that we're high
Sebastian Noack 2015/01/26 10:44:07 A while ago we agreed to don't spam code with comm
kzar 2015/01/26 10:49:55 These comments were useful and directly helped me
Sebastian Noack 2015/01/26 11:08:14 Those comments doesn't add any information that ar
kzar 2015/01/26 14:21:28 Yes they do. These two lines do not explain that a
Sebastian Noack 2015/01/26 15:11:34 Actually nothing is highlighted yellow here. highl
488 if (selectors.length > 0) 534 if (selectors.length > 0)
489 highlightElements(selectors.join(",")); 535 highlightElements(selectors.join(","));
490 536
491 highlightElement(currentElement, "#fd1708", "#f6a1b5"); 537 highlightElement(currentElement, "#fd1708", "#f6a1b5");
492 }); 538 });
493 539
494 // Make sure the browser doesn't handle this click 540 // Make sure the browser doesn't handle this click
495 e.preventDefault(); 541 e.preventDefault();
496 e.stopPropagation(); 542 e.stopPropagation();
497 } 543 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 case "clickhide-activate": 668 case "clickhide-activate":
623 clickHide_activate(); 669 clickHide_activate();
624 break; 670 break;
625 case "clickhide-deactivate": 671 case "clickhide-deactivate":
626 clickHide_deactivate(); 672 clickHide_deactivate();
627 break; 673 break;
628 case "clickhide-new-filter": 674 case "clickhide-new-filter":
629 if(lastRightClickEvent) 675 if(lastRightClickEvent)
630 { 676 {
631 clickHide_activated = true; 677 clickHide_activated = true;
632 currentElement = lastRightClickEvent.target; 678 currentElement = getBlockableElementOrAncestor(lastRightClickEvent.tar get);
633 clickHide_mouseClick(lastRightClickEvent); 679 clickHide_mouseClick(lastRightClickEvent);
634 } 680 }
635 break; 681 break;
636 case "clickhide-init": 682 case "clickhide-init":
637 if (clickHideFiltersDialog) 683 if (clickHideFiltersDialog)
638 { 684 {
639 sendResponse({filters: clickHide_filters}); 685 sendResponse({filters: clickHide_filters});
640 686
641 clickHideFiltersDialog.style.width = msg.width + "px"; 687 clickHideFiltersDialog.style.width = msg.width + "px";
642 clickHideFiltersDialog.style.height = msg.height + "px"; 688 clickHideFiltersDialog.style.height = msg.height + "px";
(...skipping 28 matching lines...) Expand all
671 lastRightClickEventValid = false; 717 lastRightClickEventValid = false;
672 else 718 else
673 lastRightClickEvent = null; 719 lastRightClickEvent = null;
674 break; 720 break;
675 } 721 }
676 }); 722 });
677 723
678 if (window == window.top) 724 if (window == window.top)
679 ext.backgroundPage.sendMessage({type: "report-html-page"}); 725 ext.backgroundPage.sendMessage({type: "report-html-page"});
680 } 726 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld