123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- /**
- * @file
- * Contains the router code and route definitions
- *
- * Inspired by Joakim Beng"s example.
- *
- * @see http://joakim.beng.se/blog/posts/a-javascript-router-in-20-lines.html
- */
- // The routes object.
- var routes = {};
- // The route registering function.
- function route(path, controller) {
- routes[path] = controller;
- }
- /**
- * 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() {
- var context = null;
- var CurrentRoute = null;
- var listener = null;
- var path = null;
- var query;
- var templateName = null;
- var urlArray = null;
- // Current route url (getting rid of "#" in hash as well):
- var matches = location.hash.match(/^#?([\w]*)(?:\?)?(.*)?/);
- path = matches[1] ? matches[1] : "/";
- query = matches[2] ? matches[2].split("&").reduce(function (accu, v) {
- var vArray = v.split("=");
- accu[vArray[0]] = vArray[1];
- return accu;
- }, {}) : {};
- // console.log("url", url, "path", path, "queryObject", queryObject);
- // Get route by path:
- CurrentRoute = routes[path];
- // Do we have a route ?
- if (CurrentRoute) {
- // Obtain the template context by passing the query to the controller.
- context = new CurrentRoute(query);
- // Render template with Handlebars
- templateName = (path === "/") ? "home" : path;
- if (ready) {
- console.log("Immediate render");
- render(contentElement, templateName, context);
- }
- else {
- 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 found but no route matching", path);
- }
- }
- // Bind router to browser events.
- window.addEventListener("hashchange", router);
- window.addEventListener("load", router);
- // Route declarations.
- route("/", function (q) {
- console.log("Home controller", q);
- });
- route("class", function (q) {
- console.log("Class controller", q);
- this.greeting = "Hello world!";
- this.moreText = "Bacon ipsum...";
- });
- route("species", function (q) {
- console.log("Species controller", q);
- this.heading = "I\"m page two!";
- });
|