|
@@ -2,7 +2,7 @@
|
|
|
* @file
|
|
|
* Contains the router code and route definitions
|
|
|
*
|
|
|
- * Inspired by Joakim Beng's example.
|
|
|
+ * Inspired by Joakim Beng"s example.
|
|
|
*
|
|
|
* @see http://joakim.beng.se/blog/posts/a-javascript-router-in-20-lines.html
|
|
|
*/
|
|
@@ -11,59 +11,98 @@
|
|
|
// The routes object.
|
|
|
var routes = {};
|
|
|
|
|
|
-// The route registering function:
|
|
|
+// The route registering function.
|
|
|
function route(path, controller) {
|
|
|
routes[path] = controller;
|
|
|
}
|
|
|
|
|
|
-// The router.
|
|
|
+/**
|
|
|
+ * Set the target content to the template result.
|
|
|
+ *
|
|
|
+ * Use only if global "ready" is true, otherwise global "templates" may not be
|
|
|
+ * entirely initialized.
|
|
|
+ *
|
|
|
+ * @param {DOMElement} target
|
|
|
+ * The element in which to inject the template output.
|
|
|
+ * @param {string} name
|
|
|
+ * The name of the template to render.
|
|
|
+ * @param {Object} context
|
|
|
+ * The template context.
|
|
|
+ *
|
|
|
+ * @returns {void}
|
|
|
+ *
|
|
|
+ * @globals templates
|
|
|
+ */
|
|
|
+function render(target, name, context) {
|
|
|
+ var output = null;
|
|
|
+ var template = templates[name];
|
|
|
+
|
|
|
+ if (!template) {
|
|
|
+ console.error("Template not found", name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ output = template(context);
|
|
|
+ target.innerHTML = output;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * The router.
|
|
|
+ *
|
|
|
+ * @returns {void}
|
|
|
+ *
|
|
|
+ * @globals contentElement, ready, EVENT_TEMPLATES_LOADED
|
|
|
+ */
|
|
|
function router() {
|
|
|
// Current route url (getting rid of "#" in hash as well):
|
|
|
var url = location.hash.slice(1) || "/";
|
|
|
|
|
|
// Get route by url:
|
|
|
- var currentRoute = routes[url];
|
|
|
+ var CurrentRoute = routes[url];
|
|
|
|
|
|
var context = null;
|
|
|
+ var listener = null;
|
|
|
var templateName = null;
|
|
|
|
|
|
- // Do we have both a view and a route ?
|
|
|
- if (contentElement) {
|
|
|
- if (currentRoute) {
|
|
|
- // Render route template with Handlebars:
|
|
|
- context = new currentRoute();
|
|
|
- templateName = (url === "/") ? "home" : url;
|
|
|
-
|
|
|
- contentElement.addEventListener(EVENT_TEMPLATES_LOADED, function () {
|
|
|
- console.log('templates', templates, 'name', url, templateName);
|
|
|
- contentElement.innerHTML = templates[templateName](context);
|
|
|
- });
|
|
|
+ // Do we have a route ?
|
|
|
+ if (CurrentRoute) {
|
|
|
+ // Render route template with Handlebars:
|
|
|
+ context = new CurrentRoute();
|
|
|
+ templateName = (url === "/") ? "home" : url;
|
|
|
+ if (ready) {
|
|
|
+ console.log('Immediate render');
|
|
|
+ render(contentElement, templateName, context);
|
|
|
}
|
|
|
else {
|
|
|
- console.warn("Content found but no route matching", url);
|
|
|
+ console.log('Deferred render');
|
|
|
+ listener = contentElement.addEventListener(EVENT_TEMPLATES_LOADED, function () {
|
|
|
+ render(contentElement, templateName, context);
|
|
|
+ contentElement.removeEventListener(EVENT_TEMPLATES_LOADED, listener);
|
|
|
+ });
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
- console.warn("Content not found.");
|
|
|
+ console.warn("Content found but no route matching", url);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Bind router to browser events.
|
|
|
-// window.addEventListener("hashchange", router);
|
|
|
+window.addEventListener("hashchange", router);
|
|
|
window.addEventListener("load", router);
|
|
|
|
|
|
// Route declarations.
|
|
|
route("/", function () {
|
|
|
- console.log('Home controller');
|
|
|
+ console.log("Home controller");
|
|
|
});
|
|
|
|
|
|
route("class", function () {
|
|
|
- console.log('Class controller');
|
|
|
+ console.log("Class controller");
|
|
|
this.greeting = "Hello world!";
|
|
|
this.moreText = "Bacon ipsum...";
|
|
|
});
|
|
|
|
|
|
route("species", function () {
|
|
|
- console.log('Species controller');
|
|
|
+ console.log("Species controller");
|
|
|
this.heading = "I\"m page two!";
|
|
|
});
|