| Index: options.js |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/options.js |
| @@ -0,0 +1,651 @@ |
| +/* |
| + * 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 acceptableAdsUrl = null; |
| + |
| + var optionObj = |
| + { |
| + collections: |
| + { |
| + push: function() |
| + { |
| + var length = Array.prototype.push.apply(this, arguments); |
| + this.sort(function(a, b) |
| + { |
| + var aValue = (a.title || a.url || a.text).toLowerCase(); |
| + var bValue = (b.title || b.url || a.text).toLowerCase(); |
| + if (aValue < bValue) |
| + return -1; |
| + if (aValue > bValue) |
| + return 1; |
| + return 0; |
| + }); |
| + for (var i=0; i < arguments.length; i++) |
| + { |
| + for (var j=0; j < this.table.length; j++) |
| + { |
| + var object = arguments[i]; |
| + var text = object.title || object.text; |
| + var access = object.url || object.text; |
| + var index = this.indexOf(object); |
| + var table = E(this.table[j].id); |
| + var template = this.table[j].template; |
| + var listener = this.table[j].listener; |
| + |
| + var list = document.createElement("li"); |
| + list.innerHTML = template; |
| + list.dataset.access = access; |
| + list.getElementsByClassName("display")[0].textContent = text; |
| + if (object.isAdsType) |
| + list.dataset.value = text.toLowerCase(); |
| + |
| + var control = list.getElementsByClassName("control")[0]; |
| + if (control) |
| + { |
| + control.addEventListener("click", listener, false); |
| + control.checked = !object.disabled; |
| + } |
| + if (table.hasChildNodes) |
| + table.insertBefore(list, table.childNodes[index]); |
| + else |
| + table.appendChild(list); |
| + } |
| + } |
| + return length; |
| + }, |
| + remove: function(obj) |
| + { |
| + var index = this.indexOf(obj); |
| + this.splice(index, 1); |
| + var access = obj.url || obj.text; |
| + for (var i=0; i < this.table.length; i++) |
| + { |
| + var table = E(this.table[i].id); |
| + var element = table.querySelector("[data-access='"+access+"']"); |
| + element.parentElement.removeChild(element); |
| + } |
| + } |
| + }, |
| + subscriptions: { |
| + getArray: function(subscription) |
| + { |
| + var collArray = null; |
| + if (subscription.isPopular) |
| + collArray = collections.popular; |
| + else if (subscription.isAdsType && subscription.disabled) |
| + collArray = collections.allLangs; |
| + else if (subscription.isAdsType && !subscription.disabled) |
| + collArray = collections.langs; |
| + else if (subscription.url == acceptableAdsUrl) |
| + collArray = collections.acceptableAds; |
| + else |
| + collArray = collections.custom; |
| + return collArray; |
| + }, |
| + update: function(subscription) |
| + { |
| + var optionSubscription = this[subscription.url]; |
| + if (optionSubscription) |
| + optionSubscription.disabled = subscription.disabled; |
| + else |
| + { |
| + var collArray = this.getArray(subscription); |
| + optionObj.observe(subscription, ["disabled"]); |
| + collArray.push = collections.push; |
| + collArray.push(subscription); |
| + this[subscription.url] = subscription; |
| + } |
| + }, |
| + remove: function(subscription) |
| + { |
| + var optionSubscription = this[subscription.url]; |
| + |
| + if (optionSubscription.isAdsType) |
| + { |
| + collections.langs.remove(optionSubscription); |
| + collections.allLangs.push(optionSubscription); |
| + } |
| + else if(optionSubscription.isPopular) |
| + { |
| + optionSubscription.disabled = true; |
| + } |
| + else |
| + { |
| + collections.custom.remove(optionSubscription); |
| + } |
| + }, |
| + chboxListener: function(e) |
| + { |
| + e.preventDefault(); |
| + var target = e.target; |
| + var isChecked = target.checked; |
| + var url = e.target.parentNode.dataset.access; |
| + if (!isChecked) |
| + SendMessage.removeSubscription(url); |
| + else |
| + SendMessage.addSubscription(url); |
| + }, |
| + acceptableAdsListener: function(e) |
| + { |
| + e.preventDefault(); |
| + var target = e.target; |
| + var isChecked = target.checked; |
| + var url = e.target.parentNode.dataset.access; |
| + |
| + if (isChecked) |
| + SendMessage.addSubscription(url); |
| + else |
| + SendMessage.removeSubscription(url); |
| + }, |
| + addBtnListener: function(e) |
| + { |
| + e.preventDefault(); |
| + var url = this.parentNode.dataset.access; |
| + SendMessage.addSubscription(url); |
| + } |
| + }, |
| + filters: |
| + { |
| + update: function(filter) |
| + { |
| + var optionFilter = this[filter.text]; |
| + var match = filter.text.match(/^@@\|\|([^\/:]+)\^\$document$/); |
| + if (match && !optionFilter) |
| + { |
| + filter.title = match[1]; |
| + collections.whitelist.push(filter); |
| + this[filter.text] = filter; |
| + } |
| + else |
| + { |
| + // TODO: add `filters[i].text` to list of custom filters |
| + } |
| + }, |
| + remove: function(filter) |
| + { |
| + collections.whitelist.remove(filter); |
| + }, |
| + deleteBtnClick: function() |
| + { |
| + var filter = this.parentNode.dataset.access; |
| + SendMessage.removeFilter(filter); |
| + } |
| + }, |
| + observe: function(obj, props) |
| + { |
| + props.forEach(function(property) |
| + { |
| + obj["__"+property] = obj[property]; |
| + Object.defineProperty(obj, property, |
| + { |
| + get: function() |
| + { |
| + return this["__"+property]; |
| + }, |
| + set: function(value) |
| + { |
| + this["__"+property] = value; |
| + var access = obj.url || obj.text; |
| + var elements = document.querySelectorAll("[data-access='" + access + "']"); |
| + for (var i=0; i < elements.length; i++) |
| + { |
| + var elem = elements[i]; |
| + var control = elem.getElementsByClassName("control")[0]; |
| + if (control.tagName == "INPUT") |
| + control.checked = !obj.disabled; |
| + if (obj.isAdsType) |
| + { |
| + collections.allLangs.remove(obj); |
| + collections.langs.push(obj); |
| + } |
| + } |
| + } |
| + }); |
| + }); |
| + } |
| + }; |
| + |
| + function createCollArray(tables) |
| + { |
| + var array = []; |
| + array.push = optionObj.collections.push; |
| + array.remove = optionObj.collections.remove; |
| + array.table = tables; |
| + return array; |
| + } |
| + |
| + var collections = optionObj.collections; |
| + collections.popular = createCollArray([ |
| + { |
| + id: "recommend-list-table", |
| + template: "<input type='checkbox' class='control' /><span class='display'></span><span class='popular'>popular</span>", |
| + listener: optionObj.subscriptions.chboxListener |
| + } |
| + ]); |
| + collections.langs = createCollArray([ |
| + { |
| + id: "blocking-languages-table", |
| + template: "<input type='checkbox' class='control' /><span class='display'></span>", |
| + listener: optionObj.subscriptions.chboxListener |
| + }, |
| + { |
| + id: "blocking-languages-modal-table", |
| + template: "<span class='display'></span>" |
| + } |
| + ]); |
| + collections.allLangs = createCollArray([ |
| + { |
| + id: "all-lang-table", |
| + template: "<button class='button-add control'><span>+add</span></button><span class='display'></span>", |
| + listener: optionObj.subscriptions.addBtnListener |
| + } |
| + ]); |
| + collections.acceptableAds = createCollArray([ |
| + { |
| + id: "acceptableads-table", |
| + template: "<input type='checkbox' class='control' /><span class='display'></span>", |
| + listener: optionObj.subscriptions.acceptableAdsListener |
| + } |
| + ]); |
| + collections.custom = createCollArray([ |
| + { |
| + id: "custom-list-table", |
| + template: "<input type='checkbox' class='control' /><span class='display'></span>", |
| + listener: optionObj.subscriptions.chboxListener |
| + } |
| + ]); |
| + collections.whitelist = createCollArray([ |
| + { |
| + id: "whitelisting-table", |
| + template: "<button class='delete control'></button><span class='display'></span>", |
| + listener: optionObj.filters.deleteBtnClick |
| + } |
| + ]); |
| + |
| + var Recommendations = |
| + { |
| + load: function() |
| + { |
| + var request = new XMLHttpRequest(); |
| + request.open("GET", "subscriptions.xml", false); |
| + request.onload = function() |
| + { |
| + var list = document.getElementById("subscriptionSelector"); |
| + var docElem = request.responseXML.documentElement; |
| + var elements = docElem.getElementsByTagName("subscription"); |
| + for (var i = 0; i < elements.length; i++) |
| + { |
| + var element = elements[i]; |
| + var subscription = Object.create(null); |
| + subscription.title = element.getAttribute("title"); |
| + subscription.url = element.getAttribute("url"); |
| + subscription.disabled = true; |
| + var prefix = element.getAttribute("prefixes"); |
| + if (prefix) |
| + { |
| + subscription.isAdsType = true; |
| + var prefix = element.getAttribute("prefixes").replace(/,/g, '_'); |
| + subscription.title = ext.i18n.getMessage("options_language_" + prefix); |
| + } |
| + else |
| + subscription.title = element.getAttribute("specialization"); |
| + |
| + if (element.getAttribute("popular")) |
| + subscription.isPopular = true; |
| + optionObj.subscriptions.update(subscription); |
| + } |
| + }.bind(this); |
| + request.send(); |
| + } |
| + }; |
| + |
| + function onDOMLoaded() |
| + { |
| + updateShareLink(); |
| + populateLists(); |
| + |
| + var tabList = document.querySelectorAll("#main-navigation-tabs li"); |
| + for (var i = 0; i < tabList.length; ++i) |
| + { |
| + tabList[i].addEventListener("click", function(ev) |
| + { |
| + document.body.dataset.tab = this.id.substr(4); |
| + }, false); |
| + } |
| + |
| + var searchLanguage = function() |
| + { |
| + var searchStyle = document.getElementById('search_style'); |
|
Thomas Greiner
2015/02/18 17:19:27
You're using `document.getElementById()` here but
|
| + var searchVal = this.value; |
| + if (!searchVal) |
| + searchStyle.innerHTML = ""; |
| + else |
| + searchStyle.innerHTML = "#all-lang-table li:not([data-value*=\"" + this.value.toLowerCase() + "\"]) { display: none; }"; |
| + }; |
| + |
| + // Update version number in navigation sidebar |
| + ext.backgroundPage.sendMessage({ |
| + method: "app.get", |
| + what: "addonVersion" |
| + }, function(addonVersion) |
| + { |
| + E("abp-version").textContent = addonVersion; |
| + }); |
| + |
| + var whitelistDomainBtnClick = function() |
| + { |
| + var domain = E("whitelisting-textbox").value; |
| + if (domain) |
| + SendMessage.addWhitelistedDomain(domain); |
| + E("whitelisting-textbox").value = ""; |
| + }; |
| + |
| + var placeholderValue = ext.i18n.getMessage("options_modal_language_find"); |
| + E("find-language").setAttribute("placeholder", placeholderValue); |
| + setLinks("block-element-explanation", "#"); |
| + |
| + E("add-blocking-list").addEventListener("click", function() |
| + { |
| + openModal("customlist"); |
| + }, false); |
| + E("add-website-language").addEventListener("click", function() |
| + { |
| + openModal("language"); |
| + }, false); |
| + E("modal-close").addEventListener("click", function() |
| + { |
| + delete document.body.dataset.modal; |
| + }, false); |
| + E("edit-ownBlockingList-btn").addEventListener("click", editOwnRulsBtnClick, false); |
| + E("find-language").addEventListener("keyup", searchLanguage, 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("import-blockingList-btn").addEventListener("click", function() |
| + { |
| + var url = E("blockingList-textbox").value; |
| + SendMessage.addSubscription(url); |
| + delete document.body.dataset.modal; |
| + }, false); |
| + } |
| + |
| + function openModal(name) |
| + { |
| + document.body.dataset.modal = name; |
| + var title = "options_modal_" + name + "_title"; |
| + E("modal-title").textContent = ext.i18n.getMessage(title); |
| + } |
| + |
| + function populateLists() |
| + { |
| + ext.backgroundPage.sendMessage( |
| + { |
| + type: "subscriptions.get", |
| + special: true |
| + }, function(subscriptions) |
| + { |
| + // Load filters |
| + for (var i = 0; i < subscriptions.length; i++) |
| + { |
| + ext.backgroundPage.sendMessage( |
| + { |
| + type: "filters.get", |
| + subscriptionUrl: subscriptions[i].url |
| + }, function(filters) |
| + { |
| + for (var i = 0; i < filters.length; i++) |
| + optionObj.filters.update(filters[i]); |
| + }); |
| + } |
| + }); |
| + Recommendations.load(); |
| + SendMessage.getAcceptableAdsURL(function(url) |
| + { |
| + acceptableAdsUrl = url; |
| + var subscription = Object.create(null); |
| + subscription.url = acceptableAdsUrl; |
| + subscription.disabled = true; |
| + subscription.title = ext.i18n.getMessage("options_acceptableAds_description"); |
| + optionObj.subscriptions.update(subscription); |
| + |
| + // Load user subscriptions |
| + ext.backgroundPage.sendMessage( |
| + { |
| + type: "subscriptions.get", |
| + downloadable: true |
| + }, function(subscriptions) |
| + { |
| + for (var i = 0; i < subscriptions.length; i++) |
| + MessageListeners.onSubscriptionMessage("added", subscriptions[i]); |
| + }); |
| + }); |
| + } |
| + |
| + function editOwnRulsBtnClick() |
| + { |
| + |
| + } |
| + |
| + var SendMessage = |
| + { |
| + getAcceptableAdsURL: function(callback) |
| + { |
| + ext.backgroundPage.sendMessage( |
| + { |
| + type: "prefs.get", |
| + key: "subscriptions_exceptionsurl" |
| + }, function(value) |
| + { |
| + SendMessage.getAcceptableAdsURL = function(callback) |
| + { |
| + callback(value); |
| + } |
| + SendMessage.getAcceptableAdsURL(callback); |
| + }); |
| + }, |
| + addSubscription: function(url, title, homepage) |
| + { |
| + var message = { |
| + type: "subscriptions.add", |
| + url: url |
| + }; |
| + if (title) |
| + message.title = title; |
| + if (homepage) |
| + message.homepage = homepage; |
| + |
| + ext.backgroundPage.sendMessage(message); |
| + }, |
| + removeSubscription: function(url) |
| + { |
| + ext.backgroundPage.sendMessage( |
| + { |
| + type: "subscriptions.remove", |
| + url: url |
| + }); |
| + }, |
| + addWhitelistedDomain: function(domain) |
| + { |
| + ext.backgroundPage.sendMessage( |
| + { |
| + type: "filters.add", |
| + text: "@@||" + domain.toLowerCase() + "^$document" |
| + }); |
| + }, |
| + removeFilter: function(filter) |
| + { |
| + ext.backgroundPage.sendMessage( |
| + { |
| + type: "filters.remove", |
| + text: filter |
| + }); |
| + } |
| + }; |
| + |
| + var MessageListeners = |
| + { |
| + onFilterMessage: function(action, filter) |
| + { |
| + switch (action) |
| + { |
| + case "added": |
| + optionObj.filters.update(filter); |
| + break; |
| + case "loaded": |
| + populateLists(); |
| + break; |
| + case "removed": |
| + optionObj.filters.remove(filter); |
| + break; |
| + } |
| + }, |
| + onSubscriptionMessage: function(action, subscription) |
| + { |
| + switch (action) |
| + { |
| + case "added": |
| + optionObj.subscriptions.update(subscription); |
| + break; |
| + case "disabled": |
| + break; |
| + case "homepage": |
| + // TODO: NYI |
| + break; |
| + case "removed": |
| + if (subscription.url == acceptableAdsUrl) |
| + { |
| + subscription.disabled = true; |
| + optionObj.subscriptions.update(subscription); |
| + } |
| + else |
| + optionObj.subscriptions.remove(subscription); |
| + break; |
| + case "title": |
| + // TODO: NYI |
| + break; |
| + } |
| + }, |
| + showAddSubscriptionDialog: function(subscription) |
| + { |
| + E("blockingList-textbox").value = subscription.url; |
| + openModal("customlist"); |
| + } |
| + }; |
| + |
| + 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 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") |
| + MessageListeners.showAddSubscriptionDialog(message.args[0]); |
| + break; |
| + case "filters.listen": |
| + MessageListeners.onFilterMessage(message.action, message.args[0]); |
| + break; |
| + case "subscriptions.listen": |
| + MessageListeners.onSubscriptionMessage(message.action, message.args[0]); |
| + 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); |
| +})(); |