| OLD | NEW | 
 | (Empty) | 
|    1 /* |  | 
|    2  * This file is part of Adblock Plus <https://adblockplus.org/>, |  | 
|    3  * Copyright (C) 2006-present eyeo GmbH |  | 
|    4  * |  | 
|    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 |  | 
|    7  * published by the Free Software Foundation. |  | 
|    8  * |  | 
|    9  * Adblock Plus is distributed in the hope that it will be useful, |  | 
|   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | 
|   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | 
|   12  * GNU General Public License for more details. |  | 
|   13  * |  | 
|   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/>. |  | 
|   16  */ |  | 
|   17  |  | 
|   18 "use strict"; |  | 
|   19  |  | 
|   20 let tab = null; |  | 
|   21  |  | 
|   22 function getPref(key, callback) |  | 
|   23 { |  | 
|   24   browser.runtime.sendMessage({type: "prefs.get", key}, callback); |  | 
|   25 } |  | 
|   26  |  | 
|   27 function setPref(key, value, callback) |  | 
|   28 { |  | 
|   29   browser.runtime.sendMessage({type: "prefs.set", key, value}, callback); |  | 
|   30 } |  | 
|   31  |  | 
|   32 function togglePref(key, callback) |  | 
|   33 { |  | 
|   34   browser.runtime.sendMessage({type: "prefs.toggle", key}, callback); |  | 
|   35 } |  | 
|   36  |  | 
|   37 function isPageWhitelisted(callback) |  | 
|   38 { |  | 
|   39   browser.runtime.sendMessage({type: "filters.isWhitelisted", tab}, callback); |  | 
|   40 } |  | 
|   41  |  | 
|   42 function whenPageReady() |  | 
|   43 { |  | 
|   44   return new Promise(resolve => |  | 
|   45   { |  | 
|   46     function onMessage(message, sender) |  | 
|   47     { |  | 
|   48       if (message.type == "composer.ready" && sender.page && |  | 
|   49           sender.page.id == tab.id) |  | 
|   50       { |  | 
|   51         browser.runtime.onMessage.removeListener(onMessage); |  | 
|   52         resolve(); |  | 
|   53       } |  | 
|   54     } |  | 
|   55  |  | 
|   56     browser.runtime.onMessage.addListener(onMessage); |  | 
|   57  |  | 
|   58     browser.runtime.sendMessage({ |  | 
|   59       type: "composer.isPageReady", |  | 
|   60       pageId: tab.id |  | 
|   61     }, |  | 
|   62     ready => |  | 
|   63     { |  | 
|   64       if (ready) |  | 
|   65       { |  | 
|   66         browser.runtime.onMessage.removeListener(onMessage); |  | 
|   67         resolve(); |  | 
|   68       } |  | 
|   69     }); |  | 
|   70   }); |  | 
|   71 } |  | 
|   72  |  | 
|   73 function toggleEnabled() |  | 
|   74 { |  | 
|   75   let disabled = document.body.classList.toggle("disabled"); |  | 
|   76   browser.runtime.sendMessage({ |  | 
|   77     type: disabled ? "filters.whitelist" : "filters.unwhitelist", |  | 
|   78     tab |  | 
|   79   }); |  | 
|   80 } |  | 
|   81  |  | 
|   82 function activateClickHide() |  | 
|   83 { |  | 
|   84   document.body.classList.add("clickhide-active"); |  | 
|   85   browser.tabs.sendMessage(tab.id, { |  | 
|   86     type: "composer.content.startPickingElement" |  | 
|   87   }); |  | 
|   88  |  | 
|   89   // Close the popup after a few seconds, so user doesn't have to |  | 
|   90   activateClickHide.timeout = window.setTimeout(window.close, 5000); |  | 
|   91 } |  | 
|   92  |  | 
|   93 function cancelClickHide() |  | 
|   94 { |  | 
|   95   if (activateClickHide.timeout) |  | 
|   96   { |  | 
|   97     window.clearTimeout(activateClickHide.timeout); |  | 
|   98     activateClickHide.timeout = null; |  | 
|   99   } |  | 
|  100   document.body.classList.remove("clickhide-active"); |  | 
|  101   browser.tabs.sendMessage(tab.id, {type: "composer.content.finished"}); |  | 
|  102 } |  | 
|  103  |  | 
|  104 function reportIssue() |  | 
|  105 { |  | 
|  106   browser.tabs.create({ |  | 
|  107     url: browser.runtime.getURL("/issue-reporter.html?" + tab.id) |  | 
|  108   }).then(() => |  | 
|  109   { |  | 
|  110     window.close(); |  | 
|  111   }); |  | 
|  112 } |  | 
|  113  |  | 
|  114 function toggleCollapse(event) |  | 
|  115 { |  | 
|  116   let collapser = event.currentTarget; |  | 
|  117   let collapsible = document.getElementById(collapser.dataset.collapsible); |  | 
|  118   collapsible.classList.toggle("collapsed"); |  | 
|  119   togglePref(collapser.dataset.option); |  | 
|  120 } |  | 
|  121  |  | 
|  122 function getDocLinks(notification) |  | 
|  123 { |  | 
|  124   if (!notification.links) |  | 
|  125     return Promise.resolve([]); |  | 
|  126  |  | 
|  127   return Promise.all( |  | 
|  128     notification.links.map(link => |  | 
|  129     { |  | 
|  130       return new Promise((resolve, reject) => |  | 
|  131       { |  | 
|  132         browser.runtime.sendMessage({ |  | 
|  133           type: "app.get", |  | 
|  134           what: "doclink", |  | 
|  135           link |  | 
|  136         }, resolve); |  | 
|  137       }); |  | 
|  138     }) |  | 
|  139   ); |  | 
|  140 } |  | 
|  141  |  | 
|  142 function insertMessage(element, text, links) |  | 
|  143 { |  | 
|  144   let match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(text); |  | 
|  145   if (!match) |  | 
|  146   { |  | 
|  147     element.appendChild(document.createTextNode(text)); |  | 
|  148     return; |  | 
|  149   } |  | 
|  150  |  | 
|  151   let before = match[1]; |  | 
|  152   let tagName = match[2]; |  | 
|  153   let value = match[3]; |  | 
|  154   let after = match[4]; |  | 
|  155  |  | 
|  156   insertMessage(element, before, links); |  | 
|  157  |  | 
|  158   let newElement = document.createElement(tagName); |  | 
|  159   if (tagName == "a" && links && links.length) |  | 
|  160     newElement.href = links.shift(); |  | 
|  161   insertMessage(newElement, value, links); |  | 
|  162   element.appendChild(newElement); |  | 
|  163  |  | 
|  164   insertMessage(element, after, links); |  | 
|  165 } |  | 
|  166  |  | 
|  167 function updateStats() |  | 
|  168 { |  | 
|  169   let statsPage = document.getElementById("stats-page"); |  | 
|  170   browser.runtime.sendMessage({ |  | 
|  171     type: "stats.getBlockedPerPage", |  | 
|  172     tab |  | 
|  173   }, |  | 
|  174   blockedPage => |  | 
|  175   { |  | 
|  176     ext.i18n.setElementText(statsPage, "stats_label_page", |  | 
|  177                             [blockedPage.toLocaleString()]); |  | 
|  178   }); |  | 
|  179  |  | 
|  180   let statsTotal = document.getElementById("stats-total"); |  | 
|  181   getPref("blocked_total", blockedTotal => |  | 
|  182   { |  | 
|  183     ext.i18n.setElementText(statsTotal, "stats_label_total", |  | 
|  184                             [blockedTotal.toLocaleString()]); |  | 
|  185   }); |  | 
|  186 } |  | 
|  187  |  | 
|  188 function toggleIconNumber() |  | 
|  189 { |  | 
|  190   togglePref("show_statsinicon", showStatsInIcon => |  | 
|  191   { |  | 
|  192     document.getElementById("show-iconnumber").setAttribute( |  | 
|  193       "aria-checked", showStatsInIcon |  | 
|  194     ); |  | 
|  195   }); |  | 
|  196 } |  | 
|  197  |  | 
|  198 document.addEventListener("DOMContentLoaded", () => |  | 
|  199 { |  | 
|  200   browser.tabs.query({active: true, lastFocusedWindow: true}, tabs => |  | 
|  201   { |  | 
|  202     if (tabs.length > 0) |  | 
|  203       tab = {id: tabs[0].id, url: tabs[0].url}; |  | 
|  204  |  | 
|  205     let urlProtocol = tab && tab.url && new URL(tab.url).protocol; |  | 
|  206  |  | 
|  207     // Mark page as 'local' to hide non-relevant elements |  | 
|  208     if (urlProtocol != "http:" && urlProtocol != "https:") |  | 
|  209     { |  | 
|  210       document.body.classList.add("local"); |  | 
|  211       document.body.classList.remove("nohtml"); |  | 
|  212     } |  | 
|  213     else |  | 
|  214     { |  | 
|  215       whenPageReady().then(() => |  | 
|  216       { |  | 
|  217         document.body.classList.remove("nohtml"); |  | 
|  218       }); |  | 
|  219     } |  | 
|  220  |  | 
|  221     // Ask content script whether clickhide is active. If so, show |  | 
|  222     // cancel button.  If that isn't the case, ask background.html |  | 
|  223     // whether it has cached filters. If so, ask the user whether she |  | 
|  224     // wants those filters. Otherwise, we are in default state. |  | 
|  225     if (tab) |  | 
|  226     { |  | 
|  227       isPageWhitelisted(whitelisted => |  | 
|  228       { |  | 
|  229         if (whitelisted) |  | 
|  230           document.body.classList.add("disabled"); |  | 
|  231       }); |  | 
|  232  |  | 
|  233       browser.tabs.sendMessage(tab.id, { |  | 
|  234         type: "composer.content.getState" |  | 
|  235       }, |  | 
|  236       response => |  | 
|  237       { |  | 
|  238         if (response && response.active) |  | 
|  239           document.body.classList.add("clickhide-active"); |  | 
|  240       }); |  | 
|  241     } |  | 
|  242  |  | 
|  243     updateStats(); |  | 
|  244     document.getElementById("stats-container").removeAttribute("hidden"); |  | 
|  245   }); |  | 
|  246  |  | 
|  247   document.getElementById("enabled").addEventListener( |  | 
|  248     "click", toggleEnabled |  | 
|  249   ); |  | 
|  250   document.getElementById("clickhide").addEventListener( |  | 
|  251     "click", activateClickHide |  | 
|  252   ); |  | 
|  253   document.getElementById("clickhide-cancel").addEventListener( |  | 
|  254     "click", cancelClickHide |  | 
|  255   ); |  | 
|  256   document.getElementById("issueReporter").addEventListener( |  | 
|  257     "click", reportIssue |  | 
|  258   ); |  | 
|  259   document.getElementById("options").addEventListener("click", () => |  | 
|  260   { |  | 
|  261     browser.runtime.sendMessage({type: "app.open", what: "options"}); |  | 
|  262     window.close(); |  | 
|  263   }); |  | 
|  264  |  | 
|  265   // Set up collapsing of menu items |  | 
|  266   for (let collapser of document.getElementsByClassName("collapse")) |  | 
|  267   { |  | 
|  268     collapser.addEventListener("click", toggleCollapse); |  | 
|  269     getPref(collapser.dataset.option, value => |  | 
|  270     { |  | 
|  271       if (value) |  | 
|  272       { |  | 
|  273         document.getElementById( |  | 
|  274           collapser.dataset.collapsible |  | 
|  275         ).classList.remove("collapsed"); |  | 
|  276       } |  | 
|  277     }); |  | 
|  278   } |  | 
|  279  |  | 
|  280   let showIconNumber = document.getElementById("show-iconnumber"); |  | 
|  281   getPref("show_statsinicon", showStatsInIcon => |  | 
|  282   { |  | 
|  283     showIconNumber.setAttribute("aria-checked", showStatsInIcon); |  | 
|  284   }); |  | 
|  285   showIconNumber.addEventListener("click", toggleIconNumber); |  | 
|  286   document.querySelector("label[for='show-iconnumber']").addEventListener( |  | 
|  287     "click", toggleIconNumber |  | 
|  288   ); |  | 
|  289 }); |  | 
|  290  |  | 
|  291 window.addEventListener("load", () => |  | 
|  292 { |  | 
|  293   browser.runtime.sendMessage({ |  | 
|  294     type: "notifications.get", |  | 
|  295     displayMethod: "popup" |  | 
|  296   }, notification => |  | 
|  297   { |  | 
|  298     if (!notification) |  | 
|  299       return; |  | 
|  300  |  | 
|  301     let titleElement = document.getElementById("notification-title"); |  | 
|  302     let messageElement = document.getElementById("notification-message"); |  | 
|  303  |  | 
|  304     titleElement.textContent = notification.texts.title; |  | 
|  305  |  | 
|  306     getDocLinks(notification).then(docLinks => |  | 
|  307     { |  | 
|  308       insertMessage(messageElement, notification.texts.message, docLinks); |  | 
|  309  |  | 
|  310       messageElement.addEventListener("click", event => |  | 
|  311       { |  | 
|  312         let link = event.target; |  | 
|  313         while (link && link != messageElement && link.localName != "a") |  | 
|  314           link = link.parentNode; |  | 
|  315         if (!link) |  | 
|  316           return; |  | 
|  317         event.preventDefault(); |  | 
|  318         event.stopPropagation(); |  | 
|  319         browser.tabs.create({url: link.href}); |  | 
|  320       }); |  | 
|  321     }); |  | 
|  322  |  | 
|  323     let notificationElement = document.getElementById("notification"); |  | 
|  324     notificationElement.className = notification.type; |  | 
|  325     notificationElement.hidden = false; |  | 
|  326     notificationElement.addEventListener("click", event => |  | 
|  327     { |  | 
|  328       if (event.target.id == "notification-close") |  | 
|  329         notificationElement.classList.add("closing"); |  | 
|  330       else if (event.target.id == "notification-optout" || |  | 
|  331                event.target.id == "notification-hide") |  | 
|  332       { |  | 
|  333         if (event.target.id == "notification-optout") |  | 
|  334           setPref("notifications_ignoredcategories", true); |  | 
|  335  |  | 
|  336         notificationElement.hidden = true; |  | 
|  337         browser.runtime.sendMessage({type: "notifications.clicked"}); |  | 
|  338       } |  | 
|  339     }, true); |  | 
|  340   }); |  | 
|  341 }); |  | 
| OLD | NEW |