API Docs for: 3.18.1
Show:

File: pluginhost/js/PluginHost.js

  1. /**
  2. * Provides the augmentable PluginHost interface, which can be added to any class.
  3. * @module pluginhost
  4. */
  5.  
  6. /**
  7. * Provides the augmentable PluginHost interface, which can be added to any class.
  8. * @module pluginhost-base
  9. */
  10.  
  11. /**
  12. * <p>
  13. * An augmentable class, which provides the augmented class with the ability to host plugins.
  14. * It adds <a href="#method_plug">plug</a> and <a href="#method_unplug">unplug</a> methods to the augmented class, which can
  15. * be used to add or remove plugins from instances of the class.
  16. * </p>
  17. *
  18. * <p>Plugins can also be added through the constructor configuration object passed to the host class' constructor using
  19. * the "plugins" property. Supported values for the "plugins" property are those defined by the <a href="#method_plug">plug</a> method.
  20. *
  21. * For example the following code would add the AnimPlugin and IOPlugin to Overlay (the plugin host):
  22. * <xmp>
  23. * var o = new Overlay({plugins: [ AnimPlugin, {fn:IOPlugin, cfg:{section:"header"}}]});
  24. * </xmp>
  25. * </p>
  26. * <p>
  27. * Plug.Host's protected <a href="#method_initPlugins">_initPlugins</a> and <a href="#method_destroyPlugins">_destroyPlugins</a>
  28. * methods should be invoked by the host class at the appropriate point in the host's lifecyle.
  29. * </p>
  30. *
  31. * @class Plugin.Host
  32. */
  33.  
  34. var L = Y.Lang;
  35.  
  36. function PluginHost() {
  37. this._plugins = {};
  38. }
  39.  
  40. PluginHost.prototype = {
  41.  
  42. /**
  43. * Adds a plugin to the host object. This will instantiate the
  44. * plugin and attach it to the configured namespace on the host object.
  45. *
  46. * @method plug
  47. * @chainable
  48. * @param P {Function | Object |Array} Accepts the plugin class, or an
  49. * object with a "fn" property specifying the plugin class and
  50. * a "cfg" property specifying the configuration for the Plugin.
  51. * <p>
  52. * Additionally an Array can also be passed in, with the above function or
  53. * object values, allowing the user to add multiple plugins in a single call.
  54. * </p>
  55. * @param config (Optional) If the first argument is the plugin class, the second argument
  56. * can be the configuration for the plugin.
  57. * @return {Base} A reference to the host object
  58. */
  59. plug: function(Plugin, config) {
  60. var i, ln, ns;
  61.  
  62. if (L.isArray(Plugin)) {
  63. for (i = 0, ln = Plugin.length; i < ln; i++) {
  64. this.plug(Plugin[i]);
  65. }
  66. } else {
  67. if (Plugin && !L.isFunction(Plugin)) {
  68. config = Plugin.cfg;
  69. Plugin = Plugin.fn;
  70. }
  71.  
  72. // Plugin should be fn by now
  73. if (Plugin && Plugin.NS) {
  74. ns = Plugin.NS;
  75.  
  76. config = config || {};
  77. config.host = this;
  78.  
  79. if (this.hasPlugin(ns)) {
  80. // Update config
  81. if (this[ns].setAttrs) {
  82. this[ns].setAttrs(config);
  83. }
  84. else {
  85. Y.log("Attempt to replug an already attached plugin, and we can't setAttrs, because it's not Attribute based: " + ns, "warn", "PluginHost");
  86. }
  87. } else {
  88. // Create new instance
  89. this[ns] = new Plugin(config);
  90. this._plugins[ns] = Plugin;
  91. }
  92. }
  93. else {
  94. Y.log("Attempt to plug in an invalid plugin. Host:" + this + ", Plugin:" + Plugin, "error", "PluginHost");
  95. }
  96. }
  97. return this;
  98. },
  99.  
  100. /**
  101. * Removes a plugin from the host object. This will destroy the
  102. * plugin instance and delete the namespace from the host object.
  103. *
  104. * @method unplug
  105. * @param {String | Function} plugin The namespace of the plugin, or the plugin class with the static NS namespace property defined. If not provided,
  106. * all registered plugins are unplugged.
  107. * @return {Base} A reference to the host object
  108. * @chainable
  109. */
  110. unplug: function(plugin) {
  111. var ns = plugin,
  112. plugins = this._plugins;
  113.  
  114. if (plugin) {
  115. if (L.isFunction(plugin)) {
  116. ns = plugin.NS;
  117. if (ns && (!plugins[ns] || plugins[ns] !== plugin)) {
  118. ns = null;
  119. }
  120. }
  121.  
  122. if (ns) {
  123. if (this[ns]) {
  124. if (this[ns].destroy) {
  125. this[ns].destroy();
  126. }
  127. delete this[ns];
  128. }
  129. if (plugins[ns]) {
  130. delete plugins[ns];
  131. }
  132. }
  133. } else {
  134. for (ns in this._plugins) {
  135. if (this._plugins.hasOwnProperty(ns)) {
  136. this.unplug(ns);
  137. }
  138. }
  139. }
  140. return this;
  141. },
  142.  
  143. /**
  144. * Determines if a plugin has plugged into this host.
  145. *
  146. * @method hasPlugin
  147. * @param {String} ns The plugin's namespace
  148. * @return {Plugin} Returns a truthy value (the plugin instance) if present, or undefined if not.
  149. */
  150. hasPlugin : function(ns) {
  151. return (this._plugins[ns] && this[ns]);
  152. },
  153.  
  154. /**
  155. * Initializes static plugins registered on the host (using the
  156. * Base.plug static method) and any plugins passed to the
  157. * instance through the "plugins" configuration property.
  158. *
  159. * @method _initPlugins
  160. * @param {Object} config The configuration object with property name/value pairs.
  161. * @private
  162. */
  163.  
  164. _initPlugins: function(config) {
  165. this._plugins = this._plugins || {};
  166.  
  167. if (this._initConfigPlugins) {
  168. this._initConfigPlugins(config);
  169. }
  170. },
  171.  
  172. /**
  173. * Unplugs and destroys all plugins on the host
  174. * @method _destroyPlugins
  175. * @private
  176. */
  177. _destroyPlugins: function() {
  178. this.unplug();
  179. }
  180. };
  181.  
  182. Y.namespace("Plugin").Host = PluginHost;
  183.