| 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-2016 Eyeo GmbH | 3  * Copyright (C) 2006-2016 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 | 
| 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 12  * GNU General Public License for more details. | 12  * GNU General Public License for more details. | 
| 13  * | 13  * | 
| 14  * You should have received a copy of the GNU General Public License | 14  * You should have received a copy of the GNU General Public License | 
| 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| 16  */ | 16  */ | 
| 17 | 17 | 
|  | 18 /* globals checkCollapse, elemhide, getURLsFromElement, typeMap  */ | 
|  | 19 | 
| 18 "use strict"; | 20 "use strict"; | 
| 19 | 21 | 
| 20 // The page ID for the popup filter selection dialog (top frame only). | 22 // The page ID for the popup filter selection dialog (top frame only). | 
| 21 let blockelementPopupId = null; | 23 let blockelementPopupId = null; | 
| 22 | 24 | 
| 23 // Element picking state (top frame only). | 25 // Element picking state (top frame only). | 
| 24 let currentlyPickingElement = false; | 26 let currentlyPickingElement = false; | 
| 25 let lastMouseOverEvent = null; | 27 let lastMouseOverEvent = null; | 
| 26 | 28 | 
| 27 // During element picking this is the currently highlighted element. When | 29 // During element picking this is the currently highlighted element. When | 
| 28 // element has been picked this is the element that is due to be blocked. | 30 // element has been picked this is the element that is due to be blocked. | 
| 29 let currentElement = null; | 31 let currentElement = null; | 
| 30 | 32 | 
| 31 // Highlighting state, used by the top frame during element picking and all | 33 // Highlighting state, used by the top frame during element picking and all | 
| 32 // frames when the chosen element is highlighted red. | 34 // frames when the chosen element is highlighted red. | 
| 33 let highlightedElementsSelector = null; | 35 let highlightedElementsSelector = null; | 
| 34 let highlightedElementsInterval = null; | 36 let highlightedElementsInterval = null; | 
| 35 | 37 | 
| 36 // Last right click state stored for element blocking via the context menu. | 38 // Last right click state stored for element blocking via the context menu. | 
| 37 let lastRightClickEvent = null; | 39 let lastRightClickEvent = null; | 
| 38 let lastRightClickEventIsMostRecent = false; | 40 let lastRightClickEventIsMostRecent = false; | 
| 39 | 41 | 
| 40 | 42 | 
| 41 /* Utilities */ | 43 /* Utilities */ | 
| 42 | 44 | 
| 43 function getFiltersForElement(element, callback) | 45 function getFiltersForElement(element, callback) | 
| 44 { | 46 { | 
| 45   let src = element.getAttribute("src"); | 47   let src = element.getAttribute("src"); | 
| 46   ext.backgroundPage.sendMessage( | 48   ext.backgroundPage.sendMessage({ | 
| 47   { |  | 
| 48     type: "composer.getFilters", | 49     type: "composer.getFilters", | 
| 49     tagName: element.localName, | 50     tagName: element.localName, | 
| 50     id: element.id, | 51     id: element.id, | 
| 51     src: src && src.length <= 1000 ? src : null, | 52     src: src && src.length <= 1000 ? src : null, | 
| 52     style: element.getAttribute("style"), | 53     style: element.getAttribute("style"), | 
| 53     classes: Array.prototype.slice.call(element.classList), | 54     classes: Array.prototype.slice.call(element.classList), | 
| 54     urls: getURLsFromElement(element), | 55     urls: getURLsFromElement(element), | 
| 55     mediatype: typeMap[element.localName], | 56     mediatype: typeMap.get(element.localName), | 
| 56     baseURL: document.location.href | 57     baseURL: document.location.href | 
| 57   }, | 58   }, | 
| 58   response => | 59   response => | 
| 59   { | 60   { | 
| 60     callback(response.filters, response.selectors); | 61     callback(response.filters, response.selectors); | 
| 61   }); | 62   }); | 
| 62 } | 63 } | 
| 63 | 64 | 
| 64 function getBlockableElementOrAncestor(element, callback) | 65 function getBlockableElementOrAncestor(element, callback) | 
| 65 { | 66 { | 
| 66   // We assume that the user doesn't want to block the whole page. | 67   // We assume that the user doesn't want to block the whole page. | 
| 67   // So we never consider the <html> or <body> element. | 68   // So we never consider the <html> or <body> element. | 
| 68   while (element && element != document.documentElement && | 69   while (element && element != document.documentElement && | 
| 69          element != document.body) | 70          element != document.body) | 
| 70   { | 71   { | 
| 71     // We can't handle non-HTML (like SVG) elements, as well as | 72     // We can't handle non-HTML (like SVG) elements, as well as | 
| 72     // <area> elements (see below). So fall back to the parent element. | 73     // <area> elements (see below). So fall back to the parent element. | 
| 73     if (!(element instanceof HTMLElement) || element.localName == "area") | 74     if (!(element instanceof HTMLElement) || element.localName == "area") | 
|  | 75     { | 
| 74       element = element.parentElement; | 76       element = element.parentElement; | 
| 75 | 77     } | 
| 76     // If image maps are used mouse events occur for the <area> element. | 78     // If image maps are used mouse events occur for the <area> element. | 
| 77     // But we have to block the image associated with the <map> element. | 79     // But we have to block the image associated with the <map> element. | 
| 78     else if (element.localName == "map") | 80     else if (element.localName == "map") | 
| 79     { | 81     { | 
| 80       let images = document.querySelectorAll("img[usemap]"); | 82       let images = document.querySelectorAll("img[usemap]"); | 
| 81       let image = null; | 83       let image = null; | 
| 82 | 84 | 
| 83       for (let currentImage of images) | 85       for (let currentImage of images) | 
| 84       { | 86       { | 
| 85         let usemap = currentImage.getAttribute("usemap"); | 87         let usemap = currentImage.getAttribute("usemap"); | 
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 381 { | 383 { | 
| 382   if (!currentElement) | 384   if (!currentElement) | 
| 383     return; | 385     return; | 
| 384 | 386 | 
| 385   let element = currentElement.prisoner || currentElement; | 387   let element = currentElement.prisoner || currentElement; | 
| 386   getFiltersForElement(element, (filters, selectors) => | 388   getFiltersForElement(element, (filters, selectors) => | 
| 387   { | 389   { | 
| 388     if (currentlyPickingElement) | 390     if (currentlyPickingElement) | 
| 389       stopPickingElement(); | 391       stopPickingElement(); | 
| 390 | 392 | 
| 391     ext.backgroundPage.sendMessage( | 393     ext.backgroundPage.sendMessage({ | 
| 392     { |  | 
| 393       type: "composer.openDialog" | 394       type: "composer.openDialog" | 
| 394     }, | 395     }, | 
| 395     popupId => | 396     popupId => | 
| 396     { | 397     { | 
| 397       ext.backgroundPage.sendMessage( | 398       ext.backgroundPage.sendMessage({ | 
| 398       { |  | 
| 399         type: "forward", | 399         type: "forward", | 
| 400         targetPageId: popupId, | 400         targetPageId: popupId, | 
| 401         payload: | 401         payload: {type: "composer.dialog.init", filters} | 
| 402         { |  | 
| 403           type: "composer.dialog.init", |  | 
| 404           filters: filters |  | 
| 405         } |  | 
| 406       }); | 402       }); | 
| 407 | 403 | 
| 408       // Only the top frame keeps a record of the popup window's ID, | 404       // Only the top frame keeps a record of the popup window's ID, | 
| 409       // so if this isn't the top frame we need to pass the ID on. | 405       // so if this isn't the top frame we need to pass the ID on. | 
| 410       if (window == window.top) | 406       if (window == window.top) | 
| 411       { | 407       { | 
| 412         blockelementPopupId = popupId; | 408         blockelementPopupId = popupId; | 
| 413       } | 409       } | 
| 414       else | 410       else | 
| 415       { | 411       { | 
| 416         ext.backgroundPage.sendMessage( | 412         ext.backgroundPage.sendMessage({ | 
| 417         { |  | 
| 418           type: "forward", | 413           type: "forward", | 
| 419           payload: | 414           payload: {type: "composer.content.dialogOpened", popupId} | 
| 420           { |  | 
| 421             type: "composer.content.dialogOpened", |  | 
| 422             popupId: popupId |  | 
| 423           } |  | 
| 424         }); | 415         }); | 
| 425       } | 416       } | 
| 426     }); | 417     }); | 
| 427 | 418 | 
| 428     if (selectors.length > 0) | 419     if (selectors.length > 0) | 
| 429       highlightElements(selectors.join(",")); | 420       highlightElements(selectors.join(",")); | 
| 430 | 421 | 
| 431     highlightElement(currentElement, "#fd1708", "#f6a1b5"); | 422     highlightElement(currentElement, "#fd1708", "#f6a1b5"); | 
| 432   }); | 423   }); | 
| 433 | 424 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 454 /* Core logic */ | 445 /* Core logic */ | 
| 455 | 446 | 
| 456 // We're done with the block element feature for now, tidy everything up. | 447 // We're done with the block element feature for now, tidy everything up. | 
| 457 function deactivateBlockElement() | 448 function deactivateBlockElement() | 
| 458 { | 449 { | 
| 459   if (currentlyPickingElement) | 450   if (currentlyPickingElement) | 
| 460     stopPickingElement(); | 451     stopPickingElement(); | 
| 461 | 452 | 
| 462   if (blockelementPopupId != null) | 453   if (blockelementPopupId != null) | 
| 463   { | 454   { | 
| 464     ext.backgroundPage.sendMessage( | 455     ext.backgroundPage.sendMessage({ | 
| 465     { |  | 
| 466       type: "forward", | 456       type: "forward", | 
| 467       targetPageId: blockelementPopupId, | 457       targetPageId: blockelementPopupId, | 
| 468       payload: | 458       payload: | 
| 469       { | 459       { | 
| 470         type: "composer.dialog.close" | 460         type: "composer.dialog.close" | 
| 471       } | 461       } | 
| 472     }); | 462     }); | 
| 473 | 463 | 
| 474     blockelementPopupId = null; | 464     blockelementPopupId = null; | 
| 475   } | 465   } | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 497   // this because the contextMenu API only provides a URL, not the actual DOM | 487   // this because the contextMenu API only provides a URL, not the actual DOM | 
| 498   // element. | 488   // element. | 
| 499   //   We also need to make sure that the previous right click event, | 489   //   We also need to make sure that the previous right click event, | 
| 500   // if there is one, is removed. We don't know which frame it is in so we must | 490   // if there is one, is removed. We don't know which frame it is in so we must | 
| 501   // send a message to the other frames to clear their old right click events. | 491   // send a message to the other frames to clear their old right click events. | 
| 502   document.addEventListener("contextmenu", event => | 492   document.addEventListener("contextmenu", event => | 
| 503   { | 493   { | 
| 504     lastRightClickEvent = event; | 494     lastRightClickEvent = event; | 
| 505     lastRightClickEventIsMostRecent = true; | 495     lastRightClickEventIsMostRecent = true; | 
| 506 | 496 | 
| 507     ext.backgroundPage.sendMessage( | 497     ext.backgroundPage.sendMessage({ | 
| 508     { |  | 
| 509       type: "forward", | 498       type: "forward", | 
| 510       payload: | 499       payload: | 
| 511       { | 500       { | 
| 512         type: "composer.content.clearPreviousRightClickEvent" | 501         type: "composer.content.clearPreviousRightClickEvent" | 
| 513       } | 502       } | 
| 514     }); | 503     }); | 
| 515   }, true); | 504   }, true); | 
| 516 | 505 | 
| 517   ext.onMessage.addListener((msg, sender, sendResponse) => | 506   ext.onMessage.addListener((msg, sender, sendResponse) => | 
| 518   { | 507   { | 
| 519     switch (msg.type) | 508     switch (msg.type) | 
| 520     { | 509     { | 
| 521       case "composer.content.getState": | 510       case "composer.content.getState": | 
| 522         if (window == window.top) | 511         if (window == window.top) | 
|  | 512         { | 
| 523           sendResponse({ | 513           sendResponse({ | 
| 524             active: currentlyPickingElement || blockelementPopupId != null | 514             active: currentlyPickingElement || blockelementPopupId != null | 
| 525           }); | 515           }); | 
|  | 516         } | 
| 526         break; | 517         break; | 
| 527       case "composer.content.startPickingElement": | 518       case "composer.content.startPickingElement": | 
| 528         if (window == window.top) | 519         if (window == window.top) | 
| 529           startPickingElement(); | 520           startPickingElement(); | 
| 530         break; | 521         break; | 
| 531       case "composer.content.contextMenuClicked": | 522       case "composer.content.contextMenuClicked": | 
| 532         let event = lastRightClickEvent; | 523         let event = lastRightClickEvent; | 
| 533         deactivateBlockElement(); | 524         deactivateBlockElement(); | 
| 534         if (event) | 525         if (event) | 
| 535         { | 526         { | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 565         break; | 556         break; | 
| 566       case "composer.content.dialogOpened": | 557       case "composer.content.dialogOpened": | 
| 567         if (window == window.top) | 558         if (window == window.top) | 
| 568           blockelementPopupId = msg.popupId; | 559           blockelementPopupId = msg.popupId; | 
| 569         break; | 560         break; | 
| 570       case "composer.content.dialogClosed": | 561       case "composer.content.dialogClosed": | 
| 571         // The onRemoved hook for the popup can create a race condition, so we | 562         // The onRemoved hook for the popup can create a race condition, so we | 
| 572         // to be careful here. (This is not perfect, but best we can do.) | 563         // to be careful here. (This is not perfect, but best we can do.) | 
| 573         if (window == window.top && blockelementPopupId == msg.popupId) | 564         if (window == window.top && blockelementPopupId == msg.popupId) | 
| 574         { | 565         { | 
| 575           ext.backgroundPage.sendMessage( | 566           ext.backgroundPage.sendMessage({ | 
| 576           { |  | 
| 577             type: "forward", | 567             type: "forward", | 
| 578             payload: | 568             payload: | 
| 579             { | 569             { | 
| 580               type: "composer.content.finished" | 570               type: "composer.content.finished" | 
| 581             } | 571             } | 
| 582           }); | 572           }); | 
| 583         } | 573         } | 
| 584         break; | 574         break; | 
| 585     } | 575     } | 
| 586   }); | 576   }); | 
| 587 | 577 | 
| 588   if (window == window.top) | 578   if (window == window.top) | 
| 589     ext.backgroundPage.sendMessage({type: "composer.ready"}); | 579     ext.backgroundPage.sendMessage({type: "composer.ready"}); | 
| 590 } | 580 } | 
| OLD | NEW | 
|---|