UNPKG

8.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.PathUtils = void 0;
4var common_1 = require("../common/common");
5var hof_1 = require("../common/hof");
6var targetState_1 = require("../state/targetState");
7var pathNode_1 = require("./pathNode");
8/**
9 * This class contains functions which convert TargetStates, Nodes and paths from one type to another.
10 */
11var PathUtils = /** @class */ (function () {
12 function PathUtils() {
13 }
14 /** Given a PathNode[], create an TargetState */
15 PathUtils.makeTargetState = function (registry, path) {
16 var state = common_1.tail(path).state;
17 return new targetState_1.TargetState(registry, state, path.map(hof_1.prop('paramValues')).reduce(common_1.mergeR, {}), {});
18 };
19 PathUtils.buildPath = function (targetState) {
20 var toParams = targetState.params();
21 return targetState.$state().path.map(function (state) { return new pathNode_1.PathNode(state).applyRawParams(toParams); });
22 };
23 /** Given a fromPath: PathNode[] and a TargetState, builds a toPath: PathNode[] */
24 PathUtils.buildToPath = function (fromPath, targetState) {
25 var toPath = PathUtils.buildPath(targetState);
26 if (targetState.options().inherit) {
27 return PathUtils.inheritParams(fromPath, toPath, Object.keys(targetState.params()));
28 }
29 return toPath;
30 };
31 /**
32 * Creates ViewConfig objects and adds to nodes.
33 *
34 * On each [[PathNode]], creates ViewConfig objects from the views: property of the node's state
35 */
36 PathUtils.applyViewConfigs = function ($view, path, states) {
37 // Only apply the viewConfigs to the nodes for the given states
38 path
39 .filter(function (node) { return common_1.inArray(states, node.state); })
40 .forEach(function (node) {
41 var viewDecls = common_1.values(node.state.views || {});
42 var subPath = PathUtils.subPath(path, function (n) { return n === node; });
43 var viewConfigs = viewDecls.map(function (view) { return $view.createViewConfig(subPath, view); });
44 node.views = viewConfigs.reduce(common_1.unnestR, []);
45 });
46 };
47 /**
48 * Given a fromPath and a toPath, returns a new to path which inherits parameters from the fromPath
49 *
50 * For a parameter in a node to be inherited from the from path:
51 * - The toPath's node must have a matching node in the fromPath (by state).
52 * - The parameter name must not be found in the toKeys parameter array.
53 *
54 * Note: the keys provided in toKeys are intended to be those param keys explicitly specified by some
55 * caller, for instance, $state.transitionTo(..., toParams). If a key was found in toParams,
56 * it is not inherited from the fromPath.
57 */
58 PathUtils.inheritParams = function (fromPath, toPath, toKeys) {
59 if (toKeys === void 0) { toKeys = []; }
60 function nodeParamVals(path, state) {
61 var node = common_1.find(path, hof_1.propEq('state', state));
62 return common_1.extend({}, node && node.paramValues);
63 }
64 var noInherit = fromPath
65 .map(function (node) { return node.paramSchema; })
66 .reduce(common_1.unnestR, [])
67 .filter(function (param) { return !param.inherit; })
68 .map(hof_1.prop('id'));
69 /**
70 * Given an [[PathNode]] "toNode", return a new [[PathNode]] with param values inherited from the
71 * matching node in fromPath. Only inherit keys that aren't found in "toKeys" from the node in "fromPath""
72 */
73 function makeInheritedParamsNode(toNode) {
74 // All param values for the node (may include default key/vals, when key was not found in toParams)
75 var toParamVals = common_1.extend({}, toNode && toNode.paramValues);
76 // limited to only those keys found in toParams
77 var incomingParamVals = common_1.pick(toParamVals, toKeys);
78 toParamVals = common_1.omit(toParamVals, toKeys);
79 var fromParamVals = common_1.omit(nodeParamVals(fromPath, toNode.state) || {}, noInherit);
80 // extend toParamVals with any fromParamVals, then override any of those those with incomingParamVals
81 var ownParamVals = common_1.extend(toParamVals, fromParamVals, incomingParamVals);
82 return new pathNode_1.PathNode(toNode.state).applyRawParams(ownParamVals);
83 }
84 // The param keys specified by the incoming toParams
85 return toPath.map(makeInheritedParamsNode);
86 };
87 /**
88 * Computes the tree changes (entering, exiting) between a fromPath and toPath.
89 */
90 PathUtils.treeChanges = function (fromPath, toPath, reloadState) {
91 var max = Math.min(fromPath.length, toPath.length);
92 var keep = 0;
93 var nodesMatch = function (node1, node2) { return node1.equals(node2, PathUtils.nonDynamicParams); };
94 while (keep < max && fromPath[keep].state !== reloadState && nodesMatch(fromPath[keep], toPath[keep])) {
95 keep++;
96 }
97 /** Given a retained node, return a new node which uses the to node's param values */
98 function applyToParams(retainedNode, idx) {
99 var cloned = retainedNode.clone();
100 cloned.paramValues = toPath[idx].paramValues;
101 return cloned;
102 }
103 var from, retained, exiting, entering, to;
104 from = fromPath;
105 retained = from.slice(0, keep);
106 exiting = from.slice(keep);
107 // Create a new retained path (with shallow copies of nodes) which have the params of the toPath mapped
108 var retainedWithToParams = retained.map(applyToParams);
109 entering = toPath.slice(keep);
110 to = retainedWithToParams.concat(entering);
111 return { from: from, to: to, retained: retained, retainedWithToParams: retainedWithToParams, exiting: exiting, entering: entering };
112 };
113 /**
114 * Returns a new path which is: the subpath of the first path which matches the second path.
115 *
116 * The new path starts from root and contains any nodes that match the nodes in the second path.
117 * It stops before the first non-matching node.
118 *
119 * Nodes are compared using their state property and their parameter values.
120 * If a `paramsFn` is provided, only the [[Param]] returned by the function will be considered when comparing nodes.
121 *
122 * @param pathA the first path
123 * @param pathB the second path
124 * @param paramsFn a function which returns the parameters to consider when comparing
125 *
126 * @returns an array of PathNodes from the first path which match the nodes in the second path
127 */
128 PathUtils.matching = function (pathA, pathB, paramsFn) {
129 var done = false;
130 var tuples = common_1.arrayTuples(pathA, pathB);
131 return tuples.reduce(function (matching, _a) {
132 var nodeA = _a[0], nodeB = _a[1];
133 done = done || !nodeA.equals(nodeB, paramsFn);
134 return done ? matching : matching.concat(nodeA);
135 }, []);
136 };
137 /**
138 * Returns true if two paths are identical.
139 *
140 * @param pathA
141 * @param pathB
142 * @param paramsFn a function which returns the parameters to consider when comparing
143 * @returns true if the the states and parameter values for both paths are identical
144 */
145 PathUtils.equals = function (pathA, pathB, paramsFn) {
146 return pathA.length === pathB.length && PathUtils.matching(pathA, pathB, paramsFn).length === pathA.length;
147 };
148 /**
149 * Return a subpath of a path, which stops at the first matching node
150 *
151 * Given an array of nodes, returns a subset of the array starting from the first node,
152 * stopping when the first node matches the predicate.
153 *
154 * @param path a path of [[PathNode]]s
155 * @param predicate a [[Predicate]] fn that matches [[PathNode]]s
156 * @returns a subpath up to the matching node, or undefined if no match is found
157 */
158 PathUtils.subPath = function (path, predicate) {
159 var node = common_1.find(path, predicate);
160 var elementIdx = path.indexOf(node);
161 return elementIdx === -1 ? undefined : path.slice(0, elementIdx + 1);
162 };
163 PathUtils.nonDynamicParams = function (node) {
164 return node.state.parameters({ inherit: false }).filter(function (param) { return !param.dynamic; });
165 };
166 /** Gets the raw parameter values from a path */
167 PathUtils.paramValues = function (path) { return path.reduce(function (acc, node) { return common_1.extend(acc, node.paramValues); }, {}); };
168 return PathUtils;
169}());
170exports.PathUtils = PathUtils;
171//# sourceMappingURL=pathUtils.js.map
\No newline at end of file