Merge lp:~bcsaller/juju-gui/routing-hash-query into lp:juju-gui/experimental

Proposed by Benjamin Saller
Status: Needs review
Proposed branch: lp:~bcsaller/juju-gui/routing-hash-query
Merge into: lp:juju-gui/experimental
Diff against target: 185 lines (+89/-16)
2 files modified
app/assets/javascripts/ns-routing-app-extension.js (+71/-16)
test/test_routing.js (+18/-0)
To merge this branch: bzr merge lp:~bcsaller/juju-gui/routing-hash-query
Reviewer Review Type Date Requested Status
Juju GUI Hackers Pending
Review via email: mp+168351@code.launchpad.net

Description of the change

Better Hash/QS support in router

`parse`, `url` and `combine` deal more gracefully with hash and qs url
options. In the case of combine the incoming url replaces any existing
values in the hash and qs portions of the URL as might be expected. (This
is rather than some artificial merge policy for example).

https://codereview.appspot.com/9830046/

To post a comment you must log in.
Revision history for this message
Benjamin Saller (bcsaller) wrote :

Reviewers: mp+168351_code.launchpad.net,

Message:
Please take a look.

Description:
Better Hash/QS support in router

`parse`, `url` and `combine` deal more gracefully with hash and qs url
options. In the case of combine the incoming url replaces any existing
values in the hash and qs portions of the URL as might be expected.
(This
is rather than some artificial merge policy for example).

https://code.launchpad.net/~bcsaller/juju-gui/routing-hash-query/+merge/168351

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/9830046/

Affected files:
   A [revision details]
   M app/assets/javascripts/ns-routing-app-extension.js
   M test/test_routing.js

Revision history for this message
Richard Harding (rharding) wrote :

LGTM with a concern about the hash parsing to test/check on please.

https://codereview.appspot.com/9830046/diff/1/app/assets/javascripts/ns-routing-app-extension.js
File app/assets/javascripts/ns-routing-app-extension.js (right):

https://codereview.appspot.com/9830046/diff/1/app/assets/javascripts/ns-routing-app-extension.js#newcode111
app/assets/javascripts/ns-routing-app-extension.js:111: var match =
url.match(/#(\w+)([?$])?/);
Can you test that this matches anchor tags with - in them? I don't
recall if \w will work for that. In our case, we've 'namespaced' our
anchors in our tabs code #bws-configuration for instance.

Since there's only one hash per url can we just directly check
location.hash and let the browser do the logic?

https://codereview.appspot.com/9830046/

Revision history for this message
j.c.sackett (jcsackett) wrote :

LGTM, with one question about using a regex over split, largely for my
own edification.

Thanks for this branch, Ben.

https://codereview.appspot.com/9830046/diff/1/app/assets/javascripts/ns-routing-app-extension.js
File app/assets/javascripts/ns-routing-app-extension.js (right):

https://codereview.appspot.com/9830046/diff/1/app/assets/javascripts/ns-routing-app-extension.js#newcode111
app/assets/javascripts/ns-routing-app-extension.js:111: var match =
url.match(/#(\w+)([?$])?/);
Is this actually better than just splitting on '#' much as getQS splits
on '?' Provided Rick's concerns are addressed, I don't know that it
matters, but regexing seems overkill for this.

https://codereview.appspot.com/9830046/

714. By Benjamin Saller

change hash to split rather than regex style code

715. By Benjamin Saller

change hash to split rather than regex style code

Revision history for this message
Benjamin Saller (bcsaller) wrote :

Unmerged revisions

715. By Benjamin Saller

change hash to split rather than regex style code

714. By Benjamin Saller

change hash to split rather than regex style code

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/assets/javascripts/ns-routing-app-extension.js'
2--- app/assets/javascripts/ns-routing-app-extension.js 2013-05-22 18:47:13 +0000
3+++ app/assets/javascripts/ns-routing-app-extension.js 2013-06-10 22:11:26 +0000
4@@ -61,9 +61,29 @@
5 return result;
6 }
7
8- var Routes = {
9- pairs: function() {return pairs(this);}
10- };
11+ var Routes = (function() {
12+ function Routes() {
13+ return Object.create(this, {
14+ defaultNamespacePresent: {
15+ enumerable: false,
16+ writable: true
17+ },
18+ hash: {
19+ enumerable: false,
20+ writable: true
21+ },
22+ search: {
23+ enumerable: false,
24+ writable: true
25+ },
26+ pairs: {
27+ enumable: false,
28+ value: function() {return pairs(this);}
29+ }
30+ });
31+ }
32+ return Routes;
33+ })();
34
35 // Multi dimensional router (TARDIS).
36 var _Router = {
37@@ -81,6 +101,25 @@
38 },
39
40 /**
41+ Return the #hash portion of the URL if present.
42+
43+ @method getHash
44+ @param {String} url to parse hash from.
45+ @return {String} hash || null.
46+ */
47+ getHash: function(url) {
48+ var idx = url.indexOf('#');
49+ if (idx === -1) {
50+ return null;
51+ }
52+ var end = url.indexOf('?');
53+ if (end === -1) {
54+ end = url.length;
55+ }
56+ return url.slice(idx + 1, end);
57+ },
58+
59+ /**
60 * Split a URL into components, a subset of the
61 * Location Object.
62 *
63@@ -94,6 +133,7 @@
64 };
65 var origin = this._regexUrlOrigin.exec(url);
66 result.search = this.getQS(url);
67+ result.hash = this.getHash(url);
68
69 if (origin) {
70 // Take the match.
71@@ -127,20 +167,23 @@
72 **/
73 parse: function(url, combineFlags) {
74 combineFlags = Y.mix(this.combineFlags || {}, combineFlags, true);
75- var result = Object.create(Routes, {
76- defaultNamespacePresent: {
77- enumerable: false,
78- writable: true
79- }
80- });
81+ var result = new Routes();
82 var parts = this.split(url);
83 url = parts.pathname;
84+ result.hash = parts.hash;
85+ result.search = parts.search;
86
87+ // If there was a hash we need to split it off url
88+ if (result.hash) {
89+ url = url.slice(0, url.indexOf('#'));
90+ }
91 parts = url.split(this._fragment);
92- // > '/foo/bar'.split(this._fragment)
93- // ["/foo/bar"]
94- // > :baz:/foo/bar'.split(this._fragment)
95- // ["", ":baz:", "/foo/bar"]
96+ // Example output
97+ // '/foo/bar'.split(this._fragment)
98+ // ["/foo/bar"]
99+ //
100+ // ':baz:/foo/bar'.split(this._fragment)
101+ // ["", ":baz:", "/foo/bar"]
102 if (parts[0]) {
103 // This is a URL fragment without a namespace.
104 parts[0] = rtrim(parts[0], '/') + '/';
105@@ -225,11 +268,20 @@
106 });
107
108 url = slash(url);
109+
110+ if (components.hash) {
111+ url += '#' + components.hash;
112+ }
113+
114+ if (components.search) {
115+ url += '?' + components.search;
116+ }
117 return url;
118 },
119
120 /**
121- * Smartly combine new namespaced url components with old.
122+ * Smartly combine new namespaced url components with old. Hash and
123+ * query string parameters from the incoming URL are preserved.
124 *
125 * @method combine
126 * @param {Object} orig url.
127@@ -260,7 +312,7 @@
128 // original value).
129 delete incoming[this.defaultNamespace];
130 }
131- var output = {};
132+ var output = new Routes();
133 Y.each(orig, function(v, k) {
134 if (v && !Y.Lang.isArray(v)) {
135 v = [v];
136@@ -290,9 +342,12 @@
137 }
138 });
139 });
140+ // TODO: Need combine support for hash/search. Output can be a Routes
141+ // object to make this work as hash/search wouldn't be in the enum set.
142+ output.hash = incoming.hash;
143+ output.search = incoming.search;
144 url = this.url(output, {excludeRootPaths: true});
145 return url;
146-
147 }
148 };
149
150
151=== modified file 'test/test_routing.js'
152--- test/test_routing.js 2013-05-23 15:46:35 +0000
153+++ test/test_routing.js 2013-06-10 22:11:26 +0000
154@@ -90,6 +90,15 @@
155 assert(u === '/:a:alpha/:b:beta/:gamma:g/');
156 });
157
158+ it('should support hashes and query strings', function() {
159+ var router = juju.Router('test');
160+ var url, parts;
161+ parts = router.parse('/foo/#bar?baz=something+else&battery=acid');
162+ assert.equal(parts.hash, 'bar');
163+ assert.equal(parts.search, 'baz=something+else&battery=acid');
164+ assert.equal(parts.test, '/foo/');
165+ });
166+
167 it('should support a default namespace', function() {
168 var router = juju.Router('charmstore');
169 var url, parts;
170@@ -115,6 +124,15 @@
171 url.should.equal('/foo/bar/');
172 url = router.combine('/foo/bar', '/:inspector:/foo/');
173 url.should.equal('/foo/bar/:inspector:/foo/');
174+
175+ // Hash and querystrings come from the second (incoming)
176+ // argument to combine, values from the original url
177+ // are discarded.
178+ url = router.combine('/foo/bar?world=gone+away',
179+ '/:inspector:/foo/#hello?world=beater');
180+ url.should.equal('/foo/bar/:inspector:/foo/#hello?world=beater');
181+
182+
183 });
184
185 it('should be able to split qualified urls', function() {

Subscribers

People subscribed via source and target branches