Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 11bb1cd

Browse files
committedOct 22, 2014
Add cause/from
Pass through metadata about the request. Useful for logging purposes.
1 parent c74706c commit 11bb1cd

10 files changed

+63
-22
lines changed
 

‎README.md

+12
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,18 @@ their APIs.
153153
- **fragment:String**: The hash portion of the requested URL, excluding the hash
154154
mark. e.g. `'this-is-the-hash'`
155155
- **first:Boolean**: Is this the first request being handled by this router?
156+
- **from(causes:String...):Boolean**: Check the cause of the request. Causes
157+
that monorouter sends are:
158+
159+
* `"startup"` - When a request is triggered by the router initialization in
160+
the browser.
161+
* `"popstate"` - When a request is triggered by a popstate event
162+
* `"link"` - When a request is triggered by a link click captured by the link
163+
hijacker
164+
165+
You may also send custom causes. For example, [connect-monorouter] uses the
166+
string '"httprequest"'. Generally, causes shouldn't be used to affect routing
167+
behavior—they are meant primarily for logging.
156168

157169

158170
### Handler Context

‎lib/LinkHijacker.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ LinkHijacker.prototype.handleClick = function(event) {
8080
event.preventDefault();
8181

8282
// Dispatch the URL.
83-
this.router.history.navigate(fullPath);
83+
this.router.history.navigate(fullPath, {cause: 'link'});
8484
};
8585

8686
module.exports = LinkHijacker;

‎lib/Request.js

