| OLD | NEW | 
|---|
| 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-present eyeo GmbH | 3  * Copyright (C) 2006-present 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 22 matching lines...) Expand all  Loading... | 
| 33 | 33 | 
| 34 // Highlighting state, used by the top frame during element picking and all | 34 // Highlighting state, used by the top frame during element picking and all | 
| 35 // frames when the chosen element is highlighted red. | 35 // frames when the chosen element is highlighted red. | 
| 36 let highlightedElementsSelector = null; | 36 let highlightedElementsSelector = null; | 
| 37 let highlightedElementsInterval = null; | 37 let highlightedElementsInterval = null; | 
| 38 | 38 | 
| 39 // Last right click state stored for element blocking via the context menu. | 39 // Last right click state stored for element blocking via the context menu. | 
| 40 let lastRightClickEvent = null; | 40 let lastRightClickEvent = null; | 
| 41 let lastRightClickEventIsMostRecent = false; | 41 let lastRightClickEventIsMostRecent = false; | 
| 42 | 42 | 
|  | 43 let perFrameMessagingSupported = false; | 
|  | 44 browser.runtime.sendMessage( | 
|  | 45   {type: "app.get", what: "application"}, | 
|  | 46   application => { perFrameMessagingSupported = application != "edge"; } | 
|  | 47 ); | 
| 43 | 48 | 
| 44 /* Utilities */ | 49 /* Utilities */ | 
| 45 | 50 | 
| 46 function getFiltersForElement(element, callback) | 51 function getFiltersForElement(element, callback) | 
| 47 { | 52 { | 
| 48   let src = element.getAttribute("src"); | 53   let src = element.getAttribute("src"); | 
| 49   browser.runtime.sendMessage({ | 54   browser.runtime.sendMessage({ | 
| 50     type: "composer.getFilters", | 55     type: "composer.getFilters", | 
| 51     tagName: element.localName, | 56     tagName: element.localName, | 
| 52     id: element.id, | 57     id: element.id, | 
| 53     src: src && src.length <= 1000 ? src : null, | 58     src: src && src.length <= 1000 ? src : null, | 
| 54     style: element.getAttribute("style"), | 59     style: element.getAttribute("style"), | 
| 55     classes: Array.prototype.slice.call(element.classList), | 60     classes: Array.prototype.slice.call(element.classList), | 
| 56     urls: getURLsFromElement(element), | 61     urls: getURLsFromElement(element), | 
| 57     mediatype: typeMap.get(element.localName), | 62     mediatype: typeMap.get(element.localName), | 
| 58     baseURL: document.location.href | 63     baseURL: document.location.href | 
| 59   }, | 64   }, | 
| 60   response => | 65   response => | 
| 61   { | 66   { | 
| 62     callback(response.filters, response.selectors); | 67     callback(response.filters, response.selectors); | 
| 63   }); | 68   }); | 
| 64 } | 69 } | 
| 65 | 70 | 
| 66 function getBlockableElementOrAncestor(element, callback) | 71 function getBlockableElementOrAncestor(element, callback) | 
| 67 { | 72 { | 
|  | 73   // If we're offering to block the iframe element given by window.frameElement | 
|  | 74   // we must use the context of the parent frame. | 
|  | 75   let document = element.ownerDocument; | 
|  | 76   let HTMLElement = document.defaultView.HTMLElement; | 
|  | 77 | 
| 68   // We assume that the user doesn't want to block the whole page. | 78   // We assume that the user doesn't want to block the whole page. | 
| 69   // So we never consider the <html> or <body> element. | 79   // So we never consider the <html> or <body> element. | 
| 70   while (element && element != document.documentElement && | 80   while (element && element != document.documentElement && | 
| 71          element != document.body) | 81          element != document.body) | 
| 72   { | 82   { | 
| 73     // We can't handle non-HTML (like SVG) elements, as well as | 83     // We can't handle non-HTML (like SVG) elements, as well as | 
| 74     // <area> elements (see below). So fall back to the parent element. | 84     // <area> elements (see below). So fall back to the parent element. | 
| 75     if (!(element instanceof HTMLElement) || element.localName == "area") | 85     if (!(element instanceof HTMLElement) || element.localName == "area") | 
| 76       element = element.parentElement; | 86       element = element.parentElement; | 
| 77 | 87 | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 116   // We reached the document root without finding a blockable element. | 126   // We reached the document root without finding a blockable element. | 
| 117   callback(null); | 127   callback(null); | 
| 118 } | 128 } | 
| 119 | 129 | 
| 120 | 130 | 
| 121 /* Element highlighting */ | 131 /* Element highlighting */ | 
| 122 | 132 | 
| 123 // Adds an overlay to an element in order to highlight it. | 133 // Adds an overlay to an element in order to highlight it. | 
| 124 function addElementOverlay(element) | 134 function addElementOverlay(element) | 
| 125 { | 135 { | 
|  | 136   let document = element.ownerDocument; | 
|  | 137 | 
| 126   let position = "absolute"; | 138   let position = "absolute"; | 
| 127   let offsetX = window.scrollX; | 139   let offsetX = window.scrollX; | 
| 128   let offsetY = window.scrollY; | 140   let offsetY = window.scrollY; | 
| 129 | 141 | 
| 130   for (let e = element; e; e = e.parentElement) | 142   for (let e = element; e; e = e.parentElement) | 
| 131   { | 143   { | 
| 132     let style = getComputedStyle(e); | 144     let style = getComputedStyle(e); | 
| 133 | 145 | 
| 134     // If the element isn't rendered (since its or one of its ancestor's | 146     // If the element isn't rendered (since its or one of its ancestor's | 
| 135     // "display" property is "none"), the overlay wouldn't match the element. | 147     // "display" property is "none"), the overlay wouldn't match the element. | 
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 415         }); | 427         }); | 
| 416       } | 428       } | 
| 417     }); | 429     }); | 
| 418 | 430 | 
| 419     if (selectors.length > 0) | 431     if (selectors.length > 0) | 
| 420       highlightElements(selectors.join(",")); | 432       highlightElements(selectors.join(",")); | 
| 421 | 433 | 
| 422     highlightElement(currentElement, "#fd1708", "#f6a1b5"); | 434     highlightElement(currentElement, "#fd1708", "#f6a1b5"); | 
| 423   }); | 435   }); | 
| 424 | 436 | 
| 425   event.preventDefault(); | 437   if (event) | 
| 426   event.stopPropagation(); | 438   { | 
|  | 439     event.preventDefault(); | 
|  | 440     event.stopPropagation(); | 
|  | 441   } | 
| 427 } | 442 } | 
| 428 | 443 | 
| 429 function stopPickingElement() | 444 function stopPickingElement() | 
| 430 { | 445 { | 
| 431   currentlyPickingElement = false; | 446   currentlyPickingElement = false; | 
| 432 | 447 | 
| 433   document.removeEventListener("mousedown", stopEventPropagation, true); | 448   document.removeEventListener("mousedown", stopEventPropagation, true); | 
| 434   document.removeEventListener("mouseup", stopEventPropagation, true); | 449   document.removeEventListener("mouseup", stopEventPropagation, true); | 
| 435   document.removeEventListener("mouseenter", stopEventPropagation, true); | 450   document.removeEventListener("mouseenter", stopEventPropagation, true); | 
| 436   document.removeEventListener("mouseleave", stopEventPropagation, true); | 451   document.removeEventListener("mouseleave", stopEventPropagation, true); | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 517             active: currentlyPickingElement || blockelementPopupId != null | 532             active: currentlyPickingElement || blockelementPopupId != null | 
| 518           }); | 533           }); | 
| 519         } | 534         } | 
| 520         break; | 535         break; | 
| 521       case "composer.content.startPickingElement": | 536       case "composer.content.startPickingElement": | 
| 522         if (window == window.top) | 537         if (window == window.top) | 
| 523           startPickingElement(); | 538           startPickingElement(); | 
| 524         break; | 539         break; | 
| 525       case "composer.content.contextMenuClicked": | 540       case "composer.content.contextMenuClicked": | 
| 526         let event = lastRightClickEvent; | 541         let event = lastRightClickEvent; | 
|  | 542         let target = event && event.target; | 
|  | 543 | 
|  | 544         // When the user attempts to block an element inside an iframe for which | 
|  | 545         // our right click event listener was trashed the best we can do is to | 
|  | 546         // offer to block the entire iframe. This doesn't work for cross origin | 
|  | 547         // frames, neither on Edge where per-frame messaging isn't supported | 
|  | 548         // yet[1], but it's the best we can do. | 
|  | 549         // [1] - https://developer.microsoft.com/en-us/microsoft-edge/platform/d
     ocumentation/extensions/api-support/supported-apis/ | 
