o_O.routes = { rules: {}, urls: [], regex_urls: [], figure_action: function(options){ var parts = options.to.split('#'); var controller = parts[0]; var action = parts[1]; controller = controller.capitalize() + "Controller"; return window[controller][action]; }, router: function(prefix){ return { root: function(options){ o_O.routes.rules['root'] = {"action": o_O.routes.figure_action(options)} }, namespace: function(prefix, callback){ callback(o_O.routes.router(prefix)); }, resources: function(name){ this.match(name, {to:name + '#index'}); this.match(name + '/new', {to:name + '#add'}); this.match(name + '/:id/edit', {to:name + '#edit'}); this.match(name + '/:id', {to:name + '#show'}); }, match: function(route, options){ var parsed_route = route.o_O_trim('/') if(typeof prefix != 'undefined') { parsed_route = prefix + '/' + parsed_route } if(parsed_route.indexOf(':') >= 0) { var regex_to_match = parsed_route.replace(/:[^\/]*/g, '([^\/]*)'); o_O.routes.rules[parsed_route] = { action: o_O.routes.figure_action(options), matchers: parsed_route.match(/:[^\/]*/g) }; o_O.routes.regex_urls.push({regex: regex_to_match, matcher:parsed_route}); } else { o_O.routes.rules[parsed_route] = { action: o_O.routes.figure_action(options), with_args: options.with_args }; o_O.routes.urls.push(parsed_route); } } } }, draw: function(callback){ $(function(){ callback(o_O.routes.router()); var parts, hash, query_string_parts; var update_hash_parts = function(){ parts = location.hash.split('?') hash = parts[0].replace(/^(#)/, '').o_O_trim('/'); query_string_parts; if(typeof parts[1] === 'string') { query_string_parts = parts[1].replace('&', '&').split('&'); } else { query_string_parts = ''; } } var compute_params = function(rule){ return function(attr){ var params = {} if(rule) { for(j = 0; j < rule.matchers.length; j++) { params[rule.matchers[j].replace(/^:/, '')] = match[j+1]; } } if(query_string_parts.length > 0) { for(k = 0; k < query_string_parts.length; k++) { var param_parts = query_string_parts[k].split('=') params[param_parts[0]] = param_parts[1]; } } if(attr) { return params[attr]; } else { return params; } } } if(location.hash.o_O_trim() == '') { update_hash_parts() if(typeof o_O.routes.rules['root'] === 'object') { o_O.routes.rules['root'].action(compute_params()); } } var route_on_hash = function(){ update_hash_parts(); if(o_O.routes.urls.indexOf(hash) >= 0) { console.log(compute_params()()) o_O.routes.rules[hash].action(compute_params()); } else { for(i = 0; i < o_O.routes.regex_urls.length; i++) { if(match = hash.match(o_O.routes.regex_urls[i].regex)) { var rule = o_O.routes.rules[o_O.routes.regex_urls[i].matcher]; rule.action(compute_params(rule)); return; } } } } $(window).bind( 'hashchange', route_on_hash); $('a').live('click', function(){ if($(this).is('a[data-ajax-history=true]')) { document.location.hash = $(this).attr('href') return false; } }); if(location.hash != '') { route_on_hash(); } }) } }