1 /** |
|
2 * MyAMS standard plug-ins loader |
|
3 * |
|
4 * Only basic JQuery, Bootstrap and MyAMS javascript extensions are typically loaded from main page. |
|
5 * Other JQuery plug-ins may be loaded dynamically. |
|
6 * Several JQuery extension plug-ins are already included and pre-configured by MyAMS. Other external |
|
7 * plug-ins can be defined and loaded dynamically using simple "data" attributes. |
|
8 * |
|
9 * WARNING: any plug-in implicated into a form submit process (like JQuery-form or JQuery-progressbar) |
|
10 * must be loaded in a synchronous way. Otherwise, if you use named buttons to submit your forms, |
|
11 * dynamic hidden input fields created by JQuery-validate plug-in will be removed from the form |
|
12 * before the form is submitted! |
|
13 */ |
|
14 (function($, globals) { |
|
15 |
|
16 "use strict"; |
|
17 |
|
18 var ams = globals.MyAMS; |
|
19 |
|
20 ams.plugins = { |
|
21 |
|
22 /** |
|
23 * Container of enabled plug-ins |
|
24 */ |
|
25 enabled: {}, |
|
26 |
|
27 /** |
|
28 * Initialize list of content plug-ins |
|
29 */ |
|
30 init: function(element) { |
|
31 |
|
32 // Initialize custom data attributes |
|
33 ams.plugins.initData(element); |
|
34 |
|
35 // Check for disabled plug-ins |
|
36 var disabled = []; |
|
37 $('[data-ams-plugins-disabled]', element).each(function() { |
|
38 var plugins = $(this).data('ams-plugins-disabled').split(/\s+/); |
|
39 for (var index = 0; index < plugins.length; index++) { |
|
40 disabled.push(plugins[index]); |
|
41 } |
|
42 }); |
|
43 |
|
44 // Scan new element for plug-ins |
|
45 var plugins = {}; |
|
46 var name; |
|
47 |
|
48 // Inner plug-in register function |
|
49 function _registerPlugin(name, new_plugin) { |
|
50 if (plugins.hasOwnProperty(name)) { |
|
51 var plugin = plugins[name]; |
|
52 plugin.css = plugin.css || new_plugin.css; |
|
53 plugin.callbacks.push({ |
|
54 callback: new_plugin.callback, |
|
55 context: new_plugin.context |
|
56 }); |
|
57 if (new_plugin.register) { |
|
58 plugin.register = true; |
|
59 } |
|
60 if (new_plugin.async === false) { |
|
61 plugin.async = false; |
|
62 } |
|
63 } else { |
|
64 plugins[name] = { |
|
65 src: new_plugin.src, |
|
66 css: new_plugin.css, |
|
67 callbacks: [{ |
|
68 callback: new_plugin.callback, |
|
69 context: new_plugin.context |
|
70 }], |
|
71 register: new_plugin.register, |
|
72 async: new_plugin.async |
|
73 }; |
|
74 } |
|
75 if (new_plugin.css) { |
|
76 ams.getCSS(new_plugin.css, name + '_css'); |
|
77 } |
|
78 } |
|
79 |
|
80 $('[data-ams-plugins]', element).each(function() { |
|
81 |
|
82 var source = $(this); |
|
83 var amsPlugins = source.data('ams-plugins'); |
|
84 if (typeof (amsPlugins) === 'string') { |
|
85 var names = source.data('ams-plugins').split(/\s+/); |
|
86 for (var index = 0; index < names.length; index++) { |
|
87 name = names[index]; |
|
88 var newPlugin = { |
|
89 src: source.data('ams-plugin-' + name + '-src'), |
|
90 css: source.data('ams-plugin-' + name + '-css'), |
|
91 callback: source.data('ams-plugin-' + name + '-callback'), |
|
92 context: source, |
|
93 register: source.data('ams-plugin-' + name + '-register'), |
|
94 async: source.data('ams-plugin-' + name + '-async') |
|
95 }; |
|
96 _registerPlugin(name, newPlugin); |
|
97 } |
|
98 } else { |
|
99 for (name in amsPlugins) { |
|
100 if (!amsPlugins.hasOwnProperty(name)) { |
|
101 continue; |
|
102 } |
|
103 _registerPlugin(name, amsPlugins[name]); |
|
104 } |
|
105 } |
|
106 }); |
|
107 |
|
108 // Inner plug-in loader function |
|
109 var plugin; |
|
110 |
|
111 function _loadPlugin(reload) { |
|
112 var index; |
|
113 var callbacks = plugin.callbacks, |
|
114 callback; |
|
115 if (callbacks && callbacks.length) { |
|
116 for (index = 0; index < callbacks.length; index++) { |
|
117 callback = callbacks[index]; |
|
118 callback.callback = ams.getFunctionByName(callback.callback); |
|
119 if (plugin.register !== false) { |
|
120 var enabled = ams.plugins.enabled; |
|
121 if (enabled.hasOwnProperty(name)) { |
|
122 enabled[name].push(callback); |
|
123 } else { |
|
124 enabled[name] = [callback]; |
|
125 } |
|
126 } |
|
127 } |
|
128 } else { |
|
129 if (plugin.register !== false) { |
|
130 ams.plugins.enabled[name] = null; |
|
131 } |
|
132 } |
|
133 // If running in async mode, newly registered plug-ins are run |
|
134 // before callback is called so we call plug-in manually |
|
135 if ((reload !== true) && callbacks && callbacks.length && (plugin.async !== false)) { |
|
136 for (index = 0; index < callbacks.length; index++) { |
|
137 callback = callbacks[index]; |
|
138 ams.executeFunctionByName(callback.callback, element, callback.context); |
|
139 } |
|
140 } |
|
141 } |
|
142 |
|
143 function _checkPluginContext() { |
|
144 // Update context for an already loaded plug-in |
|
145 var enabled = ams.plugins.enabled[name]; |
|
146 // Clean all plug-in contexts |
|
147 for (index = 0; index < enabled.length; index++) { |
|
148 var callback = enabled[index]; |
|
149 if (callback && callback.context && !ams.isInDOM(callback.context)) { |
|
150 enabled[index] = null; |
|
151 } |
|
152 } |
|
153 } |
|
154 |
|
155 for (name in plugins) { |
|
156 if (!plugins.hasOwnProperty(name)) { |
|
157 continue; |
|
158 } |
|
159 plugin = plugins[name]; |
|
160 if (ams.plugins.enabled[name] === undefined) { |
|
161 ams.getScript(plugin.src, _loadPlugin, { |
|
162 async: plugin.async === undefined ? true : plugin.async |
|
163 }); |
|
164 } else { |
|
165 _checkPluginContext(); |
|
166 _loadPlugin(true); |
|
167 } |
|
168 } |
|
169 |
|
170 // Run all enabled plug-ins |
|
171 for (var index in ams.plugins.enabled) { |
|
172 if (!ams.plugins.enabled.hasOwnProperty(index)) { |
|
173 continue; |
|
174 } |
|
175 if (disabled.indexOf(index) >= 0) { |
|
176 continue; |
|
177 } |
|
178 var callbacks = ams.plugins.enabled[index]; |
|
179 if (callbacks) { |
|
180 switch (typeof (callbacks)) { |
|
181 case 'function': |
|
182 callbacks(element); |
|
183 break; |
|
184 default: |
|
185 for (var cbIndex = 0; cbIndex < callbacks.length; cbIndex++) { |
|
186 var callback = callbacks[cbIndex]; |
|
187 switch (typeof (callback)) { |
|
188 case 'function': |
|
189 callback(element); |
|
190 break; |
|
191 default: |
|
192 if (callback && callback.callback) { |
|
193 callback.callback(callback.context); |
|
194 } |
|
195 } |
|
196 } |
|
197 } |
|
198 } |
|
199 } |
|
200 }, |
|
201 |
|
202 /** |
|
203 * Data initializer |
|
204 * This plug-in converts a single JSON "data-ams-data" attribute into a set of several equivalent "data-" attributes. |
|
205 * This way of defining data attributes can be used with HTML templates engines which don't allow you |
|
206 * to create dynamic attributes easily. |
|
207 */ |
|
208 initData: function(element) { |
|
209 $('[data-ams-data]', element).each(function() { |
|
210 var dataElement = $(this); |
|
211 var data = dataElement.data('ams-data'); |
|
212 if (data) { |
|
213 for (var name in data) { |
|
214 if (data.hasOwnProperty(name)) { |
|
215 var elementData = data[name]; |
|
216 if (typeof (elementData) !== 'string') { |
|
217 elementData = JSON.stringify(elementData); |
|
218 } |
|
219 dataElement.attr('data-' + name, elementData); |
|
220 } |
|
221 } |
|
222 } |
|
223 }); |
|
224 }, |
|
225 |
|
226 /** |
|
227 * Register a new plug-in through Javascript instead of HTML data attributes |
|
228 * |
|
229 * @plugin: plugin function caller or object containing plug-in properties |
|
230 * @name: if @plugin is a function, defines plug-in name |
|
231 * @callback: a callback function which can be called after plug-in registry |
|
232 */ |
|
233 register: function(plugin, name, callback) { |
|
234 if (typeof (name) === 'function') { |
|
235 callback = name; |
|
236 name = null; |
|
237 } |
|
238 name = name || plugin.name; |
|
239 if (ams.plugins.enabled.indexOf(name) >= 0) { |
|
240 if (console) { |
|
241 console.warn && console.warn("Plugin " + name + " is already registered!"); |
|
242 } |
|
243 return; |
|
244 } |
|
245 if (typeof (plugin) === 'object') { |
|
246 var src = plugin.src; |
|
247 if (src) { |
|
248 ams.ajax && ams.ajax.check(plugin.callback, src, function(first_load) { |
|
249 if (first_load) { |
|
250 ams.plugins.enabled[name] = ams.getFunctionByName(plugin.callback); |
|
251 if (plugin.css) { |
|
252 ams.getCSS(plugin.css, name + '_css'); |
|
253 } |
|
254 if (callback) { |
|
255 ams.executeFunctionByName(callback); |
|
256 } |
|
257 } |
|
258 }); |
|
259 } else { |
|
260 ams.plugins.enabled[name] = ams.getFunctionByName(plugin.callback); |
|
261 if (plugin.css) { |
|
262 ams.getCSS(plugin.css, name + '_css'); |
|
263 } |
|
264 if (callback) { |
|
265 ams.executeFunctionByName(callback); |
|
266 } |
|
267 } |
|
268 } else if (typeof (plugin) === 'function') { |
|
269 ams.plugins.enabled[name] = plugin; |
|
270 if (callback) { |
|
271 ams.executeFunctionByName(callback); |
|
272 } |
|
273 } |
|
274 } |
|
275 }; |
|
276 |
|
277 ams.plugins.i18n = { |
|
278 widgets: {}, |
|
279 validate: {}, |
|
280 datatables: {}, |
|
281 fancybox: { |
|
282 ERROR: "Can't load requested content.", |
|
283 RETRY: "Please check URL or try again later.", |
|
284 CLOSE: "Close", |
|
285 NEXT: "Next", |
|
286 PREVIOUS: "Previous" |
|
287 }, |
|
288 dndupload: { |
|
289 FILES_SELECTED: '{count} files selected', |
|
290 CHOOSE_FILE: 'Select file(s)', |
|
291 ADD_INFO: 'to add them to current folder,', |
|
292 DRAG_FILE: 'or drag and drop them here!', |
|
293 UPLOAD: 'Upload', |
|
294 UPLOADING: 'Uploading…', |
|
295 DONE: 'Done!', |
|
296 UPLOAD_MORE: 'Upload more?', |
|
297 ERROR: 'Error!', |
|
298 TRY_AGAIN: 'Try again?' |
|
299 } |
|
300 }; |
|
301 |
|
302 })(jQuery, this); |
|