|  | 550         if (!target && window.frameElement && perFrameMessagingSupported) | 
|  | 551           target = addElementOverlay(window.frameElement); | 
|  | 552 | 
| 527         deactivateBlockElement(); | 553         deactivateBlockElement(); | 
| 528         if (event) | 554         if (target) | 
| 529         { | 555         { | 
| 530           getBlockableElementOrAncestor(event.target, element => | 556           getBlockableElementOrAncestor(target, element => | 
| 531           { | 557           { | 
| 532             if (element) | 558             if (element) | 
| 533             { | 559             { | 
| 534               currentElement = element; | 560               currentElement = element; | 
| 535               elementPicked(event); | 561               elementPicked(event); | 
| 536             } | 562             } | 
| 537           }); | 563           }); | 
| 538         } | 564         } | 
| 539         break; | 565         break; | 
| 540       case "composer.content.finished": | 566       case "composer.content.finished": | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 587 if (document instanceof HTMLDocument) | 613 if (document instanceof HTMLDocument) | 
| 588 { | 614 { | 
| 589   // There's a bug in Firefox that causes document_end content scripts to run | 615   // There's a bug in Firefox that causes document_end content scripts to run | 
| 590   // before document_start content scripts on extension startup. In this case | 616   // before document_start content scripts on extension startup. In this case | 
| 591   // the ext object is undefined, we fail to initialize, and initializeComposer | 617   // the ext object is undefined, we fail to initialize, and initializeComposer | 
| 592   // returns false. As a workaround, try again after a timeout. | 618   // returns false. As a workaround, try again after a timeout. | 
| 593   // https://bugzilla.mozilla.org/show_bug.cgi?id=1395287 | 619   // https://bugzilla.mozilla.org/show_bug.cgi?id=1395287 | 
| 594   if (!initializeComposer()) | 620   if (!initializeComposer()) | 
| 595     setTimeout(initializeComposer, 2000); | 621     setTimeout(initializeComposer, 2000); | 
| 596 } | 622 } | 
| OLD | NEW | 
|---|