Skip to content

Commit

Permalink
Pretty sweet handling of arbitrary links in the proxy.
Browse files Browse the repository at this point in the history
Allows for .setLocation('push/one') and will use '#!/' or pushState depending on availability
  • Loading branch information
quirkey committed Mar 15, 2011
1 parent 2e6167f commit 35c012e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 10 deletions.
22 changes: 14 additions & 8 deletions lib/sammy.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,14 +234,14 @@

// bind the proxy events to the current app.
bind: function() {
var proxy = this, app = this.app;
var proxy = this, app = this.app, lp = Sammy.DefaultLocationProxy;
$(window).bind('hashchange.' + this.app.eventNamespace(), function(e, non_native) {
// if we receive a native hash change event, set the proxy accordingly
// and stop polling
if (proxy.is_native === false && !non_native) {
Sammy.log('native hash change exists, using');
proxy.is_native = true;
window.clearInterval(Sammy.DefaultLocationProxy._interval);
window.clearInterval(lp._interval);
}
app.trigger('location-changed');
});
Expand All @@ -252,19 +252,18 @@
});
// bind to link clicks that have routes
$('a').live('click.history-' + this.app.eventNamespace(), function(e) {
var full_path = Sammy.DefaultLocationProxy.fullPath(this);
e.preventDefault();
var full_path = lp.fullPath(this);
if (this.hostname == window.location.hostname && app.lookupRoute('get', full_path)) {
e.preventDefault();
proxy.setLocation(full_path);
return false;
}
return false;
});
}
if (!Sammy.DefaultLocationProxy._bindings) {
Sammy.DefaultLocationProxy._bindings = 0;
if (!lp._bindings) {
lp._bindings = 0;
}
Sammy.DefaultLocationProxy._bindings++;
lp._bindings++;
},

// unbind the proxy events from the current app
Expand All @@ -285,6 +284,13 @@

// set the current location to `new_location`
setLocation: function(new_location) {
if (/^([^#\/]|$)/.test(new_location)) { // non-prefixed url
if (_has_history) {
new_location = '/' + new_location;
} else {
new_location = '#!/' + new_location;
}
}
// HTML5 History exists and new_location is a full path
if (_has_history && /^\//.test(new_location)) {
history.pushState({ path: new_location }, window.title, new_location);
Expand Down
40 changes: 38 additions & 2 deletions test/test_sammy_location_proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
this.app = new Sammy.Application(function() {});
this.proxy = this.app._location_proxy;
this.has_native = ('onhashchange' in window);
this.has_history = window.history && history.pushState;
}
})
.should('store a pointer to the app', function() {
Expand Down Expand Up @@ -65,7 +66,7 @@
equal(this.proxy.getLocation(), [window.location.pathname, window.location.search, window.location.hash].join(''));
})
.should('push and pop state if History is available', function(t, spec) {
if (window.history && history.pushState) {
if (this.has_history) {
var locations = [], app = this.app, proxy = this.proxy;
app.bind('location-changed', function(e) {
locations.push(this.app.getLocation());
Expand Down Expand Up @@ -94,7 +95,7 @@
}
})
.should('bind to push state links', function(e, spec) {
if (window.history && history.pushState) {
if (this.has_history) {
var locations = [], app = this.app, proxy = this.proxy;
app.get('/push', function(e) {
locations.push(this.app.getLocation());
Expand All @@ -112,6 +113,7 @@
equal(proxy.getLocation(), '/push');
$('#pop').click();
equal(proxy.getLocation(), '/');
proxy.setLocation(original_location)
setTimeout(function() {
equal(locations.length, 2);
equal(locations[0], '/push');
Expand All @@ -124,6 +126,40 @@
ok(true);
spec.pending('Browser does not have HTML5 history');
}
})
.should('handle arbitrary non-specific locations', function(e) {
var app = this.app, proxy = this.proxy, has_history = this.has_history;
var triggered = false, locations = [];
app.get('/testing', function(e) {
triggered = true;
locations.push(this.app.getLocation());
});
app.get('/', function(e) {
triggered = true;
locations.push(this.app.getLocation());
});
app.run();
ok(app.isRunning());
var original_location = proxy.getLocation();
expect(5);
stop();
proxy.setLocation('testing');
setTimeout(function() {
if (has_history) {
equal(proxy.getLocation(), '/testing');
} else {
equal(proxy.getLocation(), '/#!/testing');
}
proxy.setLocation('');
equal(proxy.getLocation(), '/');
proxy.setLocation(original_location)
setTimeout(function() {
matches(/testing/, locations[0]);
matches(/\//, locations[1]);
app.unload();
start();
}, 1000);
}, 1000);
});


Expand Down

0 comments on commit 35c012e

Please sign in to comment.