(function() { var NodeTypes, ParameterMissing, Utils, defaults, __hasProp = {}.hasOwnProperty; ParameterMissing = function(message) { this.message = message; }; ParameterMissing.prototype = new Error(); defaults = { prefix: "PREFIX", default_url_options: DEFAULT_URL_OPTIONS }; NodeTypes = NODE_TYPES; Utils = { serialize: function(object, prefix) { var element, i, key, prop, result, s, _i, _len; if (prefix == null) { prefix = null; } if (!object) { return ""; } if (!prefix && !(this.get_object_type(object) === "object")) { throw new Error("Url parameters should be a javascript hash"); } if (window.jQuery) { result = window.jQuery.param(object); return (!result ? "" : result); } s = []; switch (this.get_object_type(object)) { case "array": for (i = _i = 0, _len = object.length; _i < _len; i = ++_i) { element = object[i]; s.push(this.serialize(element, prefix + "[]")); } break; case "object": for (key in object) { if (!__hasProp.call(object, key)) continue; prop = object[key]; if (!(prop != null)) { continue; } if (prefix != null) { key = "" + prefix + "[" + key + "]"; } s.push(this.serialize(prop, key)); } break; default: if (object) { s.push("" + (encodeURIComponent(prefix.toString())) + "=" + (encodeURIComponent(object.toString()))); } } if (!s.length) { return ""; } return s.join("&"); }, clean_path: function(path) { var last_index; path = path.split("://"); last_index = path.length - 1; path[last_index] = path[last_index].replace(/\/+/g, "/"); return path.join("://"); }, set_default_url_options: function(optional_parts, options) { var i, part, _i, _len, _results; _results = []; for (i = _i = 0, _len = optional_parts.length; _i < _len; i = ++_i) { part = optional_parts[i]; if (!options.hasOwnProperty(part) && defaults.default_url_options.hasOwnProperty(part)) { _results.push(options[part] = defaults.default_url_options[part]); } } return _results; }, extract_anchor: function(options) { var anchor; anchor = ""; if (options.hasOwnProperty("anchor")) { anchor = "#" + options.anchor; delete options.anchor; } return anchor; }, extract_options: function(number_of_params, args) { var last_el; last_el = args[args.length - 1]; if (args.length > number_of_params || ((last_el != null) && "object" === this.get_object_type(last_el) && !this.look_like_serialized_model(last_el))) { return args.pop(); } else { return {}; } }, look_like_serialized_model: function(object) { return "id" in object || "to_param" in object; }, path_identifier: function(object) { var property; if (object === 0) { return "0"; } if (!object) { return ""; } property = object; if (this.get_object_type(object) === "object") { if ("to_param" in object) { property = object.to_param; } else if ("id" in object) { property = object.id; } else { property = object; } if (this.get_object_type(property) === "function") { property = property.call(object); } } return property.toString(); }, clone: function(obj) { var attr, copy, key; if ((obj == null) || "object" !== this.get_object_type(obj)) { return obj; } copy = obj.constructor(); for (key in obj) { if (!__hasProp.call(obj, key)) continue; attr = obj[key]; copy[key] = attr; } return copy; }, prepare_parameters: function(required_parameters, actual_parameters, options) { var i, result, val, _i, _len; result = this.clone(options) || {}; for (i = _i = 0, _len = required_parameters.length; _i < _len; i = ++_i) { val = required_parameters[i]; if (i < actual_parameters.length) { result[val] = actual_parameters[i]; } } return result; }, build_path: function(required_parameters, optional_parts, route, args) { var anchor, opts, parameters, result, url, url_params; args = Array.prototype.slice.call(args); opts = this.extract_options(required_parameters.length, args); if (args.length > required_parameters.length) { throw new Error("Too many parameters provided for path"); } parameters = this.prepare_parameters(required_parameters, args, opts); this.set_default_url_options(optional_parts, parameters); anchor = this.extract_anchor(parameters); result = "" + (this.get_prefix()) + (this.visit(route, parameters)); url = Utils.clean_path("" + result); if ((url_params = this.serialize(parameters)).length) { url += "?" + url_params; } url += anchor; return url; }, visit: function(route, parameters, optional) { var left, left_part, right, right_part, type, value; if (optional == null) { optional = false; } type = route[0], left = route[1], right = route[2]; switch (type) { case NodeTypes.GROUP: return this.visit(left, parameters, true); case NodeTypes.STAR: return this.visit_globbing(left, parameters, true); case NodeTypes.LITERAL: case NodeTypes.SLASH: case NodeTypes.DOT: return left; case NodeTypes.CAT: left_part = this.visit(left, parameters, optional); right_part = this.visit(right, parameters, optional); if (optional && !(left_part && right_part)) { return ""; } return "" + left_part + right_part; case NodeTypes.SYMBOL: value = parameters[left]; if (value != null) { delete parameters[left]; return this.path_identifier(value); } if (optional) { return ""; } else { throw new ParameterMissing("Route parameter missing: " + left); } break; default: throw new Error("Unknown Rails node type"); } }, visit_globbing: function(route, parameters, optional) { var left, right, type, value; type = route[0], left = route[1], right = route[2]; if (left.replace(/^\*/i, "") !== left) { route[1] = left = left.replace(/^\*/i, ""); } value = parameters[left]; if (value == null) { return this.visit(route, parameters, optional); } parameters[left] = (function() { switch (this.get_object_type(value)) { case "array": return value.join("/"); default: return value; } }).call(this); return this.visit(route, parameters, optional); }, get_prefix: function() { var prefix; prefix = defaults.prefix; if (prefix !== "") { prefix = (prefix.match("/$") ? prefix : "" + prefix + "/"); } return prefix; }, _classToTypeCache: null, _classToType: function() { var name, _i, _len, _ref; if (this._classToTypeCache != null) { return this._classToTypeCache; } this._classToTypeCache = {}; _ref = "Boolean Number String Function Array Date RegExp Object Error".split(" "); for (_i = 0, _len = _ref.length; _i < _len; _i++) { name = _ref[_i]; this._classToTypeCache["[object " + name + "]"] = name.toLowerCase(); } return this._classToTypeCache; }, get_object_type: function(obj) { if (window.jQuery && (window.jQuery.type != null)) { return window.jQuery.type(obj); } if (obj == null) { return "" + obj; } if (typeof obj === "object" || typeof obj === "function") { return this._classToType()[Object.prototype.toString.call(obj)] || "object"; } else { return typeof obj; } }, namespace: function(root, namespaceString) { var current, parts; parts = (namespaceString ? namespaceString.split(".") : []); if (!parts.length) { return; } current = parts.shift(); root[current] = root[current] || {}; return Utils.namespace(root[current], parts.join(".")); } }; Utils.namespace(window, "NAMESPACE"); window.NAMESPACE = ROUTES; window.NAMESPACE.options = defaults; }).call(this);