app/assets/javascripts/joosy/core/router.js.coffee in joosy-0.1.0.RC2 vs app/assets/javascripts/joosy/core/router.js.coffee in joosy-0.1.0.RC3

- old
+ new

@@ -1,58 +1,124 @@ #= require joosy/core/joosy +# +# Router. Reacts on a hash change event and loads proper pages +# +# Example: +# Joosy.Router.map +# 404 : (path) -> alert "Page '#{path}' was not found :(" +# '/' : Welcome.IndexPage +# '/resources' : +# '/' : Resource.IndexPage +# '/:id' : Resource.ShowPage +# '/:id/edit' : Resource.EditPage +# '/new' : Resource.EditPage +# +# @module +# Joosy.Router = + # + # The Object containing route parts in keys and pages/lambdas in values + # rawRoutes: Object.extended() + + # + # Flattern routes mapped to regexps (to check if current route is what we + # need) and actual executors + # routes: Object.extended() + # + # Clears the routes + # reset: -> @rawRoutes = Object.extended() @routes = Object.extended() + # + # Registers the set of raw routes + # This method will only store routes and will not make them act immediately + # Routes get registered only once at system initialization during #__setupRoutes call + # + # @param [Object] routes Set of routes in inner format (see class description) + # map: (routes) -> Joosy.Module.merge @rawRoutes, routes - setupRoutes: -> - @prepareRoutes @rawRoutes - @respondRoute location.hash + # + # Changes current hash with shebang (#!) and therefore triggers new route loading + # to be loaded + # + # @param [String] to Route to navigate to + # + navigate: (to) -> + location.hash = '!' + to + + # + # Inits the routing system and loads the current route + # Binds the window hashchange event and therefore should only be called once + # during system startup + # + __setupRoutes: -> + @__prepareRoutes @rawRoutes + @__respondRoute location.hash $(window).hashchange => - @respondRoute location.hash + @__respondRoute location.hash - prepareRoutes: (routes, namespace='') -> + # + # Compiles routes to map object + # Object will contain regexp string as key and lambda/Page to load as value + # + # @param [Object] routes Raw routes to prepare + # @param [String] namespace Inner cursor for recursion + # + __prepareRoutes: (routes, namespace='') -> if !namespace && routes[404] @wildcardAction = routes[404] delete routes[404] Object.each routes, (path, response) => path = (namespace + path).replace /\/{2,}/, '/' if response && (Object.isFunction(response) || response.prototype?) - Joosy.Module.merge @routes, @prepareRoute(path, response) + Joosy.Module.merge @routes, @__prepareRoute(path, response) else - @prepareRoutes response, path + @__prepareRoutes response, path - prepareRoute: (path, response) -> + # + # Compiles one single route + # + # @param [String] path Full path from raw route + # @param [Joosy.Page] response Page that should be loaded at this route + # @param [Function] response Lambda to call at this route + # + __prepareRoute: (path, response) -> matchPath = path.replace(/\/:([^\/]+)/g, '/([^/]+)').replace(/^\/?/, '^/?').replace(/\/?$/, '/?$') result = Object.extended() result[matchPath] = capture: (path.match(/\/:[^\/]+/g) || []).map (str) -> str.substr 2 action: response result - respondRoute: (hash) -> + # + # Searches the corresponding route through compiled routes + # + # @param [String] hash Hash value to search route for + # + __respondRoute: (hash) -> Joosy.Modules.Log.debug "Router> Answering '#{hash}'" fullPath = hash.replace /^#!?/, '' @currentPath = fullPath found = false queryArray = fullPath.split '&' path = queryArray.shift() - urlParams = @paramsFromQueryArray queryArray + urlParams = @__paramsFromQueryArray queryArray for regex, route of @routes when @routes.hasOwnProperty regex if vals = path.match new RegExp(regex) - params = @paramsFromRouteMatch(vals, route).merge urlParams + params = @__paramsFromRouteMatch(vals, route).merge urlParams if Joosy.Module.hasAncestor route.action, Joosy.Page Joosy.Application.setCurrentPage route.action, params else route.action.call this, params @@ -61,27 +127,37 @@ break if !found && @wildcardAction? @wildcardAction path, urlParams - paramsFromRouteMatch: (vals, route) -> + # + # Collects params from route placeholders (/foo/:placeholder) + # + # @param [Array] vals Array of value gathered by regexp + # @param [Object] route Compiled route + # @returns [Object] Hash of params + # + __paramsFromRouteMatch: (vals, route) -> params = Object.extended() vals.shift() for param in route.capture params[param] = vals.shift() params - paramsFromQueryArray: (queryArray) -> + # + # Collects params from query routes (/foo/&a=b) + # + # @param [Array] queryArray Array of query string split by '&' sign + # @returns [Object] Hash of params + # + __paramsFromQueryArray: (queryArray) -> params = Object.extended() if queryArray $.each queryArray, -> unless @isBlank() pair = @split '=' params[pair[0]] = pair[1] - params - - navigate: (to) -> - location.hash = '!' + to + params \ No newline at end of file