Skip to content

Commit

Permalink
refactor(HookRegistry): Remove HookRegistry class/mixin
Browse files Browse the repository at this point in the history
  • Loading branch information
christopherthielen committed Nov 29, 2016
1 parent a9410f3 commit f0dcdce
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 94 deletions.
61 changes: 10 additions & 51 deletions src/transition/hookRegistry.ts
Expand Up @@ -30,7 +30,7 @@ export function matchState(state: State, criterion: HookMatchCriterion) {
function matchGlobs(_state: State) {
let globStrings = <string[]> toMatch;
for (let i = 0; i < globStrings.length; i++) {
let glob = Glob.fromString(globStrings[i]);
let glob = new Glob(globStrings[i]);

if ((glob && glob.matches(_state.name)) || (!glob && globStrings[i] === _state.name)) {
return true;
Expand Down Expand Up @@ -75,9 +75,9 @@ export class EventHook implements IEventHook {
let mc = this.matchCriteria, _matchingNodes = EventHook._matchingNodes;

let matches: IMatchingNodes = {
to: _matchingNodes([tail(treeChanges.to)], mc.to),
from: _matchingNodes([tail(treeChanges.from)], mc.from),
exiting: _matchingNodes(treeChanges.exiting, mc.exiting),
to: _matchingNodes([tail(treeChanges.to)], mc.to),
from: _matchingNodes([tail(treeChanges.from)], mc.from),
exiting: _matchingNodes(treeChanges.exiting, mc.exiting),
retained: _matchingNodes(treeChanges.retained, mc.retained),
entering: _matchingNodes(treeChanges.entering, mc.entering),
};
Expand All @@ -92,10 +92,13 @@ export class EventHook implements IEventHook {
}

/** @hidden */
interface ITransitionEvents { [key: string]: IEventHook[]; }
export interface IEventHooks {
[key: string]: IEventHook[];
}

/** @hidden Return a registration function of the requested type. */
function makeHookRegistrationFn(hooks: ITransitionEvents, name: string): IHookRegistration {
export function makeHookRegistrationFn(hooks: IEventHooks, name:string): IHookRegistration {
hooks[name] = [];
return function (matchObject, callback, options = {}) {
let eventHook = new EventHook(matchObject, callback, options);
hooks[name].push(eventHook);
Expand All @@ -105,48 +108,4 @@ function makeHookRegistrationFn(hooks: ITransitionEvents, name: string): IHookRe
removeFrom(hooks[name])(eventHook);
};
};
}

/**
* Mixin class acts as a Transition Hook registry.
*
* Holds the registered [[HookFn]] objects.
* Exposes functions to register new hooks.
*
* This is a Mixin class which can be applied to other objects.
*
* The hook registration functions are [[onBefore]], [[onStart]], [[onEnter]], [[onRetain]], [[onExit]], [[onFinish]], [[onSuccess]], [[onError]].
*
* This class is mixed into both the [[TransitionService]] and every [[Transition]] object.
* Global hooks are added to the [[TransitionService]].
* Since each [[Transition]] is itself a `HookRegistry`, hooks can also be added to individual Transitions
* (note: the hook criteria still must match the Transition).
*/
export class HookRegistry implements IHookRegistry {
static mixin(source: HookRegistry, target: IHookRegistry) {
Object.keys(source._transitionEvents).concat(["getHooks"]).forEach(key => target[key] = source[key]);
}

private _transitionEvents: ITransitionEvents = {
onBefore: [], onStart: [], onEnter: [], onRetain: [], onExit: [], onFinish: [], onSuccess: [], onError: []
};

getHooks = (name: string) => this._transitionEvents[name];

/** @inheritdoc */
onBefore = makeHookRegistrationFn(this._transitionEvents, "onBefore");
/** @inheritdoc */
onStart = makeHookRegistrationFn(this._transitionEvents, "onStart");
/** @inheritdoc */
onEnter = makeHookRegistrationFn(this._transitionEvents, "onEnter");
/** @inheritdoc */
onRetain = makeHookRegistrationFn(this._transitionEvents, "onRetain");
/** @inheritdoc */
onExit = makeHookRegistrationFn(this._transitionEvents, "onExit");
/** @inheritdoc */
onFinish = makeHookRegistrationFn(this._transitionEvents, "onFinish");
/** @inheritdoc */
onSuccess = makeHookRegistrationFn(this._transitionEvents, "onSuccess");
/** @inheritdoc */
onError = makeHookRegistrationFn(this._transitionEvents, "onError");
}
}
44 changes: 27 additions & 17 deletions src/transition/transition.ts
Expand Up @@ -11,12 +11,14 @@ import { prop, propEq, val, not } from "../common/hof";

import {StateDeclaration, StateOrName} from "../state/interface";
import {
TransitionOptions, TransitionHookOptions, TreeChanges, IHookRegistry, IHookGetter,
HookMatchCriteria, TransitionHookFn, TransitionStateHookFn, HookRegOptions
TransitionOptions, TransitionHookOptions, TreeChanges, IHookRegistry,
IHookGetter, HookMatchCriteria, HookRegOptions, IEventHook
} from "./interface";

import { TransitionStateHookFn, TransitionHookFn } from "./interface"; // has or is using

import {TransitionHook} from "./transitionHook";
import {HookRegistry, matchState} from "./hookRegistry";
import {matchState, IEventHooks, makeHookRegistrationFn} from "./hookRegistry";
import {HookBuilder} from "./hookBuilder";
import {PathNode} from "../path/node";
import {PathFactory} from "../path/pathFactory";
Expand Down Expand Up @@ -83,31 +85,42 @@ export class Transition implements IHookRegistry {
/** @hidden */
private _error: any;

/** @hidden Holds the hook registration functions such as those passed to Transition.onStart() */
private _transitionEvents: IEventHooks = { };

/** @hidden */
private _options: TransitionOptions;
/** @hidden */
private _treeChanges: TreeChanges;
/** @hidden */
private _targetState: TargetState;

/** @hidden Creates a hook registration function (which can then be used to register hooks) */
private createHookRegFn (hookName: string) {
return makeHookRegistrationFn(this._transitionEvents, hookName);
}

/** @hidden */
onBefore = this.createHookRegFn('onBefore');
/** @inheritdoc */
onBefore (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };
/** @inheritdoc */
onStart (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };
onStart = this.createHookRegFn('onStart');
/** @inheritdoc */
onExit (matchCriteria: HookMatchCriteria, callback: TransitionStateHookFn, options?: HookRegOptions) : Function { throw ""; };
onExit = this.createHookRegFn('onExit');
/** @inheritdoc */
onRetain (matchCriteria: HookMatchCriteria, callback: TransitionStateHookFn, options?: HookRegOptions) : Function { throw ""; };
onRetain = this.createHookRegFn('onRetain');
/** @inheritdoc */
onEnter (matchCriteria: HookMatchCriteria, callback: TransitionStateHookFn, options?: HookRegOptions) : Function { throw ""; };
onEnter = this.createHookRegFn('onEnter');
/** @inheritdoc */
onFinish (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };
onFinish = this.createHookRegFn('onFinish');
/** @inheritdoc */
onSuccess (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };
onSuccess = this.createHookRegFn('onSuccess');
/** @inheritdoc */
onError (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };
onError = this.createHookRegFn('onError');

getHooks: IHookGetter;
/** @hidden @internalapi */
getHooks(hookName: string): IEventHook[] {
return this._transitionEvents[hookName];
}

/**
* Creates a new Transition object.
Expand All @@ -129,9 +142,6 @@ export class Transition implements IHookRegistry {
throw new Error(targetState.error());
}

// Makes the Transition instance a hook registry (onStart, etc)
HookRegistry.mixin(new HookRegistry(), this);

// current() is assumed to come from targetState.options, but provide a naive implementation otherwise.
this._options = extend({ current: val(this) }, targetState.options());
this.$id = transitionCount++;
Expand Down Expand Up @@ -188,7 +198,7 @@ export class Transition implements IHookRegistry {
*
* @returns The state declaration object for the Transition's target state ("to state").
*/
to() {
to(): StateDeclaration {
return this.$to().self;
}

Expand Down
59 changes: 33 additions & 26 deletions src/transition/transitionService.ts
@@ -1,11 +1,12 @@
/** @coreapi @module transition */ /** for typedoc */
import { IHookRegistry, TransitionOptions } from "./interface";

import {
IHookRegistry, TransitionOptions, HookMatchCriteria, HookRegOptions,
TransitionStateHookFn, TransitionHookFn
} from "./interface";
HookMatchCriteria, HookRegOptions, TransitionStateHookFn, TransitionHookFn
} from "./interface"; // has or is using

import {Transition} from "./transition";
import {HookRegistry} from "./hookRegistry";
import {IEventHooks, makeHookRegistrationFn} from "./hookRegistry";
import {TargetState} from "../state/targetState";
import {PathNode} from "../path/node";
import {IEventHook} from "./interface";
Expand Down Expand Up @@ -49,6 +50,7 @@ export let defaultTransOpts: TransitionOptions = {
export class TransitionService implements IHookRegistry {
/** @hidden */
public $view: ViewService;
private _transitionEvents: IEventHooks = { };

/**
* This object has hook de-registration functions for the built-in hooks.
Expand All @@ -71,11 +73,15 @@ export class TransitionService implements IHookRegistry {

constructor(private _router: UIRouter) {
this.$view = _router.viewService;
HookRegistry.mixin(new HookRegistry(), this);
this._deregisterHookFns = <any> {};
this.registerTransitionHooks();
}

/** @hidden Creates a hook registration function (which can then be used to register hooks) */
private createHookRegFn (hookName: string) {
return makeHookRegistrationFn(this._transitionEvents, hookName);
}

/** @hidden */
private registerTransitionHooks() {
let fns = this._deregisterHookFns;
Expand Down Expand Up @@ -103,27 +109,6 @@ export class TransitionService implements IHookRegistry {
fns.lazyLoad = registerLazyLoadHook(this);
}

/** @inheritdoc */
onBefore (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };
/** @inheritdoc */
onStart (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };
/** @inheritdoc */
onExit (matchCriteria: HookMatchCriteria, callback: TransitionStateHookFn, options?: HookRegOptions) : Function { throw ""; };
/** @inheritdoc */
onRetain (matchCriteria: HookMatchCriteria, callback: TransitionStateHookFn, options?: HookRegOptions) : Function { throw ""; };
/** @inheritdoc */
onEnter (matchCriteria: HookMatchCriteria, callback: TransitionStateHookFn, options?: HookRegOptions) : Function { throw ""; };
/** @inheritdoc */
onFinish (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };
/** @inheritdoc */
onSuccess (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };
/** @inheritdoc */
onError (matchCriteria: HookMatchCriteria, callback: TransitionHookFn, options?: HookRegOptions) : Function { throw ""; };


/** @hidden */
getHooks : (hookName: string) => IEventHook[];

/**
* Creates a new [[Transition]] object
*
Expand All @@ -137,4 +122,26 @@ export class TransitionService implements IHookRegistry {
create(fromPath: PathNode[], targetState: TargetState): Transition {
return new Transition(fromPath, targetState, this._router);
}

/** @inheritdoc */
onBefore = this.createHookRegFn('onBefore');
/** @inheritdoc */
onStart = this.createHookRegFn('onStart');
/** @inheritdoc */
onExit = this.createHookRegFn('onExit');
/** @inheritdoc */
onRetain = this.createHookRegFn('onRetain');
/** @inheritdoc */
onEnter = this.createHookRegFn('onEnter');
/** @inheritdoc */
onFinish = this.createHookRegFn('onFinish');
/** @inheritdoc */
onSuccess = this.createHookRegFn('onSuccess');
/** @inheritdoc */
onError = this.createHookRegFn('onError');

/** @hidden */
getHooks(hookName: string): IEventHook[] {
return this._transitionEvents[hookName];
}
}

0 comments on commit f0dcdce

Please sign in to comment.