Index: safari/common.js |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/safari/common.js |
@@ -0,0 +1,203 @@ |
+/* |
+ * This file is part of Adblock Plus <http://adblockplus.org/>, |
+ * Copyright (C) 2006-2013 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/>. |
+ */ |
+ |
+(function() { |
+ /* Events */ |
+ |
+ WrappedEventTarget = function(target, eventName, capture) { |
+ this._listeners = []; |
+ this._wrappedListeners = []; |
+ |
+ this._target = target; |
+ this._eventName = eventName; |
+ this._capture = capture; |
+ }; |
+ WrappedEventTarget.prototype = { |
+ addListener: function(listener) { |
+ var wrappedListener = this._wrapListener(listener); |
+ |
+ this._listeners.push(listener); |
+ this._wrappedListeners.push(wrappedListener); |
+ |
+ this._target.addEventListener( |
+ this._eventName, |
+ wrappedListener, |
+ this._capture |
+ ); |
+ }, |
+ removeListener: function(listener) { |
+ var idx = this._listeners.indexOf(listener); |
+ |
+ if (idx != -1) { |
+ this._target.removeEventListener( |
+ this._eventName, |
+ this._wrappedListeners[idx], |
+ this._capture |
+ ); |
+ |
+ this._listeners.splice(idx, 1); |
+ this._wrappedListeners.splice(idx, 1); |
+ } |
+ } |
+ }; |
+ |
+ |
+ MessageEventTarget = function(target) { |
+ WrappedEventTarget.call(this, target, "message", false); |
+ }; |
+ MessageEventTarget.prototype = { |
+ __proto__: WrappedEventTarget.prototype, |
+ _wrapListener: function(listener) { |
+ return function(event) { |
+ if (event.name.indexOf("request-") != 0) |
+ return; |
+ |
+ var sender = {}; |
+ var dispatcher; |
+ |
+ if (event.target instanceof SafariBrowserTab) { |
+ dispatcher = event.target.page; |
+ sender.tab = new Tab(event.target); |
+ } else { |
+ dispatcher = event.target.tab; |
+ sender.tab = null; |
+ } |
+ |
+ listener(event.message, sender, function(message) { |
+ dispatcher.dispatchMessage("response-" + event.name.substr(8), message); |
+ }); |
+ }; |
+ } |
+ }; |
+ |
+ |
+ /* Message passing */ |
+ |
+ var requestCounter = 0; |
+ |
+ sendMessage = function(message, responseCallback) { |
+ var requestId = ++requestCounter; |
+ |
+ if (responseCallback) { |
+ var eventTarget = this._eventTarget; |
+ var responseListener = function(event) { |
+ if (event.name == "response-" + requestId) { |
+ eventTarget.removeEventListener("message", responseListener, false); |
+ responseCallback(event.message); |
+ } |
+ }; |
+ eventTarget.addEventListener("message", responseListener, false); |
+ } |
+ |
+ this._messageDispatcher.dispatchMessage("request-" + requestId, message); |
+ }; |
+ |
+ |
+ /* I18n */ |
+ |
+ var I18n = function() { |
+ this._localeCandidates = this._getLocaleCandidates(); |
+ this._uiLocale = this._localeCandidates[0]; |
+ }; |
+ I18n.prototype = { |
+ _getLocaleCandidates: function() { |
+ var bits, i, locale; |
+ var candidates = []; |
+ var default_locale = "en_US"; |
+ |
+ for (i = (bits = navigator.language.split("-")).length; i > 0; i--) { |
+ locale = bits.slice(0, i).join("_"); |
+ candidates.push(locale); |
+ |
+ if (locale == default_locale) |
+ return candidates; |
+ } |
+ |
+ candidates.push(default_locale); |
+ return candidates; |
+ }, |
+ _getCatalog: function(locale) { |
+ var xhr = new XMLHttpRequest(); |
+ |
+ xhr.open("GET", safari.extension.baseURI + "_locales/" + locale + "/messages.json", false); |
+ |
+ try { |
+ xhr.send(); |
+ } catch (e) { |
+ return null; |
+ } |
+ |
+ return JSON.parse(xhr.responseText); |
+ }, |
+ getMessage: function(msgId, substitutions) { |
+ if (msgId == "@@ui_locale") |
+ return this._uiLocale; |
+ |
+ for (var i = 0; i < this._localeCandidates.length; i++) { |
+ var catalog = this._getCatalog(this._localeCandidates[i]); |
+ if (!catalog) { |
+ // if there is no catalog for this locale |
+ // candidate, dont"t try to load it again |
+ this._localeCandidates.splice(i--, 1); |
+ continue; |
+ } |
+ |
+ var msg = catalog[msgId]; |
+ if (!msg) |
+ continue; |
+ |
+ var msgstr = msg.message; |
+ if (!msgstr) |
+ continue; |
+ |
+ for (var placeholder in msg.placeholders) { |
+ var placeholderDetails = msg.placeholders[placeholder]; |
+ if (!placeholderDetails || !placeholderDetails.content) |
+ continue; |
+ if (placeholderDetails.content.indexOf("$") != 0) |
+ continue; |
+ |
+ var placeholderIdx = parseInt(placeholderDetails.content.substr(1)); |
+ if (isNaN(placeholderIdx) || placeholderIdx < 1) |
+ continue; |
+ |
+ var placeholderValue; |
+ if (Object.prototype.toString.call(substitutions) == "[object Array]") |
+ placeholderValue = substitutions[placeholderIdx - 1]; |
+ else if (placeholderIdx == 1) |
+ placeholderValue = substitutions; |
+ |
+ msgstr = msgstr.replace("$" + placeholder + "$", placeholderValue || ""); |
+ } |
+ |
+ return msgstr; |
+ } |
+ |
+ return ""; |
+ } |
+ }; |
+ |
+ |
+ /* API */ |
+ |
+ ext = { |
+ getURL: function(path) { |
+ return safari.extension.baseURI + path; |
+ }, |
+ i18n: new I18n() |
+ }; |
+})(); |