diff --git a/src/router.ts b/src/router.ts index d9bf546b..cca94243 100644 --- a/src/router.ts +++ b/src/router.ts @@ -69,8 +69,9 @@ export class UIRouter { * * #### Example: * ```js - * export class MyAuthPlugin { + * export class MyAuthPlugin implements UIRouterPlugin { * constructor(router: UIRouter, options: any) { + * this.name = "MyAuthPlugin"; * let $transitions = router.transitionService; * let $state = router.stateService; * @@ -90,12 +91,20 @@ export class UIRouter { * } * ``` * - * @param pluginFactory a function which accepts a [[UIRouter]] instance and returns a UI-Router Plugin instance - * @param options options to pass to the plugin - * @returns {T} + * @param plugin one of: + * - a plugin class which implements [[UIRouterPlugin]] + * - a constructor function for a [[UIRouterPlugin]] which accepts a [[UIRouter]] instance + * - a factory function which accepts a [[UIRouter]] instance and returns a [[UIRouterPlugin]] instance + * @param options options to pass to the plugin class/factory + * @returns the registered plugin instance */ - plugin(pluginFactory: PluginFactory, options: any = {}): T { - let pluginInstance = pluginFactory(this, options); + plugin(plugin: { new(router: UIRouter, options?: any): T }, options?: any): T; + /** Allow javascript constructor function */ + plugin(plugin: { (router: UIRouter, options?: any): void }, options?: any): T; + /** Allow javascript factory function */ + plugin(plugin: PluginFactory, options?: any): T; + plugin(plugin: any, options: any = {}): T { + let pluginInstance = new plugin(this, options); if (!pluginInstance.name) throw new Error("Required property `name` missing on plugin: " + pluginInstance); return this._plugins[pluginInstance.name] = pluginInstance; } diff --git a/test/pluginSpec.ts b/test/pluginSpec.ts index 3a5e894e..9d13759a 100644 --- a/test/pluginSpec.ts +++ b/test/pluginSpec.ts @@ -22,15 +22,37 @@ describe('plugin api', function () { router.stateRegistry.stateQueue.autoFlush($state); }); - class FancyPlugin implements UIRouterPlugin { + class FancyPluginClass implements UIRouterPlugin { constructor(public router: UIRouter) { } name = "fancyplugin" } + function FancyPluginConstructor(router: UIRouter, options: any) { + this.name = "fancyplugin"; + } + describe('initialization', () => { + it('should accept a plugin class', () => { + let plugin = router.plugin(FancyPluginClass); + expect(plugin instanceof FancyPluginClass).toBeTruthy(); + }); + + it('should accept a constructor function', () => { + let plugin = router.plugin(FancyPluginConstructor); + expect(plugin instanceof FancyPluginConstructor).toBeTruthy(); + }); + + it('should accept a factory function', () => { + function factoryFn(router: UIRouter, options: any) { + return new FancyPluginClass(router); + } + let plugin = router.plugin(factoryFn); + expect(plugin instanceof FancyPluginClass).toBeTruthy(); + }); + it('should return an instance of the plugin', () => { - let plugin = router.plugin(() => new FancyPlugin(router)); - expect(plugin instanceof FancyPlugin).toBeTruthy(); + let plugin = router.plugin(() => new FancyPluginClass(router)); + expect(plugin instanceof FancyPluginClass).toBeTruthy(); }); it('should pass the router instance to the plugin constructor', () => { @@ -55,9 +77,9 @@ describe('plugin api', function () { describe('getPlugin', () => { it('should return the plugin instance', () => { - router.plugin(() => new FancyPlugin(router)); + router.plugin(() => new FancyPluginClass(router)); let plugin = router.getPlugin('fancyplugin'); - expect(plugin instanceof FancyPlugin).toBeTruthy(); + expect(plugin instanceof FancyPluginClass).toBeTruthy(); }); }) });