Skip to content

Instantly share code, notes, and snippets.

@philoye
Forked from toolmantim/router.coffee
Created May 31, 2012 04:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philoye/2841035 to your computer and use it in GitHub Desktop.
Save philoye/2841035 to your computer and use it in GitHub Desktop.
A Backbone.js router subclass that disables the hash fallback mechanism in favour of just navigating to the location (just like a normal link would behave)
class MyApp.Router extends Backbone.Router
hasPushState: window.history and window.history.pushState
# Override the navigate function to remove Backbone's #hash fallback for
# non-pushState browsers. Instead we just navigate to the new location using
# window.location
navigate: (fragment, trigger) ->
if @hasPushState
super(arguments...)
else
# Backbone navigate paths don't start with a forward slash, so we may
# need to add one
fragment = "/#{fragment}" unless fragment.match(/^\//)
window.location = fragment
# Navigates to the href property of an event's currentTarget whilst ignoring
# right clicks, middle clicks, shift-clicks etc.
#
# Handy for using from within event handlers:
#
# class MyApp.HeaderView extends Backbone.View
# events:
# "click a.home": "home"
# home: (e) ->
# MyApp.router.navigateToLink(e)
navigateToLink: (e, trigger=true) ->
if e.which == 2 or e.metaKey or e.ctrlKey or e.shiftKey
# Make sure we return true in case we're used as the return value for
# the event handling function
return true
else
# Update document page title if title attribute is set on the link
document.title = 'MyAppName'
if e.target.title
document.title = e.target.title + ' - ' + document.title
# Backbone navigate paths don't start with a forward slash
@navigate e.target.pathname.replace(/^\//,''), trigger
e.preventDefault()
# Send all links to the Router if data-app="true" is set.
#
# This way you don't have to explicitly set up events for routing. You can
# simply user normal links and backbone transparently takes over.
#
# <a href="/home" data-app="true" title="Homepage">Home</a>
initialize: ->
$(document).on "click", 'a', (e) =>
if $(e.target).attr('data-app')
e.preventDefault()
@navigateToLink e
# your backbone init stuff
(function() {
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
}, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
MyApp.Router = (function() {
__extends(Router, Backbone.Router);
function Router() {
Router.__super__.constructor.apply(this, arguments);
}
Router.prototype.hasPushState = window.history && window.history.pushState;
Router.prototype.navigate = function(fragment, trigger) {
if (this.hasPushState) {
return Router.__super__.navigate.apply(this, arguments);
} else {
if (!fragment.match(/^\//)) {
fragment = "/" + fragment;
}
return window.location = fragment;
}
};
Router.prototype.navigateToLink = function(e, trigger) {
if (trigger == null) {
trigger = true;
}
if (e.which === 2 || e.metaKey || e.ctrlKey || e.shiftKey) {
return true;
} else {
document.title = 'MyAppName';
if (e.target.title) {
document.title = e.target.title + ' - ' + document.title;
}
this.navigate(e.target.pathname.replace(/^\//, ''), trigger);
return e.preventDefault();
}
};
Router.prototype.initialize = function() {
return $(document).on("click", 'a', __bind(function(e) {
if ($(e.target).attr('data-app')) {
e.preventDefault();
return this.navigateToLink(e);
}
}, this));
};
return Router;
})();
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment