ui-router-core
Version:
UI-Router Core: Framework agnostic, State-based routing for JavaScript Single Page Apps
91 lines • 3.9 kB
JavaScript
;
/** @module state */ /** for typedoc */
var common_1 = require("../common/common");
var predicates_1 = require("../common/predicates");
var stateObject_1 = require("./stateObject");
var hof_1 = require("../common/hof");
/** @internalapi */
var StateQueueManager = (function () {
function StateQueueManager($registry, $urlRouter, states, builder, listeners) {
this.$registry = $registry;
this.$urlRouter = $urlRouter;
this.states = states;
this.builder = builder;
this.listeners = listeners;
this.queue = [];
this.matcher = $registry.matcher;
}
/** @internalapi */
StateQueueManager.prototype.dispose = function () {
this.queue = [];
};
StateQueueManager.prototype.register = function (stateDecl) {
var queue = this.queue;
var state = stateObject_1.StateObject.create(stateDecl);
var name = state.name;
if (!predicates_1.isString(name))
throw new Error("State must have a valid name");
if (this.states.hasOwnProperty(name) || common_1.inArray(queue.map(hof_1.prop('name')), name))
throw new Error("State '" + name + "' is already defined");
queue.push(state);
this.flush();
return state;
};
StateQueueManager.prototype.flush = function () {
var _this = this;
var _a = this, queue = _a.queue, states = _a.states, builder = _a.builder;
var registered = [], // states that got registered
orphans = [], // states that don't yet have a parent registered
previousQueueLength = {}; // keep track of how long the queue when an orphan was first encountered
var getState = function (name) {
return _this.states.hasOwnProperty(name) && _this.states[name];
};
while (queue.length > 0) {
var state = queue.shift();
var name_1 = state.name;
var result = builder.build(state);
var orphanIdx = orphans.indexOf(state);
if (result) {
var existingState = getState(name_1);
if (existingState && existingState.name === name_1) {
throw new Error("State '" + name_1 + "' is already defined");
}
var existingFutureState = getState(name_1 + ".**");
if (existingFutureState) {
// Remove future state of the same name
this.$registry.deregister(existingFutureState);
}
states[name_1] = state;
this.attachRoute(state);
if (orphanIdx >= 0)
orphans.splice(orphanIdx, 1);
registered.push(state);
continue;
}
var prev = previousQueueLength[name_1];
previousQueueLength[name_1] = queue.length;
if (orphanIdx >= 0 && prev === queue.length) {
// Wait until two consecutive iterations where no additional states were dequeued successfully.
// throw new Error(`Cannot register orphaned state '${name}'`);
queue.push(state);
return states;
}
else if (orphanIdx < 0) {
orphans.push(state);
}
queue.push(state);
}
if (registered.length) {
this.listeners.forEach(function (listener) { return listener("registered", registered.map(function (s) { return s.self; })); });
}
return states;
};
StateQueueManager.prototype.attachRoute = function (state) {
if (state.abstract || !state.url)
return;
this.$urlRouter.rule(this.$urlRouter.urlRuleFactory.create(state));
};
return StateQueueManager;
}());
exports.StateQueueManager = StateQueueManager;
//# sourceMappingURL=stateQueueManager.js.map