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

Delta Between Two Patch Sets: include.postload.js

Issue 4923599135703040: Issue 1610 - Don't remove overlays before the "Block element" dialog is closed (Closed)
Left Patch Set: Created Nov. 26, 2014, 10:48 a.m.
Right Patch Set: Rebased and addressed comments Created Nov. 26, 2014, 2:40 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 | « no previous file | no next file » | 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 <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH 3 * Copyright (C) 2006-2014 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 { 168 {
169 Array.prototype.forEach.call( 169 Array.prototype.forEach.call(
170 document.querySelectorAll(highlightedElementsSelector), 170 document.querySelectorAll(highlightedElementsSelector),
171 unhighlightElement 171 unhighlightElement
172 ); 172 );
173 173
174 highlightedElementsSelector = null; 174 highlightedElementsSelector = null;
175 } 175 }
176 } 176 }
177 177
178 function getElementURLs(element) {
179 var urls = [];
180
181 if (element.src)
182 urls.push(element.src);
183
184 switch (element.localName)
185 {
186 case "object":
187 var url = element.getAttribute("data");
188 if (url)
189 return [resolveURL(url)];
190
191 for (var i = 0; i < element.children.length; i++)
192 {
193 var child = element.children[i];
194 if (child.localName != "param")
195 continue;
196
197 var name = child.getAttribute("name");
198 if (name != "movie" && name != "src")
199 continue;
200
201 var value = child.getAttribute("value");
202 if (!value)
203 continue;
204
205 return [resolveURL(value)];
206 }
207
208 return [];
209
210 case "video":
211 case "audio":
212 case "picture":
213 for (var i = 0; i < element.children.length; i++)
214 {
215 var child = element.children[i];
216
217 if (child.localName != "source")
218 continue;
219
220 if (child.src)
221 urls.push(child.src);
222
223 urls = urls.concat(parseSrcSet(child));
224 }
225
226 if (element.poster)
227 urls.push(element.poster);
228
229 break;
230
231 case "img":
232 urls = urls.concat(parseSrcSet(element));
233 }
234
235 return urls;
236 }
237
238 function isBlockable(element)
239 {
240 if (element.id)
241 return true;
242 if (element.classList.length > 0)
243 return true;
244 if (getElementURLs(element).length > 0)
245 return true;
246
247 // We only generate filters based on the "style" attribute,
248 // if this is the only way we can generate a filter, and
249 // only if there are at least two CSS properties defined.
250 if (/:.+:/.test(element.getAttribute("style")))
251 return true;
252
253 return false;
254 }
255
178 // Gets the absolute position of an element by walking up the DOM tree, 256 // Gets the absolute position of an element by walking up the DOM tree,
179 // adding up offsets. 257 // adding up offsets.
180 // I hope there's a better way because it just seems absolutely stupid 258 // I hope there's a better way because it just seems absolutely stupid
181 // that the DOM wouldn't have a direct way to get this, given that it 259 // that the DOM wouldn't have a direct way to get this, given that it
182 // has hundreds and hundreds of other methods that do random junk. 260 // has hundreds and hundreds of other methods that do random junk.
183 function getAbsolutePosition(elt) { 261 function getAbsolutePosition(elt) {
184 var l = 0; 262 var l = 0;
185 var t = 0; 263 var t = 0;
186 for(; elt; elt = elt.offsetParent) { 264 for(; elt; elt = elt.offsetParent) {
187 l += elt.offsetLeft; 265 l += elt.offsetLeft;
188 t += elt.offsetTop; 266 t += elt.offsetTop;
189 } 267 }
190 return [l, t]; 268 return [l, t];
191 } 269 }
192 270
193 // Adds an overlay to an element, which is probably a Flash object 271 // Adds an overlay to an element, which is probably a Flash object
194 function addElementOverlay(elt) { 272 function addElementOverlay(elt) {
195 // If this element is enclosed in an object tag, we prefer to block that inste ad 273 // If this element is enclosed in an object tag, we prefer to block that inste ad
196 if(!elt) 274 if(!elt)
197 return null; 275 return null;
198 276
199 // If element doesn't have at least one of class name, ID or URL, give up 277 // If element doesn't have at least one of class name, ID or URL, give up
200 // because we don't know how to construct a filter rule for it 278 // because we don't know how to construct a filter rule for it
201 if(!hasFilters(elt)) 279 if(!isBlockable(elt))
202 return; 280 return;
281
282 // If the element isn't rendered (since its or one of its ancestor's
283 // "diplay" property is "none"), the overlay wouldn't match the element.
284 if (!elt.offsetParent)
285 return;
286
203 var thisStyle = getComputedStyle(elt, null); 287 var thisStyle = getComputedStyle(elt, null);
204 var overlay = document.createElement('div'); 288 var overlay = document.createElement('div');
205 overlay.prisoner = elt; 289 overlay.prisoner = elt;
206 overlay.className = "__adblockplus__overlay"; 290 overlay.className = "__adblockplus__overlay";
207 overlay.setAttribute('style', 'opacity:0.4; background-color:#ffffff; display: inline-box; ' + 'width:' + thisStyle.width + '; height:' + thisStyle.height + '; position:absolute; overflow:hidden; -webkit-box-sizing:border-box; z-index: 999 99'); 291 overlay.setAttribute('style', 'opacity:0.4; background-color:#ffffff; display: inline-box; ' + 'width:' + thisStyle.width + '; height:' + thisStyle.height + '; position:absolute; overflow:hidden; -webkit-box-sizing:border-box;');
208 var pos = getAbsolutePosition(elt); 292 var pos = getAbsolutePosition(elt);
209 overlay.style.left = pos[0] + "px"; 293 overlay.style.left = pos[0] + "px";
210 overlay.style.top = pos[1] + "px"; 294 overlay.style.top = pos[1] + "px";
295
296 if (thisStyle.position != "static")
297 overlay.style.zIndex = thisStyle.zIndex;
298 else
299 overlay.style.zIndex = getComputedStyle(elt.offsetParent).zIndex;
300
211 // elt.parentNode.appendChild(overlay, elt); 301 // elt.parentNode.appendChild(overlay, elt);
212 document.body.appendChild(overlay); 302 document.body.appendChild(overlay);
213 return overlay; 303 return overlay;
214 } 304 }
215 305
216 // Show dialog asking user whether she wants to add the proposed filters derived 306 // Show dialog asking user whether she wants to add the proposed filters derived
217 // from selected page element 307 // from selected page element
218 function clickHide_showDialog(left, top, filters) 308 function clickHide_showDialog(left, top, filters)
219 { 309 {
220 // If we are already selecting, abort now 310 // If we are already selecting, abort now
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 // on whether the user actually wants these filters 364 // on whether the user actually wants these filters
275 function clickHide_rulesPending() { 365 function clickHide_rulesPending() {
276 clickHide_activated = false; 366 clickHide_activated = false;
277 document.removeEventListener("mouseover", clickHide_mouseOver, true); 367 document.removeEventListener("mouseover", clickHide_mouseOver, true);
278 document.removeEventListener("mouseout", clickHide_mouseOut, true); 368 document.removeEventListener("mouseout", clickHide_mouseOut, true);
279 document.removeEventListener("click", clickHide_mouseClick, true); 369 document.removeEventListener("click", clickHide_mouseClick, true);
280 document.removeEventListener("keydown", clickHide_keyDown, true); 370 document.removeEventListener("keydown", clickHide_keyDown, true);
281 } 371 }
282 372
283 // Turn off click-to-hide 373 // Turn off click-to-hide
284 function clickHide_deactivate(keepOverlays) 374 function clickHide_deactivate(keepOverlays)
kzar 2014/11/26 14:14:04 We're relying on the legacy code not passing this
Sebastian Noack 2014/11/26 14:41:39 Correct. I tried to keep the patch as compact as p
285 { 375 {
286 if (clickHideFiltersDialog) 376 if (clickHideFiltersDialog)
287 { 377 {
288 document.body.removeChild(clickHideFiltersDialog); 378 document.body.removeChild(clickHideFiltersDialog);
289 clickHideFiltersDialog = null; 379 clickHideFiltersDialog = null;
290 } 380 }
291 381
292 clickHide_activated = false; 382 clickHide_activated = false;
293 clickHide_filters = null; 383 clickHide_filters = null;
294 if(!document) 384 if(!document)
295 return; // This can happen inside a nuked iframe...I think 385 return; // This can happen inside a nuked iframe...I think
296 document.removeEventListener("mouseover", clickHide_mouseOver, true); 386 document.removeEventListener("mouseover", clickHide_mouseOver, true);
297 document.removeEventListener("mouseout", clickHide_mouseOut, true); 387 document.removeEventListener("mouseout", clickHide_mouseOut, true);
298 document.removeEventListener("click", clickHide_mouseClick, true); 388 document.removeEventListener("click", clickHide_mouseClick, true);
299 document.removeEventListener("keydown", clickHide_keyDown, true); 389 document.removeEventListener("keydown", clickHide_keyDown, true);
300 390
301 if (!keepOverlays) 391 if (!keepOverlays)
302 { 392 {
303 if(currentElement) { 393 if (currentElement) {
kzar 2014/11/26 14:14:04 Nitpick: Should be space between "if" and "("?
Sebastian Noack 2014/11/26 14:41:39 I just copied the code from above, but I have adde
304 currentElement.removeEventListener("contextmenu", clickHide_elementClickHa ndler, false); 394 currentElement.removeEventListener("contextmenu", clickHide_elementClickH andler, true);
kzar 2014/11/26 14:14:04 Last parameter should be true?
Sebastian Noack 2014/11/26 14:41:39 Yes, this patch was created on top of a version, w
305 unhighlightElements(); 395 unhighlightElements();
306 unhighlightElement(currentElement); 396 unhighlightElement(currentElement);
307 currentElement = null; 397 currentElement = null;
308 clickHideFilters = null; 398 clickHideFilters = null;
309 } 399 }
310 unhighlightElements(); 400 unhighlightElements();
311 401
312 var overlays = document.getElementsByClassName("__adblockplus__overlay"); 402 var overlays = document.getElementsByClassName("__adblockplus__overlay");
313 while (overlays.length > 0) 403 while (overlays.length > 0)
314 overlays[0].parentNode.removeChild(overlays[0]); 404 overlays[0].parentNode.removeChild(overlays[0]);
315 } 405 }
316 } 406 }
317 407
318 function clickHide_elementClickHandler(ev) { 408 function clickHide_elementClickHandler(ev) {
319 ev.preventDefault(); 409 ev.preventDefault();
320 ev.stopPropagation(); 410 ev.stopPropagation();
321 clickHide_mouseClick(ev); 411 clickHide_mouseClick(ev);
322 } 412 }
323 413
324 // Hovering over an element so highlight it 414 // Hovering over an element so highlight it
325 function clickHide_mouseOver(e) 415 function clickHide_mouseOver(e)
326 { 416 {
327 if (clickHide_activated == false) 417 if (clickHide_activated == false)
328 return; 418 return;
329 419
330 var target = e.target; 420 var target = e.target;
331 while (target.parentNode && !hasFilters(target)) 421 while (target.parentNode && !isBlockable(target))
332 target = target.parentNode; 422 target = target.parentNode;
333 if (target == document.documentElement || target == document.body) 423 if (target == document.documentElement || target == document.body)
334 target = null; 424 target = null;
335 425
336 if (target && target instanceof HTMLElement) 426 if (target && target instanceof HTMLElement)
337 { 427 {
338 currentElement = target; 428 currentElement = target;
339 429
340 highlightElement(target, "#d6d84b", "#f8fa47"); 430 highlightElement(target, "#d6d84b", "#f8fa47");
341 target.addEventListener("contextmenu", clickHide_elementClickHandler, true); 431 target.addEventListener("contextmenu", clickHide_elementClickHandler, true);
(...skipping 23 matching lines...) Expand all
365 payload: 455 payload:
366 { 456 {
367 type: "clickhide-deactivate" 457 type: "clickhide-deactivate"
368 } 458 }
369 }); 459 });
370 e.preventDefault(); 460 e.preventDefault();
371 e.stopPropagation(); 461 e.stopPropagation();
372 } 462 }
373 } 463 }
374 464
375
376
377 // When the user clicks, the currentElement is the one we want. 465 // When the user clicks, the currentElement is the one we want.
378 // We should have ABP rules ready for when the 466 // We should have ABP rules ready for when the
379 // popup asks for them. 467 // popup asks for them.
380 function clickHide_mouseClick(e) 468 function clickHide_mouseClick(e)
381 { 469 {
382 if (!currentElement || !clickHide_activated) 470 if (!currentElement || !clickHide_activated)
383 return; 471 return;
384 472
385 var elt = currentElement; 473 var elt = currentElement;
386 if (currentElement.classList.contains("__adblockplus__overlay")) 474 if (currentElement.classList.contains("__adblockplus__overlay"))
(...skipping 21 matching lines...) Expand all
408 for (var i = 0; i < elt.classList.length; i++) 496 for (var i = 0; i < elt.classList.length; i++)
409 selector += "." + escapeCSS(elt.classList[i]); 497 selector += "." + escapeCSS(elt.classList[i]);
410 498
411 addSelector(selector); 499 addSelector(selector);
412 } 500 }
413 501
414 var urls = getElementURLs(elt); 502 var urls = getElementURLs(elt);
415 for (var i = 0; i < urls.length; i++) 503 for (var i = 0; i < urls.length; i++)
416 { 504 {
417 var url = urls[i]; 505 var url = urls[i];
418 var isHTTP = /^https?:/i.test(url); 506
419 507 if (/^https?:/i.test(url))
420 if (isHTTP)
421 { 508 {
422 var filter = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"); 509 var filter = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||");
423 510
424 if (clickHideFilters.indexOf(filter) != -1) 511 if (clickHideFilters.indexOf(filter) == -1)
425 continue; 512 clickHideFilters.push(filter);
426 513
427 clickHideFilters.push(filter); 514 continue;
428 } 515 }
429 516
430 if (url == elt.src) 517 if (url == elt.src)
431 { 518 addSelector(escapeCSS(elt.localName) + '[src=' + quote(elt.getAttribute("s rc")) + ']');
432 var selector = escapeCSS(elt.localName) + '[src=' + quote(elt.getAttribute ("src")) + ']';
433
434 if (isHTTP)
435 selectorList.push(selector);
436 else
437 addSelector(selector);
438 }
439 } 519 }
440 520
441 // restore the original style, before generating the fallback filter that 521 // restore the original style, before generating the fallback filter that
442 // will include the style, and to prevent highlightElements from saving those 522 // will include the style, and to prevent highlightElements from saving those
443 unhighlightElement(currentElement); 523 unhighlightElement(currentElement);
444 524
445 // as last resort, create a filter based on inline styles 525 // as last resort, create a filter based on inline styles
446 if (clickHideFilters.length == 0) 526 if (clickHideFilters.length == 0)
447 { 527 {
448 var style = elt.getAttribute("style"); 528 var style = elt.getAttribute("style");
(...skipping 24 matching lines...) Expand all
473 for (var i = 0; i < urls.length; i++) 553 for (var i = 0; i < urls.length; i++)
474 { 554 {
475 var url = urls[i].replace(/^\s+/, "").replace(/(\s+\S+)?\s*$/, ""); 555 var url = urls[i].replace(/^\s+/, "").replace(/(\s+\S+)?\s*$/, "");
476 if (url) 556 if (url)
477 urls[i] = resolveURL(url); 557 urls[i] = resolveURL(url);
478 else 558 else
479 urls.splice(i--, 1); 559 urls.splice(i--, 1);
480 } 560 }
481 561
482 return urls; 562 return urls;
483 }
484
485 function getElementURLs(elt) {
486 var urls = [];
487
488 if (elt.src)
489 urls.push(elt.src);
490
491 switch (elt.localName)
492 {
493 case "object":
494 var url = elt.getAttribute("data");
495 if (url)
496 return [resolveURL(url)];
497
498 for (var i = 0; i < elt.children.length; i++)
499 {
500 var child = elt.children[i];
501 if (child.localName != "param")
502 continue;
503
504 var name = child.getAttribute("name");
505 if (name != "movie" && name != "src")
506 continue;
507
508 var value = child.getAttribute("value");
509 if (!value)
510 continue;
511
512 return [resolveURL(value)];
513 }
514
515 return [];
516
517 case "video":
518 case "audio":
519 case "picture":
520 for (var i = 0; i < elt.children.length; i++)
521 {
522 var child = elt.children[i];
523
524 if (child.localName != "source")
525 continue;
526
527 if (child.src)
528 urls.push(child.src);
529
530 urls = urls.concat(parseSrcSet(child));
531 }
532
533 if (elt.poster)
534 urls.push(elt.poster);
535
536 break;
537
538 case "img":
539 urls = urls.concat(parseSrcSet(elt));
540 }
541
542 return urls;
543 }
544
545 function hasFilters(element)
546 {
547 if (element.id)
548 return true;
549 if (element.classList.length > 0)
550 return true;
551 if (getElementURLs(element).length > 0)
552 return true;
553 if (/:.+:/.test(element.getAttribute("style")))
554 return true;
555
556 return false;
557 } 563 }
558 564
559 // This function Copyright (c) 2008 Jeni Tennison, from jquery.uri.js 565 // This function Copyright (c) 2008 Jeni Tennison, from jquery.uri.js
560 // and licensed under the MIT license. See jquery-*.min.js for details. 566 // and licensed under the MIT license. See jquery-*.min.js for details.
561 function removeDotSegments(u) { 567 function removeDotSegments(u) {
562 var r = '', m = []; 568 var r = '', m = [];
563 if (/\./.test(u)) { 569 if (/\./.test(u)) {
564 while (u !== undefined && u !== '') { 570 while (u !== undefined && u !== '') {
565 if (u === '.' || u === '..') { 571 if (u === '.' || u === '..') {
566 u = ''; 572 u = '';
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 break; 715 break;
710 default: 716 default:
711 sendResponse({}); 717 sendResponse({});
712 break; 718 break;
713 } 719 }
714 }); 720 });
715 721
716 if (window == window.top) 722 if (window == window.top)
717 ext.backgroundPage.sendMessage({type: "report-html-page"}); 723 ext.backgroundPage.sendMessage({type: "report-html-page"});
718 } 724 }
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
This is Rietveld