@uirouter/core
Version:
UI-Router Core: Framework agnostic, State-based routing for JavaScript Single Page Apps
118 lines • 5.82 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.HookBuilder = void 0;
var common_1 = require("../common/common");
var predicates_1 = require("../common/predicates");
var interface_1 = require("./interface");
var transitionHook_1 = require("./transitionHook");
/**
* This class returns applicable TransitionHooks for a specific Transition instance.
*
* Hooks ([[RegisteredHook]]) may be registered globally, e.g., $transitions.onEnter(...), or locally, e.g.
* myTransition.onEnter(...). The HookBuilder finds matching RegisteredHooks (where the match criteria is
* determined by the type of hook)
*
* The HookBuilder also converts RegisteredHooks objects to TransitionHook objects, which are used to run a Transition.
*
* The HookBuilder constructor is given the $transitions service and a Transition instance. Thus, a HookBuilder
* instance may only be used for one specific Transition object. (side note: the _treeChanges accessor is private
* in the Transition class, so we must also provide the Transition's _treeChanges)
*/
var HookBuilder = /** @class */ (function () {
function HookBuilder(transition) {
this.transition = transition;
}
HookBuilder.prototype.buildHooksForPhase = function (phase) {
var _this = this;
var $transitions = this.transition.router.transitionService;
return $transitions._pluginapi
._getEvents(phase)
.map(function (type) { return _this.buildHooks(type); })
.reduce(common_1.unnestR, [])
.filter(common_1.identity);
};
/**
* Returns an array of newly built TransitionHook objects.
*
* - Finds all RegisteredHooks registered for the given `hookType` which matched the transition's [[TreeChanges]].
* - Finds [[PathNode]] (or `PathNode[]`) to use as the TransitionHook context(s)
* - For each of the [[PathNode]]s, creates a TransitionHook
*
* @param hookType the type of the hook registration function, e.g., 'onEnter', 'onFinish'.
*/
HookBuilder.prototype.buildHooks = function (hookType) {
var transition = this.transition;
var treeChanges = transition.treeChanges();
// Find all the matching registered hooks for a given hook type
var matchingHooks = this.getMatchingHooks(hookType, treeChanges, transition);
if (!matchingHooks)
return [];
var baseHookOptions = {
transition: transition,
current: transition.options().current,
};
var makeTransitionHooks = function (hook) {
// Fetch the Nodes that caused this hook to match.
var matches = hook.matches(treeChanges, transition);
// Select the PathNode[] that will be used as TransitionHook context objects
var matchingNodes = matches[hookType.criteriaMatchPath.name];
// Return an array of HookTuples
return matchingNodes.map(function (node) {
var _options = common_1.extend({
bind: hook.bind,
traceData: { hookType: hookType.name, context: node },
}, baseHookOptions);
var state = hookType.criteriaMatchPath.scope === interface_1.TransitionHookScope.STATE ? node.state.self : null;
var transitionHook = new transitionHook_1.TransitionHook(transition, state, hook, _options);
return { hook: hook, node: node, transitionHook: transitionHook };
});
};
return matchingHooks
.map(makeTransitionHooks)
.reduce(common_1.unnestR, [])
.sort(tupleSort(hookType.reverseSort))
.map(function (tuple) { return tuple.transitionHook; });
};
/**
* Finds all RegisteredHooks from:
* - The Transition object instance hook registry
* - The TransitionService ($transitions) global hook registry
*
* which matched:
* - the eventType
* - the matchCriteria (to, from, exiting, retained, entering)
*
* @returns an array of matched [[RegisteredHook]]s
*/
HookBuilder.prototype.getMatchingHooks = function (hookType, treeChanges, transition) {
var isCreate = hookType.hookPhase === interface_1.TransitionHookPhase.CREATE;
// Instance and Global hook registries
var $transitions = this.transition.router.transitionService;
var registries = isCreate ? [$transitions] : [this.transition, $transitions];
return registries
.map(function (reg) { return reg.getHooks(hookType.name); }) // Get named hooks from registries
.filter(common_1.assertPredicate(predicates_1.isArray, "broken event named: " + hookType.name)) // Sanity check
.reduce(common_1.unnestR, []) // Un-nest RegisteredHook[][] to RegisteredHook[] array
.filter(function (hook) { return hook.matches(treeChanges, transition); }); // Only those satisfying matchCriteria
};
return HookBuilder;
}());
exports.HookBuilder = HookBuilder;
/**
* A factory for a sort function for HookTuples.
*
* The sort function first compares the PathNode depth (how deep in the state tree a node is), then compares
* the EventHook priority.
*
* @param reverseDepthSort a boolean, when true, reverses the sort order for the node depth
* @returns a tuple sort function
*/
function tupleSort(reverseDepthSort) {
if (reverseDepthSort === void 0) { reverseDepthSort = false; }
return function nodeDepthThenPriority(l, r) {
var factor = reverseDepthSort ? -1 : 1;
var depthDelta = (l.node.state.path.length - r.node.state.path.length) * factor;
return depthDelta !== 0 ? depthDelta : r.hook.priority - l.hook.priority;
};
}
//# sourceMappingURL=hookBuilder.js.map
;