| Index: adblockplus/extensionBridge.js |
| =================================================================== |
| rename from adblockplus/Api.jsm |
| rename to adblockplus/extensionBridge.js |
| --- a/adblockplus/Api.jsm |
| +++ b/adblockplus/extensionBridge.js |
| @@ -10,362 +10,228 @@ |
| * 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/>. |
| */ |
| -var EXPORTED_SYMBOLS = ["AdblockPlusApi"]; |
| +"use strict"; |
| -const Cc = Components.classes; |
| -const Ci = Components.interfaces; |
| -const Cr = Components.results; |
| -const Cu = Components.utils; |
| +const {defaultMatcher} = require("matcher"); |
| +const {Filter, RegExpFilter} = require("filterClasses"); |
| +const {FilterNotifier} = require("filterNotifier"); |
| +const {FilterStorage} = require("filterStorage"); |
| +const {Prefs} = require("prefs"); |
| +const {Subscription, DownloadableSubscription, SpecialSubscription} = |
| + require("subscriptionClasses"); |
| +const {Synchronizer} = require("synchronizer"); |
| -Cu.import("resource://gre/modules/Services.jsm"); |
| -Cu.import("resource://gre/modules/Messaging.jsm"); |
| +const ENABLE_PROP = "enable"; |
| +const HOST_PROP = "host"; |
| +const TITLE_PROP = "title"; |
| +const URL_PROP = "url"; |
| -let XMLHttpRequest = Components.Constructor( |
| - "@mozilla.org/xmlextras/xmlhttprequest;1", "nsIXMLHttpRequest"); |
| - |
| -function require(module) |
| +function init() |
| { |
| - let result = {}; |
| - result.wrappedJSObject = result; |
| - Services.obs.notifyObservers(result, "adblockplus-require", module); |
| - return result.exports; |
| + Promise.all([FilterNotifier.once("load"), Prefs.untilLoaded]).then(onLoaded); |
| } |
| -let {Filter, RegExpFilter} = require("filterClasses"); |
| -let {FilterNotifier} = require("filterNotifier"); |
| -let {FilterStorage} = require("filterStorage"); |
| -let {defaultMatcher} = require("matcher"); |
| -let {Prefs} = require("prefs"); |
| -let {Subscription, SpecialSubscription, RegularSubscription, DownloadableSubscription, ExternalSubscription} = require("subscriptionClasses"); |
| -let {Synchronizer} = require("synchronizer"); |
| -let {UI} = require("ui"); |
| - |
| -const SUBSCRIPTIONS_SAVED_PREF = "subscriptions_saved"; |
| -const USER_REMOVED_BLOCK_SUBS_PREF = "user_removed_block_subscriptions"; |
| -const USER_REMOVED_EXCEPTIONS_SUB_PREF = "user_removed_exception_subscription"; |
| - |
| -function initFilterListeners() |
| +function onLoaded() |
| { |
| - FilterNotifier.on("load", onFiltersLoad); |
| - FilterNotifier.on("save", onFiltersSave); |
| + browser.runtime.registerAbbMessageListener(handleMessage); |
| + browser.runtime.sendAbbMessage("OnLoaded"); |
| + FilterNotifier.on("save", onFiltersSaved); |
| } |
| -function onFiltersLoad() |
| +function onFiltersSaved() |
| { |
| - let detectedSubscriptionFailure = !hasBlockSubscription() && |
| - (!getBoolPref(SUBSCRIPTIONS_SAVED_PREF) || !getBoolPref(USER_REMOVED_BLOCK_SUBS_PREF) || FilterStorage.loadFromDiskFailed); |
| - |
| - // We will only try to recover the default subscription settings if the addonVersion hasn't changed, |
| - // otherwise it will be handled in firstRunActions(), inside ui.js |
| - let {addonVersion} = require("info"); |
| - if (Prefs.currentVersion == addonVersion && detectedSubscriptionFailure) |
| - { |
| - if (getBoolPref(USER_REMOVED_EXCEPTIONS_SUB_PREF)) |
| - { |
| - UI.addSubscription(UI.currentWindow, Prefs.currentVersion); |
| - } |
| - else |
| - { |
| - UI.addSubscription(UI.currentWindow, "0.0"); |
| - } |
| - } |
| - EventDispatcher.instance.sendRequest({type: "Abb:OnFiltersLoad"}); |
| + browser.runtime.sendAbbMessage("OnFiltersSaved"); |
| } |
| -function onFiltersSave() |
| +function handleMessage(data) |
| { |
| - if (hasBlockSubscription()) |
| + switch ((data["action"])) |
| { |
| - setBoolPref(SUBSCRIPTIONS_SAVED_PREF, true); |
| + case "getAdblockPlusEnabled": |
| + return successData(Prefs.enabled); |
| + |
| + case "setAdblockPlusEnabled": |
| + if (!checkData(data, ENABLE_PROP)) break; |
| + Prefs.enabled = !!data[ENABLE_PROP]; |
| + return successData(); |
| + |
| + case "getAcceptableAdsEnabled": |
| + return successData(isSubscriptionEnabled( |
| + Prefs.subscriptions_exceptionsurl)); |
| + |
| + case "setAcceptableAdsEnabled": |
| + if (!checkData(data, ENABLE_PROP)) break; |
| + const acceptableAdsTitle = "Allow non-intrusive advertising"; |
| + setSubscriptionEnabled(!!data[ENABLE_PROP], |
| + Prefs.subscriptions_exceptionsurl, acceptableAdsTitle); |
| + return successData(); |
| + |
| + case "getEnabledSubscriptions": |
| + return successData(getEnabledSubscriptions()); |
| + |
| + case "isSubscriptionEnabled": |
| + if (!checkData(data, URL_PROP)) break; |
| + return successData(isSubscriptionEnabled(data[URL_PROP])); |
| + |
| + case "addSubscription": |
| + if (!checkData(data, URL_PROP)) break; |
| + setSubscriptionEnabled(true, data[URL_PROP], data[TITLE_PROP]); |
| + return successData(); |
| + |
| + case "removeSubscription": |
| + if (!checkData(data, URL_PROP)) break; |
| + setSubscriptionEnabled(false, data[URL_PROP]); |
| + return successData(); |
| + |
| + case "getWhitelistedDomains": |
| + return successData(getWhitelistedDomains()); |
| + |
| + case "isDomainWhitelisted": |
| + if (!checkData(data, [URL_PROP, HOST_PROP])) break; |
| + return successData(isDomainWhitelisted(data[URL_PROP], data[HOST_PROP])); |
| + |
| + case "whitelistDomain": |
| + if (!checkData(data, [ENABLE_PROP, URL_PROP, HOST_PROP])) break; |
| + setDomainWhitelisted(!!data[ENABLE_PROP], data[URL_PROP], data[HOST_PROP]); |
| + return successData(); |
| + |
| } |
| - EventDispatcher.instance.sendRequest({type: "Abb:OnFiltersSave"}); |
| + return errorData("Malformed request"); |
| } |
| -function getBoolPref(name) |
| +function getEnabledSubscriptions() |
| { |
| - let branch = getPrefsBranch(); |
| - try |
| + return FilterStorage.subscriptions.filter(sub => !sub.disabled).map(sub => |
| + ({[TITLE_PROP]: sub.title, [URL_PROP]: sub.url})); |
| +} |
| + |
| +function isSubscriptionEnabled(url) |
| +{ |
| + const sub = Subscription.fromURL(url); |
| + return sub.url in FilterStorage.knownSubscriptions && !sub.disabled; |
| +} |
| + |
| +function setSubscriptionEnabled(isEnabled, url, title) |
| +{ |
| + if (isSubscriptionEnabled(url) == isEnabled) return; |
| + if (isEnabled) addSubscription(url, title); |
| + else removeSubscription(url); |
| +} |
| + |
| +function addSubscription(url, title) |
| +{ |
| + const sub = Subscription.fromURL(url); |
| + sub.disabled = false; |
| + if (title) sub.title = title; |
| + FilterStorage.addSubscription(sub); |
| + |
| + if (sub instanceof DownloadableSubscription && !sub.lastDownload) |
| { |
| - return branch.getBoolPref(name); |
| - } |
| - catch (e) |
| - { |
| - return null; |
| + Synchronizer.execute(sub); |
| } |
| } |
| -function setBoolPref(name, value) |
| +function removeSubscription(url) |
| { |
| - let branch = getPrefsBranch(); |
| - branch.setBoolPref(name, value); |
| - Services.prefs.savePrefFile(null); |
| + FilterStorage.removeSubscription(Subscription.fromURL(url)); |
| } |
| -function getPrefsBranch() |
| +function addFilter(text) |
| { |
| - let {addonRoot, addonName} = require("info"); |
| - let branchName = "extensions." + addonName + "."; |
| - return Services.prefs.getBranch(branchName); |
| + const filter = Filter.fromText(text); |
| + if (filter.disabled) filter.disabled = false; |
| + if (!filter.subscriptions.length) FilterStorage.addFilter(filter); |
| } |
| -function hasBlockSubscription() |
| +function removeFilter(filter) |
| { |
| - return FilterStorage.subscriptions.some( |
| - subscription => subscription instanceof DownloadableSubscription && subscription.url != Prefs.subscriptions_exceptionsurl); |
| + FilterStorage.removeFilter(filter); |
| + if (filter.subscriptions.length) filter.disabled = true; |
| +} |
| + |
| +function getWhitelistedDomains() |
| +{ |
| + const whitelistRegex = /^@@\|\|([^/:]+)\^\$document$/; |
| + const results = []; |
| + |
| + for (const sub of FilterStorage.subscriptions) |
| + { |
| + if (!(sub instanceof SpecialSubscription) || sub.disabled) continue; |
| + for (const filter of sub.filters) |
| + { |
| + const match = filter.text.match(whitelistRegex); |
| + if (match) results.push({[URL_PROP]: match[1]}); |
| + } |
| + } |
| + |
| + return results; |
| +} |
| + |
| +function isDomainWhitelisted(url, host) |
| +{ |
| + return !!getWhitelistingFilter(url, host); |
| +} |
| + |
| +function setDomainWhitelisted(isWhitelisted, url, host) |
| +{ |
| + if (isDomainWhitelisted(url, host) == isWhitelisted) return; |
| + if (isWhitelisted) addDomainToWhitelist(host); |
| + else removeDomainFromWhitelist(url, host); |
| +} |
| + |
| +function addDomainToWhitelist(host) |
| +{ |
| + addFilter("@@||" + host + "^$document"); |
| +} |
| + |
| +function removeDomainFromWhitelist(url, host) |
| +{ |
| + let filter = getWhitelistingFilter(url, host); |
| + while (filter) |
| + { |
| + removeFilter(filter); |
| + filter = getWhitelistingFilter(url, host); |
| + } |
| } |
| function getWhitelistingFilter(url, host) |
| { |
| try |
| { |
| return defaultMatcher.whitelist.matchesAny( |
| - url, RegExpFilter.typeMap.DOCUMENT, host, false, null, false); |
| + url, RegExpFilter.typeMap.DOCUMENT, host, false, null, false); |
| } |
| - catch (e) |
| - { |
| - return null; |
| - } |
| + catch (e) {} |
| + return null; |
| } |
| -var AdblockPlusApi = |
| +function checkData(data, check) |
| { |
| - get filtersLoaded() |
| - { |
| - return !FilterStorage._loading; |
| - }, |
| - get adblockPlusEnabled() |
| - { |
| - return Prefs.enabled; |
| - }, |
| - set adblockPlusEnabled(adblockPlusEnabled) |
| - { |
| - Prefs.enabled = adblockPlusEnabled |
| - }, |
| - get acceptableAdsEnabled() |
| - { |
| - return FilterStorage.subscriptions.some( |
| - (subscription) => subscription.url == Prefs.subscriptions_exceptionsurl); |
| - }, |
| - set acceptableAdsEnabled(acceptableAdsEnabled) |
| - { |
| - if (acceptableAdsEnabled != AdblockPlusApi.acceptableAdsEnabled) |
| - UI.toggleAcceptableAds(); |
| - }, |
| - get subscriptionsXml() |
| - { |
| - let request = new XMLHttpRequest(); |
| - // Synchronous requests are deprecated, but using an asynchronous request |
| - // here (for a static resource that doesn't need to be downloaded anyway) |
| - // would require a huge code change on the Java side, so we stick to |
| - // synchronous requests |
| - request.open("GET", |
| - "chrome://adblockplus/content/ui/subscriptions.xml", |
| - false); |
| - request.send(); |
| - return request.responseText; |
| - }, |
| - isSubscriptionListed: function(url) |
| - { |
| - return url in FilterStorage.knownSubscriptions; |
| - }, |
| - addSubscription: function(url, title) |
| - { |
| - let subscriptionToAdd = Subscription.fromURL(url); |
| - if (title) |
| - subscriptionToAdd.title = title; |
| - FilterStorage.addSubscription(subscriptionToAdd); |
| - let subscription = FilterStorage.knownSubscriptions[url]; |
| - if (subscription) |
| - { |
| - subscription.disabled = false; |
| - if (!subscription.lastDownload) |
| - { |
| - Synchronizer.execute(subscription); |
| - } |
| - } |
| - if (url == Prefs.subscriptions_exceptionsurl) |
| - { |
| - setBoolPref(USER_REMOVED_EXCEPTIONS_SUB_PREF, false); |
| - } |
| - else if (hasBlockSubscription()) |
| - { |
| - setBoolPref(USER_REMOVED_BLOCK_SUBS_PREF, false); |
| - } |
| - }, |
| - removeSubscription: function(url) |
| - { |
| - FilterStorage.removeSubscription(FilterStorage.knownSubscriptions[url]); |
| - if (url == Prefs.subscriptions_exceptionsurl) |
| - { |
| - setBoolPref(USER_REMOVED_EXCEPTIONS_SUB_PREF, true); |
| - } |
| - else if (!hasBlockSubscription()) |
| - { |
| - setBoolPref(USER_REMOVED_BLOCK_SUBS_PREF, true); |
| - } |
| - }, |
| - getActiveSubscriptions: function() |
| - { |
| - let subscriptions = []; |
| - for (let i = 0; i < FilterStorage.subscriptions.length; i++) |
| - { |
| - let subscription = FilterStorage.subscriptions[i]; |
| - if (!subscription.disabled) |
| - subscriptions.push({"title": subscription.title, "url": subscription.url}); |
| - } |
| - return subscriptions; |
| - }, |
| - get whitelistedWebsites() |
| - { |
| - let whitelistedWebsites = []; |
| - for (let i = 0; i < FilterStorage.subscriptions.length; i++) |
| - { |
| - let subscription = FilterStorage.subscriptions[i]; |
| - if (subscription.url && subscription.url.startsWith("~user~") && subscription.filters) |
| - { |
| - for (let j = 0; j < subscription.filters.length; j++) |
| - { |
| - let filter = subscription.filters[j]; |
| - let whitelistMatch = filter.text ? filter.text.match(/^@@\|\|([^/:]+)\^\$document$/) : null; |
| - if(whitelistMatch) |
| - { |
| - whitelistedWebsites.push({"url": whitelistMatch[1]}) |
| - } |
| - } |
| - } |
| - } |
| - return whitelistedWebsites; |
| - }, |
| - isWebsiteWhitelisted: function(url, host) |
| - { |
| - return !!getWhitelistingFilter(url, host); |
| - }, |
| - whitelistWebsite: function(url, host, whitelisted) |
| - { |
| - if (whitelisted) |
| - { |
| - var filter = Filter.fromText("@@||" + host + "^$document"); |
| - if (filter.subscriptions.length && filter.disabled) |
| - { |
| - filter.disabled = false; |
| - } |
| - else |
| - { |
| - filter.disabled = false; |
| - FilterStorage.addFilter(filter); |
| - } |
| - } |
| - else |
| - { |
| - // Remove any exception rules applying to this URL |
| - var filter = getWhitelistingFilter(url, host); |
| - while (filter) |
| - { |
| - FilterStorage.removeFilter(filter); |
| - if (filter.subscriptions.length) |
| - { |
| - filter.disabled = true; |
| - } |
| - filter = getWhitelistingFilter(url); |
| - } |
| - } |
| - }, |
| - initCommunication: function() |
| - { |
| - initFilterListeners(); |
| + if (!data) return false; |
| + const properties = [].concat(check || []); |
| + return properties.every(function(item) { |
| + return item in data; |
| + }); |
| +} |
| - EventDispatcher.instance.registerListener((event, data, callback) => |
| - { |
| - if (!data) |
| - { |
| - callback.onError("malformed request"); |
| - return; |
| - } |
| +function successData(value) |
| +{ |
| + const data = {}; |
| + data.success = true; |
| + if (value != null) data.value = value; |
| + return data; |
| +} |
| - if (!this.filtersLoaded) |
| - { |
| - callback.onError("filters not loaded"); |
| - return; |
| - } |
| +function errorData(errorMsg) |
| +{ |
| + const data = {}; |
| + if (errorMsg) data.error = errorMsg; |
| + return data; |
| +} |
| - switch (data["action"]) |
| - { |
| - case "getAdblockPlusEnabled": |
| - callback.onSuccess({"value": this.adblockPlusEnabled}); |
| - return; |
| - case "setAdblockPlusEnabled": |
| - if ("enable" in data) |
| - { |
| - this.adblockPlusEnabled = !!data["enable"]; |
| - callback.onSuccess({}); |
| - return; |
| - } |
| - break; |
| - case "getAcceptableAdsEnabled": |
| - callback.onSuccess({"value": this.acceptableAdsEnabled}); |
| - return; |
| - case "setAcceptableAdsEnabled": |
| - if ("enable" in data) |
| - { |
| - this.acceptableAdsEnabled = !!data["enable"]; |
| - callback.onSuccess({}); |
| - return; |
| - } |
| - break; |
| - case "getSubscriptionsXml": |
| - callback.onSuccess({"value": this.subscriptionsXml}); |
| - return; |
| - case "getActiveSubscriptions": |
| - callback.onSuccess({"value": this.getActiveSubscriptions()}); |
| - return; |
| - case "isSubscriptionListed": |
| - if ("url" in data) |
| - { |
| - callback.onSuccess({"value": this.isSubscriptionListed(data["url"])}); |
| - return; |
| - } |
| - break; |
| - case "addSubscription": |
| - if ("url" in data) |
| - { |
| - this.addSubscription(data["url"], data["title"]); |
| - callback.onSuccess({}); |
| - return; |
| - } |
| - break; |
| - case "removeSubscription": |
| - if ("url" in data) |
| - { |
| - this.removeSubscription(data["url"]); |
| - callback.onSuccess({}); |
| - return; |
| - } |
| - break; |
| - case "getWhitelistedWebsites": |
| - callback.onSuccess({"value": this.whitelistedWebsites}); |
| - return; |
| - case "isWebsiteWhitelisted": |
| - if ("url" in data && "host" in data) |
| - { |
| - callback.onSuccess({"value": this.isWebsiteWhitelisted(data["url"], data["host"])}); |
| - return; |
| - } |
| - break; |
| - case "whitelistWebsite": |
| - if ("url" in data && "host" in data && "whitelisted" in data) |
| - { |
| - this.whitelistWebsite(data["url"], data["host"], data["whitelisted"]); |
| - callback.onSuccess({}); |
| - return; |
| - } |
| - break; |
| - } |
| - callback.onError("malformed request"); |
| - }, "AdblockPlus:Api"); |
| - } |
| -}; |
| +init(); |