/
symphony.js
264 lines (226 loc) · 6.38 KB
/
symphony.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/**
* @package assets
*/
/**
* The Symphony object provides language, message and context management.
*
* @class
*/
var Symphony = (function($) {
// Internal Symphony storage
var Storage = {
Context: {},
Dictionary: {},
Support: {}
};
/*-------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------*/
// Replace variables in string
function replaceVariables(string, inserts) {
if($.type(string) === 'string' && $.type(inserts) === 'object') {
$.each(inserts, function(index, value) {
string = string.replace('{$' + index + '}', value);
});
}
return string;
};
// Get localised strings
function translate(strings) {
var namespace = $.trim(Symphony.Context.get('env')['page-namespace']),
data = {
'strings': strings
};
// Validate and set namespace
if($.type(namespace) === 'string' && namespace !== '') {
data['namespace'] = namespace;
}
// Request translations
$.ajax({
async: false,
type: 'GET',
url: Symphony.Context.get('root') + '/symphony/ajax/translate/',
data: data,
dataType: 'json',
// Add localised strings
success: function(result) {
$.extend(true, Storage.Dictionary, result);
},
// Use English strings on error
error: function(jqXHR, textStatus, errorThrown) {
$.extend(true, Storage.Dictionary, strings);
}
});
};
/*-----------------------------------------------------------------------*/
// Set browser support information
try {
Storage.Support.localStorage = !!localStorage.getItem;
} catch(e) {
Storage.Support.localStorage = false;
}
// Deep copy jQuery.support
$.extend(true, Storage.Support, $.support);
/*-------------------------------------------------------------------------
Symphony API
-------------------------------------------------------------------------*/
return {
/**
* The Context object contains general information about the system,
* the backend, the current user. It includes an add and a get function.
* This is a private object and can only be accessed via add and get.
*
* @class
*/
Context: {
/**
* Add data to the Context object
*
* @param {String} group
* Name of the data group
* @param {String|Object} values
* Object or string to be stored
*/
add: function addContext(group, values) {
// Extend existing group
if(Storage.Context[group] && $.type(values) !== 'string') {
$.extend(Storage.Context[group], values);
}
// Add new group
else {
Storage.Context[group] = values;
}
// Always return
return true;
},
/**
* Get data from the Context object
*
* @param {String} group
* Name of the group to be returned
*/
get: function getContext(group) {
// Return full context, if no group is set
if(!group) {
return Storage.Context;
}
// Return false if group does not exist in Storage
if(typeof Storage.Context[group] === undefined) {
return false;
}
// Default: Return context group
return Storage.Context[group];
}
},
/**
* The Language object stores the dictionary with all needed translations.
* It offers public functions to add strings and get their translation and
* it offers private functions to handle variables and get the translations via
* an synchronous AJAX request.
* Since Symphony 2.3, it is also possible to define different translations
* for the same string, by using page namespaces.
* This is a private object
*
* @class
*/
Language: {
/**
* Add strings to the Dictionary
*
* @param {Object} strings
* Object with English string as key, value should be false
*/
add: function addStrings(strings) {
// English system
if(Symphony.Context.get('lang') === 'en') {
$.extend(true, Storage.Dictionary, strings);
}
// Localised system
else {
// Check if strings have already been translated
$.each(strings, function checkStrings(index, key) {
if(key in Storage.Dictionary) {
delete strings[key];
}
});
// Translate strings
if(!$.isEmptyObject(strings)) {
translate(strings);
}
}
},
/**
* Get translated string from the Dictionary.
* The function replaces variables like {$name} with the a specified value if
* an object of inserts is passed in the function call.
*
* @param {String} string
* English string to be translated
* @param {Object} inserts
* Object with variable name and value pairs
* @return {String}
* Returns the translated string
*/
get: function getString(string, inserts) {
var translation = Storage.Dictionary[string];
// Validate and set translation
if($.type(translation) === 'string') {
string = translation;
}
// Insert variables
string = replaceVariables(string, inserts);
// Return translated string
return string;
}
},
/**
* The message object handles system messages that should be displayed on the fly.
* It offers a post and a clear function to set and remove messages. Absolute dates
* and times will be replaced by a representation relative to the user's system time.
*
* @class
* @deprecated
* To be removed in Symphony 2.4 – please use Notify methods directly
*/
Message: {
/**
* Post system message
*
* @param {String} message
* Message to be shown
* @param {String} type
* Message type to be used as class name
* @deprecated
* To be removed in Symphony 2.4 – please use Notify methods directly
*/
post: function postMessage(message, type) {
$('header div.notifier').trigger('attach.notify', [message, type]);
},
/**
* Clear last message of a type
*
* @param {String} type
* Message type
* @deprecated
* To be removed in Symphony 2.4 – please use Notify methods directly
*/
clear: function clearMessage(type) {
$('header p.notice').filter('.' + type).first().trigger('detach.notify');
}
},
/**
* A collection of properties that represent the presence of
* different browser features and also contains the test results
* from jQuery.support.
*
* @class
*/
Support: Storage.Support,
/**
* A namespace for extension to store global functions
*
* @since Symphony 2.3
*/
Extensions: {}
};
}(window.jQuery));