+17
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ function Request(url, opts) {
5252
this.fragment = parsed.hash.replace(/^#/, '');
5353
this.initialOnly = opts && opts.initialOnly;
5454
this.first = opts && opts.first;
55+
this.cause = opts && opts.cause;
5556
}
5657

5758
// Make requests event emitters.
@@ -67,6 +68,22 @@ Request.prototype.param = function(indexOrName) {
6768
return this.params[indexOrName];
6869
};
6970

71+
/**
72+
* Check whether the request triggered by one of the the specified causes.
73+
*/
74+
Request.prototype.from = function() {
75+
var causes;
76+
if (typeof arguments[0] === 'string') causes = arguments;
77+
else causes = arguments[0];
78+
79+
if (causes && causes.length) {
80+
for (var i = 0, len = causes.length; i < len; i++) {
81+
if (causes[i] === this.cause) return true;
82+
}
83+
}
84+
return false;
85+
};
86+
7087
Request.prototype.cancel = function() {
7188
if (!this.canceled) {
7289
this.canceled = true;

‎lib/Router.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,10 @@ Router.prototype.dispatch = function(url, opts, callback) {
132132
if (callback) callback(err, err ? null : res);
133133
}.bind(this);
134134

135+
var first = (opts && opts.first) || !this._dispatchedFirstRequest;
135136
var req = new Request(url, extend(opts, {
136-
first: (opts && opts.first) || !this._dispatchedFirstRequest,
137+
cause: opts && opts.cause,
138+
first: first,
137139
root: RouterClass.rootUrl
138140
}));
139141
this._dispatchedFirstRequest = true;

‎lib/__tests__/Request-test.js

+10
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,14 @@ describe('Request', function() {
4949
expect(req.originalUrl).toBe('/a/b/c?search=hi');
5050
});
5151

52+
it('can tell you the cause', function() {
53+
var req = new Request('http://example.com/a/b/c?search=hi',
54+
{cause: 'popstate'});
55+
expect(req.from('popstate')).toBe(true);
56+
expect(req.from('somethingelse')).toBe(false);
57+
expect(req.from('somethingelse', 'popstate')).toBe(true);
58+
expect(req.from(['somethingelse', 'popstate'])).toBe(true);
59+
expect(req.from(['somethingelse'])).toBe(false);
60+
});
61+
5262
});

‎lib/attach.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,30 @@ function attach(Router, element, opts) {
2222
// Now that the view has been bootstrapped (i.e. is in its inital state), it
2323
// can be updated.
2424
update();
25-
history.on('update', function() {
26-
update();
25+
history.on('update', function(meta) {
26+
update(meta);
2727
});
2828
};
2929

3030
var previousURL;
31-
var update = function(isInitial) {
31+
var update = function(meta) {
3232
var url = history.currentURL();
3333
if (url === previousURL) return;
3434
previousURL = url;
3535

36-
var res = router.dispatch(url, function(err) {
36+
var res = router.dispatch(url, meta, function(err) {
3737
if (err && (err.name !== 'Unhandled') && (err.name !== 'Cancel')) {
3838
throw err;
3939
}
4040
});
4141

42-
if (isInitial) {
42+
if (meta && meta.cause === 'startup') {
4343
res.once('initialReady', onInitialReady);
4444
}
4545
};
4646

4747
// Start the process.
48-
update(true);
48+
update({cause: 'startup'});
4949

5050
return router;
5151
}

‎lib/history/BaseHistory.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ inherits(BaseHistory, EventEmitter);
1111
* Navigate to the provided URL without creating a duplicate history entry if
1212
* you're already there.
1313
*/
14-
BaseHistory.prototype.navigate = function(url) {
14+
BaseHistory.prototype.navigate = function(url, meta) {
1515
if (url !== this.currentURL()) {
16-
this.push(url);
16+
this.push(url, meta);
1717
} else {
18-
this.replace(url);
18+
this.replace(url, meta);
1919
}
2020
};
2121

‎lib/history/DummyHistory.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ DummyHistory.prototype.currentURL = function() {
1212
return this.history[this.history.length - 1];
1313
};
1414

15-
DummyHistory.prototype.push = function(path) {
15+
DummyHistory.prototype.push = function(path, meta) {
1616
this.history.push(path);
17-
this.emit('update');
17+
this.emit('update', meta);
1818
};
1919

20-
DummyHistory.prototype.replace = function(path) {
20+
DummyHistory.prototype.replace = function(path, meta) {
2121
this.history.pop();
2222
this.history.push(path);
23-
this.emit('update');
23+
this.emit('update', meta);
2424
};
2525

2626
DummyHistory.prototype.pop = function() {

‎lib/history/FallbackHistory.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ FallbackHistory.prototype.push = function(path) {
2424
window.location = path;
2525
};
2626

27-
FallbackHistory.prototype.replace = function(path) {
27+
FallbackHistory.prototype.replace = function(path, meta) {
2828
// For the fallback history, `replace` won't actually change the browser
2929
// address, but will update its own URL. This is because `replace` usually
3030
// corresponds to "lesser" state changes: having a stale browser URL is
3131
// considered more acceptable than refreshing the entire page.
3232
this._url = path;
33-
this.emit('update');
33+
this.emit('update', meta);
3434
};
3535

3636
module.exports = FallbackHistory;

‎lib/history/PushStateHistory.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var urllite = require ('urllite');
88
*/
99
function PushStateHistory() {
1010
window.addEventListener('popstate', function(event) {
11-
this.emit('update');
11+
this.emit('update', {cause: 'popstate'});
1212
}.bind(this));
1313
}
1414

@@ -20,14 +20,14 @@ PushStateHistory.prototype.currentURL = function() {
2020
return parsed.pathname + parsed.search + parsed.hash;
2121
};
2222

23-
PushStateHistory.prototype.push = function(path) {
23+
PushStateHistory.prototype.push = function(path, meta) {
2424
window.history.pushState({}, '', path);
25-
this.emit('update');
25+
this.emit('update', meta);
2626
};
2727

28-
PushStateHistory.prototype.replace = function(path) {
28+
PushStateHistory.prototype.replace = function(path, meta) {
2929
window.history.replaceState({}, '', path);
30-
this.emit('update');
30+
this.emit('update', meta);
3131
};
3232

3333
module.exports = PushStateHistory;

0 commit comments

Comments
 (0)
Please sign in to comment.