Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: safari/ext/common.js

Issue 6326608939974656: Issue 1502 - Cache translation catalogs on Safari (Closed)
Patch Set: Renamed "source" variable to avoid confusion Created Oct. 29, 2014, 7:58 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 })();
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld