| LEFT | RIGHT | 
|---|
| 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 | 
| 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 "use strict"; | 18 "use strict"; | 
| 19 | 19 | 
| 20 const {require} = ext.backgroundPage.getWindow(); | 20 let tab = null; | 
| 21 | 21 | 
| 22 const {Filter} = require("filterClasses"); | 22 function getPref(key, callback) | 
| 23 const {FilterStorage} = require("filterStorage"); |  | 
| 24 const {checkWhitelisted} = require("whitelisting"); |  | 
| 25 const {getDecodedHostname} = require("url"); |  | 
| 26 |  | 
| 27 let page = null; |  | 
| 28 |  | 
| 29 function checkPageReady(pageId, callback) |  | 
| 30 { | 23 { | 
| 31   chrome.runtime.sendMessage({type: "composer.isPageReady", pageId}, callback); | 24   chrome.runtime.sendMessage({type: "prefs.get", key}, callback); | 
| 32 } | 25 } | 
| 33 | 26 | 
| 34 function waitForPageReady(pageId, callback) | 27 function togglePref(key, callback) | 
| 35 { | 28 { | 
| 36   let listener = (message, sender) => | 29   chrome.runtime.sendMessage({type: "prefs.toggle", key}, callback); | 
|  | 30 } | 
|  | 31 | 
|  | 32 function isPageWhitelisted(callback) | 
|  | 33 { | 
|  | 34   chrome.runtime.sendMessage({type: "filters.isWhitelisted", tab}, callback); | 
|  | 35 } | 
|  | 36 | 
|  | 37 function whenPageReady() | 
|  | 38 { | 
|  | 39   return new Promise(resolve => | 
| 37   { | 40   { | 
| 38     if (message.type == "composer.ready" && sender.page.id == pageId) | 41     function onMessage(message, sender) | 
| 39     { | 42     { | 
| 40       ext.onMessage.removeListener(listener); | 43       if (message.type == "composer.ready" && sender.page && | 
| 41       callback(); | 44           sender.page.id == tab.id) | 
|  | 45       { | 
|  | 46         ext.onMessage.removeListener(onMessage); | 
|  | 47         resolve(); | 
|  | 48       } | 
| 42     } | 49     } | 
| 43   }; |  | 
| 44 | 50 | 
| 45   ext.onMessage.addListener(listener); | 51     ext.onMessage.addListener(onMessage); | 
|  | 52 | 
|  | 53     chrome.runtime.sendMessage({ | 
|  | 54       type: "composer.isPageReady", | 
|  | 55       pageId: tab.id | 
|  | 56     }, | 
|  | 57     ready => | 
|  | 58     { | 
|  | 59       if (ready) | 
|  | 60       { | 
|  | 61         ext.onMessage.removeListener(onMessage); | 
|  | 62         resolve(); | 
|  | 63       } | 
|  | 64     }); | 
|  | 65   }); | 
| 46 } | 66 } | 
| 47 | 67 | 
| 48 function onLoad() | 68 function onLoad() | 
| 49 { | 69 { | 
| 50   ext.pages.query({active: true, lastFocusedWindow: true}, pages => | 70   chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => | 
| 51   { | 71   { | 
| 52     page = pages[0]; | 72     if (tabs.length > 0) | 
|  | 73       tab = {id: tabs[0].id, url: tabs[0].url}; | 
| 53 | 74 | 
| 54     // Mark page as 'local' or 'nohtml' to hide non-relevant elements | 75     let urlProtocol = tab && tab.url && new URL(tab.url).protocol; | 
| 55     if (!page || (page.url.protocol != "http:" && | 76 | 
| 56                   page.url.protocol != "https:")) | 77     // Mark page as 'local' to hide non-relevant elements | 
|  | 78     if (urlProtocol != "http:" && urlProtocol != "https:") | 
| 57     { | 79     { | 
| 58       document.body.classList.add("local"); | 80       document.body.classList.add("local"); | 
|  | 81       document.body.classList.remove("nohtml"); | 
| 59     } | 82     } | 
| 60     else | 83     else | 
| 61     { | 84     { | 
| 62       checkPageReady(page.id, ready => | 85       whenPageReady().then(() => | 
| 63       { | 86       { | 
| 64         if (!ready) | 87         document.body.classList.remove("nohtml"); | 
| 65         { |  | 
| 66           document.body.classList.add("nohtml"); |  | 
| 67           waitForPageReady(page.id, () => |  | 
| 68           { |  | 
| 69             document.body.classList.remove("nohtml"); |  | 
| 70           }); |  | 
| 71         } |  | 
| 72       }); | 88       }); | 
| 73     } | 89     } | 
| 74 | 90 | 
| 75     // Ask content script whether clickhide is active. If so, show | 91     // Ask content script whether clickhide is active. If so, show | 
| 76     // cancel button.  If that isn't the case, ask background.html | 92     // cancel button.  If that isn't the case, ask background.html | 
| 77     // whether it has cached filters. If so, ask the user whether she | 93     // whether it has cached filters. If so, ask the user whether she | 
| 78     // wants those filters. Otherwise, we are in default state. | 94     // wants those filters. Otherwise, we are in default state. | 
| 79     if (page) | 95     if (tab) | 
| 80     { | 96     { | 
| 81       if (checkWhitelisted(page)) | 97       isPageWhitelisted(whitelisted => | 
| 82         document.body.classList.add("disabled"); | 98       { | 
|  | 99         if (whitelisted) | 
|  | 100           document.body.classList.add("disabled"); | 
|  | 101       }); | 
| 83 | 102 | 
| 84       page.sendMessage({type: "composer.content.getState"}, response => | 103       chrome.tabs.sendMessage(tab.id, { | 
|  | 104         type: "composer.content.getState" | 
|  | 105       }, | 
|  | 106       response => | 
| 85       { | 107       { | 
| 86         if (response && response.active) | 108         if (response && response.active) | 
| 87           document.body.classList.add("clickhide-active"); | 109           document.body.classList.add("clickhide-active"); | 
| 88       }); | 110       }); | 
| 89     } | 111     } | 
| 90   }); | 112   }); | 
| 91 | 113 | 
| 92   document.getElementById("enabled").addEventListener( | 114   document.getElementById("enabled").addEventListener( | 
| 93     "click", toggleEnabled, false | 115     "click", toggleEnabled, false | 
| 94   ); | 116   ); | 
| 95   document.getElementById("clickhide").addEventListener( | 117   document.getElementById("clickhide").addEventListener( | 
| 96     "click", activateClickHide, false | 118     "click", activateClickHide, false | 
| 97   ); | 119   ); | 
| 98   document.getElementById("clickhide-cancel").addEventListener( | 120   document.getElementById("clickhide-cancel").addEventListener( | 
| 99     "click", cancelClickHide, false | 121     "click", cancelClickHide, false | 
| 100   ); | 122   ); | 
| 101   document.getElementById("options").addEventListener("click", () => | 123   document.getElementById("options").addEventListener("click", () => | 
| 102   { | 124   { | 
| 103     ext.showOptions(); | 125     ext.showOptions(window.close); | 
| 104   }, false); | 126   }, false); | 
| 105 | 127 | 
| 106   // Set up collapsing of menu items | 128   // Set up collapsing of menu items | 
| 107   for (let collapser of document.getElementsByClassName("collapse")) | 129   for (let collapser of document.getElementsByClassName("collapse")) | 
| 108   { | 130   { | 
| 109     collapser.addEventListener("click", toggleCollapse, false); | 131     collapser.addEventListener("click", toggleCollapse, false); | 
| 110     ext.prefs.get(collapser.dataset.option, value => | 132     getPref(collapser.dataset.option, value => | 
| 111     { | 133     { | 
| 112       if (value) | 134       if (value) | 
| 113       { | 135       { | 
| 114         document.getElementById( | 136         document.getElementById( | 
| 115           collapser.dataset.collapsible | 137           collapser.dataset.collapsible | 
| 116         ).classList.remove("collapsed"); | 138         ).classList.remove("collapsed"); | 
| 117       } | 139       } | 
| 118     }); | 140     }); | 
| 119   } | 141   } | 
| 120 } | 142 } | 
| 121 | 143 | 
| 122 function toggleEnabled() | 144 function toggleEnabled() | 
| 123 { | 145 { | 
| 124   let disabled = document.body.classList.toggle("disabled"); | 146   let disabled = document.body.classList.toggle("disabled"); | 
| 125   if (disabled) | 147   chrome.runtime.sendMessage({ | 
| 126   { | 148     type: disabled ? "filters.whitelist" : "filters.unwhitelist", | 
| 127     let host = getDecodedHostname(page.url).replace(/^www\./, ""); | 149     tab | 
| 128     let filter = Filter.fromText("@@||" + host + "^$document"); | 150   }); | 
| 129     if (filter.subscriptions.length && filter.disabled) |  | 
| 130       filter.disabled = false; |  | 
| 131     else |  | 
| 132     { |  | 
| 133       filter.disabled = false; |  | 
| 134       FilterStorage.addFilter(filter); |  | 
| 135     } |  | 
| 136   } |  | 
| 137   else |  | 
| 138   { |  | 
| 139     // Remove any exception rules applying to this URL |  | 
| 140     let filter = checkWhitelisted(page); |  | 
| 141     while (filter) |  | 
| 142     { |  | 
| 143       FilterStorage.removeFilter(filter); |  | 
| 144       if (filter.subscriptions.length) |  | 
| 145         filter.disabled = true; |  | 
| 146       filter = checkWhitelisted(page); |  | 
| 147     } |  | 
| 148   } |  | 
| 149 } | 151 } | 
| 150 | 152 | 
| 151 function activateClickHide() | 153 function activateClickHide() | 
| 152 { | 154 { | 
| 153   document.body.classList.add("clickhide-active"); | 155   document.body.classList.add("clickhide-active"); | 
| 154   page.sendMessage({type: "composer.content.startPickingElement"}); | 156   chrome.tabs.sendMessage(tab.id, { | 
|  | 157     type: "composer.content.startPickingElement" | 
|  | 158   }); | 
| 155 | 159 | 
| 156   // Close the popup after a few seconds, so user doesn't have to | 160   // Close the popup after a few seconds, so user doesn't have to | 
| 157   activateClickHide.timeout = window.setTimeout(ext.closePopup, 5000); | 161   activateClickHide.timeout = window.setTimeout(window.close, 5000); | 
| 158 } | 162 } | 
| 159 | 163 | 
| 160 function cancelClickHide() | 164 function cancelClickHide() | 
| 161 { | 165 { | 
| 162   if (activateClickHide.timeout) | 166   if (activateClickHide.timeout) | 
| 163   { | 167   { | 
| 164     window.clearTimeout(activateClickHide.timeout); | 168     window.clearTimeout(activateClickHide.timeout); | 
| 165     activateClickHide.timeout = null; | 169     activateClickHide.timeout = null; | 
| 166   } | 170   } | 
| 167   document.body.classList.remove("clickhide-active"); | 171   document.body.classList.remove("clickhide-active"); | 
| 168   page.sendMessage({type: "composer.content.finished"}); | 172   chrome.tabs.sendMessage(tab.id, {type: "composer.content.finished"}); | 
| 169 } | 173 } | 
| 170 | 174 | 
| 171 function toggleCollapse(event) | 175 function toggleCollapse(event) | 
| 172 { | 176 { | 
| 173   let collapser = event.currentTarget; | 177   let collapser = event.currentTarget; | 
| 174   let collapsible = document.getElementById(collapser.dataset.collapsible); | 178   let collapsible = document.getElementById(collapser.dataset.collapsible); | 
| 175   collapsible.classList.toggle("collapsed"); | 179   collapsible.classList.toggle("collapsed"); | 
| 176   ext.prefs.toggle(collapser.dataset.option); | 180   togglePref(collapser.dataset.option); | 
| 177 } | 181 } | 
| 178 | 182 | 
| 179 document.addEventListener("DOMContentLoaded", onLoad, false); | 183 document.addEventListener("DOMContentLoaded", onLoad, false); | 
| LEFT | RIGHT | 
|---|