Index: options.js |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/options.js |
@@ -0,0 +1,709 @@ |
+/* |
+ * This file is part of Adblock Plus <https://adblockplus.org/>, |
+ * Copyright (C) 2006-2015 Eyeo GmbH |
+ * |
+ * Adblock Plus is free software: you can redistribute it and/or modify |
+ * it under the terms of the GNU General Public License version 3 as |
+ * published by the Free Software Foundation. |
+ * |
+ * Adblock Plus is distributed in the hope that it will be useful, |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ * GNU General Public License for more details. |
+ * |
+ * You should have received a copy of the GNU General Public License |
+ * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
+ */ |
+ |
+"use strict"; |
+ |
+(function() |
+{ |
+ var optionSubscriptions = {}; |
+ var acceptableAdsUrl = null; |
+ |
+ function onDOMLoaded() |
+ { |
+ initTabs(); |
+ updateVersionNumber(); |
+ updateShareLink(); |
+ populateLists(); |
+ |
+ setLinks("block-element-explanation", "#"); |
+ |
+ E("add-blocking-list").addEventListener("click", Modal.open, false); |
+ E("add-website-language").addEventListener("click", Modal.open, false); |
+ E("modal-close").addEventListener("click", Modal.close, false); |
+ E("whitelisting-add-icon").addEventListener("click", whitelistDomainBtnClick, false); |
+ E("whitelisting-add-btn").addEventListener("click", whitelistDomainBtnClick, false); |
+ E("whitelisting-enter-icon").addEventListener("click", whitelistDomainBtnClick, false); |
+ E("whitelisting-textbox").addEventListener("keypress", function(e) { |
+ if (e.keyCode == 13) |
+ whitelistDomainBtnClick(); |
+ }, false); |
+ E("whitelisting-cancel-btn").addEventListener("click", function(){ |
+ E("whitelisting-textbox").value = ""; |
+ }, false); |
+ E("allow-whitelist-cb").addEventListener("click", toggleAcceptableAds, false); |
+ E("import-blockingList-btn").addEventListener("click", importListBtnCLick, false); |
+ E("edit-ownBlockingList-btn").addEventListener("click", editOwnRulsBtnClick, false); |
+ E("find-language").addEventListener("keyup", searchLanguage, false); |
+ } |
+ |
+ function initTabs() |
+ { |
+ var showContent = function(tab) |
+ { |
+ var tab = tab.querySelector(".tabs li.active"); |
+ if (tab.dataset.show) |
+ E(tab.dataset.show).style.display = "block"; |
+ }; |
+ var optionList = document.querySelectorAll('.tabs li[data-show]'); |
+ for (var i = 0; i < optionList.length; ++i) |
+ { |
+ optionList[i].addEventListener("click", function(ev) |
+ { |
+ var tab = this.parentNode.querySelector(".active"); |
+ tab.classList.remove("active"); |
+ this.classList.add("active"); |
+ E(tab.dataset.show).style.display = "none";; |
+ showContent(this.parentNode); |
+ }, false); |
+ } |
+ showContent(E("main-navigation-tabs")); |
+ showContent(E("blocking-list-tabs")); |
+ } |
+ |
+ var Modal = |
+ { |
+ open: function (content) |
+ { |
+ var modal = E("modal"); |
+ var content = E(this && this.dataset ? this.dataset.show : content); |
+ content.style.display = "block"; |
+ modal.style.visibility = "visible"; |
+ E("modal-background").style.display = "block"; |
+ if (content.dataset.title) |
+ E("modal-title").innerHTML = ext.i18n.getMessage(content.dataset.title); |
+ modal.style.marginTop = -(modal.clientHeight/2)+"px"; |
+ }, |
+ close: function () |
+ { |
+ var contents = E("modal-content").childNodes; |
+ for (var i = 0; i < contents.length; ++i) |
+ { |
+ if (contents[i].style) |
+ contents[i].style.display = "none"; |
+ } |
+ E("modal-background").style.display = "none"; |
+ E("modal").style.visibility = "hidden"; |
+ } |
+ } |
+ |
+ function populateLists() |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "subscriptions.get", |
+ special: true |
+ }, function(subscriptions) |
+ { |
+ for (var i = 0; i < subscriptions.length; i++) |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "filters.get", |
+ subscriptionUrl: subscriptions[i].url |
+ }, function(filters) |
+ { |
+ var whitelistArray = []; |
+ for (var i = 0; i < filters.length; i++) |
+ { |
+ var match = filters[i].text.match(/^@@\|\|([^\/:]+)\^\$document$/); |
+ if (match[1]) |
+ { |
+ whitelistArray.push(match[1]); |
+ } |
+ else |
+ { |
+ // TODO: add `filters[i].text` to list of custom filters |
+ } |
+ } |
+ |
+ if (whitelistArray.length > 0) |
+ { |
+ whitelistArray.sort(); |
+ for (var i = 0; i < whitelistArray.length; i++) |
+ { |
+ var domain = whitelistArray[i]; |
+ E("whitelisting-table").appendChild(createWhitelistElem(domain)); |
+ } |
+ } |
+ }); |
+ } |
+ }); |
+ |
+ loadRecommendations(function(recommends) |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "subscriptions.get", |
+ downloadable: true |
+ }, function(subscriptions) |
+ { |
+ getAcceptableAdsURL(function(url) |
+ { |
+ acceptableAdsUrl = url; |
+ for (var i = 0; i < subscriptions.length; i++) |
+ { |
+ if (subscriptions[i].url == acceptableAdsUrl) |
+ { |
+ E("allow-whitelist-cb").previousSibling.checked = !subscriptions[i].disabled; |
+ continue; |
+ } |
+ |
+ var subscription = recommends[subscriptions[i].url]; |
+ if (!subscription) |
+ recommends[subscriptions[i].url] = subscriptions[i]; |
+ else |
+ { |
+ subscription.disabled = subscriptions[i].disabled; |
+ if (subscription.type == "ads") |
+ subscription.isAdded = true; |
+ } |
+ } |
+ for (var key in recommends) |
+ addOptionItem(recommends[key]); |
+ }); |
+ }); |
+ }); |
+ } |
+ |
+ function loadRecommendations(callback) |
+ { |
+ var recommendations = {}; |
+ var request = new XMLHttpRequest(); |
+ request.open("GET", "subscriptions.xml"); |
+ request.onload = function() |
+ { |
+ var list = document.getElementById("subscriptionSelector"); |
+ var elements = request.responseXML.documentElement.getElementsByTagName("subscription"); |
+ for (var i = 0; i < elements.length; i++) |
+ { |
+ var element = elements[i]; |
+ var subscription = {}; |
+ subscription.title = element.getAttribute("title"); |
+ subscription.url = element.getAttribute("url"); |
+ subscription.disabled = true; |
+ var prefix = element.getAttribute("prefixes"); |
+ if (prefix) |
+ { |
+ subscription.prefixes = element.getAttribute("prefixes"); |
+ subscription.type = "ads"; |
+ subscription.display = ext.i18n.getMessage("options_language_"+subscription.prefixes.replace(/,/g, '_')); |
+ } |
+ else |
+ subscription.display = element.getAttribute("specialization"); |
+ |
+ var popular = element.getAttribute("popular"); |
+ if (popular) |
+ subscription.popular = element.getAttribute("popular"); |
+ |
+ recommendations[subscription.url] = subscription; |
+ } |
+ optionSubscriptions = recommendations; |
+ callback(recommendations); |
+ } |
+ request.send(); |
+ } |
+ |
+ function searchLanguage() |
+ { |
+ var searchVal = this.value; |
+ var items = E("all-lang-table").childNodes; |
+ for (var i = 0; i < items.length; ++i) |
+ { |
+ var item = items[i]; |
+ var language = item.getElementsByTagName("span")[1].innerHTML; |
+ if (language.toLowerCase().indexOf(searchVal.toLowerCase()) > -1) |
+ item.style.display = "block"; |
+ else |
+ item.style.display = "none"; |
+ } |
+ } |
+ |
+ function addOptionItem(subscription) |
+ { |
+ var display = subscription.display ? subscription.display : subscription.title; |
+ var getPossition = function(elements, subscription) |
+ { |
+ var localArray = []; |
+ for (var i = 0; i < elements.length; i++) |
+ { |
+ var elem = elements[i]; |
+ localArray.push(elem); |
+ } |
+ |
+ localArray.push(subscription); |
+ return localArray.sort(function(a, b) { |
+ var aPopular = a.getElementsByClassName("popular").length > 0; |
+ var bPopular = b.getElementsByClassName("popular").length > 0; |
+ if(aPopular == bPopular) |
+ { |
+ var aValue = a.getElementsByClassName("display")[0].innerHTML.toLowerCase(); |
+ var bValue = b.getElementsByClassName("display")[0].innerHTML.toLowerCase(); |
+ if (aValue < bValue) |
+ return -1; |
+ if (aValue > bValue) |
+ return 1; |
+ return 0; |
+ } |
+ if (aPopular == "true") |
+ return 1; |
+ else |
+ return -1; |
+ }).indexOf(subscription); |
+ }; |
+ |
+ var checkBoxClick = function() |
+ { |
+ toggleSubscription(subscription); |
+ }; |
+ |
+ var appendToTable = function(table, elem) |
+ { |
+ var elements = table.getElementsByTagName("li"); |
+ if (elements.length == 0) |
+ table.appendChild(elem); |
+ else |
+ { |
+ var possition = getPossition(elements, elem); |
+ table.insertBefore(elem, table.childNodes[possition]); |
+ } |
+ }; |
+ |
+ if (subscription.type && subscription.type == "ads") |
+ { |
+ if (!subscription.isAdded) |
+ { |
+ var listElem = generateListElement(subscription, subscription.display, "add"); |
+ listElem.dataset.url = subscription.url; |
+ listElem._subscription = subscription; |
+ listElem.getElementsByTagName("button")[0].addEventListener("click", function() |
+ { |
+ addSubscription(this.dataset.url); |
+ }.bind(listElem), false); |
+ appendToTable(E("all-lang-table"), listElem); |
+ } |
+ else |
+ { |
+ var listElem = generateListElement(subscription, display, "checkbox"); |
+ listElem.dataset.url = subscription.url; |
+ listElem._subscription = subscription; |
+ listElem.getElementsByTagName("span")[0].addEventListener("click", checkBoxClick, false); |
+ appendToTable(E("blocking-languages-table"), listElem); |
+ var listElem = generateListElement(subscription, display); |
+ listElem.dataset.url = subscription.url; |
+ listElem._subscription = subscription; |
+ appendToTable(E("blocking-languages-modal-table"), listElem); |
+ } |
+ } |
+ else |
+ { |
+ var listElem = generateListElement(subscription, display, "checkbox"); |
+ listElem.dataset.url = subscription.url; |
+ listElem._subscription = subscription; |
+ listElem.getElementsByTagName("span")[0].addEventListener("click", checkBoxClick, false); |
+ appendToTable(E("further-list-table"), listElem); |
+ } |
+ } |
+ |
+ function addLanguageSubscription(subscription) |
+ { |
+ var optionSubscription = getOptionSubscription(subscription.url); |
+ var elems = getElementsByUrl(subscription.url); |
+ for (var i = 0; i < elems.length; i++) |
+ elems[i].parentNode.removeChild(elems[i]); |
+ optionSubscription.isAdded = true; |
+ optionSubscription.disabled = false; |
+ addOptionItem(optionSubscription); |
+ } |
+ |
+ function createWhitelistElem(domain) |
+ { |
+ var listElem = generateListElement(null, domain, "delete"); |
+ listElem.dataset.domain = domain; |
+ listElem.getElementsByTagName("button")[0].addEventListener("click", removeWhitelistBtnClick.bind(listElem), false); |
+ return listElem; |
+ } |
+ |
+ function addFurtherList(subscription) |
+ { |
+ var optionSubscription = getOptionSubscription(subscription.url); |
+ if (optionSubscription) |
+ { |
+ optionSubscription.disabled = false; |
+ addOptionItem(optionSubscription); |
+ } |
+ else |
+ { |
+ optionSubscriptions[subscription.url] = subscription; |
+ addOptionItem(subscription); |
+ } |
+ } |
+ |
+ function updateSubscriptionState(subscription, state) |
+ { |
+ var elem = getElementsByUrl(subscription.url); |
+ if (elem.length > 0) |
+ { |
+ for (var i = 0; i < elem.length; i++) |
+ { |
+ var checkbox = elem[i].getElementsByTagName("input")[0]; |
+ if (checkbox) |
+ checkbox.checked = state; |
+ } |
+ } |
+ else |
+ { |
+ if (subscription.url == acceptableAdsUrl) |
+ E("allow-whitelist-cb").previousSibling.checked = state; |
+ else |
+ addFurtherList(subscription); |
+ } |
+ } |
+ |
+ function getElementsByUrl(url) |
+ { |
+ return document.querySelectorAll("[data-url='"+url+"']"); |
+ } |
+ |
+ function generateListElement(subscription, text, type) |
+ { |
+ var list = document.createElement("li"); |
+ if (type == "checkbox") |
+ { |
+ var input = document.createElement("input"); |
+ input.setAttribute("type", "checkbox"); |
+ if (subscription.disabled == false) |
+ input.checked = true; |
+ list.appendChild(input); |
+ var span = document.createElement("span"); |
+ list.appendChild(span); |
+ } |
+ else if (type == "delete") |
+ { |
+ var button = document.createElement("button"); |
+ button.setAttribute("class", "delete"); |
+ list.appendChild(button); |
+ } |
+ else if (type == "add") |
+ { |
+ var button = document.createElement("button"); |
+ button.setAttribute("class", "button-add"); |
+ var span = document.createElement("span"); |
+ span.innerHTML = "+" + ext.i18n.getMessage("options_btn_add"); |
+ button.appendChild(span); |
+ list.appendChild(button); |
+ } |
+ var span = document.createElement("span"); |
+ span.setAttribute("class", "display"); |
+ span.innerHTML = text; |
+ list.appendChild(span); |
+ |
+ if (subscription && subscription.popular == "true") |
+ { |
+ var popular = document.createElement("span"); |
+ popular.setAttribute("class", "popular"); |
+ popular.innerHTML = "popular"; |
+ list.appendChild(popular); |
+ } |
+ |
+ return list; |
+ } |
+ |
+ function getOptionSubscription(url) |
+ { |
+ return optionSubscriptions[url]; |
+ } |
+ |
+ function importListBtnCLick() |
+ { |
+ var url = E("blockingList-textbox").value; |
+ addSubscription(url); |
+ Modal.close(); |
+ } |
+ |
+ function whitelistDomainBtnClick() |
+ { |
+ var domain = E("whitelisting-textbox").value; |
+ if (domain) |
+ addWhitelistedDomain(domain); |
+ } |
+ |
+ function removeWhitelistBtnClick() |
+ { |
+ removeWhitelistedDomain(this.dataset.domain); |
+ } |
+ |
+ function editOwnRulsBtnClick() |
+ { |
+ |
+ } |
+ |
+ function showAddSubscriptionDialog(action, subscription) |
+ { |
+ E("blockingList-textbox").value = subscription.url; |
+ Modal.open("further-blocking-modal"); |
+ } |
+ |
+ function getAcceptableAdsURL(callback) |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "prefs.get", |
+ key: "subscriptions_exceptionsurl" |
+ }, function(value) |
+ { |
+ getAcceptableAdsURL = function(callback) |
+ { |
+ callback(value); |
+ } |
+ getAcceptableAdsURL(callback); |
+ }); |
+ } |
+ |
+ function toggleSubscription(subscription) |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "subscriptions.toggle", |
+ url: subscription.url, |
+ title: subscription.title, |
+ homepage: subscription.homepage |
+ }); |
+ } |
+ |
+ function toggleAcceptableAds() |
+ { |
+ var acceptableCheckbox = this.previousSibling; |
+ getAcceptableAdsURL(function(url) |
+ { |
+ var isChecked = acceptableCheckbox.checked; |
+ var title = "Allow non-intrusive advertising"; |
+ if (isChecked) |
+ removeSubscription(url); |
+ else |
+ addSubscription(url, title); |
+ }); |
+ } |
+ |
+ function addSubscription(url, title, homepage) |
+ { |
+ var message = { |
+ type: "subscriptions.add", |
+ url: url |
+ }; |
+ if (title) |
+ message.title = title; |
+ if (homepage) |
+ message.homepage = homepage; |
+ |
+ ext.backgroundPage.sendMessage(message); |
+ } |
+ |
+ function removeSubscription(url) |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "subscriptions.remove", |
+ url: url |
+ }); |
+ } |
+ |
+ function addWhitelistedDomain(domain) |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "filters.add", |
+ text: "@@||" + domain.toLowerCase() + "^$document" |
+ }); |
+ } |
+ |
+ function removeWhitelistedDomain(domain) |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "filters.remove", |
+ text: "@@||" + domain.toLowerCase() + "^$document" |
+ }); |
+ } |
+ |
+ function onFilterMessage(action, filter) |
+ { |
+ switch (action) |
+ { |
+ case "added": |
+ var match = filter.text.match(/^@@\|\|([^\/:]+)\^\$document$/); |
+ if (match[1]) |
+ { |
+ var whitelistTbl = E("whitelisting-table"); |
+ var items = whitelistTbl.getElementsByClassName("display"); |
+ var domains = []; |
+ for (var i = 0; i < items.length; i++) |
+ { |
+ domains.push(items[i].innerHTML); |
+ } |
+ var domain = match[1]; |
+ domains.push(domain); |
+ domains.sort(); |
+ |
+ whitelistTbl.insertBefore(createWhitelistElem(domain), whitelistTbl.childNodes[domains.indexOf(domain)]); |
+ E("whitelisting-textbox").value = ""; |
+ } |
+ else |
+ { |
+ // TODO: add `filters[i].text` to list of custom filters |
+ } |
+ break; |
+ case "loaded": |
+ populateLists(); |
+ break; |
+ case "removed": |
+ var match = filter.text.match(/^@@\|\|([^\/:]+)\^\$document$/); |
+ if (match[1]) |
+ { |
+ var elem = document.querySelector("[data-domain='"+match[1]+"']"); |
+ elem.parentNode.removeChild(elem); |
+ } |
+ break; |
+ } |
+ } |
+ |
+ function onSubscriptionMessage(action, subscription) |
+ { |
+ switch (action) |
+ { |
+ case "added": |
+ var optionSubscription = getOptionSubscription(subscription.url); |
+ if (optionSubscription) |
+ { |
+ var isAdsType = optionSubscription.type && optionSubscription.type == "ads"; |
+ if (isAdsType && !optionSubscription.isAdded) |
+ addLanguageSubscription(subscription); |
+ else |
+ updateSubscriptionState(subscription, true); |
+ } |
+ else if (subscription.url == acceptableAdsUrl) |
+ updateSubscriptionState(subscription, true); |
+ else |
+ addFurtherList(subscription); |
+ break; |
+ case "disabled": |
+ updateSubscriptionState(subscription, false); |
+ break; |
+ case "homepage": |
+ // TODO: NYI |
+ break; |
+ case "removed": |
+ updateSubscriptionState(subscription, false); |
+ break; |
+ case "title": |
+ // TODO: NYI |
+ break; |
+ } |
+ } |
+ |
+ function updateShareLink() |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "filters.blocked", |
+ url: "https://platform.twitter.com/widgets/", |
+ requestType: "SCRIPT", |
+ docDomain: "adblockplus.org", |
+ thirdParty: true |
+ }, function(blocked) |
+ { |
+ // TODO: modify "share" link accordingly |
+ }); |
+ } |
+ |
+ function updateVersionNumber() |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ method: "app.get", |
+ what: "addonVersion" |
+ }, function(addonVersion) |
+ { |
+ E("abp-version").innerHTML = addonVersion; |
+ }); |
+ } |
+ |
+ function getDocLink(link, callback) |
+ { |
+ ext.backgroundPage.sendMessage({ |
+ type: "app.get", |
+ what: "doclink", |
+ link: link |
+ }, callback); |
+ } |
+ |
+ function setLinks(id) |
+ { |
+ var element = E(id); |
+ if (!element) |
+ { |
+ return; |
+ } |
+ |
+ var links = element.getElementsByTagName("a"); |
+ |
+ for (var i = 0; i < links.length; i++) |
+ { |
+ if (typeof arguments[i + 1] == "string") |
+ { |
+ links[i].href = arguments[i + 1]; |
+ links[i].setAttribute("target", "_blank"); |
+ } |
+ else if (typeof arguments[i + 1] == "function") |
+ { |
+ links[i].href = "javascript:void(0);"; |
+ links[i].addEventListener("click", arguments[i + 1], false); |
+ } |
+ } |
+ } |
+ |
+ function E(id) |
+ { |
+ return document.getElementById(id); |
+ } |
+ |
+ ext.onMessage.addListener(function(message) |
+ { |
+ switch (message.type) |
+ { |
+ case "app.listen": |
+ if (message.action == "addSubscription") |
+ { |
+ message.args.unshift(message.action); |
+ showAddSubscriptionDialog.apply(null, message.args); |
+ } |
+ break; |
+ case "filters.listen": |
+ message.args.unshift(message.action); |
+ onFilterMessage.apply(null, message.args); |
+ break; |
+ case "subscriptions.listen": |
+ message.args.unshift(message.action); |
+ onSubscriptionMessage.apply(null, message.args); |
+ break; |
+ } |
+ }); |
+ |
+ ext.backgroundPage.sendMessage({ |
+ type: "app.listen", |
+ filter: ["addSubscription"] |
+ }); |
+ ext.backgroundPage.sendMessage({ |
+ type: "filters.listen", |
+ filter: ["added", "loaded", "removed"] |
+ }); |
+ ext.backgroundPage.sendMessage({ |
+ type: "subscriptions.listen", |
+ filter: ["added", "disabled", "homepage", "removed", "title"] |
+ }); |
+ |
+ window.addEventListener("DOMContentLoaded", onDOMLoaded, false); |
+})(); |