| 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") | 
| 74       element = element.parentElement; | 75       element = element.parentElement; | 
| 75 |  | 
| 76     // If image maps are used mouse events occur for the <area> element. | 76     // 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. | 77     // But we have to block the image associated with the <map> element. | 
| 78     else if (element.localName == "map") | 78     else if (element.localName == "map") | 
| 79     { | 79     { | 
| 80       let images = document.querySelectorAll("img[usemap]"); | 80       let images = document.querySelectorAll("img[usemap]"); | 
| 81       let image = null; | 81       let image = null; | 
| 82 | 82 | 
| 83       for (let currentImage of images) | 83       for (let currentImage of images) | 
| 84       { | 84       { | 
| 85         let usemap = currentImage.getAttribute("usemap"); | 85         let usemap = currentImage.getAttribute("usemap"); | 
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 381 { | 381 { | 
| 382   if (!currentElement) | 382   if (!currentElement) | 
| 383     return; | 383     return; | 
| 384 | 384 | 
| 385   let element = currentElement.prisoner || currentElement; | 385   let element = currentElement.prisoner || currentElement; | 
| 386   getFiltersForElement(element, (filters, selectors) => | 386   getFiltersForElement(element, (filters, selectors) => | 
| 387   { | 387   { | 
| 388     if (currentlyPickingElement) | 388     if (currentlyPickingElement) | 
| 389       stopPickingElement(); | 389       stopPickingElement(); | 
| 390 | 390 | 
| 391     ext.backgroundPage.sendMessage( | 391     ext.backgroundPage.sendMessage({ | 
| 392     { |  | 
| 393       type: "composer.openDialog" | 392       type: "composer.openDialog" | 
| 394     }, | 393     }, | 
| 395     popupId => | 394     popupId => | 
| 396     { | 395     { | 
| 397       ext.backgroundPage.sendMessage( | 396       ext.backgroundPage.sendMessage({ | 
| 398       { |  | 
| 399         type: "forward", | 397         type: "forward", | 
| 400         targetPageId: popupId, | 398         targetPageId: popupId, | 
| 401         payload: | 399         payload: {type: "composer.dialog.init", filters} | 
| 402         { |  | 
| 403           type: "composer.dialog.init", |  | 
| 404           filters: filters |  | 
| 405         } |  | 
| 406       }); | 400       }); | 
| 407 | 401 | 
| 408       // Only the top frame keeps a record of the popup window's ID, | 402       // 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. | 403       // so if this isn't the top frame we need to pass the ID on. | 
| 410       if (window == window.top) | 404       if (window == window.top) | 
| 411       { |  | 
| 412         blockelementPopupId = popupId; | 405         blockelementPopupId = popupId; | 
| 413       } |  | 
| 414       else | 406       else | 
| 415       { | 407       { | 
| 416         ext.backgroundPage.sendMessage( | 408         ext.backgroundPage.sendMessage({ | 
| 417         { |  | 
| 418           type: "forward", | 409           type: "forward", | 
| 419           payload: | 410           payload: {type: "composer.content.dialogOpened", popupId} | 
| 420           { |  | 
| 421             type: "composer.content.dialogOpened", |  | 
| 422             popupId: popupId |  | 
| 423           } |  | 
| 424         }); | 411         }); | 
| 425       } | 412       } | 
| 426     }); | 413     }); | 
| 427 | 414 | 
| 428     if (selectors.length > 0) | 415     if (selectors.length > 0) | 
| 429       highlightElements(selectors.join(",")); | 416       highlightElements(selectors.join(",")); | 
| 430 | 417 | 
| 431     highlightElement(currentElement, "#fd1708", "#f6a1b5"); | 418     highlightElement(currentElement, "#fd1708", "#f6a1b5"); | 
| 432   }); | 419   }); | 
| 433 | 420 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 454 /* Core logic */ | 441 /* Core logic */ | 
| 455 | 442 | 
| 456 // We're done with the block element feature for now, tidy everything up. | 443 // We're done with the block element feature for now, tidy everything up. | 
| 457 function deactivateBlockElement() | 444 function deactivateBlockElement() | 
| 458 { | 445 { | 
| 459   if (currentlyPickingElement) | 446   if (currentlyPickingElement) | 
| 460     stopPickingElement(); | 447     stopPickingElement(); | 
| 461 | 448 | 
| 462   if (blockelementPopupId != null) | 449   if (blockelementPopupId != null) | 
| 463   { | 450   { | 
| 464     ext.backgroundPage.sendMessage( | 451     ext.backgroundPage.sendMessage({ | 
| 465     { |  | 
| 466       type: "forward", | 452       type: "forward", | 
| 467       targetPageId: blockelementPopupId, | 453       targetPageId: blockelementPopupId, | 
| 468       payload: | 454       payload: | 
| 469       { | 455       { | 
| 470         type: "composer.dialog.close" | 456         type: "composer.dialog.close" | 
| 471       } | 457       } | 
| 472     }); | 458     }); | 
| 473 | 459 | 
| 474     blockelementPopupId = null; | 460     blockelementPopupId = null; | 
| 475   } | 461   } | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 497   // this because the contextMenu API only provides a URL, not the actual DOM | 483   // this because the contextMenu API only provides a URL, not the actual DOM | 
| 498   // element. | 484   // element. | 
| 499   //   We also need to make sure that the previous right click event, | 485   //   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 | 486   // 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. | 487   // send a message to the other frames to clear their old right click events. | 
| 502   document.addEventListener("contextmenu", event => | 488   document.addEventListener("contextmenu", event => | 
| 503   { | 489   { | 
| 504     lastRightClickEvent = event; | 490     lastRightClickEvent = event; | 
| 505     lastRightClickEventIsMostRecent = true; | 491     lastRightClickEventIsMostRecent = true; | 
| 506 | 492 | 
| 507     ext.backgroundPage.sendMessage( | 493     ext.backgroundPage.sendMessage({ | 
| 508     { |  | 
| 509       type: "forward", | 494       type: "forward", | 
| 510       payload: | 495       payload: | 
| 511       { | 496       { | 
| 512         type: "composer.content.clearPreviousRightClickEvent" | 497         type: "composer.content.clearPreviousRightClickEvent" | 
| 513       } | 498       } | 
| 514     }); | 499     }); | 
| 515   }, true); | 500   }, true); | 
| 516 | 501 | 
| 517   ext.onMessage.addListener((msg, sender, sendResponse) => | 502   ext.onMessage.addListener((msg, sender, sendResponse) => | 
| 518   { | 503   { | 
| 519     switch (msg.type) | 504     switch (msg.type) | 
| 520     { | 505     { | 
| 521       case "composer.content.getState": | 506       case "composer.content.getState": | 
| 522         if (window == window.top) | 507         if (window == window.top) | 
|  | 508         { | 
| 523           sendResponse({ | 509           sendResponse({ | 
| 524             active: currentlyPickingElement || blockelementPopupId != null | 510             active: currentlyPickingElement || blockelementPopupId != null | 
| 525           }); | 511           }); | 
|  | 512         } | 
| 526         break; | 513         break; | 
| 527       case "composer.content.startPickingElement": | 514       case "composer.content.startPickingElement": | 
| 528         if (window == window.top) | 515         if (window == window.top) | 
| 529           startPickingElement(); | 516           startPickingElement(); | 
| 530         break; | 517         break; | 
| 531       case "composer.content.contextMenuClicked": | 518       case "composer.content.contextMenuClicked": | 
| 532         let event = lastRightClickEvent; | 519         let event = lastRightClickEvent; | 
| 533         deactivateBlockElement(); | 520         deactivateBlockElement(); | 
| 534         if (event) | 521         if (event) | 
| 535         { | 522         { | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 565         break; | 552         break; | 
| 566       case "composer.content.dialogOpened": | 553       case "composer.content.dialogOpened": | 
| 567         if (window == window.top) | 554         if (window == window.top) | 
| 568           blockelementPopupId = msg.popupId; | 555           blockelementPopupId = msg.popupId; | 
| 569         break; | 556         break; | 
| 570       case "composer.content.dialogClosed": | 557       case "composer.content.dialogClosed": | 
| 571         // The onRemoved hook for the popup can create a race condition, so we | 558         // 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.) | 559         // to be careful here. (This is not perfect, but best we can do.) | 
| 573         if (window == window.top && blockelementPopupId == msg.popupId) | 560         if (window == window.top && blockelementPopupId == msg.popupId) | 
| 574         { | 561         { | 
| 575           ext.backgroundPage.sendMessage( | 562           ext.backgroundPage.sendMessage({ | 
| 576           { |  | 
| 577             type: "forward", | 563             type: "forward", | 
| 578             payload: | 564             payload: | 
| 579             { | 565             { | 
| 580               type: "composer.content.finished" | 566               type: "composer.content.finished" | 
| 581             } | 567             } | 
| 582           }); | 568           }); | 
| 583         } | 569         } | 
| 584         break; | 570         break; | 
| 585     } | 571     } | 
| 586   }); | 572   }); | 
| 587 | 573 | 
| 588   if (window == window.top) | 574   if (window == window.top) | 
| 589     ext.backgroundPage.sendMessage({type: "composer.ready"}); | 575     ext.backgroundPage.sendMessage({type: "composer.ready"}); | 
| 590 } | 576 } | 
| OLD | NEW | 
|---|