| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <http://adblockplus.org/>, | 2 * This file is part of Adblock Plus <http://adblockplus.org/>, |
| 3 * Copyright (C) 2006-2014 Eyeo GmbH | 3 * Copyright (C) 2006-2014 Eyeo GmbH |
| 4 * | 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 | 70 |
| 71 this._messageDispatcher.dispatchMessage("request", request); | 71 this._messageDispatcher.dispatchMessage("request", request); |
| 72 } | 72 } |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 ext.onMessage = new ext._EventTarget(); | 75 ext.onMessage = new ext._EventTarget(); |
| 76 | 76 |
| 77 | 77 |
| 78 /* I18n */ | 78 /* I18n */ |
| 79 | 79 |
| 80 var localeCandidates = null; | |
| 81 var uiLocale; | |
| 82 | |
| 83 var getLocaleCandidates = function() | 80 var getLocaleCandidates = function() |
| 84 { | 81 { |
| 85 var candidates = []; | 82 var candidates = []; |
| 86 var defaultLocale = "en_US"; | 83 var defaultLocale = "en_US"; |
| 87 | 84 |
| 88 // e.g. "ja-jp-mac" -> "ja", "jp", note that the part after the second | 85 // e.g. "ja-jp-mac" -> "ja", "jp", note that the part after the second |
| 89 // dash is dropped, since we only support language and region | 86 // dash is dropped, since we only support language and region |
| 90 var [language, region] = navigator.language.split("-"); | 87 var [language, region] = navigator.language.split("-"); |
| 91 | 88 |
| 92 if (region) | 89 if (region) |
| 93 candidates.push(language + "_" + region.toUpperCase()); | 90 candidates.push(language + "_" + region.toUpperCase()); |
| 94 | 91 |
| 95 candidates.push(language); | 92 candidates.push(language); |
| 96 | 93 |
| 97 if (candidates.indexOf(defaultLocale) == -1) | 94 if (candidates.indexOf(defaultLocale) == -1) |
| 98 candidates.push(defaultLocale); | 95 candidates.push(defaultLocale); |
| 99 | 96 |
| 100 return candidates; | 97 return candidates; |
| 101 }; | 98 }; |
| 102 | 99 |
| 103 var getCatalog = function(locale) | 100 var locales = getLocaleCandidates(); |
| 101 var catalog = {__proto__: null, "@@ui_locale": [locales[0], []]}; | |
| 102 | |
| 103 var replacePlaceholder = function(text, placeholder, content) | |
| 104 { | |
| 105 return text.split("$" + placeholder + "$").join(content || ""); | |
|
Wladimir Palant
2014/10/30 23:00:44
Why not keep the more obvious text.replace(...)? A
Sebastian Noack
2014/10/30 23:53:01
Because .replace() with a string as first argument
| |
| 106 }; | |
| 107 | |
| 108 var parseMessage = function(rawMessage) | |
| 109 { | |
| 110 var text = rawMessage.message; | |
| 111 var placeholders = []; | |
| 112 | |
| 113 for (var placeholder in rawMessage.placeholders) | |
|
Wladimir Palant
2014/10/30 23:00:44
I didn't expect it but apparently one can iterate
Sebastian Noack
2014/10/30 23:53:01
You can. Iterating over null (or undefined) has th
| |
| 114 { | |
| 115 var content = rawMessage.placeholders[placeholder].content; | |
| 116 | |
| 117 if (/^\$\d+$/.test(content)) | |
| 118 placeholders[parseInt(content.substr(1)) - 1] = placeholder; | |
|
Wladimir Palant
2014/10/30 23:00:44
Doing both regular expressions and string manipula
Sebastian Noack
2014/10/30 23:53:01
Neither the old code, nor most other calls to pars
| |
| 119 else | |
| 120 text = replacePlaceholder(text, placeholder, content); | |
| 121 } | |
| 122 | |
| 123 return [text, placeholders]; | |
| 124 }; | |
| 125 | |
| 126 var readCatalog = function(locale) | |
| 104 { | 127 { |
| 105 var xhr = new XMLHttpRequest(); | 128 var xhr = new XMLHttpRequest(); |
| 106 | |
| 107 xhr.open("GET", safari.extension.baseURI + "_locales/" + locale + "/messages .json", false); | 129 xhr.open("GET", safari.extension.baseURI + "_locales/" + locale + "/messages .json", false); |
| 108 | 130 |
| 109 try { | 131 try |
| 132 { | |
| 110 xhr.send(); | 133 xhr.send(); |
| 111 } | 134 } |
| 112 catch (e) | 135 catch (e) |
| 113 { | 136 { |
| 114 return null; | 137 return; |
| 115 } | 138 } |
| 116 | 139 |
| 117 if (xhr.status != 200 && xhr.status != 0) | 140 if (xhr.status != 200 && xhr.status != 0) |
| 118 return null; | 141 return; |
| 119 | 142 |
| 120 return JSON.parse(xhr.responseText); | 143 var rawCatalog = JSON.parse(xhr.responseText); |
| 144 for (var msgId in rawCatalog) | |
| 145 { | |
| 146 if (!(msgId in catalog)) | |
| 147 catalog[msgId] = parseMessage(rawCatalog[msgId]); | |
| 148 } | |
| 121 }; | 149 }; |
| 122 | 150 |
| 123 ext.i18n = { | 151 ext.i18n = { |
| 124 getMessage: function(msgId, substitutions) | 152 getMessage: function(msgId, substitutions) |
| 125 { | 153 { |
| 126 if (!localeCandidates) | 154 while (true) |
| 127 { | 155 { |
| 128 localeCandidates = getLocaleCandidates(); | 156 var message = catalog[msgId]; |
| 129 uiLocale = localeCandidates[0]; | 157 if (message) |
| 130 } | 158 { |
| 159 var [text, placeholders] = message; | |
| 131 | 160 |
| 132 if (msgId == "@@ui_locale") | 161 if (!(substitutions instanceof Array)) |
| 133 return uiLocale; | 162 substitutions = [substitutions]; |
| 134 | 163 |
| 135 for (var i = 0; i < localeCandidates.length; i++) | 164 for (var i = 0; i < placeholders.length; i++) |
| 136 { | 165 text = replacePlaceholder(text, placeholders[i], substitutions[i]); |
| 137 var catalog = getCatalog(localeCandidates[i]); | 166 |
| 138 if (!catalog) | 167 return text; |
| 139 { | |
| 140 // if there is no catalog for this locale | |
| 141 // candidate, don't try to load it again | |
| 142 localeCandidates.splice(i--, 1); | |
| 143 continue; | |
| 144 } | 168 } |
| 145 | 169 |
| 146 var msg = catalog[msgId]; | 170 if (locales.length == 0) |
| 147 if (!msg) | 171 return ""; |
| 148 continue; | |
| 149 | 172 |
| 150 var msgstr = msg.message; | 173 readCatalog(locales.shift()); |
| 151 if (!msgstr) | |
| 152 continue; | |
| 153 | |
| 154 for (var placeholder in msg.placeholders) | |
| 155 { | |
| 156 var placeholderDetails = msg.placeholders[placeholder]; | |
| 157 if (!placeholderDetails || !placeholderDetails.content) | |
| 158 continue; | |
| 159 if (placeholderDetails.content.indexOf("$") != 0) | |
| 160 continue; | |
| 161 | |
| 162 var placeholderIdx = parseInt(placeholderDetails.content.substr(1)); | |
| 163 if (isNaN(placeholderIdx) || placeholderIdx < 1) | |
| 164 continue; | |
| 165 | |
| 166 var placeholderValue; | |
| 167 if (typeof substitutions != "string") | |
| 168 placeholderValue = substitutions[placeholderIdx - 1]; | |
| 169 else if (placeholderIdx == 1) | |
| 170 placeholderValue = substitutions; | |
| 171 | |
| 172 msgstr = msgstr.replace("$" + placeholder + "$", placeholderValue || " "); | |
| 173 } | |
| 174 | |
| 175 return msgstr; | |
| 176 } | 174 } |
| 177 | |
| 178 return ""; | |
| 179 } | 175 } |
| 180 }; | 176 }; |
| 181 | 177 |
| 182 | 178 |
| 183 /* Utils */ | 179 /* Utils */ |
| 184 | 180 |
| 185 ext.getURL = function(path) | 181 ext.getURL = function(path) |
| 186 { | 182 { |
| 187 return safari.extension.baseURI + path; | 183 return safari.extension.baseURI + path; |
| 188 }; | 184 }; |
| 189 })(); | 185 })(); |
| OLD | NEW |