lib/routes.js.coffee in js-routes-1.1.2 vs lib/routes.js.coffee in js-routes-1.2.0
- old
+ new
@@ -11,10 +11,18 @@
prefix: "PREFIX"
default_url_options: DEFAULT_URL_OPTIONS
NodeTypes = NODE_TYPES
+ReservedOptions = [
+ 'anchor'
+ 'trailing_slash'
+ 'host'
+ 'port'
+ 'protocol'
+]
+
Utils =
default_serializer: (object, prefix = null) ->
return "" unless object?
if !prefix and !(@get_object_type(object) is "object")
@@ -51,38 +59,18 @@
path = path.split("://")
last_index = path.length - 1
path[last_index] = path[last_index].replace(/\/+/g, "/")
path.join "://"
- set_default_url_options: (optional_parts, options) ->
- for part, i in optional_parts when (not options.hasOwnProperty(part) and defaults.default_url_options.hasOwnProperty(part))
- options[part] = defaults.default_url_options[part]
-
- extract_anchor: (options) ->
- anchor = ""
- if options.hasOwnProperty("anchor")
- anchor = "##{options.anchor}"
- delete options.anchor
- anchor
-
- extract_trailing_slash: (options) ->
- trailing_slash = false
- if defaults.default_url_options.hasOwnProperty("trailing_slash")
- trailing_slash = defaults.default_url_options.trailing_slash
- if options.hasOwnProperty("trailing_slash")
- trailing_slash = options.trailing_slash
- delete options.trailing_slash
- trailing_slash
-
extract_options: (number_of_params, args) ->
last_el = args[args.length - 1]
- if args.length > number_of_params or (last_el? and "object" is @get_object_type(last_el) and !@look_like_serialized_model(last_el))
- args.pop()
+ if (args.length > number_of_params and last_el == undefined) or(last_el? and "object" is @get_object_type(last_el) and !@looks_like_serialized_model(last_el))
+ args.pop() || {}
else
{}
- look_like_serialized_model: (object) ->
+ looks_like_serialized_model: (object) ->
# consider object a model if it have a path identifier properties like id and to_param
"id" of object or "to_param" of object
path_identifier: (object) ->
@@ -105,37 +93,51 @@
return obj if !obj? or "object" isnt @get_object_type(obj)
copy = obj.constructor()
copy[key] = attr for own key, attr of obj
copy
- prepare_parameters: (required_parameters, actual_parameters, options) ->
- result = @clone(options) or {}
- for val, i in required_parameters when i < actual_parameters.length
- result[val] = actual_parameters[i]
+ merge: (xs...) ->
+ tap = (o, fn) -> fn(o); o
+ if xs?.length > 0
+ tap {}, (m) -> m[k] = v for k, v of x for x in xs
+
+ normalize_options: (url_defaults, required_parameters, optional_parts, actual_parameters) ->
+ options = @extract_options(required_parameters.length, actual_parameters)
+ if actual_parameters.length > required_parameters.length
+ throw new Error("Too many parameters provided for path")
+ options = @merge(defaults.default_url_options, url_defaults, options)
+ result = {}
+ url_parameters = {}
+ result['url_parameters'] = url_parameters
+ for own key, value of options
+ if ReservedOptions.indexOf(key) >= 0
+ result[key] = value
+ else
+ url_parameters[key] = value
+
+ for value, i in required_parameters when i < actual_parameters.length
+ url_parameters[value] = actual_parameters[i]
result
- build_path: (required_parameters, optional_parts, route, args) ->
+ build_route: (required_parameters, optional_parts, route, url_defaults, args) ->
args = Array::slice.call(args)
- opts = @extract_options(required_parameters.length, args)
- if args.length > required_parameters.length
- throw new Error("Too many parameters provided for path")
- parameters = @prepare_parameters(required_parameters, args, opts)
- @set_default_url_options optional_parts, parameters
- # options
- anchor = @extract_anchor(parameters)
- trailing_slash = @extract_trailing_slash(parameters)
+ options = @normalize_options(url_defaults, required_parameters, optional_parts, args)
+ parameters = options['url_parameters']
+
# path
result = "#{@get_prefix()}#{@visit(route, parameters)}"
url = Utils.clean_path("#{result}")
# set trailing_slash
- url = url.replace(/(.*?)[\/]?$/, "$1/") if trailing_slash is true
+ url = url.replace(/(.*?)[\/]?$/, "$1/") if options['trailing_slash'] is true
# set additional url params
if (url_params = @serialize(parameters)).length
url += "?#{url_params}"
# set anchor
- url += anchor
+ url += if options.anchor then "##{options.anchor}" else ""
+ if url_defaults
+ url = @route_url(options) + url
url
#
# This function is JavaScript impelementation of the
# Journey::Visitors::Formatter that builds route by given parameters
@@ -227,14 +229,45 @@
prefix
#
# route function: create route path function and add spec to it
#
- route: (required_parts, optional_parts, route_spec) ->
- path_fn = -> Utils.build_path(required_parts, optional_parts, route_spec, arguments)
+ route: (required_parts, optional_parts, route_spec, url_defaults) ->
+ path_fn = ->
+ Utils.build_route(required_parts, optional_parts, route_spec, url_defaults, arguments)
path_fn.required_params = required_parts
path_fn.toString = -> Utils.build_path_spec(route_spec)
path_fn
+
+
+ route_url: (route_defaults) ->
+ return route_defaults if typeof route_defaults == 'string'
+ protocol = route_defaults.protocol || Utils.current_protocol()
+ hostname = route_defaults.host || window.location.hostname
+ port = route_defaults.port || (Utils.current_port() unless route_defaults.host)
+ port = if port then ":#{port}" else ''
+
+ protocol + "://" + hostname + port
+
+
+ has_location: ->
+ typeof window != 'undefined' && typeof window.location != 'undefined'
+
+ current_host: ->
+ @has_location() && window.location.hostname
+
+ current_protocol: () ->
+ if @has_location() && window.location.protocol != ''
+ # location.protocol includes the colon character
+ window.location.protocol.replace(/:$/, '')
+ else
+ 'http'
+
+ current_port: () ->
+ if @has_location() && window.location.port != ''
+ window.location.port
+ else
+ ''
#
# This is helper method to define object type.
# The typeof operator is probably the biggest design flaw of JavaScript, simply because it's basically completely broken.
#