js-routes 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/Readme.md +3 -3
- data/lib/js_routes.rb +31 -32
- data/lib/js_routes/version.rb +1 -1
- data/lib/routes.js +131 -69
- data/lib/routes.js.coffee +73 -40
- data/spec/js_routes/options_spec.rb +54 -11
- data/spec/spec_helper.rb +17 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e61c1a78d1a68a39e174a3459048f939ac1a5491
         | 
| 4 | 
            +
              data.tar.gz: 2690497a175312cb4fd282626eae3adf87718cbb
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 1698494469561e6a34ae36c1f38ae74da0b2a94ecb6e6a4531e25725021772e852f9d1d55f3be7eb9b373c00ad63d57ef67f909c6bbe4ed4dc843096bbc53250
         | 
| 7 | 
            +
              data.tar.gz: 04cc89d4715e92eb63c32ff6bd0498c1164d271cab2c976de65a3da3731a6f565691d169f3f1a8dfbf2c336ab6534ce4bdd60bf94cb848753a4082198ede0609
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,16 @@ | |
| 1 1 | 
             
            ## master
         | 
| 2 2 |  | 
| 3 | 
            +
            ## v1.2.0
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Support host, port and protocol inline parameters
         | 
| 6 | 
            +
            * Support host, port and protocol parameters given to a route explicitly
         | 
| 7 | 
            +
            * Remove all incompatibilities between actiondispatch and js-routes in handling route URLs
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            ## v1.1.2
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            * Bugfix support nested object null parameters #164
         | 
| 12 | 
            +
            * Bugfix support for nested optional parameters #162 #163
         | 
| 13 | 
            +
             | 
| 3 14 | 
             
            ## v1.1.1
         | 
| 4 15 |  | 
| 5 16 | 
             
            * Bugfix regression in serialisation on blank strings caused by [#155](https://github.com/railsware/js-routes/pull/155/files)
         | 
    
        data/Readme.md
    CHANGED
    
    | @@ -45,8 +45,7 @@ Available options: | |
| 45 45 |  | 
| 46 46 | 
             
            * `default_url_options` - default parameters used when generating URLs
         | 
| 47 47 | 
             
              * Note that only specific options are supported at this time.
         | 
| 48 | 
            -
              *  | 
| 49 | 
            -
              * Example: {:format => "json", :trailing_slash => true, :protocol => "https", :host => "example.com", :port => 3000}
         | 
| 48 | 
            +
              * Example: {:format => "json", :trailing\_slash => true, :protocol => "https", :host => "example.com", :port => 3000}
         | 
| 50 49 | 
             
              * Default: {}
         | 
| 51 50 | 
             
            * `exclude` - Array of regexps to exclude from js routes.
         | 
| 52 51 | 
             
              * Default: []
         | 
| @@ -65,7 +64,7 @@ Available options: | |
| 65 64 | 
             
            * `url_links` (version >= 0.8.9) - Generate `*_url` helpers (in addition to the default `*_path` helpers).
         | 
| 66 65 | 
             
              * Example: true
         | 
| 67 66 | 
             
              * Default: false
         | 
| 68 | 
            -
              *  | 
| 67 | 
            +
              * Note: generated URLs will first use the protocol, host, and port options specified in the route definition. Otherwise, the URL will be based on the option specified in the `default_url_options` config. If no default option has been set, then the URL will fallback to the current URL based on `window.location`.
         | 
| 69 68 | 
             
            * `compact` (version > 0.9.9) - Remove `_path` suffix in path routes(`*_url` routes stay untouched if they were enabled)
         | 
| 70 69 | 
             
              * Default: false
         | 
| 71 70 | 
             
              * Sample route call when option is set to true: Routes.users() => `/users`
         | 
| @@ -118,6 +117,7 @@ Configuration above will create a nice javascript file with `Routes` object that | |
| 118 117 | 
             
            Routes.users_path() // => "/users"
         | 
| 119 118 | 
             
            Routes.user_path(1) // => "/users/1"
         | 
| 120 119 | 
             
            Routes.user_path(1, {format: 'json'}) // => "/users/1.json"
         | 
| 120 | 
            +
            Routes.user_path(1, {anchor: 'profile'}) // => "/users/1#profile"
         | 
| 121 121 | 
             
            Routes.new_user_project_path(1, {format: 'json'}) // => "/users/1/projects/new.json"
         | 
| 122 122 | 
             
            Routes.user_project_path(1,2, {q: 'hello', custom: true}) // => "/users/1/projects/2?q=hello&custom=true"
         | 
| 123 123 | 
             
            Routes.user_project_path(1,2, {hello: ['world', 'mars']}) // => "/users/1/projects/2?hello%5B%5D=world&hello%5B%5D=mars"
         | 
    
        data/lib/js_routes.rb
    CHANGED
    
    | @@ -16,7 +16,7 @@ class JsRoutes | |
| 16 16 | 
             
                include: //,
         | 
| 17 17 | 
             
                file: DEFAULT_PATH,
         | 
| 18 18 | 
             
                prefix: nil,
         | 
| 19 | 
            -
                url_links:  | 
| 19 | 
            +
                url_links: false,
         | 
| 20 20 | 
             
                camel_case: false,
         | 
| 21 21 | 
             
                default_url_options: {},
         | 
| 22 22 | 
             
                compact: false,
         | 
| @@ -173,45 +173,44 @@ class JsRoutes | |
| 173 173 |  | 
| 174 174 | 
             
              def build_js(route, parent_route)
         | 
| 175 175 | 
             
                name = [parent_route.try(:name), route.name].compact
         | 
| 176 | 
            -
                parent_spec = parent_route.try(:path).try(:spec)
         | 
| 177 | 
            -
                required_parts, optional_parts = route.required_parts.clone, (route.parts-route.required_parts)
         | 
| 178 | 
            -
                optional_parts.push(required_parts.delete :format) if required_parts.include?(:format)
         | 
| 179 176 | 
             
                route_name = generate_route_name(name, (:path unless @options[:compact]))
         | 
| 180 | 
            -
                 | 
| 177 | 
            +
                parent_spec = parent_route.try(:path).try(:spec)
         | 
| 178 | 
            +
                route_arguments = route_js_arguments(route, parent_spec)
         | 
| 179 | 
            +
                url_link = generate_url_link(name, route_name, route_arguments, route)
         | 
| 181 180 | 
             
                _ = <<-JS.strip!
         | 
| 182 181 | 
             
              // #{name.join('.')} => #{parent_spec}#{route.path.spec}
         | 
| 183 | 
            -
              // function(#{ | 
| 184 | 
            -
              #{route_name}: Utils.route(#{ | 
| 182 | 
            +
              // function(#{build_params(route.required_parts, true)})
         | 
| 183 | 
            +
              #{route_name}: Utils.route(#{route_arguments})#{",\n" + url_link if url_link.length > 0}
         | 
| 185 184 | 
             
              JS
         | 
| 186 185 | 
             
              end
         | 
| 187 186 |  | 
| 188 | 
            -
              def  | 
| 187 | 
            +
              def route_js_arguments(route, parent_spec)
         | 
| 188 | 
            +
                required_parts, optional_parts = route.required_parts.clone, (route.parts-route.required_parts)
         | 
| 189 | 
            +
                optional_parts.push(required_parts.delete :format) if required_parts.include?(:format)
         | 
| 190 | 
            +
                [json(required_parts), json(optional_parts), json(serialize(route.path.spec, parent_spec))].join(", ")
         | 
| 191 | 
            +
              end
         | 
| 192 | 
            +
             | 
| 193 | 
            +
              def generate_url_link(name, route_name, route_arguments, route)
         | 
| 189 194 | 
             
                return "" unless @options[:url_links]
         | 
| 190 | 
            -
                 | 
| 191 | 
            -
                 | 
| 192 | 
            -
                 | 
| 193 | 
            -
                }
         | 
| 195 | 
            +
                defaults = @options[:url_links] == true ? route.defaults.slice(:host, :port, :protocol) : deprecated_base_url
         | 
| 196 | 
            +
                <<-JS.strip!
         | 
| 197 | 
            +
                #{generate_route_name(name, :url)}: Utils.route(#{route_arguments}, #{json(defaults)})
         | 
| 194 198 | 
             
                JS
         | 
| 195 199 | 
             
              end
         | 
| 196 200 |  | 
| 197 | 
            -
              def  | 
| 198 | 
            -
                 | 
| 199 | 
            -
             | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 202 | 
            -
             | 
| 203 | 
            -
                 | 
| 204 | 
            -
             | 
| 205 | 
            -
             | 
| 206 | 
            -
                   | 
| 207 | 
            -
                  port  | 
| 208 | 
            -
             | 
| 209 | 
            -
             | 
| 210 | 
            -
                    raise "A :default_url_options[:host] must be configured in order to generate *_url helpers"
         | 
| 211 | 
            -
                  end
         | 
| 212 | 
            -
             | 
| 213 | 
            -
                  return %Q|'#{protocol}://#{hostname}#{port}'|
         | 
| 214 | 
            -
                end
         | 
| 201 | 
            +
              def deprecated_base_url
         | 
| 202 | 
            +
                ActiveSupport::Deprecation.warn('js-routes url_links config value must be a boolean. Use default_url_options for specifying a default host.')
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                
         | 
| 205 | 
            +
                raise "invalid URL format in url_links (ex: http[s]://example.com)" if @options[:url_links].match(URI::Parser.new.make_regexp(%w(http https))).nil?
         | 
| 206 | 
            +
                uri = URI.parse(@options[:url_links])
         | 
| 207 | 
            +
                default_port = uri.scheme == "https" ? 443 : 80
         | 
| 208 | 
            +
                port = uri.port == default_port ? nil : uri.port
         | 
| 209 | 
            +
                {
         | 
| 210 | 
            +
                  host: uri.host,
         | 
| 211 | 
            +
                  port: port,
         | 
| 212 | 
            +
                  protocol: uri.scheme,
         | 
| 213 | 
            +
                }
         | 
| 215 214 | 
             
              end
         | 
| 216 215 |  | 
| 217 216 | 
             
              def generate_route_name(name, suffix)
         | 
| @@ -224,11 +223,11 @@ class JsRoutes | |
| 224 223 | 
             
                self.class.json(string)
         | 
| 225 224 | 
             
              end
         | 
| 226 225 |  | 
| 227 | 
            -
              def build_params(required_parts)
         | 
| 226 | 
            +
              def build_params(required_parts, unprotected = false)
         | 
| 228 227 | 
             
                params = required_parts.map do |name|
         | 
| 229 228 | 
             
                  # prepending each parameter name with underscore
         | 
| 230 229 | 
             
                  # to prevent conflict with JS reserved words
         | 
| 231 | 
            -
                  "_#{name}"
         | 
| 230 | 
            +
                  unprotected ? name : "_#{name}"
         | 
| 232 231 | 
             
                end << LAST_OPTIONS_KEY
         | 
| 233 232 | 
             
                params.join(", ")
         | 
| 234 233 | 
             
              end
         | 
    
        data/lib/js_routes/version.rb
    CHANGED
    
    
    
        data/lib/routes.js
    CHANGED
    
    | @@ -1,11 +1,13 @@ | |
| 1 1 | 
             
            /*
         | 
| 2 2 | 
             
            File generated by js-routes GEM_VERSION
         | 
| 3 3 | 
             
            Based on Rails routes of APP_CLASS
         | 
| 4 | 
            -
             | 
| 4 | 
            +
            */
         | 
| 5 | 
            +
             | 
