weisk
8/27/2016 - 6:32 AM

URL Helpers

URL Helpers

define([
    'lodash'
], function(_) {

    // Regular expressions
    var digitTest = /^\d+$/,
        keyBreaker = /([^\[\]]+)|(\[\])/g,
        plus = /\+/g,
        paramTest = /([^?#]*)(#.*)?$/;

    /**
     * taken from https://github.com/jupiterjs/jquerymx/blob/master/lang/string/deparam/deparam.js
     * @function buildQueryParams
     * Takes a string of name value pairs and returns a Object literal that represents those params.
     * @param {String} params a string like <code>"foo=bar&person[age]=3"</code>
     * @return {Object} A JavaScript Object that represents the params:
     *     {
     *       foo: "bar",
     *       person: {
     *         age: "3"
     *       }
     *     }
     */
    function buildQueryParams(queryString) {
        if(!queryString || !paramTest.test(queryString) ) {
            return {};
        }

        var data = {},
            pairs = queryString.split('&'),
            current;

        for (var i=0;i < pairs.length; i++) {
            current = data;
            var pair = pairs[i].split('=');

            // if we find foo=1+1=2
            if (pair.length != 2) {
                pair = [pair[0], pair.slice(1).join('=')]
            }

            var key = decodeURIComponent(pair[0].replace(plus, ' '));
            var value = decodeURIComponent(pair[1].replace(plus, ' '));
            var parts = key.match(keyBreaker);

            for (var j = 0; j < parts.length - 1; j++) {
                var part = parts[j];
                if (!current[part] ) {
                    // if what we are pointing to looks like an array
                    current[part] = digitTest.test(parts[j+1]) || parts[j+1] == '[]' ? [] : {}
                }
                current = current[part];
            }

            var lastPart = parts[parts.length - 1];
            if (lastPart == '[]') {
                current.push(value)
            } else {
                current[lastPart] = value;
            }
        }

        return data;
    }

    /**
     * function getQueryParams
     * Convert Current URL string into an object
     * @param {Object} location
     * @return {Object} params
     **/
    function getQueryParams(location) {
        location = location || window.location || {};

        if (_.isEmpty(location.search)) {
            return {};
        }

        var search = location.search.substr(1);
        return buildQueryParams(search);
    }

    /**
     * function serializeParams
     * Serialize object into valid URL queryString
     * @param {Object} obj
     * @return {String} params
     **/
    function serializeParams(obj, prefix) {
        // http://stackoverflow.com/a/1714899/1807545
        var str = [];
        for (var param in obj) {
            if (obj.hasOwnProperty(param)) {
                var key = prefix ? prefix + '[' + param + ']' : param;
                var val = obj[param];
                if (!val) {
                    continue;
                }
                str.push(typeof val == 'object' ?
                    serializeParams(val, key) :
                    encodeURIComponent(key) + '=' + encodeURIComponent(val));
            }
        }
        return str.join('&');
    }

    return {
        buildQueryParams: buildQueryParams,
        getQueryParams: getQueryParams,
        serializeParams: function(obj) {
            return '?' + serializeParams(obj)
        },
    };
})