Skip to content

Instantly share code, notes, and snippets.

@ryan-scott-dev
Created March 25, 2014 03:15
Show Gist options
  • Save ryan-scott-dev/9754607 to your computer and use it in GitHub Desktop.
Save ryan-scott-dev/9754607 to your computer and use it in GitHub Desktop.
Maria Routing Example
(function() {
function removeThrobber() {
var loading = document.getElementById('loading');
loading.parentNode.removeChild(loading);
}
maria.on(window, 'load', function() {
application.app = bootstrapModel.createAppModel();
application.app.load({
success: function() {
removeThrobber();
// You should only directly access the view for testing purposes!
application.appview = new application.AppView(application.app);
// Tell app to route to the current url
application.app.router().toWindowLocation();
// Show the app to the user.
document.body.appendChild(application.appview.build());
},
failure: function(jqXHR, textStatus, errorThrown) {
removeThrobber();
// Show an error message to the user.
document.body.appendChild(document.createTextNode('Error: Unable to load the app.'));
}
});
});
});
}());
application.Model.subclass(application, 'NavigationModel', {
constructor: function(appModel) {
this._appModel = appModel;
},
attributes: {
_appModel: null,
_lastTarget: 'home',
_lastHashPath: null
},
properties: {
hasChangedHashPath: function() {
var newHashPath = '/' + window.location.hash;
return this._lastHashPath !== newHashPath;
},
wasLastTarget: function(target) {
return this.getLastTarget() == target;
},
onNavigate: function(target, callback) {
this.addEventListener('navigate', function(navigationEvent) {
if (navigationEvent.target == target) {
callback(navigationEvent);
}
});
},
onNavigated: function(target, callback) {
this.addEventListener('navigated', function(navigatedEvent) {
if (navigatedEvent.target == target) {
callback(navigatedEvent);
}
});
},
onNavigatedAny: function(callback) {
this.addEventListener('navigated', function(navigatedEvent) {
callback(navigatedEvent);
});
},
navigatedWith: function(navigationEvent) {
var navigationData =
{
type: 'navigated',
target: navigationEvent.target,
targetLink: navigationEvent.targetLink,
title: navigationEvent.title,
url: navigationEvent.url,
data: navigationEvent.data
};
if (navigationEvent.pushHistory) {
if (application.hasHistoryAPI()) {
history.pushState(navigationData,
navigationEvent.title,
navigationEvent.url);
} else {
var url = navigationEvent.url.stripHostname();
var hashPath = url.convertToHashPath();
this._lastHashPath = hashPath;
window.location.href = hashPath;
}
}
application.analytics.trackPageView(navigationEvent);
this.setLastTarget(navigationEvent.target);
this.dispatchEvent(navigationData);
},
navigateTo: function(title, target, targetLink, data, url) {
if (!url) {
if (targetLink) {
url = targetLink.href;
} else {
url = '/' + target;
}
}
var pattern = /(.+)\?.*/;
if (pattern.test(url)) {
url = pattern.exec(url)[1];
}
var navigationData =
{
type: 'navigate',
target: target,
targetLink: targetLink,
title: title,
data: data,
url: url,
pushHistory: true
};
this.dispatchEvent(navigationData);
},
navigateToPoppedHistoryState: function(navigationState) {
if (!navigationState) {
navigationState = {
target: 'home',
title: 'Home'
};
}
var navigationData =
{
type: 'navigate',
target: navigationState.target,
targetLink: navigationState.targetLink,
title: navigationState.title,
url: navigationState.url,
data: navigationState.data,
pushHistory: false
};
this.dispatchEvent(navigationData);
},
toThing: function(thing) {
this.navigateTo(thing.getName(), 'thing', thing.getRepository().getLink('self'));
},
toHome: function() {
this.navigateTo("Home", 'home', null, null, '/');
}
}
});
application.Model.subclass(application, 'Router', {
attributes: {
_routes: [],
_defaultRoute: null
},
properties: {
toWindowLocation: function() {
var locationPath = window.location.pathname;
var locationHash = window.location.hash;
var location = locationPath;
if (locationHash !== '') {
// Always direct to the location hash if is available
location = '/' + window.location.hash.slice(1);
} else if (!application.hasHistoryAPI()) {
// Convert the path to a hash if in IE
var url = window.location.pathname;
var hashPath = url.convertToHashPath();
window.location.replace(hashPath);
location = locationPath;
}
this.routeAppTo(application.app, location);
},
routeTo: function(path) {
var routes = this.getRoutes();
var found = false;
for(var i = 0; i < routes.length; i++) {
var result = routes[i].pattern.exec(path);
if (result) {
found = true;
routes[i].callback(path, result.slice(1));
break;
}
}
if (!found && this.getDefaultRoute()) {
this.getDefaultRoute()(path);
}
return found;
},
addRoute: function(pattern, callback) {
this.getRoutes().push({
pattern: pattern,
callback: callback
});
},
routeAppTo: function(app, path) {
this.addRoute(/^\/search\/(.*)/, function(path, match) {
app.navigate().toSearch(match[0]);
});
this.addRoute(/^\/things\/([0-9]+)/, function(path, match) {
var id = match[0];
var link = app.getRepository().getShowThingLink();
var thing = application.ThingModel.fromId(id, link, {
success: function() {
if (!thing) return;
app.navigate().toThing(thing);
}
});
});
this.setDefaultRoute(function(path) {
app.navigate().toHome();
});
this.routeTo(path);
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment