Skip to content

Commit d15e1f6

Browse files
committed
Merge branch 'master' into init-stores-with-state
* master: Match route before init stores (choojs#698) more timings (choojs#578) Disable hash routing by default (choojs#699)
2 parents 11e8ed0 + a871818 commit d15e1f6

File tree

4 files changed

+69
-19
lines changed

4 files changed

+69
-19
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,12 @@ Querystrings (e.g. `?foo=bar`) are ignored when matching routes. An object
284284
containing the key-value mappings exists as `state.query`.
285285

286286
### Hash routing
287-
By default hashes are treated as part of the url when routing. Using hashes to
288-
delimit routes (e.g. `/foo#bar`) can be disabled by setting the `hash`
289-
[option](#app--chooopts) to `false`. Regardless, when a hash is found we also
290-
check if there's an available anchor on the same page, and will scroll the
291-
screen to the position. Using both hashes in URLs and anchor links on the page
292-
is generally not recommended.
287+
By default, hashes are ignored when routing. When enabling hash routing
288+
(`choo({ hash: true })`) hashes will be treated as part of the url, converting
289+
`/foo#bar` to `/foo/bar`. This is useful if the application is not mounted at
290+
the website root. Unless hash routing is enabled, if a hash is found we check if
291+
there's an anchor on the same page, and will scroll the element into view. Using
292+
both hashes in URLs and anchor links on the page is generally not recommended.
293293

294294
### Following links
295295
By default all clicks on `<a>` tags are handled by the router through the
@@ -534,7 +534,7 @@ Initialize a new `choo` instance. `opts` can also contain the following values:
534534
- __opts.cache:__ default: `undefined`. Override default class cache used by
535535
`state.cache`. Can be a a `number` (maximum number of instances in cache,
536536
default `100`) or an `object` with a [nanolru][nanolru]-compatible API.
537-
- __opts.hash:__ default: `true`. Treat hashes in URLs as part of the pathname,
537+
- __opts.hash:__ default: `false`. Treat hashes in URLs as part of the pathname,
538538
transforming `/foo#bar` to `/foo/bar`. This is useful if the application is
539539
not mounted at the website root.
540540

index.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module.exports = Choo
1616
var HISTORY_OBJECT = {}
1717

1818
function Choo (opts) {
19+
var timing = nanotiming('choo.constructor')
1920
if (!(this instanceof Choo)) return new Choo(opts)
2021
opts = opts || {}
2122

@@ -37,7 +38,7 @@ function Choo (opts) {
3738
// properties for internal use only
3839
this._historyEnabled = opts.history === undefined ? true : opts.history
3940
this._hrefEnabled = opts.href === undefined ? true : opts.href
40-
this._hashEnabled = opts.hash === undefined ? true : opts.hash
41+
this._hashEnabled = opts.hash === undefined ? false : opts.hash
4142
this._hasWindow = typeof window !== 'undefined'
4243
this._cache = opts.cache
4344
this._loaded = false
@@ -72,12 +73,15 @@ function Choo (opts) {
7273
if (self._hasWindow) document.title = title
7374
})
7475
}
76+
timing()
7577
}
7678

7779
Choo.prototype.route = function (route, handler) {
80+
var routeTiming = nanotiming("choo.route('" + route + "')")
7881
assert.equal(typeof route, 'string', 'choo.route: route should be type string')
7982
assert.equal(typeof handler, 'function', 'choo.handler: route should be type function')
8083
this.router.on(route, handler)
84+
routeTiming()
8185
}
8286

8387
Choo.prototype.use = function (cb) {
@@ -94,6 +98,7 @@ Choo.prototype.use = function (cb) {
9498

9599
Choo.prototype.start = function () {
96100
assert.equal(typeof window, 'object', 'choo.start: window was not found. .start() must be called in a browser, use .toString() if running in Node')
101+
var startTiming = nanotiming('choo.start')
97102

98103
var self = this
99104
if (this._historyEnabled) {
@@ -139,11 +144,11 @@ Choo.prototype.start = function () {
139144
}
140145

141146
this._setCache(this.state)
147+
this._matchRoute(this.state)
142148
this._stores.forEach(function (initStore) {
143149
initStore(self.state)
144150
})
145151

146-
this._matchRoute(this.state)
147152
this._tree = this._prerender(this.state)
148153
assert.ok(this._tree, 'choo.start: no valid DOM node returned for location ' + this.state.href)
149154

@@ -168,13 +173,16 @@ Choo.prototype.start = function () {
168173
self._loaded = true
169174
})
170175

176+
startTiming()
171177
return this._tree
172178
}
173179

174180
Choo.prototype.mount = function mount (selector) {
181+
var mountTiming = nanotiming("choo.mount('" + selector + "')")
175182
if (typeof window !== 'object') {
176183
assert.ok(typeof selector === 'string', 'choo.mount: selector should be type String')
177184
this.selector = selector
185+
mountTiming()
178186
return this
179187
}
180188

@@ -202,6 +210,7 @@ Choo.prototype.mount = function mount (selector) {
202210

203211
renderTiming()
204212
})
213+
mountTiming()
205214
}
206215

207216
Choo.prototype.toString = function (location, state) {
@@ -214,12 +223,12 @@ Choo.prototype.toString = function (location, state) {
214223
assert.equal(typeof state, 'object', 'choo.toString: state should be type object')
215224

216225
this._setCache(state)
226+
this._matchRoute(state, location)
217227
this.emitter.removeAllListeners()
218228
this._stores.forEach(function (initStore) {
219229
initStore(state)
220230
})
221231

222-
this._matchRoute(state, location)
223232
var html = this._prerender(state)
224233
assert.ok(html, 'choo.toString: no valid value returned for the route ' + location)
225234
assert(!Array.isArray(html), 'choo.toString: return value was an array for the route ' + location)

test/browser.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ tape('should expose a public API', function (t) {
5252
t.end()
5353
})
5454

55-
tape('should enable history and hash by defaut', function (t) {
55+
tape('should enable history and href by defaut', function (t) {
5656
var app = choo()
5757
t.true(app._historyEnabled, 'history enabled')
5858
t.true(app._hrefEnabled, 'href enabled')
@@ -82,9 +82,9 @@ tape('router should support a default route', function (t) {
8282
app.mount(container)
8383
})
8484

85-
tape('router should treat hashes as slashes by default', function (t) {
85+
tape('enabling hash routing should treat hashes as slashes', function (t) {
8686
t.plan(1)
87-
var app = choo()
87+
var app = choo({ hash: true })
8888
var container = init('/account#security')
8989
app.route('/account/security', function (state, emit) {
9090
t.pass()
@@ -93,9 +93,9 @@ tape('router should treat hashes as slashes by default', function (t) {
9393
app.mount(container)
9494
})
9595

96-
tape('router should ignore hashes if hash is disabled', function (t) {
96+
tape('router should ignore hashes by default', function (t) {
9797
t.plan(1)
98-
var app = choo({ hash: false })
98+
var app = choo()
9999
var container = init('/account#security')
100100
app.route('/account', function (state, emit) {
101101
t.pass()
@@ -191,6 +191,27 @@ tape('state should include location on render', function (t) {
191191
app.mount(container)
192192
})
193193

194+
tape('state should include location on store init', function (t) {
195+
t.plan(6)
196+
var app = choo()
197+
var container = init('/foo/bar/file.txt?bin=baz')
198+
app.use(store)
199+
app.route('/:first/:second/*', function (state, emit) {
200+
return html`<div></div>`
201+
})
202+
app.mount(container)
203+
204+
function store (state, emit) {
205+
var params = { first: 'foo', second: 'bar', wildcard: 'file.txt' }
206+
t.equal(state.href, '/foo/bar/file.txt', 'state has href')
207+
t.equal(state.route, ':first/:second/*', 'state has route')
208+
t.ok(state.hasOwnProperty('params'), 'state has params')
209+
t.deepEqual(state.params, params, 'params match')
210+
t.ok(state.hasOwnProperty('query'), 'state has query')
211+
t.deepEqual(state.query, { bin: 'baz' }, 'query match')
212+
}
213+
})
214+
194215
tape('state should include title', function (t) {
195216
t.plan(3)
196217
document.title = 'foo'

test/node.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ tape('router should support a default route', function (t) {
7676
t.end()
7777
})
7878

79-
tape('router should treat hashes as slashes by default', function (t) {
79+
tape('enabling hash routing should treat hashes as slashes', function (t) {
8080
t.plan(1)
81-
var app = choo()
81+
var app = choo({ hash: true })
8282
app.route('/account/security', function (state, emit) {
8383
t.pass()
8484
return html`<div></div>`
@@ -87,9 +87,9 @@ tape('router should treat hashes as slashes by default', function (t) {
8787
t.end()
8888
})
8989

90-
tape('router should ignore hashes if hash is disabled', function (t) {
90+
tape('router should ignore hashes by default', function (t) {
9191
t.plan(1)
92-
var app = choo({ hash: false })
92+
var app = choo()
9393
app.route('/account', function (state, emit) {
9494
t.pass()
9595
return html`<div></div>`
@@ -185,6 +185,26 @@ tape('state should include location on render', function (t) {
185185
t.end()
186186
})
187187

188+
tape('state should include location on store init', function (t) {
189+
t.plan(6)
190+
var app = choo()
191+
app.use(store)
192+
app.route('/:first/:second/*', function (state, emit) {
193+
return html`<div></div>`
194+
})
195+
app.toString('/foo/bar/file.txt?bin=baz')
196+
197+
function store (state, emit) {
198+
var params = { first: 'foo', second: 'bar', wildcard: 'file.txt' }
199+
t.equal(state.href, '/foo/bar/file.txt', 'state has href')
200+
t.equal(state.route, ':first/:second/*', 'state has route')
201+
t.ok(state.hasOwnProperty('params'), 'state has params')
202+
t.deepEqual(state.params, params, 'params match')
203+
t.ok(state.hasOwnProperty('query'), 'state has query')
204+
t.deepEqual(state.query, { bin: 'baz' }, 'query match')
205+
}
206+
})
207+
188208
tape('state should include cache', function (t) {
189209
t.plan(6)
190210
var app = choo()

0 commit comments

Comments
 (0)