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,242 @@ |
* 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.abbRegisterRequestListener(handleRequest); |
+ browser.runtime.abbSendRequest("Abb: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.abbSendRequest("Abb:OnFiltersSaved"); |
} |
-function onFiltersSave() |
+function handleRequest(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(getAllSubscriptions()); |
+ |
+ 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) |
+// remove |
+function getAllSubscriptions() |
{ |
- let branch = getPrefsBranch(); |
- try |
+ return FilterStorage.subscriptions.map(sub => ({"title": sub.title, "url": sub.url, "downloadable": (sub instanceof DownloadableSubscription), "special": (sub instanceof SpecialSubscription), "disabled": sub.disabled})); |
+} |
+ |
+function getEnabledSubscriptions() |
+{ |
+ 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 = []; |
+ |
+ FilterStorage.subscriptions.forEach(function(sub) { |
+ if (!(sub instanceof SpecialSubscription) || sub.disabled) return; |
+ sub.filters.forEach(function(filter) { |
+ const match = filter.text.match(whitelistRegex); |
+ if (match) results.push({[URL_PROP]: match[1]}); |
+ }); |
+ }); |
+ |
+ return results; |
+} |
+ |
+function flatIt(array) |
+{ |
+ let flatArray = []; |
+ array.forEach(function(item) { |
+ flatArray = flatArray.concat(item); |
+ }); |
+ return flatArray; |
+} |
+ |
+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.errorMsg = 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(); |