UNPKG

7.09 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.StateRegistry = void 0;
4var stateMatcher_1 = require("./stateMatcher");
5var stateBuilder_1 = require("./stateBuilder");
6var stateQueueManager_1 = require("./stateQueueManager");
7var common_1 = require("../common/common");
8var hof_1 = require("../common/hof");
9/**
10 * A registry for all of the application's [[StateDeclaration]]s
11 *
12 * This API is found at `router.stateRegistry` ([[UIRouter.stateRegistry]])
13 */
14var StateRegistry = /** @class */ (function () {
15 /** @internal */
16 function StateRegistry(router) {
17 this.router = router;
18 this.states = {};
19 /** @internal */
20 this.listeners = [];
21 this.matcher = new stateMatcher_1.StateMatcher(this.states);
22 this.builder = new stateBuilder_1.StateBuilder(this.matcher, router.urlMatcherFactory);
23 this.stateQueue = new stateQueueManager_1.StateQueueManager(router, this.states, this.builder, this.listeners);
24 this._registerRoot();
25 }
26 /** @internal */
27 StateRegistry.prototype._registerRoot = function () {
28 var rootStateDef = {
29 name: '',
30 url: '^',
31 views: null,
32 params: {
33 '#': { value: null, type: 'hash', dynamic: true },
34 },
35 abstract: true,
36 };
37 var _root = (this._root = this.stateQueue.register(rootStateDef));
38 _root.navigable = null;
39 };
40 /** @internal */
41 StateRegistry.prototype.dispose = function () {
42 var _this = this;
43 this.stateQueue.dispose();
44 this.listeners = [];
45 this.get().forEach(function (state) { return _this.get(state) && _this.deregister(state); });
46 };
47 /**
48 * Listen for a State Registry events
49 *
50 * Adds a callback that is invoked when states are registered or deregistered with the StateRegistry.
51 *
52 * #### Example:
53 * ```js
54 * let allStates = registry.get();
55 *
56 * // Later, invoke deregisterFn() to remove the listener
57 * let deregisterFn = registry.onStatesChanged((event, states) => {
58 * switch(event) {
59 * case: 'registered':
60 * states.forEach(state => allStates.push(state));
61 * break;
62 * case: 'deregistered':
63 * states.forEach(state => {
64 * let idx = allStates.indexOf(state);
65 * if (idx !== -1) allStates.splice(idx, 1);
66 * });
67 * break;
68 * }
69 * });
70 * ```
71 *
72 * @param listener a callback function invoked when the registered states changes.
73 * The function receives two parameters, `event` and `state`.
74 * See [[StateRegistryListener]]
75 * @return a function that deregisters the listener
76 */
77 StateRegistry.prototype.onStatesChanged = function (listener) {
78 this.listeners.push(listener);
79 return function deregisterListener() {
80 common_1.removeFrom(this.listeners)(listener);
81 }.bind(this);
82 };
83 /**
84 * Gets the implicit root state
85 *
86 * Gets the root of the state tree.
87 * The root state is implicitly created by UI-Router.
88 * Note: this returns the internal [[StateObject]] representation, not a [[StateDeclaration]]
89 *
90 * @return the root [[StateObject]]
91 */
92 StateRegistry.prototype.root = function () {
93 return this._root;
94 };
95 /**
96 * Adds a state to the registry
97 *
98 * Registers a [[StateDeclaration]] or queues it for registration.
99 *
100 * Note: a state will be queued if the state's parent isn't yet registered.
101 *
102 * @param stateDefinition the definition of the state to register.
103 * @returns the internal [[StateObject]] object.
104 * If the state was successfully registered, then the object is fully built (See: [[StateBuilder]]).
105 * If the state was only queued, then the object is not fully built.
106 */
107 StateRegistry.prototype.register = function (stateDefinition) {
108 return this.stateQueue.register(stateDefinition);
109 };
110 /** @internal */
111 StateRegistry.prototype._deregisterTree = function (state) {
112 var _this = this;
113 var all = this.get().map(function (s) { return s.$$state(); });
114 var getChildren = function (states) {
115 var _children = all.filter(function (s) { return states.indexOf(s.parent) !== -1; });
116 return _children.length === 0 ? _children : _children.concat(getChildren(_children));
117 };
118 var children = getChildren([state]);
119 var deregistered = [state].concat(children).reverse();
120 deregistered.forEach(function (_state) {
121 var rulesApi = _this.router.urlService.rules;
122 // Remove URL rule
123 rulesApi
124 .rules()
125 .filter(hof_1.propEq('state', _state))
126 .forEach(function (rule) { return rulesApi.removeRule(rule); });
127 // Remove state from registry
128 delete _this.states[_state.name];
129 });
130 return deregistered;
131 };
132 /**
133 * Removes a state from the registry
134 *
135 * This removes a state from the registry.
136 * If the state has children, they are are also removed from the registry.
137 *
138 * @param stateOrName the state's name or object representation
139 * @returns {StateObject[]} a list of removed states
140 */
141 StateRegistry.prototype.deregister = function (stateOrName) {
142 var _state = this.get(stateOrName);
143 if (!_state)
144 throw new Error("Can't deregister state; not found: " + stateOrName);
145 var deregisteredStates = this._deregisterTree(_state.$$state());
146 this.listeners.forEach(function (listener) {
147 return listener('deregistered', deregisteredStates.map(function (s) { return s.self; }));
148 });
149 return deregisteredStates;
150 };
151 StateRegistry.prototype.get = function (stateOrName, base) {
152 var _this = this;
153 if (arguments.length === 0)
154 return Object.keys(this.states).map(function (name) { return _this.states[name].self; });
155 var found = this.matcher.find(stateOrName, base);
156 return (found && found.self) || null;
157 };
158 /**
159 * Registers a [[BuilderFunction]] for a specific [[StateObject]] property (e.g., `parent`, `url`, or `path`).
160 * More than one BuilderFunction can be registered for a given property.
161 *
162 * The BuilderFunction(s) will be used to define the property on any subsequently built [[StateObject]] objects.
163 *
164 * @param property The name of the State property being registered for.
165 * @param builderFunction The BuilderFunction which will be used to build the State property
166 * @returns a function which deregisters the BuilderFunction
167 */
168 StateRegistry.prototype.decorator = function (property, builderFunction) {
169 return this.builder.builder(property, builderFunction);
170 };
171 return StateRegistry;
172}());
173exports.StateRegistry = StateRegistry;
174//# sourceMappingURL=stateRegistry.js.map
\No newline at end of file