1 /** 2 * Olives http://flams.github.com/olives 3 * The MIT License (MIT) 4 * Copyright (c) 2012-2014 Olivier Scherrer <pode.fr@gmail.com> - Olivier Wietrich <olivier.wietrich@gmail.com> 5 */ 6 "use strict"; 7 8 var Tools = require("emily").Tools, 9 DomUtils = require("./DomUtils"); 10 11 /** 12 * @class 13 * Plugins is the link between the UI and your plugins. 14 * You can design your own plugin, declare them in your UI, and call them 15 * from the template, like : 16 * <tag data-yourPlugin="method: param"></tag> 17 * @see Model-Plugin for instance 18 * @requires Tools 19 */ 20 module.exports = function PluginsConstructor($plugins) { 21 22 /** 23 * The list of plugins 24 * @private 25 */ 26 var _plugins = {}, 27 28 /** 29 * Just a "functionalification" of trim 30 * for code readability 31 * @private 32 */ 33 trim = function trim(string) { 34 return string.trim(); 35 }, 36 37 /** 38 * Call the plugins methods, passing them the dom node 39 * A phrase can be : 40 * <tag data-plugin='method: param, param; method:param...'/> 41 * the function has to call every method of the plugin 42 * passing it the node, and the given params 43 * @private 44 */ 45 applyPlugin = function applyPlugin(node, phrase, plugin) { 46 // Split the methods 47 phrase.split(";") 48 .forEach(function (couple) { 49 // Split the result between method and params 50 var split = couple.split(":"), 51 // Trim the name 52 method = split[0].trim(), 53 // And the params, if any 54 params = split[1] ? split[1].split(",").map(trim) : []; 55 56 // The first param must be the dom node 57 params.unshift(node); 58 59 if (_plugins[plugin] && _plugins[plugin][method]) { 60 // Call the method with the following params for instance : 61 // [node, "param1", "param2" .. ] 62 _plugins[plugin][method].apply(_plugins[plugin], params); 63 } 64 65 }); 66 }; 67 68 /** 69 * Add a plugin 70 * 71 * Note that once added, the function adds a "plugins" property to the plugin. 72 * It's an object that holds a name property, with the registered name of the plugin 73 * and an apply function, to use on new nodes that the plugin would generate 74 * 75 * @param {String} name the name of the data that the plugin should look for 76 * @param {Object} plugin the plugin that has the functions to execute 77 * @returns true if plugin successfully added. 78 */ 79 this.add = function add(name, plugin) { 80 var that = this, 81 propertyName = "plugins"; 82 83 if (typeof name == "string" && typeof plugin == "object" && plugin) { 84 _plugins[name] = plugin; 85 86 plugin[propertyName] = { 87 name: name, 88 apply: function apply() { 89 return that.apply.apply(that, arguments); 90 } 91 }; 92 return true; 93 } else { 94 return false; 95 } 96 }; 97 98 /** 99 * Add multiple plugins at once 100 * @param {Object} list key is the plugin name and value is the plugin 101 * @returns true if correct param 102 */ 103 this.addAll = function addAll(list) { 104 return Tools.loop(list, function (plugin, name) { 105 this.add(name, plugin); 106 }, this); 107 }; 108 109 /** 110 * Get a previously added plugin 111 * @param {String} name the name of the plugin 112 * @returns {Object} the plugin 113 */ 114 this.get = function get(name) { 115 return _plugins[name]; 116 }; 117 118 /** 119 * Delete a plugin from the list 120 * @param {String} name the name of the plugin 121 * @returns {Boolean} true if success 122 */ 123 this.del = function del(name) { 124 return delete _plugins[name]; 125 }; 126 127 /** 128 * Apply the plugins to a NodeList 129 * @param {HTMLElement|SVGElement} dom the dom nodes on which to apply the plugins 130 * @returns {Boolean} true if the param is a dom node 131 */ 132 this.apply = function apply(dom) { 133 134 var nodes; 135 136 if (DomUtils.isAcceptedType(dom)) { 137 138 nodes = DomUtils.getNodes(dom); 139 Tools.loop(Tools.toArray(nodes), function (node) { 140 Tools.loop(DomUtils.getDataset(node), function (phrase, plugin) { 141 applyPlugin(node, phrase, plugin); 142 }); 143 }); 144 145 return dom; 146 147 } else { 148 return false; 149 } 150 }; 151 152 this.addAll($plugins); 153 154 };