src/pyams_skin/resources/js/myams-plugins-loader.js
changeset 566 a1707c607eec
parent 565 318533413200
child 567 bca1726b1d85
equal deleted inserted replaced
565:318533413200 566:a1707c607eec
     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&hellip;',
       
   295 			DONE: 'Done!',
       
   296 			UPLOAD_MORE: 'Upload more?',
       
   297 			ERROR: 'Error!',
       
   298 			TRY_AGAIN: 'Try again?'
       
   299 		}
       
   300 	};
       
   301 
       
   302 })(jQuery, this);