flickerstreak@1
|
1 --[[
|
flickerstreak@1
|
2 Name: AceLocale-2.2
|
flickerstreak@7
|
3 Revision: $Rev$
|
flickerstreak@1
|
4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
|
flickerstreak@1
|
5 Inspired By: Ace 1.x by Turan (turan@gryphon.com)
|
flickerstreak@1
|
6 Website: http://www.wowace.com/
|
flickerstreak@1
|
7 Documentation: http://www.wowace.com/index.php/AceLocale-2.2
|
flickerstreak@1
|
8 SVN: http://svn.wowace.com/root/trunk/Ace2/AceLocale-2.2
|
flickerstreak@1
|
9 Description: Localization library for addons to use to handle proper
|
flickerstreak@1
|
10 localization and internationalization.
|
flickerstreak@1
|
11 Dependencies: AceLibrary
|
flickerstreak@7
|
12 License: LGPL v2.1
|
flickerstreak@1
|
13 ]]
|
flickerstreak@1
|
14
|
flickerstreak@1
|
15 local MAJOR_VERSION = "AceLocale-2.2"
|
flickerstreak@7
|
16 local MINOR_VERSION = "$Revision: 20000 $"
|
flickerstreak@1
|
17
|
flickerstreak@1
|
18 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
|
flickerstreak@1
|
19 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
flickerstreak@1
|
20
|
flickerstreak@1
|
21 local AceLocale = {}
|
flickerstreak@1
|
22
|
flickerstreak@1
|
23 local DEFAULT_LOCALE = "enUS"
|
flickerstreak@1
|
24 local _G = getfenv(0)
|
flickerstreak@1
|
25
|
flickerstreak@1
|
26 local BASE_TRANSLATIONS, DEBUGGING, TRANSLATIONS, BASE_LOCALE, TRANSLATION_TABLES, REVERSE_TRANSLATIONS, STRICTNESS, DYNAMIC_LOCALES, CURRENT_LOCALE, NAME
|
flickerstreak@1
|
27
|
flickerstreak@1
|
28 local rawget = rawget
|
flickerstreak@1
|
29 local rawset = rawset
|
flickerstreak@1
|
30 local type = type
|
flickerstreak@1
|
31
|
flickerstreak@1
|
32 local newRegistries = {}
|
flickerstreak@1
|
33 local scheduleClear
|
flickerstreak@1
|
34
|
flickerstreak@1
|
35 local lastSelf
|
flickerstreak@1
|
36 local __index = function(self, key)
|
flickerstreak@1
|
37 lastSelf = self
|
flickerstreak@1
|
38 local value = (rawget(self, TRANSLATIONS) or AceLocale.prototype)[key]
|
flickerstreak@1
|
39 rawset(self, key, value)
|
flickerstreak@1
|
40 return value
|
flickerstreak@1
|
41 end
|
flickerstreak@1
|
42
|
flickerstreak@1
|
43 local __newindex = function(self, k, v)
|
flickerstreak@1
|
44 if type(v) ~= "function" and type(k) ~= "table" then
|
flickerstreak@1
|
45 AceLocale.error(self, "Cannot change the values of an AceLocale instance.")
|
flickerstreak@1
|
46 end
|
flickerstreak@1
|
47 rawset(self, k, v)
|
flickerstreak@1
|
48 end
|
flickerstreak@1
|
49
|
flickerstreak@1
|
50 local __tostring = function(self)
|
flickerstreak@1
|
51 if type(rawget(self, 'GetLibraryVersion')) == "function" then
|
flickerstreak@1
|
52 return self:GetLibraryVersion()
|
flickerstreak@1
|
53 else
|
flickerstreak@1
|
54 return "AceLocale(" .. self[NAME] .. ")"
|
flickerstreak@1
|
55 end
|
flickerstreak@1
|
56 end
|
flickerstreak@1
|
57
|
flickerstreak@1
|
58 local function clearCache(self)
|
flickerstreak@1
|
59 if not rawget(self, BASE_TRANSLATIONS) then
|
flickerstreak@1
|
60 return
|
flickerstreak@1
|
61 end
|
flickerstreak@1
|
62
|
flickerstreak@1
|
63 local cache = self[BASE_TRANSLATIONS]
|
flickerstreak@1
|
64 rawset(self, REVERSE_TRANSLATIONS, nil)
|
flickerstreak@1
|
65
|
flickerstreak@1
|
66 for k in pairs(self) do
|
flickerstreak@1
|
67 if rawget(cache, k) ~= nil then
|
flickerstreak@1
|
68 self[k] = nil
|
flickerstreak@1
|
69 end
|
flickerstreak@1
|
70 end
|
flickerstreak@1
|
71 rawset(self, 'tmp', true)
|
flickerstreak@1
|
72 self.tmp = nil
|
flickerstreak@1
|
73 end
|
flickerstreak@1
|
74
|
flickerstreak@1
|
75 local function refixInstance(instance)
|
flickerstreak@1
|
76 if getmetatable(instance) then
|
flickerstreak@1
|
77 setmetatable(instance, nil)
|
flickerstreak@1
|
78 end
|
flickerstreak@1
|
79 local translations = instance[TRANSLATIONS]
|
flickerstreak@1
|
80 if translations then
|
flickerstreak@1
|
81 if getmetatable(translations) then
|
flickerstreak@1
|
82 setmetatable(translations, nil)
|
flickerstreak@1
|
83 end
|
flickerstreak@1
|
84 local baseTranslations = instance[BASE_TRANSLATIONS]
|
flickerstreak@1
|
85 if getmetatable(baseTranslations) then
|
flickerstreak@1
|
86 setmetatable(baseTranslations, nil)
|
flickerstreak@1
|
87 end
|
flickerstreak@1
|
88 if translations == baseTranslations or instance[STRICTNESS] then
|
flickerstreak@1
|
89 setmetatable(instance, {
|
flickerstreak@1
|
90 __index = __index,
|
flickerstreak@1
|
91 __newindex = __newindex,
|
flickerstreak@1
|
92 __tostring = __tostring
|
flickerstreak@1
|
93 })
|
flickerstreak@1
|
94
|
flickerstreak@1
|
95 setmetatable(translations, {
|
flickerstreak@1
|
96 __index = AceLocale.prototype
|
flickerstreak@1
|
97 })
|
flickerstreak@1
|
98 else
|
flickerstreak@1
|
99 setmetatable(instance, {
|
flickerstreak@1
|
100 __index = __index,
|
flickerstreak@1
|
101 __newindex = __newindex,
|
flickerstreak@1
|
102 __tostring = __tostring
|
flickerstreak@1
|
103 })
|
flickerstreak@1
|
104
|
flickerstreak@1
|
105 setmetatable(translations, {
|
flickerstreak@1
|
106 __index = baseTranslations,
|
flickerstreak@1
|
107 })
|
flickerstreak@1
|
108
|
flickerstreak@1
|
109 setmetatable(baseTranslations, {
|
flickerstreak@1
|
110 __index = AceLocale.prototype,
|
flickerstreak@1
|
111 })
|
flickerstreak@1
|
112 end
|
flickerstreak@1
|
113 else
|
flickerstreak@1
|
114 setmetatable(instance, {
|
flickerstreak@1
|
115 __index = __index,
|
flickerstreak@1
|
116 __newindex = __newindex,
|
flickerstreak@1
|
117 __tostring = __tostring,
|
flickerstreak@1
|
118 })
|
flickerstreak@1
|
119 end
|
flickerstreak@1
|
120 clearCache(instance)
|
flickerstreak@1
|
121 newRegistries[instance] = true
|
flickerstreak@1
|
122 scheduleClear()
|
flickerstreak@1
|
123 return instance
|
flickerstreak@1
|
124 end
|
flickerstreak@1
|
125
|
flickerstreak@1
|
126 function AceLocale:new(name)
|
flickerstreak@1
|
127 self:argCheck(name, 2, "string")
|
flickerstreak@1
|
128
|
flickerstreak@1
|
129 if self.registry[name] and type(rawget(self.registry[name], 'GetLibraryVersion')) ~= "function" then
|
flickerstreak@1
|
130 return self.registry[name]
|
flickerstreak@1
|
131 end
|
flickerstreak@1
|
132
|
flickerstreak@1
|
133 AceLocale.registry[name] = refixInstance({
|
flickerstreak@1
|
134 [STRICTNESS] = false,
|
flickerstreak@1
|
135 [NAME] = name,
|
flickerstreak@1
|
136 })
|
flickerstreak@1
|
137 newRegistries[AceLocale.registry[name]] = true
|
flickerstreak@1
|
138 return AceLocale.registry[name]
|
flickerstreak@1
|
139 end
|
flickerstreak@1
|
140
|
flickerstreak@1
|
141 AceLocale.prototype = { class = AceLocale }
|
flickerstreak@1
|
142
|
flickerstreak@1
|
143 function AceLocale.prototype:EnableDebugging()
|
flickerstreak@1
|
144 if rawget(self, BASE_TRANSLATIONS) then
|
flickerstreak@1
|
145 AceLocale.error(self, "Cannot enable debugging after a translation has been registered.")
|
flickerstreak@1
|
146 end
|
flickerstreak@1
|
147 rawset(self, DEBUGGING, true)
|
flickerstreak@1
|
148 end
|
flickerstreak@1
|
149
|
flickerstreak@1
|
150 function AceLocale.prototype:EnableDynamicLocales(override)
|
flickerstreak@1
|
151 AceLocale.argCheck(self, override, 2, "boolean", "nil")
|
flickerstreak@1
|
152 if not override and rawget(self, BASE_TRANSLATIONS) then
|
flickerstreak@1
|
153 AceLocale.error(self, "Cannot enable dynamic locales after a translation has been registered.")
|
flickerstreak@1
|
154 end
|
flickerstreak@1
|
155 if not rawget(self, DYNAMIC_LOCALES) then
|
flickerstreak@1
|
156 rawset(self, DYNAMIC_LOCALES, true)
|
flickerstreak@1
|
157 if rawget(self, BASE_LOCALE) then
|
flickerstreak@1
|
158 if not rawget(self, TRANSLATION_TABLES) then
|
flickerstreak@1
|
159 rawset(self, TRANSLATION_TABLES, {})
|
flickerstreak@1
|
160 end
|
flickerstreak@1
|
161 self[TRANSLATION_TABLES][self[BASE_LOCALE]] = self[BASE_TRANSLATIONS]
|
flickerstreak@1
|
162 self[TRANSLATION_TABLES][self[CURRENT_LOCALE]] = self[TRANSLATIONS]
|
flickerstreak@1
|
163 end
|
flickerstreak@1
|
164 end
|
flickerstreak@1
|
165 end
|
flickerstreak@1
|
166
|
flickerstreak@1
|
167 function AceLocale.prototype:RegisterTranslations(locale, func)
|
flickerstreak@1
|
168 AceLocale.argCheck(self, locale, 2, "string")
|
flickerstreak@1
|
169 AceLocale.argCheck(self, func, 3, "function")
|
flickerstreak@1
|
170
|
flickerstreak@1
|
171 if locale == rawget(self, BASE_LOCALE) then
|
flickerstreak@1
|
172 AceLocale.error(self, "Cannot provide the same locale more than once. %q provided twice.", locale)
|
flickerstreak@1
|
173 end
|
flickerstreak@1
|
174
|
flickerstreak@1
|
175 if rawget(self, BASE_TRANSLATIONS) and GetLocale() ~= locale then
|
flickerstreak@1
|
176 if rawget(self, DEBUGGING) or rawget(self, DYNAMIC_LOCALES) then
|
flickerstreak@1
|
177 if not rawget(self, TRANSLATION_TABLES) then
|
flickerstreak@1
|
178 rawset(self, TRANSLATION_TABLES, {})
|
flickerstreak@1
|
179 end
|
flickerstreak@1
|
180 if self[TRANSLATION_TABLES][locale] then
|
flickerstreak@1
|
181 AceLocale.error(self, "Cannot provide the same locale more than once. %q provided twice.", locale)
|
flickerstreak@1
|
182 end
|
flickerstreak@1
|
183 local t = func()
|
flickerstreak@1
|
184 func = nil
|
flickerstreak@1
|
185 if type(t) ~= "table" then
|
flickerstreak@1
|
186 AceLocale.error(self, "Bad argument #3 to `RegisterTranslations'. function did not return a table. (expected table, got %s)", type(t))
|
flickerstreak@1
|
187 end
|
flickerstreak@1
|
188 self[TRANSLATION_TABLES][locale] = t
|
flickerstreak@1
|
189 t = nil
|
flickerstreak@1
|
190 end
|
flickerstreak@1
|
191 func = nil
|
flickerstreak@1
|
192 return
|
flickerstreak@1
|
193 end
|
flickerstreak@1
|
194 local t = func()
|
flickerstreak@1
|
195 func = nil
|
flickerstreak@1
|
196 if type(t) ~= "table" then
|
flickerstreak@1
|
197 AceLocale.error(self, "Bad argument #3 to `RegisterTranslations'. function did not return a table. (expected table, got %s)", type(t))
|
flickerstreak@1
|
198 end
|
flickerstreak@1
|
199
|
flickerstreak@1
|
200 rawset(self, TRANSLATIONS, t)
|
flickerstreak@1
|
201 if not rawget(self, BASE_TRANSLATIONS) then
|
flickerstreak@1
|
202 rawset(self, BASE_TRANSLATIONS, t)
|
flickerstreak@1
|
203 rawset(self, BASE_LOCALE, locale)
|
flickerstreak@1
|
204 for key,value in pairs(t) do
|
flickerstreak@1
|
205 if value == true then
|
flickerstreak@1
|
206 t[key] = key
|
flickerstreak@1
|
207 end
|
flickerstreak@1
|
208 end
|
flickerstreak@1
|
209 else
|
flickerstreak@1
|
210 for key, value in pairs(self[TRANSLATIONS]) do
|
flickerstreak@1
|
211 if not rawget(self[BASE_TRANSLATIONS], key) then
|
flickerstreak@1
|
212 AceLocale.error(self, "Improper translation exists. %q is likely misspelled for locale %s.", key, locale)
|
flickerstreak@1
|
213 end
|
flickerstreak@1
|
214 if value == true then
|
flickerstreak@1
|
215 AceLocale.error(self, "Can only accept true as a value on the base locale. %q is the base locale, %q is not.", rawget(self, BASE_LOCALE), locale)
|
flickerstreak@1
|
216 end
|
flickerstreak@1
|
217 end
|
flickerstreak@1
|
218 end
|
flickerstreak@1
|
219 rawset(self, CURRENT_LOCALE, locale)
|
flickerstreak@7
|
220 if not rawget(self, 'reverse') then
|
flickerstreak@7
|
221 rawset(self, 'reverse', setmetatable({}, { __index = function(self2, key)
|
flickerstreak@7
|
222 local self = AceLocale.reverseToBase[self2]
|
flickerstreak@7
|
223 if not rawget(self, REVERSE_TRANSLATIONS) then
|
flickerstreak@7
|
224 self:GetReverseTranslation(key)
|
flickerstreak@7
|
225 end
|
flickerstreak@7
|
226 self.reverse = self[REVERSE_TRANSLATIONS]
|
flickerstreak@7
|
227 return self.reverse[key]
|
flickerstreak@7
|
228 end }))
|
flickerstreak@7
|
229 AceLocale.reverseToBase[self.reverse] = self
|
flickerstreak@7
|
230 end
|
flickerstreak@1
|
231 refixInstance(self)
|
flickerstreak@1
|
232 if rawget(self, DEBUGGING) or rawget(self, DYNAMIC_LOCALES) then
|
flickerstreak@1
|
233 if not rawget(self, TRANSLATION_TABLES) then
|
flickerstreak@1
|
234 rawset(self, TRANSLATION_TABLES, {})
|
flickerstreak@1
|
235 end
|
flickerstreak@1
|
236 self[TRANSLATION_TABLES][locale] = t
|
flickerstreak@1
|
237 end
|
flickerstreak@1
|
238 t = nil
|
flickerstreak@1
|
239 end
|
flickerstreak@1
|
240
|
flickerstreak@1
|
241 function AceLocale.prototype:SetLocale(locale)
|
flickerstreak@1
|
242 AceLocale.argCheck(self, locale, 2, "string", "boolean")
|
flickerstreak@1
|
243 if not rawget(self, DYNAMIC_LOCALES) then
|
flickerstreak@1
|
244 AceLocale.error(self, "Cannot call `SetLocale' without first calling `EnableDynamicLocales'.")
|
flickerstreak@1
|
245 end
|
flickerstreak@1
|
246 if not rawget(self, TRANSLATION_TABLES) then
|
flickerstreak@1
|
247 AceLocale.error(self, "Cannot call `SetLocale' without first calling `RegisterTranslations'.")
|
flickerstreak@1
|
248 end
|
flickerstreak@1
|
249 if locale == true then
|
flickerstreak@1
|
250 locale = GetLocale()
|
flickerstreak@1
|
251 if not self[TRANSLATION_TABLES][locale] then
|
flickerstreak@1
|
252 locale = self[BASE_LOCALE]
|
flickerstreak@1
|
253 end
|
flickerstreak@1
|
254 end
|
flickerstreak@1
|
255
|
flickerstreak@1
|
256 if self[CURRENT_LOCALE] == locale then
|
flickerstreak@1
|
257 return
|
flickerstreak@1
|
258 end
|
flickerstreak@1
|
259
|
flickerstreak@1
|
260 if not self[TRANSLATION_TABLES][locale] then
|
flickerstreak@1
|
261 AceLocale.error(self, "Locale %q not registered.", locale)
|
flickerstreak@1
|
262 end
|
flickerstreak@1
|
263
|
flickerstreak@1
|
264 self[TRANSLATIONS] = self[TRANSLATION_TABLES][locale]
|
flickerstreak@1
|
265 self[CURRENT_LOCALE] = locale
|
flickerstreak@1
|
266 refixInstance(self)
|
flickerstreak@1
|
267 end
|
flickerstreak@1
|
268
|
flickerstreak@1
|
269 function AceLocale.prototype:GetLocale()
|
flickerstreak@1
|
270 if not rawget(self, TRANSLATION_TABLES) then
|
flickerstreak@1
|
271 AceLocale.error(self, "Cannot call `GetLocale' without first calling `RegisterTranslations'.")
|
flickerstreak@1
|
272 end
|
flickerstreak@1
|
273 return self[CURRENT_LOCALE]
|
flickerstreak@1
|
274 end
|
flickerstreak@1
|
275
|
flickerstreak@1
|
276 local function iter(t, position)
|
flickerstreak@1
|
277 return (next(t, position))
|
flickerstreak@1
|
278 end
|
flickerstreak@1
|
279
|
flickerstreak@1
|
280 function AceLocale.prototype:IterateAvailableLocales()
|
flickerstreak@1
|
281 if not rawget(self, DYNAMIC_LOCALES) then
|
flickerstreak@1
|
282 AceLocale.error(self, "Cannot call `IterateAvailableLocales' without first calling `EnableDynamicLocales'.")
|
flickerstreak@1
|
283 end
|
flickerstreak@1
|
284 if not rawget(self, TRANSLATION_TABLES) then
|
flickerstreak@1
|
285 AceLocale.error(self, "Cannot call `IterateAvailableLocales' without first calling `RegisterTranslations'.")
|
flickerstreak@1
|
286 end
|
flickerstreak@1
|
287 return iter, self[TRANSLATION_TABLES], nil
|
flickerstreak@1
|
288 end
|
flickerstreak@1
|
289
|
flickerstreak@1
|
290 function AceLocale.prototype:HasLocale(locale)
|
flickerstreak@1
|
291 if not rawget(self, DYNAMIC_LOCALES) then
|
flickerstreak@1
|
292 AceLocale.error(self, "Cannot call `HasLocale' without first calling `EnableDynamicLocales'.")
|
flickerstreak@1
|
293 end
|
flickerstreak@1
|
294 AceLocale.argCheck(self, locale, 2, "string")
|
flickerstreak@1
|
295 return rawget(self, TRANSLATION_TABLES) and self[TRANSLATION_TABLES][locale] ~= nil
|
flickerstreak@1
|
296 end
|
flickerstreak@1
|
297
|
flickerstreak@1
|
298 function AceLocale.prototype:SetStrictness(strict)
|
flickerstreak@1
|
299 AceLocale.argCheck(self, strict, 2, "boolean")
|
flickerstreak@1
|
300 local mt = getmetatable(self)
|
flickerstreak@1
|
301 if not mt then
|
flickerstreak@1
|
302 AceLocale.error(self, "Cannot call `SetStrictness' without a metatable.")
|
flickerstreak@1
|
303 end
|
flickerstreak@1
|
304 if not rawget(self, TRANSLATIONS) then
|
flickerstreak@1
|
305 AceLocale.error(self, "No translations registered.")
|
flickerstreak@1
|
306 end
|
flickerstreak@1
|
307 rawset(self, STRICTNESS, strict)
|
flickerstreak@1
|
308 refixInstance(self)
|
flickerstreak@1
|
309 end
|
flickerstreak@1
|
310
|
flickerstreak@1
|
311 local function initReverse(self)
|
flickerstreak@7
|
312 rawset(self, REVERSE_TRANSLATIONS, setmetatable({}, { __index = function(_, key)
|
flickerstreak@7
|
313 AceLocale.error(self, "Reverse translation for %q does not exist", key)
|
flickerstreak@7
|
314 end }))
|
flickerstreak@1
|
315 local alpha = self[TRANSLATIONS]
|
flickerstreak@1
|
316 local bravo = self[REVERSE_TRANSLATIONS]
|
flickerstreak@1
|
317 for base, localized in pairs(alpha) do
|
flickerstreak@1
|
318 bravo[localized] = base
|
flickerstreak@1
|
319 end
|
flickerstreak@1
|
320 end
|
flickerstreak@1
|
321
|
flickerstreak@1
|
322 function AceLocale.prototype:GetTranslation(text)
|
flickerstreak@1
|
323 AceLocale.argCheck(self, text, 1, "string", "number")
|
flickerstreak@1
|
324 if not rawget(self, TRANSLATIONS) then
|
flickerstreak@1
|
325 AceLocale.error(self, "No translations registered")
|
flickerstreak@1
|
326 end
|
flickerstreak@1
|
327 return self[text]
|
flickerstreak@1
|
328 end
|
flickerstreak@1
|
329
|
flickerstreak@1
|
330 function AceLocale.prototype:GetStrictTranslation(text)
|
flickerstreak@1
|
331 AceLocale.argCheck(self, text, 1, "string", "number")
|
flickerstreak@1
|
332 local x = rawget(self, TRANSLATIONS)
|
flickerstreak@1
|
333 if not x then
|
flickerstreak@1
|
334 AceLocale.error(self, "No translations registered")
|
flickerstreak@1
|
335 end
|
flickerstreak@1
|
336 local value = rawget(x, text)
|
flickerstreak@1
|
337 if value == nil then
|
flickerstreak@1
|
338 AceLocale.error(self, "Translation %q does not exist for locale %s", text, self[CURRENT_LOCALE])
|
flickerstreak@1
|
339 end
|
flickerstreak@1
|
340 return value
|
flickerstreak@1
|
341 end
|
flickerstreak@1
|
342
|
flickerstreak@1
|
343 function AceLocale.prototype:GetReverseTranslation(text)
|
flickerstreak@1
|
344 local x = rawget(self, REVERSE_TRANSLATIONS)
|
flickerstreak@1
|
345 if not x then
|
flickerstreak@1
|
346 if not rawget(self, TRANSLATIONS) then
|
flickerstreak@1
|
347 AceLocale.error(self, "No translations registered")
|
flickerstreak@1
|
348 end
|
flickerstreak@1
|
349 initReverse(self)
|
flickerstreak@1
|
350 x = self[REVERSE_TRANSLATIONS]
|
flickerstreak@1
|
351 end
|
flickerstreak@1
|
352 local translation = x[text]
|
flickerstreak@1
|
353 if not translation then
|
flickerstreak@1
|
354 AceLocale.error(self, "Reverse translation for %q does not exist", text)
|
flickerstreak@1
|
355 end
|
flickerstreak@1
|
356 return translation
|
flickerstreak@1
|
357 end
|
flickerstreak@1
|
358
|
flickerstreak@1
|
359 function AceLocale.prototype:GetIterator()
|
flickerstreak@1
|
360 local x = rawget(self, TRANSLATIONS)
|
flickerstreak@1
|
361 if not x then
|
flickerstreak@1
|
362 AceLocale.error(self, "No translations registered")
|
flickerstreak@1
|
363 end
|
flickerstreak@1
|
364 return next, x, nil
|
flickerstreak@1
|
365 end
|
flickerstreak@1
|
366
|
flickerstreak@1
|
367 function AceLocale.prototype:GetReverseIterator()
|
flickerstreak@1
|
368 local x = rawget(self, REVERSE_TRANSLATIONS)
|
flickerstreak@1
|
369 if not x then
|
flickerstreak@1
|
370 if not rawget(self, TRANSLATIONS) then
|
flickerstreak@1
|
371 AceLocale.error(self, "No translations registered")
|
flickerstreak@1
|
372 end
|
flickerstreak@1
|
373 initReverse(self)
|
flickerstreak@1
|
374 x = self[REVERSE_TRANSLATIONS]
|
flickerstreak@1
|
375 end
|
flickerstreak@1
|
376 return next, x, nil
|
flickerstreak@1
|
377 end
|
flickerstreak@1
|
378
|
flickerstreak@1
|
379 function AceLocale.prototype:HasTranslation(text)
|
flickerstreak@1
|
380 AceLocale.argCheck(self, text, 1, "string", "number")
|
flickerstreak@1
|
381 local x = rawget(self, TRANSLATIONS)
|
flickerstreak@1
|
382 if not x then
|
flickerstreak@1
|
383 AceLocale.error(self, "No translations registered")
|
flickerstreak@1
|
384 end
|
flickerstreak@1
|
385 return rawget(x, text) and true
|
flickerstreak@1
|
386 end
|
flickerstreak@1
|
387
|
flickerstreak@1
|
388 function AceLocale.prototype:HasReverseTranslation(text)
|
flickerstreak@1
|
389 local x = rawget(self, REVERSE_TRANSLATIONS)
|
flickerstreak@1
|
390 if not x then
|
flickerstreak@1
|
391 if not rawget(self, TRANSLATIONS) then
|
flickerstreak@1
|
392 AceLocale.error(self, "No translations registered")
|
flickerstreak@1
|
393 end
|
flickerstreak@1
|
394 initReverse(self)
|
flickerstreak@1
|
395 x = self[REVERSE_TRANSLATIONS]
|
flickerstreak@1
|
396 end
|
flickerstreak@7
|
397 return rawget(x, text) and true
|
flickerstreak@1
|
398 end
|
flickerstreak@1
|
399
|
flickerstreak@1
|
400 function AceLocale.prototype:Debug()
|
flickerstreak@1
|
401 if not rawget(self, DEBUGGING) then
|
flickerstreak@1
|
402 return
|
flickerstreak@1
|
403 end
|
flickerstreak@1
|
404 local words = {}
|
flickerstreak@1
|
405 local locales = {"enUS", "deDE", "frFR", "koKR", "zhCN", "zhTW", "esES"}
|
flickerstreak@1
|
406 local localizations = {}
|
flickerstreak@1
|
407 DEFAULT_CHAT_FRAME:AddMessage("--- AceLocale Debug ---")
|
flickerstreak@1
|
408 for _,locale in ipairs(locales) do
|
flickerstreak@1
|
409 if not self[TRANSLATION_TABLES][locale] then
|
flickerstreak@7
|
410 DEFAULT_CHAT_FRAME:AddMessage(("Locale %q not found"):format(locale))
|
flickerstreak@1
|
411 else
|
flickerstreak@1
|
412 localizations[locale] = self[TRANSLATION_TABLES][locale]
|
flickerstreak@1
|
413 end
|
flickerstreak@1
|
414 end
|
flickerstreak@1
|
415 local localeDebug = {}
|
flickerstreak@1
|
416 for locale, localization in pairs(localizations) do
|
flickerstreak@1
|
417 localeDebug[locale] = {}
|
flickerstreak@1
|
418 for word in pairs(localization) do
|
flickerstreak@1
|
419 if type(localization[word]) == "table" then
|
flickerstreak@1
|
420 if type(words[word]) ~= "table" then
|
flickerstreak@1
|
421 words[word] = {}
|
flickerstreak@1
|
422 end
|
flickerstreak@1
|
423 for bit in pairs(localization[word]) do
|
flickerstreak@1
|
424 if type(localization[word][bit]) == "string" then
|
flickerstreak@1
|
425 words[word][bit] = true
|
flickerstreak@1
|
426 end
|
flickerstreak@1
|
427 end
|
flickerstreak@1
|
428 elseif type(localization[word]) == "string" then
|
flickerstreak@1
|
429 words[word] = true
|
flickerstreak@1
|
430 end
|
flickerstreak@1
|
431 end
|
flickerstreak@1
|
432 end
|
flickerstreak@1
|
433 for word in pairs(words) do
|
flickerstreak@1
|
434 if type(words[word]) == "table" then
|
flickerstreak@1
|
435 for bit in pairs(words[word]) do
|
flickerstreak@1
|
436 for locale, localization in pairs(localizations) do
|
flickerstreak@1
|
437 if not rawget(localization, word) or not localization[word][bit] then
|
flickerstreak@1
|
438 localeDebug[locale][word .. "::" .. bit] = true
|
flickerstreak@1
|
439 end
|
flickerstreak@1
|
440 end
|
flickerstreak@1
|
441 end
|
flickerstreak@1
|
442 else
|
flickerstreak@1
|
443 for locale, localization in pairs(localizations) do
|
flickerstreak@1
|
444 if not rawget(localization, word) then
|
flickerstreak@1
|
445 localeDebug[locale][word] = true
|
flickerstreak@1
|
446 end
|
flickerstreak@1
|
447 end
|
flickerstreak@1
|
448 end
|
flickerstreak@1
|
449 end
|
flickerstreak@1
|
450 for locale, t in pairs(localeDebug) do
|
flickerstreak@1
|
451 if not next(t) then
|
flickerstreak@7
|
452 DEFAULT_CHAT_FRAME:AddMessage(("Locale %q complete"):format(locale))
|
flickerstreak@1
|
453 else
|
flickerstreak@7
|
454 DEFAULT_CHAT_FRAME:AddMessage(("Locale %q missing:"):format(locale))
|
flickerstreak@1
|
455 for word in pairs(t) do
|
flickerstreak@7
|
456 DEFAULT_CHAT_FRAME:AddMessage((" %q"):format(word))
|
flickerstreak@1
|
457 end
|
flickerstreak@1
|
458 end
|
flickerstreak@1
|
459 end
|
flickerstreak@1
|
460 DEFAULT_CHAT_FRAME:AddMessage("--- End AceLocale Debug ---")
|
flickerstreak@1
|
461 end
|
flickerstreak@1
|
462
|
flickerstreak@1
|
463 setmetatable(AceLocale.prototype, {
|
flickerstreak@1
|
464 __index = function(self, k)
|
flickerstreak@1
|
465 if type(k) ~= "table" and k ~= 0 and k ~= "GetLibraryVersion" and k ~= "error" and k ~= "assert" and k ~= "argCheck" and k ~= "pcall" then -- HACK: remove "GetLibraryVersion" and such later.
|
flickerstreak@1
|
466 AceLocale.error(lastSelf or self, "Translation %q does not exist.", k)
|
flickerstreak@1
|
467 end
|
flickerstreak@1
|
468 return nil
|
flickerstreak@1
|
469 end
|
flickerstreak@1
|
470 })
|
flickerstreak@1
|
471
|
flickerstreak@1
|
472 local function activate(self, oldLib, oldDeactivate)
|
flickerstreak@1
|
473 AceLocale = self
|
flickerstreak@1
|
474
|
flickerstreak@1
|
475 self.frame = oldLib and oldLib.frame or CreateFrame("Frame")
|
flickerstreak@1
|
476 self.registry = oldLib and oldLib.registry or {}
|
flickerstreak@1
|
477 self.BASE_TRANSLATIONS = oldLib and oldLib.BASE_TRANSLATIONS or {}
|
flickerstreak@1
|
478 self.DEBUGGING = oldLib and oldLib.DEBUGGING or {}
|
flickerstreak@1
|
479 self.TRANSLATIONS = oldLib and oldLib.TRANSLATIONS or {}
|
flickerstreak@1
|
480 self.BASE_LOCALE = oldLib and oldLib.BASE_LOCALE or {}
|
flickerstreak@1
|
481 self.TRANSLATION_TABLES = oldLib and oldLib.TRANSLATION_TABLES or {}
|
flickerstreak@1
|
482 self.REVERSE_TRANSLATIONS = oldLib and oldLib.REVERSE_TRANSLATIONS or {}
|
flickerstreak@1
|
483 self.STRICTNESS = oldLib and oldLib.STRICTNESS or {}
|
flickerstreak@1
|
484 self.NAME = oldLib and oldLib.NAME or {}
|
flickerstreak@1
|
485 self.DYNAMIC_LOCALES = oldLib and oldLib.DYNAMIC_LOCALES or {}
|
flickerstreak@1
|
486 self.CURRENT_LOCALE = oldLib and oldLib.CURRENT_LOCALE or {}
|
flickerstreak@7
|
487 self.reverseToBase = oldLib and oldLib.reverseToBase or {}
|
flickerstreak@1
|
488
|
flickerstreak@1
|
489 BASE_TRANSLATIONS = self.BASE_TRANSLATIONS
|
flickerstreak@1
|
490 DEBUGGING = self.DEBUGGING
|
flickerstreak@1
|
491 TRANSLATIONS = self.TRANSLATIONS
|
flickerstreak@1
|
492 BASE_LOCALE = self.BASE_LOCALE
|
flickerstreak@1
|
493 TRANSLATION_TABLES = self.TRANSLATION_TABLES
|
flickerstreak@1
|
494 REVERSE_TRANSLATIONS = self.REVERSE_TRANSLATIONS
|
flickerstreak@1
|
495 STRICTNESS = self.STRICTNESS
|
flickerstreak@1
|
496 NAME = self.NAME
|
flickerstreak@1
|
497 DYNAMIC_LOCALES = self.DYNAMIC_LOCALES
|
flickerstreak@1
|
498 CURRENT_LOCALE = self.CURRENT_LOCALE
|
flickerstreak@1
|
499
|
flickerstreak@1
|
500
|
flickerstreak@1
|
501 local GetTime = GetTime
|
flickerstreak@1
|
502 local timeUntilClear = GetTime() + 5
|
flickerstreak@1
|
503 scheduleClear = function()
|
flickerstreak@1
|
504 if next(newRegistries) then
|
flickerstreak@1
|
505 self.frame:Show()
|
flickerstreak@1
|
506 timeUntilClear = GetTime() + 5
|
flickerstreak@1
|
507 end
|
flickerstreak@1
|
508 end
|
flickerstreak@1
|
509
|
flickerstreak@1
|
510 if not self.registry then
|
flickerstreak@1
|
511 self.registry = {}
|
flickerstreak@1
|
512 else
|
flickerstreak@1
|
513 for name, instance in pairs(self.registry) do
|
flickerstreak@1
|
514 local name = name
|
flickerstreak@1
|
515 local mt = getmetatable(instance)
|
flickerstreak@1
|
516 setmetatable(instance, nil)
|
flickerstreak@1
|
517 instance[NAME] = name
|
flickerstreak@1
|
518 local strict
|
flickerstreak@1
|
519 if instance[STRICTNESS] ~= nil then
|
flickerstreak@1
|
520 strict = instance[STRICTNESS]
|
flickerstreak@1
|
521 elseif instance[TRANSLATIONS] ~= instance[BASE_TRANSLATIONS] then
|
flickerstreak@1
|
522 if getmetatable(instance[TRANSLATIONS]).__index == oldLib.prototype then
|
flickerstreak@1
|
523 strict = true
|
flickerstreak@1
|
524 end
|
flickerstreak@1
|
525 end
|
flickerstreak@1
|
526 instance[STRICTNESS] = strict and true or false
|
flickerstreak@1
|
527 refixInstance(instance)
|
flickerstreak@1
|
528 end
|
flickerstreak@1
|
529 end
|
flickerstreak@1
|
530
|
flickerstreak@1
|
531 self.frame:SetScript("OnEvent", scheduleClear)
|
flickerstreak@1
|
532 self.frame:SetScript("OnUpdate", function() -- (this, elapsed)
|
flickerstreak@1
|
533 if timeUntilClear - GetTime() <= 0 then
|
flickerstreak@1
|
534 self.frame:Hide()
|
flickerstreak@1
|
535 for k in pairs(newRegistries) do
|
flickerstreak@1
|
536 clearCache(k)
|
flickerstreak@1
|
537 newRegistries[k] = nil
|
flickerstreak@1
|
538 k = nil
|
flickerstreak@1
|
539 end
|
flickerstreak@1
|
540 end
|
flickerstreak@1
|
541 end)
|
flickerstreak@1
|
542 self.frame:UnregisterAllEvents()
|
flickerstreak@1
|
543 self.frame:RegisterEvent("ADDON_LOADED")
|
flickerstreak@1
|
544 self.frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
flickerstreak@1
|
545 self.frame:Show()
|
flickerstreak@1
|
546
|
flickerstreak@1
|
547 if oldDeactivate then
|
flickerstreak@1
|
548 oldDeactivate(oldLib)
|
flickerstreak@1
|
549 end
|
flickerstreak@1
|
550 end
|
flickerstreak@1
|
551
|
flickerstreak@1
|
552 AceLibrary:Register(AceLocale, MAJOR_VERSION, MINOR_VERSION, activate)
|