/** * Service for URL templating. */ import root from './root'; import query from './query'; import template from './template'; import {each, merge, isArray, isFunction, isObject, isPlainObject, isString} from '../util'; export default function Url(url, params) { var self = this || {}, options = url, transform; if (isString(url)) { options = {url, params}; } options = merge({}, Url.options, self.$options, options); Url.transforms.forEach(handler => { if (isString(handler)) { handler = Url.transform[handler]; } if (isFunction(handler)) { transform = factory(handler, transform, self.$vm); } }); return transform(options); } /** * Url options. */ Url.options = { url: '', root: null, params: {} }; /** * Url transforms. */ Url.transform = {template, query, root}; Url.transforms = ['template', 'query', 'root']; /** * Encodes a Url parameter string. * * @param {Object} obj */ Url.params = function (obj) { var params = [], escape = encodeURIComponent; params.add = function (key, value) { if (isFunction(value)) { value = value(); } if (value === null) { value = ''; } this.push(escape(key) + '=' + escape(value)); }; serialize(params, obj); return params.join('&').replace(/%20/g, '+'); }; /** * Parse a URL and return its components. * * @param {String} url */ Url.parse = function (url) { var el = document.createElement('a'); if (document.documentMode) { el.href = url; url = el.href; } el.href = url; return { href: el.href, protocol: el.protocol ? el.protocol.replace(/:$/, '') : '', port: el.port, host: el.host, hostname: el.hostname, pathname: el.pathname.charAt(0) === '/' ? el.pathname : '/' + el.pathname, search: el.search ? el.search.replace(/^\?/, '') : '', hash: el.hash ? el.hash.replace(/^#/, '') : '' }; }; function factory(handler, next, vm) { return options => { return handler.call(vm, options, next); }; } function serialize(params, obj, scope) { var array = isArray(obj), plain = isPlainObject(obj), hash; each(obj, (value, key) => { hash = isObject(value) || isArray(value); if (scope) { key = scope + '[' + (plain || hash ? key : '') + ']'; } if (!scope && array) { params.add(value.name, value.value); } else if (hash) { serialize(params, value, key); } else { params.add(key, value); } }); }