1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.StateRegistry = void 0;
|
4 | var stateMatcher_1 = require("./stateMatcher");
|
5 | var stateBuilder_1 = require("./stateBuilder");
|
6 | var stateQueueManager_1 = require("./stateQueueManager");
|
7 | var common_1 = require("../common/common");
|
8 | var 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 | */
|
14 | var 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 | }());
|
173 | exports.StateRegistry = StateRegistry;
|
174 | //# sourceMappingURL=stateRegistry.js.map |
\ | No newline at end of file |