Skip to content

Commit 020b8a8

Browse files
committed
WIP
1 parent 6deee59 commit 020b8a8

File tree

5 files changed

+43
-47
lines changed

5 files changed

+43
-47
lines changed

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
"contributors": [
77
{
88
"name": "Nate Abele",
9-
"email": "nate@unionofrad.com",
10-
"web": "https://github.com/nateabele"
9+
"email": "nate@radify.io",
10+
"web": "https://radify.io"
1111
},
1212
{
1313
"name": "Tim Kindberg",

src/state.js

+16-10
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ function StateQueueManager(states, builder, $urlRouterProvider, $state) {
6767
return state;
6868
},
6969

70-
flush: function() {
70+
flush: function($state) {
7171
var result, state, orphans = [], orphanIdx, previousQueueLength = {};
7272

7373
while (queue.length > 0) {
@@ -79,7 +79,7 @@ function StateQueueManager(states, builder, $urlRouterProvider, $state) {
7979
if (states[state.name] !== undefined)
8080
throw new Error("State '" + name + "' is already defined");
8181
states[state.name] = state;
82-
this.attachRoute(state);
82+
this.attachRoute($state, state);
8383
if (orphanIdx >= 0) orphans.splice(orphanIdx, 1);
8484
continue;
8585
}
@@ -98,7 +98,7 @@ function StateQueueManager(states, builder, $urlRouterProvider, $state) {
9898
return states;
9999
},
100100

101-
attachRoute: function(state) {
101+
attachRoute: function($state, state) {
102102
if (state[abstractKey] || !state.url) return;
103103

104104
$urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {
@@ -593,6 +593,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactoryProvider) {
593593
views: null,
594594
'abstract': true
595595
}, true);
596+
596597
root.navigable = null;
597598

598599
extend($state, {
@@ -602,7 +603,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactoryProvider) {
602603
transition: null
603604
});
604605

605-
queue.flush();
606+
queue.flush($state);
606607

607608
$transition.init(root, $state.params, function(ref, options) {
608609
return matcher.find(ref, options.relative);
@@ -760,6 +761,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactoryProvider) {
760761
reload: false
761762
}, options));
762763

764+
// Rejected by $transitionProvider handler... TODO: add unit test
765+
if (!transition) return REJECT.prevented;
766+
763767
var stateHandler = {
764768
retryIfNotFound: function(transition) {
765769
/**
@@ -800,6 +804,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactoryProvider) {
800804
},
801805

802806
checkIgnoredOrPrevented: function(transition) {
807+
var notify = transition.options().notify;
808+
803809
if (transition.ignored()) {
804810
var isDynamic = $stateParams.$set(toParams, toState.url);
805811

@@ -810,7 +816,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactoryProvider) {
810816

811817
if (isDynamic || to.locals === from.locals) {
812818
if (!isDynamic) $urlRouter.update();
813-
if (options.notify) $rootScope.$broadcast('$stateChangeIgnored', transition);
819+
if (notify) $rootScope.$broadcast('$stateChangeIgnored', transition);
814820
$state.transition = null;
815821
return $state.current;
816822
}
@@ -840,7 +846,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactoryProvider) {
840846
* })
841847
* </pre>
842848
*/
843-
if (options.notify && $rootScope.$broadcast('$stateChangeStart', transition).defaultPrevented) {
849+
if (notify && $rootScope.$broadcast('$stateChangeStart', transition).defaultPrevented) {
844850
$urlRouter.update();
845851
return TransitionPrevented;
846852
}
@@ -851,10 +857,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactoryProvider) {
851857

852858
transition.ensureValid(stateHandler.retryIfNotFound)
853859
.then(stateHandler.checkIgnoredOrPrevented, REJECT.aborted)
854-
.then(function() {
855-
console.log("WIN", arguments);
856-
}, function() {
857-
console.log("FALE", arguments);
860+
.then(function(transition) {
861+
console.log("WIN", transition);
862+
}, function(transition) {
863+
console.log("FALE", transition);
858864
});
859865

860866

src/stateDirectives.js

+2-7
Original file line numberDiff line numberDiff line change
@@ -240,19 +240,14 @@ function $StateRefActiveDirective($state, $stateParams, $interpolate) {
240240

241241
// Update route state
242242
function update() {
243-
if (isMatch()) {
244-
$element.addClass(activeClass);
245-
} else {
246-
$element.removeClass(activeClass);
247-
}
243+
$element[(isMatch() ? "add" : "remove") + "Class"](activeClass);
248244
}
249245

250246
function isMatch() {
251247
if (typeof $attrs.uiSrefActiveEq !== 'undefined') {
252248
return $state.$current.self === state && matchesParams();
253-
} else {
254-
return $state.includes(state.name) && matchesParams();
255249
}
250+
return $state.includes(state.name) && matchesParams();
256251
}
257252

258253
function matchesParams() {

src/urlMatcherFactory.js

+16-13
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ UrlMatcher.prototype.exec = function (path, searchParams, options) {
154154
current = current.parent;
155155
}
156156

157-
if (match.length !== 1) throw new Error("Unbalanced capture group in route '" + this.source + "'");
158157
if (options.isolate) return result;
159158

160159
var collapsed = {};
@@ -513,39 +512,43 @@ function $UrlMatcherFactory() {
513512
return isObject(cfg) ? cfg : { value: cfg };
514513
}
515514

516-
var idMap = {}, formatMap = {}, search = [];
515+
var idMap = {}, formatMap = {}, search = [], query, url = pattern;
517516

518-
if (pattern.indexOf('?') >= 0) {
519-
var split = pattern.split('?');
520-
pattern = split.shift();
521-
522-
forEach(split.join("?").split("&"), function(key) {
523-
search.push(key);
524-
addParameter(key, null, extend({ search: true }, paramConfig(key)));
525-
});
517+
if (url.indexOf('?') >= 0) {
518+
var split = url.split('?');
519+
url = split.shift();
520+
query = split.join("&").split("&").filter(function(val) { return !!val; });
526521
}
527522

528-
var formatString = pattern.replace(placeholder, function(_, wild, name1, name2, typeName) {
523+
var formatString = url.replace(placeholder, function(_, wild, name1, name2, typeName) {
529524
var id = Math.round(Math.random() * 100000) + "",
530525
name = name1 || name2,
531526
cfg = paramConfig(name),
532527
type = (typeName && self.$types[typeName]) || new Type({
533-
pattern: new RegExp(type || (wild === "*" ? '.*' : '[^/]*'))
528+
pattern: new RegExp(typeName || (wild === "*" ? '.*' : '[^/]*'))
534529
});
535530

536531
addParameter(name, type, cfg);
537532
formatMap[name] = id;
538533
idMap[id] = { name: name, type: type, config: cfg };
539534
return "__ " + id + " __";
540535
});
536+
537+
if (query) {
538+
forEach(query, function(key) {
539+
search.push(key);
540+
addParameter(key, null, extend({ search: true }, paramConfig(key)));
541+
});
542+
}
543+
541544
var prefix = this.parent ? this.parent.source.pattern : '^';
542545

543546
var compiled = prefix + quoteRegExp(formatString).replace(/__ (\d+) __/g, function(_, id) {
544547
var mapped = idMap[id];
545548
return mapped.type.$subPattern({ optional: isDefined(mapped.config.value), wrap: true });
546549
});
547550

548-
var fullPattern = this.parent ? this.parent.source.append(pattern) : pattern;
551+
var fullPattern = this.parent ? this.parent.source.append(url) : url;
549552

550553
this.source = {
551554
toString: function() { return fullPattern; },

test/urlMatcherFactorySpec.js

+7-15
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ describe("UrlMatcher", function () {
6767
it("should encode and decode duplicate query string values as array", function () {
6868
var matcher = new UrlMatcher('/?foo'), array = { foo: ["bar", "baz"] };
6969
expect(matcher.exec('/', array)).toEqual(array);
70-
expect(matcher.format(array)).toBe('/?foo=bar&foo=baz');
70+
expect(matcher.format(array)).toBe('/?foo[]=bar&foo[]=baz');
7171
});
7272

7373
describe("snake-case parameters", function() {
@@ -112,25 +112,17 @@ describe("UrlMatcher", function () {
112112
expect(new UrlMatcher('/users/:id').exec('/users/100%25', {})).toEqual({ id: '100%25'});
113113
});
114114

115-
it('should throw on unbalanced capture list', function () {
116-
var shouldThrow = {
115+
it('should allow embedded capture groups', function () {
116+
var shouldPass = {
117117
"/url/{matchedParam:([a-z]+)}/child/{childParam}": '/url/someword/child/childParam',
118118
"/url/{matchedParam:([a-z]+)}/child/{childParam}?foo": '/url/someword/child/childParam'
119119
};
120120

121-
angular.forEach(shouldThrow, function(url, route) {
122-
expect(function() { new UrlMatcher(route).exec(url, {}); }).toThrow(
123-
"Unbalanced capture group in route '" + route + "'"
124-
);
125-
});
126-
127-
var shouldPass = {
128-
"/url/{matchedParam:[a-z]+}/child/{childParam}": '/url/someword/child/childParam',
129-
"/url/{matchedParam:[a-z]+}/child/{childParam}?foo": '/url/someword/child/childParam'
130-
};
131-
132121
angular.forEach(shouldPass, function(url, route) {
133-
expect(function() { new UrlMatcher(route).exec(url, {}); }).not.toThrow();
122+
expect(new UrlMatcher(route).exec(url, {})).toEqual({
123+
childParam: "childParam",
124+
matchedParam: "someword"
125+
});
134126
});
135127
});
136128
});

0 commit comments

Comments
 (0)