Skip to content

Commit cdc8755

Browse files
committed
Additional state builder refactoring.
1 parent ae591e6 commit cdc8755

File tree

1 file changed

+38
-19
lines changed

1 file changed

+38
-19
lines changed

src/state.js

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
55

66
// Builds state properties from definition passed to registerState()
77
var stateBuilder = {
8+
89
// Derive parent state from a hierarchical name only if 'parent' is not explicitly defined.
910
// state.children = [];
1011
// if (parent) parent.children.push(state);
@@ -92,28 +93,52 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
9293
if (own) ownParams.push(p);
9394
});
9495
return ownParams;
96+
},
97+
98+
// Keep a full path from the root down to this state as this is needed for state activation.
99+
path: function(state) {
100+
return state.parent ? state.parent.path.concat(state) : []; // exclude root from path
101+
},
102+
103+
// Speed up $state.contains() as it's used a lot
104+
includes: function(state) {
105+
var includes = state.parent ? extend({}, state.parent.includes) : {};
106+
includes[state.name] = true;
107+
return includes;
95108
}
96109
};
97110

98-
function findState(stateOrName) {
99-
var state;
100-
if (isString(stateOrName)) {
101-
state = states[stateOrName];
102-
if (!state) throw new Error("No such state '" + stateOrName + "'");
103-
} else {
104-
state = states[stateOrName.name];
105-
if (!state || state !== stateOrName && state.self !== stateOrName)
106-
throw new Error("Invalid or unregistered state");
111+
112+
function findState(stateOrName, base) {
113+
var isStr = isString(stateOrName),
114+
name = isStr ? stateOrName : stateOrName.name,
115+
path = isStr ? name.match(/^((?:(?:\^)(?:\.)?){1,})(.+)/) : null;
116+
117+
if (path && path.length) {
118+
if (!base) throw new Error("No reference point given for path '" + stateOrName + "'");
119+
var rel = path[1].split("."), i = 0, pathLength = rel.length - 1, current = base;
120+
121+
for (; i < pathLength; i++) {
122+
if (rel[i] === "^") current = current.parent;
123+
if (!current) throw new Error("Path '" + name + "' not valid for state '" + base.name + "'");
124+
}
125+
name = current.name + "." + path[2];
126+
}
127+
var state = states[name];
128+
129+
if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) {
130+
return state;
107131
}
108-
return state;
132+
throw new Error(isStr ? "No such state '" + name + "'" : "Invalid or unregistered state");
109133
}
110134

135+
111136
function registerState(state) {
112137
// Wrap a new object around the state so we can store our private details easily.
113138
state = inherit(state, {
114139
self: state,
115140
resolve: state.resolve || {},
116-
toString: function () { return this.name; }
141+
toString: function() { return this.name; }
117142
});
118143

119144
var name = state.name;
@@ -123,13 +148,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
123148
for (var key in stateBuilder) {
124149
state[key] = stateBuilder[key](state);
125150
}
126-
127-
// Keep a full path from the root down to this state as this is needed for state activation.
128-
state.path = state.parent ? state.parent.path.concat(state) : []; // exclude root from path
129-
130-
// Speed up $state.contains() as it's used a lot
131-
var includes = state.includes = state.parent ? extend({}, state.parent.includes) : {};
132-
includes[name] = true;
151+
states[name] = state;
133152

134153
// Register the state in the global state list and with $urlRouter if necessary.
135154
if (!state['abstract'] && state.url) {
@@ -139,10 +158,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
139158
}
140159
}]);
141160
}
142-
states[name] = state;
143161
return state;
144162
}
145163

164+
146165
// Implicit root state that is always active
147166
root = registerState({
148167
name: '',

0 commit comments

Comments
 (0)