| 5 6 |  | 
| 6 7 | 
             
            (function() {
         | 
| 7 | 
            -
              var NodeTypes, ParameterMissing, Utils, createGlobalJsRoutesObject, defaults, root,
         | 
| 8 | 
            -
                 | 
| 8 | 
            +
              var NodeTypes, ParameterMissing, ReservedOptions, Utils, createGlobalJsRoutesObject, defaults, root,
         | 
| 9 | 
            +
                __hasProp = {}.hasOwnProperty,
         | 
| 10 | 
            +
                __slice = [].slice;
         | 
| 9 11 |  | 
| 10 12 | 
             
              root = typeof exports !== "undefined" && exports !== null ? exports : this;
         | 
| 11 13 |  | 
| @@ -22,9 +24,12 @@ Based on Rails routes of APP_CLASS | |
| 22 24 |  | 
| 23 25 | 
             
              NodeTypes = NODE_TYPES;
         | 
| 24 26 |  | 
| 27 | 
            +
              ReservedOptions = ['anchor', 'trailing_slash', 'host', 'port', 'protocol'];
         | 
| 28 | 
            +
             | 
| 25 29 | 
             
              Utils = {
         | 
| 26 30 | 
             
                default_serializer: function(object, prefix) {
         | 
| 27 | 
            -
                  var element, i,  | 
| 31 | 
            +
                  var element, i, key, prop, s, _i, _len;
         | 
| 32 | 
            +
             | 
| 28 33 | 
             
                  if (prefix == null) {
         | 
| 29 34 | 
             
                    prefix = null;
         | 
| 30 35 | 
             
                  }
         | 
| @@ -37,21 +42,21 @@ Based on Rails routes of APP_CLASS | |
| 37 42 | 
             
                  s = [];
         | 
| 38 43 | 
             
                  switch (this.get_object_type(object)) {
         | 
| 39 44 | 
             
                    case "array":
         | 
| 40 | 
            -
                      for (i =  | 
| 45 | 
            +
                      for (i = _i = 0, _len = object.length; _i < _len; i = ++_i) {
         | 
| 41 46 | 
             
                        element = object[i];
         | 
| 42 47 | 
             
                        s.push(this.default_serializer(element, prefix + "[]"));
         | 
| 43 48 | 
             
                      }
         | 
| 44 49 | 
             
                      break;
         | 
| 45 50 | 
             
                    case "object":
         | 
| 46 51 | 
             
                      for (key in object) {
         | 
| 47 | 
            -
                        if (! | 
| 52 | 
            +
                        if (!__hasProp.call(object, key)) continue;
         | 
| 48 53 | 
             
                        prop = object[key];
         | 
| 49 54 | 
             
                        if ((prop == null) && (prefix != null)) {
         | 
| 50 55 | 
             
                          prop = "";
         | 
| 51 56 | 
             
                        }
         | 
| 52 57 | 
             
                        if (prop != null) {
         | 
| 53 58 | 
             
                          if (prefix != null) {
         | 
| 54 | 
            -
                            key = prefix + "[" + key + "]";
         | 
| 59 | 
            +
                            key = "" + prefix + "[" + key + "]";
         | 
| 55 60 | 
             
                          }
         | 
| 56 61 | 
             
                          s.push(this.default_serializer(prop, key));
         | 
| 57 62 | 
             
                        }
         | 
| @@ -59,7 +64,7 @@ Based on Rails routes of APP_CLASS | |
| 59 64 | 
             
                      break;
         | 
| 60 65 | 
             
                    default:
         | 
| 61 66 | 
             
                      if (object != null) {
         | 
| 62 | 
            -
                        s.push((encodeURIComponent(prefix.toString())) + "=" + (encodeURIComponent(object.toString())));
         | 
| 67 | 
            +
                        s.push("" + (encodeURIComponent(prefix.toString())) + "=" + (encodeURIComponent(object.toString())));
         | 
| 63 68 | 
             
                      }
         | 
| 64 69 | 
             
                  }
         | 
| 65 70 | 
             
                  if (!s.length) {
         | 
| @@ -77,57 +82,28 @@ Based on Rails routes of APP_CLASS | |
| 77 82 | 
             
                },
         | 
| 78 83 | 
             
                clean_path: function(path) {
         | 
| 79 84 | 
             
                  var last_index;
         | 
| 85 | 
            +
             | 
| 80 86 | 
             
                  path = path.split("://");
         | 
| 81 87 | 
             
                  last_index = path.length - 1;
         | 
| 82 88 | 
             
                  path[last_index] = path[last_index].replace(/\/+/g, "/");
         | 
| 83 89 | 
             
                  return path.join("://");
         | 
| 84 90 | 
             
                },
         | 
| 85 | 
            -
                set_default_url_options: function(optional_parts, options) {
         | 
| 86 | 
            -
                  var i, j, len, part, results;
         | 
| 87 | 
            -
                  results = [];
         | 
| 88 | 
            -
                  for (i = j = 0, len = optional_parts.length; j < len; i = ++j) {
         | 
| 89 | 
            -
                    part = optional_parts[i];
         | 
| 90 | 
            -
                    if (!options.hasOwnProperty(part) && defaults.default_url_options.hasOwnProperty(part)) {
         | 
| 91 | 
            -
                      results.push(options[part] = defaults.default_url_options[part]);
         | 
| 92 | 
            -
                    }
         | 
| 93 | 
            -
                  }
         | 
| 94 | 
            -
                  return results;
         | 
| 95 | 
            -
                },
         | 
| 96 | 
            -
                extract_anchor: function(options) {
         | 
| 97 | 
            -
                  var anchor;
         | 
| 98 | 
            -
                  anchor = "";
         | 
| 99 | 
            -
                  if (options.hasOwnProperty("anchor")) {
         | 
| 100 | 
            -
                    anchor = "#" + options.anchor;
         | 
| 101 | 
            -
                    delete options.anchor;
         | 
| 102 | 
            -
                  }
         | 
| 103 | 
            -
                  return anchor;
         | 
| 104 | 
            -
                },
         | 
| 105 | 
            -
                extract_trailing_slash: function(options) {
         | 
| 106 | 
            -
                  var trailing_slash;
         | 
| 107 | 
            -
                  trailing_slash = false;
         | 
| 108 | 
            -
                  if (defaults.default_url_options.hasOwnProperty("trailing_slash")) {
         | 
| 109 | 
            -
                    trailing_slash = defaults.default_url_options.trailing_slash;
         | 
| 110 | 
            -
                  }
         | 
| 111 | 
            -
                  if (options.hasOwnProperty("trailing_slash")) {
         | 
| 112 | 
            -
                    trailing_slash = options.trailing_slash;
         | 
| 113 | 
            -
                    delete options.trailing_slash;
         | 
| 114 | 
            -
                  }
         | 
| 115 | 
            -
                  return trailing_slash;
         | 
| 116 | 
            -
                },
         | 
| 117 91 | 
             
                extract_options: function(number_of_params, args) {
         | 
| 118 92 | 
             
                  var last_el;
         | 
| 93 | 
            +
             | 
| 119 94 | 
             
                  last_el = args[args.length - 1];
         | 
| 120 | 
            -
                  if (args.length > number_of_params || ((last_el != null) && "object" === this.get_object_type(last_el) && !this. | 
| 121 | 
            -
                    return args.pop();
         | 
| 95 | 
            +
                  if ((args.length > number_of_params && last_el === void 0) || ((last_el != null) && "object" === this.get_object_type(last_el) && !this.looks_like_serialized_model(last_el))) {
         | 
| 96 | 
            +
                    return args.pop() || {};
         | 
| 122 97 | 
             
                  } else {
         | 
| 123 98 | 
             
                    return {};
         | 
| 124 99 | 
             
                  }
         | 
| 125 100 | 
             
                },
         | 
| 126 | 
            -
                 | 
| 101 | 
            +
                looks_like_serialized_model: function(object) {
         | 
| 127 102 | 
             
                  return "id" in object || "to_param" in object;
         | 
| 128 103 | 
             
                },
         | 
| 129 104 | 
             
                path_identifier: function(object) {
         | 
| 130 105 | 
             
                  var property;
         | 
| 106 | 
            +
             | 
| 131 107 | 
             
                  if (object === 0) {
         | 
| 132 108 | 
             
                    return "0";
         | 
| 133 109 | 
             
                  }
         | 
| @@ -151,52 +127,99 @@ Based on Rails routes of APP_CLASS | |
| 151 127 | 
             
                },
         | 
| 152 128 | 
             
                clone: function(obj) {
         | 
| 153 129 | 
             
                  var attr, copy, key;
         | 
| 130 | 
            +
             | 
| 154 131 | 
             
                  if ((obj == null) || "object" !== this.get_object_type(obj)) {
         | 
| 155 132 | 
             
                    return obj;
         | 
| 156 133 | 
             
                  }
         | 
| 157 134 | 
             
                  copy = obj.constructor();
         | 
| 158 135 | 
             
                  for (key in obj) {
         | 
| 159 | 
            -
                    if (! | 
| 136 | 
            +
                    if (!__hasProp.call(obj, key)) continue;
         | 
| 160 137 | 
             
                    attr = obj[key];
         | 
| 161 138 | 
             
                    copy[key] = attr;
         | 
| 162 139 | 
             
                  }
         | 
| 163 140 | 
             
                  return copy;
         | 
| 164 141 | 
             
                },
         | 
| 165 | 
            -
                 | 
| 166 | 
            -
                  var  | 
| 167 | 
            -
             | 
| 168 | 
            -
                   | 
| 169 | 
            -
             | 
| 142 | 
            +
                merge: function() {
         | 
| 143 | 
            +
                  var tap, xs;
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                  xs = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
         | 
| 146 | 
            +
                  tap = function(o, fn) {
         | 
| 147 | 
            +
                    fn(o);
         | 
| 148 | 
            +
                    return o;
         | 
| 149 | 
            +
                  };
         | 
| 150 | 
            +
                  if ((xs != null ? xs.length : void 0) > 0) {
         | 
| 151 | 
            +
                    return tap({}, function(m) {
         | 
| 152 | 
            +
                      var k, v, x, _i, _len, _results;
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                      _results = [];
         | 
| 155 | 
            +
                      for (_i = 0, _len = xs.length; _i < _len; _i++) {
         | 
| 156 | 
            +
                        x = xs[_i];
         | 
| 157 | 
            +
                        _results.push((function() {
         | 
| 158 | 
            +
                          var _results1;
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                          _results1 = [];
         | 
| 161 | 
            +
                          for (k in x) {
         | 
| 162 | 
            +
                            v = x[k];
         | 
| 163 | 
            +
                            _results1.push(m[k] = v);
         | 
| 164 | 
            +
                          }
         | 
| 165 | 
            +
                          return _results1;
         | 
| 166 | 
            +
                        })());
         | 
| 167 | 
            +
                      }
         | 
| 168 | 
            +
                      return _results;
         | 
| 169 | 
            +
                    });
         | 
| 170 | 
            +
                  }
         | 
| 171 | 
            +
                },
         | 
| 172 | 
            +
                normalize_options: function(url_defaults, required_parameters, optional_parts, actual_parameters) {
         | 
| 173 | 
            +
                  var i, key, options, result, url_parameters, value, _i, _len;
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                  options = this.extract_options(required_parameters.length, actual_parameters);
         | 
| 176 | 
            +
                  if (actual_parameters.length > required_parameters.length) {
         | 
| 177 | 
            +
                    throw new Error("Too many parameters provided for path");
         | 
| 178 | 
            +
                  }
         | 
| 179 | 
            +
                  options = this.merge(defaults.default_url_options, url_defaults, options);
         | 
| 180 | 
            +
                  result = {};
         | 
| 181 | 
            +
                  url_parameters = {};
         | 
| 182 | 
            +
                  result['url_parameters'] = url_parameters;
         | 
| 183 | 
            +
                  for (key in options) {
         | 
| 184 | 
            +
                    if (!__hasProp.call(options, key)) continue;
         | 
| 185 | 
            +
                    value = options[key];
         | 
| 186 | 
            +
                    if (ReservedOptions.indexOf(key) >= 0) {
         | 
| 187 | 
            +
                      result[key] = value;
         | 
| 188 | 
            +
                    } else {
         | 
| 189 | 
            +
                      url_parameters[key] = value;
         | 
| 190 | 
            +
                    }
         | 
| 191 | 
            +
                  }
         | 
| 192 | 
            +
                  for (i = _i = 0, _len = required_parameters.length; _i < _len; i = ++_i) {
         | 
| 193 | 
            +
                    value = required_parameters[i];
         | 
| 170 194 | 
             
                    if (i < actual_parameters.length) {
         | 
| 171 | 
            -
                       | 
| 195 | 
            +
                      url_parameters[value] = actual_parameters[i];
         | 
| 172 196 | 
             
                    }
         | 
| 173 197 | 
             
                  }
         | 
| 174 198 | 
             
                  return result;
         | 
| 175 199 | 
             
                },
         | 
| 176 | 
            -
                 | 
| 177 | 
            -
                  var  | 
| 200 | 
            +
                build_route: function(required_parameters, optional_parts, route, url_defaults, args) {
         | 
| 201 | 
            +
                  var options, parameters, result, url, url_params;
         | 
| 202 | 
            +
             | 
| 178 203 | 
             
                  args = Array.prototype.slice.call(args);
         | 
| 179 | 
            -
                   | 
| 180 | 
            -
                   | 
| 181 | 
            -
                    throw new Error("Too many parameters provided for path");
         | 
| 182 | 
            -
                  }
         | 
| 183 | 
            -
                  parameters = this.prepare_parameters(required_parameters, args, opts);
         | 
| 184 | 
            -
                  this.set_default_url_options(optional_parts, parameters);
         | 
| 185 | 
            -
                  anchor = this.extract_anchor(parameters);
         | 
| 186 | 
            -
                  trailing_slash = this.extract_trailing_slash(parameters);
         | 
| 204 | 
            +
                  options = this.normalize_options(url_defaults, required_parameters, optional_parts, args);
         | 
| 205 | 
            +
                  parameters = options['url_parameters'];
         | 
| 187 206 | 
             
                  result = "" + (this.get_prefix()) + (this.visit(route, parameters));
         | 
| 188 207 | 
             
                  url = Utils.clean_path("" + result);
         | 
| 189 | 
            -
                  if (trailing_slash === true) {
         | 
| 208 | 
            +
                  if (options['trailing_slash'] === true) {
         | 
| 190 209 | 
             
                    url = url.replace(/(.*?)[\/]?$/, "$1/");
         | 
| 191 210 | 
             
                  }
         | 
| 192 211 | 
             
                  if ((url_params = this.serialize(parameters)).length) {
         | 
| 193 212 | 
             
                    url += "?" + url_params;
         | 
| 194 213 | 
             
                  }
         | 
| 195 | 
            -
                  url += anchor;
         | 
| 214 | 
            +
                  url += options.anchor ? "#" + options.anchor : "";
         | 
| 215 | 
            +
                  if (url_defaults) {
         | 
| 216 | 
            +
                    url = this.route_url(options) + url;
         | 
| 217 | 
            +
                  }
         | 
| 196 218 | 
             
                  return url;
         | 
| 197 219 | 
             
                },
         | 
| 198 220 | 
             
                visit: function(route, parameters, optional) {
         | 
| 199 221 | 
             
                  var left, left_part, right, right_part, type, value;
         | 
| 222 | 
            +
             | 
| 200 223 | 
             
                  if (optional == null) {
         | 
| 201 224 | 
             
                    optional = false;
         | 
| 202 225 | 
             
                  }
         | 
| @@ -235,6 +258,7 @@ Based on Rails routes of APP_CLASS | |
| 235 258 | 
             
                },
         | 
| 236 259 | 
             
                build_path_spec: function(route, wildcard) {
         | 
| 237 260 | 
             
                  var left, right, type;
         | 
| 261 | 
            +
             | 
| 238 262 | 
             
                  if (wildcard == null) {
         | 
| 239 263 | 
             
                    wildcard = false;
         | 
| 240 264 | 
             
                  }
         | 
| @@ -263,6 +287,7 @@ Based on Rails routes of APP_CLASS | |
| 263 287 | 
             
                },
         | 
| 264 288 | 
             
                visit_globbing: function(route, parameters, optional) {
         | 
| 265 289 | 
             
                  var left, right, type, value;
         | 
| 290 | 
            +
             | 
| 266 291 | 
             
                  type = route[0], left = route[1], right = route[2];
         | 
| 267 292 | 
             
                  if (left.replace(/^\*/i, "") !== left) {
         | 
| 268 293 | 
             
                    route[1] = left = left.replace(/^\*/i, "");
         | 
| @@ -283,16 +308,18 @@ Based on Rails routes of APP_CLASS | |
| 283 308 | 
             
                },
         | 
| 284 309 | 
             
                get_prefix: function() {
         | 
| 285 310 | 
             
                  var prefix;
         | 
| 311 | 
            +
             | 
| 286 312 | 
             
                  prefix = defaults.prefix;
         | 
| 287 313 | 
             
                  if (prefix !== "") {
         | 
| 288 | 
            -
                    prefix = (prefix.match("/$") ? prefix : prefix + "/");
         | 
| 314 | 
            +
                    prefix = (prefix.match("/$") ? prefix : "" + prefix + "/");
         | 
| 289 315 | 
             
                  }
         | 
| 290 316 | 
             
                  return prefix;
         | 
| 291 317 | 
             
                },
         | 
| 292 | 
            -
                route: function(required_parts, optional_parts, route_spec) {
         | 
| 318 | 
            +
                route: function(required_parts, optional_parts, route_spec, url_defaults) {
         | 
| 293 319 | 
             
                  var path_fn;
         | 
| 320 | 
            +
             | 
| 294 321 | 
             
                  path_fn = function() {
         | 
| 295 | 
            -
                    return Utils. | 
| 322 | 
            +
                    return Utils.build_route(required_parts, optional_parts, route_spec, url_defaults, arguments);
         | 
| 296 323 | 
             
                  };
         | 
| 297 324 | 
             
                  path_fn.required_params = required_parts;
         | 
| 298 325 | 
             
                  path_fn.toString = function() {
         | 
| @@ -300,16 +327,49 @@ Based on Rails routes of APP_CLASS | |
| 300 327 | 
             
                  };
         | 
| 301 328 | 
             
                  return path_fn;
         | 
| 302 329 | 
             
                },
         | 
| 330 | 
            +
                route_url: function(route_defaults) {
         | 
| 331 | 
            +
                  var hostname, port, protocol;
         | 
| 332 | 
            +
             | 
| 333 | 
            +
                  if (typeof route_defaults === 'string') {
         | 
| 334 | 
            +
                    return route_defaults;
         | 
| 335 | 
            +
                  }
         | 
| 336 | 
            +
                  protocol = route_defaults.protocol || Utils.current_protocol();
         | 
| 337 | 
            +
                  hostname = route_defaults.host || window.location.hostname;
         | 
| 338 | 
            +
                  port = route_defaults.port || (!route_defaults.host ? Utils.current_port() : void 0);
         | 
| 339 | 
            +
                  port = port ? ":" + port : '';
         | 
| 340 | 
            +
                  return protocol + "://" + hostname + port;
         | 
| 341 | 
            +
                },
         | 
| 342 | 
            +
                has_location: function() {
         | 
| 343 | 
            +
                  return typeof window !== 'undefined' && typeof window.location !== 'undefined';
         | 
| 344 | 
            +
                },
         | 
| 345 | 
            +
                current_host: function() {
         | 
| 346 | 
            +
                  return this.has_location() && window.location.hostname;
         | 
| 347 | 
            +
                },
         | 
| 348 | 
            +
                current_protocol: function() {
         | 
| 349 | 
            +
                  if (this.has_location() && window.location.protocol !== '') {
         | 
| 350 | 
            +
                    return window.location.protocol.replace(/:$/, '');
         | 
| 351 | 
            +
                  } else {
         | 
| 352 | 
            +
                    return 'http';
         | 
| 353 | 
            +
                  }
         | 
| 354 | 
            +
                },
         | 
| 355 | 
            +
                current_port: function() {
         | 
| 356 | 
            +
                  if (this.has_location() && window.location.port !== '') {
         | 
| 357 | 
            +
                    return window.location.port;
         | 
| 358 | 
            +
                  } else {
         | 
| 359 | 
            +
                    return '';
         | 
| 360 | 
            +
                  }
         | 
| 361 | 
            +
                },
         | 
| 303 362 | 
             
                _classToTypeCache: null,
         | 
| 304 363 | 
             
                _classToType: function() {
         | 
| 305 | 
            -
                  var  | 
| 364 | 
            +
                  var name, _i, _len, _ref;
         | 
| 365 | 
            +
             | 
| 306 366 | 
             
                  if (this._classToTypeCache != null) {
         | 
| 307 367 | 
             
                    return this._classToTypeCache;
         | 
| 308 368 | 
             
                  }
         | 
| 309 369 | 
             
                  this._classToTypeCache = {};
         | 
| 310 | 
            -
                   | 
| 311 | 
            -
                  for ( | 
| 312 | 
            -
                    name =  | 
| 370 | 
            +
                  _ref = "Boolean Number String Function Array Date RegExp Object Error".split(" ");
         | 
| 371 | 
            +
                  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 372 | 
            +
                    name = _ref[_i];
         | 
| 313 373 | 
             
                    this._classToTypeCache["[object " + name + "]"] = name.toLowerCase();
         | 
| 314 374 | 
             
                  }
         | 
| 315 375 | 
             
                  return this._classToTypeCache;
         | 
| @@ -331,8 +391,10 @@ Based on Rails routes of APP_CLASS | |
| 331 391 |  | 
| 332 392 | 
             
              createGlobalJsRoutesObject = function() {
         | 
| 333 393 | 
             
                var namespace;
         | 
| 394 | 
            +
             | 
| 334 395 | 
             
                namespace = function(mainRoot, namespaceString) {
         | 
| 335 396 | 
             
                  var current, parts;
         | 
| 397 | 
            +
             | 
| 336 398 | 
             
                  parts = (namespaceString ? namespaceString.split(".") : []);
         | 
| 337 399 | 
             
                  if (!parts.length) {
         | 
| 338 400 | 
             
                    return;
         | 
    
        data/lib/routes.js.coffee
    CHANGED
    
    | @@ -13,6 +13,14 @@ defaults = | |
| 13 13 |  | 
| 14 14 | 
             
            NodeTypes = NODE_TYPES
         | 
| 15 15 |  | 
| 16 | 
            +
            ReservedOptions = [
         | 
| 17 | 
            +
              'anchor'
         | 
| 18 | 
            +
              'trailing_slash'
         | 
| 19 | 
            +
              'host'
         | 
| 20 | 
            +
              'port'
         | 
| 21 | 
            +
              'protocol'
         | 
| 22 | 
            +
            ]
         | 
| 23 | 
            +
             | 
| 16 24 | 
             
            Utils =
         | 
| 17 25 |  | 
| 18 26 | 
             
              default_serializer: (object, prefix = null) ->
         | 
| @@ -53,34 +61,14 @@ Utils = | |
| 53 61 | 
             
                path[last_index] = path[last_index].replace(/\/+/g, "/")
         | 
| 54 62 | 
             
                path.join "://"
         | 
| 55 63 |  | 
| 56 | 
            -
              set_default_url_options: (optional_parts, options) ->
         | 
| 57 | 
            -
                for part, i in optional_parts when (not options.hasOwnProperty(part) and defaults.default_url_options.hasOwnProperty(part))
         | 
| 58 | 
            -
                  options[part] = defaults.default_url_options[part]
         | 
| 59 | 
            -
             | 
| 60 | 
            -
              extract_anchor: (options) ->
         | 
| 61 | 
            -
                anchor = ""
         | 
| 62 | 
            -
                if options.hasOwnProperty("anchor")
         | 
| 63 | 
            -
                  anchor = "##{options.anchor}"
         | 
| 64 | 
            -
                  delete options.anchor
         | 
| 65 | 
            -
                anchor
         | 
| 66 | 
            -
             | 
| 67 | 
            -
              extract_trailing_slash: (options) ->
         | 
| 68 | 
            -
                trailing_slash = false
         | 
| 69 | 
            -
                if defaults.default_url_options.hasOwnProperty("trailing_slash")
         | 
| 70 | 
            -
                  trailing_slash = defaults.default_url_options.trailing_slash
         | 
| 71 | 
            -
                if options.hasOwnProperty("trailing_slash")
         | 
| 72 | 
            -
                  trailing_slash = options.trailing_slash
         | 
| 73 | 
            -
                  delete options.trailing_slash
         | 
| 74 | 
            -
                trailing_slash
         | 
| 75 | 
            -
             | 
| 76 64 | 
             
              extract_options: (number_of_params, args) ->
         | 
| 77 65 | 
             
                last_el = args[args.length - 1]
         | 
| 78 | 
            -
                if args.length > number_of_params or | 
| 79 | 
            -
                  args.pop()
         | 
| 66 | 
            +
                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))
         | 
| 67 | 
            +
                  args.pop() || {}
         | 
| 80 68 | 
             
                else
         | 
| 81 69 | 
             
                  {}
         | 
| 82 70 |  | 
| 83 | 
            -
               | 
| 71 | 
            +
              looks_like_serialized_model: (object) ->
         | 
| 84 72 | 
             
                # consider object a model if it have a path identifier properties like id and to_param
         | 
| 85 73 | 
             
                "id" of object or "to_param" of object
         | 
| 86 74 |  | 
| @@ -107,33 +95,47 @@ Utils = | |
| 107 95 | 
             
                copy[key] = attr for own key, attr of obj
         | 
| 108 96 | 
             
                copy
         | 
| 109 97 |  | 
| 110 | 
            -
               | 
| 111 | 
            -
                 | 
| 112 | 
            -
                 | 
| 113 | 
            -
                   | 
| 98 | 
            +
              merge: (xs...) ->
         | 
| 99 | 
            +
                tap = (o, fn) -> fn(o); o
         | 
| 100 | 
            +
                if xs?.length > 0
         | 
| 101 | 
            +
                  tap {}, (m) -> m[k] = v for k, v of x for x in xs
         | 
| 102 | 
            +
             | 
| 103 | 
            +
              normalize_options: (url_defaults, required_parameters, optional_parts, actual_parameters) ->
         | 
| 104 | 
            +
                options = @extract_options(required_parameters.length, actual_parameters)
         | 
| 105 | 
            +
                if actual_parameters.length > required_parameters.length
         | 
| 106 | 
            +
                  throw new Error("Too many parameters provided for path")
         | 
| 107 | 
            +
                options = @merge(defaults.default_url_options, url_defaults, options)
         | 
| 108 | 
            +
                result = {}
         | 
| 109 | 
            +
                url_parameters = {}
         | 
| 110 | 
            +
                result['url_parameters'] = url_parameters
         | 
| 111 | 
            +
                for own key, value of options
         | 
| 112 | 
            +
                  if ReservedOptions.indexOf(key) >= 0
         | 
| 113 | 
            +
                    result[key] = value
         | 
| 114 | 
            +
                  else
         | 
| 115 | 
            +
                    url_parameters[key] = value
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                for value, i in required_parameters when i < actual_parameters.length
         | 
| 118 | 
            +
                  url_parameters[value] = actual_parameters[i]
         | 
| 114 119 | 
             
                result
         | 
| 115 120 |  | 
| 116 | 
            -
               | 
| 121 | 
            +
              build_route: (required_parameters, optional_parts, route, url_defaults, args) ->
         | 
| 117 122 | 
             
                args = Array::slice.call(args)
         | 
| 118 | 
            -
                opts = @extract_options(required_parameters.length, args)
         | 
| 119 123 |  | 
| 120 | 
            -
                 | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
                @set_default_url_options optional_parts, parameters
         | 
| 124 | 
            -
                # options
         | 
| 125 | 
            -
                anchor = @extract_anchor(parameters)
         | 
| 126 | 
            -
                trailing_slash = @extract_trailing_slash(parameters)
         | 
| 124 | 
            +
                options = @normalize_options(url_defaults, required_parameters, optional_parts, args)
         | 
| 125 | 
            +
                parameters = options['url_parameters']
         | 
| 126 | 
            +
             | 
| 127 127 | 
             
                # path
         | 
| 128 128 | 
             
                result = "#{@get_prefix()}#{@visit(route, parameters)}"
         | 
| 129 129 | 
             
                url = Utils.clean_path("#{result}")
         | 
| 130 130 | 
             
                # set trailing_slash
         | 
| 131 | 
            -
                url = url.replace(/(.*?)[\/]?$/, "$1/") if trailing_slash is true
         | 
| 131 | 
            +
                url = url.replace(/(.*?)[\/]?$/, "$1/") if options['trailing_slash'] is true
         | 
| 132 132 | 
             
                # set additional url params
         | 
| 133 133 | 
             
                if (url_params = @serialize(parameters)).length
         | 
| 134 134 | 
             
                  url += "?#{url_params}"
         | 
| 135 135 | 
             
                # set anchor
         | 
| 136 | 
            -
                url += anchor
         | 
| 136 | 
            +
                url += if options.anchor then "##{options.anchor}" else ""
         | 
| 137 | 
            +
                if url_defaults
         | 
| 138 | 
            +
                  url = @route_url(options) + url
         | 
| 137 139 | 
             
                url
         | 
| 138 140 |  | 
| 139 141 | 
             
              #
         | 
| @@ -229,12 +231,43 @@ Utils = | |
| 229 231 | 
             
              #
         | 
| 230 232 | 
             
              # route function: create route path function and add spec to it
         | 
| 231 233 | 
             
              #
         | 
| 232 | 
            -
              route: (required_parts, optional_parts, route_spec) ->
         | 
| 233 | 
            -
                path_fn = -> | 
| 234 | 
            +
              route: (required_parts, optional_parts, route_spec, url_defaults) ->
         | 
| 235 | 
            +
                path_fn = ->
         | 
| 236 | 
            +
                  Utils.build_route(required_parts, optional_parts, route_spec, url_defaults, arguments)
         | 
| 234 237 | 
             
                path_fn.required_params = required_parts
         | 
| 235 238 | 
             
                path_fn.toString = -> Utils.build_path_spec(route_spec)
         | 
| 236 239 | 
             
                path_fn
         | 
| 237 240 |  | 
| 241 | 
            +
             | 
| 242 | 
            +
              route_url: (route_defaults) ->
         | 
| 243 | 
            +
                return route_defaults if typeof route_defaults == 'string'
         | 
| 244 | 
            +
                protocol = route_defaults.protocol || Utils.current_protocol()
         | 
| 245 | 
            +
                hostname = route_defaults.host || window.location.hostname
         | 
| 246 | 
            +
                port = route_defaults.port || (Utils.current_port() unless route_defaults.host)
         | 
| 247 | 
            +
                port = if port then ":#{port}" else ''
         | 
| 248 | 
            +
             | 
| 249 | 
            +
                protocol + "://" + hostname + port
         | 
| 250 | 
            +
             | 
| 251 | 
            +
             | 
| 252 | 
            +
              has_location: ->
         | 
| 253 | 
            +
                typeof window != 'undefined' && typeof window.location != 'undefined'
         | 
| 254 | 
            +
             | 
| 255 | 
            +
              current_host: ->
         | 
| 256 | 
            +
                @has_location() && window.location.hostname
         | 
| 257 | 
            +
             | 
| 258 | 
            +
              current_protocol: () ->
         | 
| 259 | 
            +
                if @has_location() && window.location.protocol != ''
         | 
| 260 | 
            +
                  # location.protocol includes the colon character
         | 
| 261 | 
            +
                  window.location.protocol.replace(/:$/, '')
         | 
| 262 | 
            +
                else
         | 
| 263 | 
            +
                  'http'
         | 
| 264 | 
            +
             | 
| 265 | 
            +
              current_port: () ->
         | 
| 266 | 
            +
                if @has_location() && window.location.port != ''
         | 
| 267 | 
            +
                  window.location.port
         | 
| 268 | 
            +
                else
         | 
| 269 | 
            +
                  ''
         | 
| 270 | 
            +
             | 
| 238 271 | 
             
              #
         | 
| 239 272 | 
             
              # This is helper method to define object type.
         | 
| 240 273 | 
             
              # The typeof operator is probably the biggest design flaw of JavaScript, simply because it's basically completely broken.
         | 
| @@ -138,15 +138,17 @@ describe JsRoutes, "options" do | |
| 138 138 | 
             
                  expect(evaljs("Routes.inbox_path(1, {format: null})")).to eq(routes.inbox_path(1))
         | 
| 139 139 | 
             
                end
         | 
| 140 140 |  | 
| 141 | 
            -
                it "shouldn't include the format when {:format => false} is specified" do
         | 
| 142 | 
            -
                  expect(evaljs("Routes.no_format_path()")).to eq(routes.no_format_path)
         | 
| 143 | 
            -
                end
         | 
| 144 141 |  | 
| 145 142 | 
             
                it "shouldn't require the format" do
         | 
| 146 143 | 
             
                  expect(evaljs("Routes.json_only_path()")).to eq(routes.json_only_path(:format => 'json'))
         | 
| 147 144 | 
             
                end
         | 
| 148 145 | 
             
              end
         | 
| 149 146 |  | 
| 147 | 
            +
              it "shouldn't include the format when {:format => false} is specified" do
         | 
| 148 | 
            +
                expect(evaljs("Routes.no_format_path()")).to eq(routes.no_format_path())
         | 
| 149 | 
            +
                expect(evaljs("Routes.no_format_path({format: 'json'})")).to eq(routes.no_format_path(format: 'json'))
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
             | 
| 150 152 | 
             
              describe "when namespace option is specified" do
         | 
| 151 153 | 
             
                let(:_options) { {:namespace => "PHM"} }
         | 
| 152 154 | 
             
                it "should use this namespace for routing" do
         | 
| @@ -192,7 +194,6 @@ describe JsRoutes, "options" do | |
| 192 194 | 
             
                context "with required route parts" do
         | 
| 193 195 | 
             
                  let(:_options) { {:default_url_options => {:inbox_id => "12"}} }
         | 
| 194 196 | 
             
                  it "should use this opions to fill optional parameters" do
         | 
| 195 | 
            -
                    pending
         | 
| 196 197 | 
             
                    expect(evaljs("Routes.inbox_messages_path()")).to eq(routes.inbox_messages_path(:inbox_id => 12))
         | 
| 197 198 | 
             
                  end
         | 
| 198 199 | 
             
                end
         | 
| @@ -308,12 +309,6 @@ describe JsRoutes, "options" do | |
| 308 309 | 
             
                end
         | 
| 309 310 |  | 
| 310 311 | 
             
                context "when configuring with default_url_options" do
         | 
| 311 | 
            -
                  context "when default host is not specified" do
         | 
| 312 | 
            -
                    it "raises an error" do
         | 
| 313 | 
            -
                      expect { JsRoutes.generate({ :url_links => true }) }.to raise_error RuntimeError
         | 
| 314 | 
            -
                    end
         | 
| 315 | 
            -
                  end
         | 
| 316 | 
            -
             | 
| 317 312 | 
             
                  context "when only host option is specified" do
         | 
| 318 313 | 
             
                    let(:_options) { { :url_links => true, :default_url_options => {:host => "example.com"} } }
         | 
| 319 314 |  | 
| @@ -366,7 +361,7 @@ describe JsRoutes, "options" do | |
| 366 361 | 
             
                    end
         | 
| 367 362 |  | 
| 368 363 | 
             
                    it "does not override host, protocol, or port when host is specified in route" do
         | 
| 369 | 
            -
                      expect(evaljs("Routes.sso_url()")).to eq(routes. | 
| 364 | 
            +
                      expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com:3000" + routes.sso_path)
         | 
| 370 365 | 
             
                    end
         | 
| 371 366 |  | 
| 372 367 | 
             
                    it "does not override port when specified in route" do
         | 
| @@ -404,6 +399,54 @@ describe JsRoutes, "options" do | |
| 404 399 | 
             
                    end
         | 
| 405 400 | 
             
                  end
         | 
| 406 401 | 
             
                end
         | 
| 402 | 
            +
             | 
| 403 | 
            +
                context 'when window.location is present' do
         | 
| 404 | 
            +
                  let(:current_protocol) { 'http:' } # window.location.protocol includes the colon character
         | 
| 405 | 
            +
                  let(:current_hostname) { 'current.example.com' }
         | 
| 406 | 
            +
                  let(:current_port){ '' } # an empty string means port 80
         | 
| 407 | 
            +
                  let(:current_host) do
         | 
| 408 | 
            +
                    host = "#{current_hostname}"
         | 
| 409 | 
            +
                    host += ":#{current_port}" unless current_port == ''
         | 
| 410 | 
            +
                    host
         | 
| 411 | 
            +
                  end
         | 
| 412 | 
            +
             | 
| 413 | 
            +
                  before do
         | 
| 414 | 
            +
                    jscontext['window'] = {
         | 
| 415 | 
            +
                      :location => {
         | 
| 416 | 
            +
                        :protocol => current_protocol,
         | 
| 417 | 
            +
                        :hostname => current_hostname,
         | 
| 418 | 
            +
                        :port => current_port,
         | 
| 419 | 
            +
                        :host => current_host
         | 
| 420 | 
            +
                      }
         | 
| 421 | 
            +
                    }
         | 
| 422 | 
            +
                  end
         | 
| 423 | 
            +
             | 
| 424 | 
            +
                  context "without specifying a default host" do
         | 
| 425 | 
            +
                    let(:_options) { { :url_links => true } }
         | 
| 426 | 
            +
             | 
| 427 | 
            +
                    it "uses the current host" do
         | 
| 428 | 
            +
                      expect(evaljs("Routes.inbox_path")).not_to be_nil
         | 
| 429 | 
            +
                      expect(evaljs("Routes.inbox_url")).not_to be_nil
         | 
| 430 | 
            +
                      expect(evaljs("Routes.inbox_url(1)")).to eq("http://current.example.com#{routes.inbox_path(1)}")
         | 
| 431 | 
            +
                      expect(evaljs("Routes.inbox_url(1, { test_key: \"test_val\" })")).to eq("http://current.example.com#{routes.inbox_path(1, :test_key => "test_val")}")
         | 
| 432 | 
            +
                      expect(evaljs("Routes.new_session_url()")).to eq("https://current.example.com#{routes.new_session_path}")
         | 
| 433 | 
            +
                      expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com#{routes.sso_path}")
         | 
| 434 | 
            +
             | 
| 435 | 
            +
                    end
         | 
| 436 | 
            +
             | 
| 437 | 
            +
                    it "uses host option as an argument" do
         | 
| 438 | 
            +
                      expect(evaljs("Routes.portals_url({host: 'another.com'})")).to eq(routes.portals_url(host: 'another.com'))
         | 
| 439 | 
            +
                    end
         | 
| 440 | 
            +
             | 
| 441 | 
            +
                    it "uses port option as an argument" do
         | 
| 442 | 
            +
                      expect(evaljs("Routes.portals_url({host: 'localhost', port: 8080})")).to eq(routes.portals_url(host: 'localhost', port: 8080))
         | 
| 443 | 
            +
                    end
         | 
| 444 | 
            +
             | 
| 445 | 
            +
                    it "uses protocol option as an argument" do
         | 
| 446 | 
            +
                      expect(evaljs("Routes.portals_url({host: 'localhost', protocol: 'https'})")).to eq(routes.portals_url(protocol: 'https', host: 'localhost'))
         | 
| 447 | 
            +
                    end
         | 
| 448 | 
            +
                  end
         | 
| 449 | 
            +
                end
         | 
| 407 450 | 
             
              end
         | 
| 408 451 |  | 
| 409 452 | 
             
              describe "when the compact mode is enabled" do
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -147,6 +147,22 @@ RSpec.configure do |config| | |
| 147 147 |  | 
| 148 148 | 
             
              config.before :each do
         | 
| 149 149 | 
             
                evaljs("var window = this;", true)
         | 
| 150 | 
            -
             | 
| 150 | 
            +
             | 
| 151 | 
            +
                def inspectify(value)
         | 
| 152 | 
            +
                  case value
         | 
| 153 | 
            +
                  when V8::Object
         | 
| 154 | 
            +
                    value.to_h.map do |k,v|
         | 
| 155 | 
            +
                      [k, inspectify(v)]
         | 
| 156 | 
            +
                    end.to_h
         | 
| 157 | 
            +
                  when String, nil
         | 
| 158 | 
            +
                    value
         | 
| 159 | 
            +
                  else
         | 
| 160 | 
            +
                    raise "wtf #{value.class}?"
         | 
| 161 | 
            +
                  end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                end
         | 
| 164 | 
            +
                jscontext[:log] = lambda do |context, value|
         | 
| 165 | 
            +
                  puts inspectify(value).to_json
         | 
| 166 | 
            +
                end
         | 
| 151 167 | 
             
              end
         | 
| 152 168 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: js-routes
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Bogdan Gusiev
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015- | 
| 11 | 
            +
            date: 2015-12-22 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: railties
         |