milojs/proto

View on GitHub
lib/dot/string.jst

Summary

Maintainability
Test Coverage
'use strict';
{{# def.definitions }}
{{# def.keys }}

var slice = Array.prototype.slice;

/**
 * - [firstUpperCase](#firstUpperCase)
 * - [firstLowerCase](#firstLowerCase)
 * - [toRegExp](#toRegExp)
 * - [toFunction](#toFunction)
 * - [toDate](#toDate)
 * - [toQueryString](#toQueryString)
 * - [fromQueryString](#fromQueryString)
 * - [jsonParse](#jsonParse)
 * - [hashCode](#hashCode)
 * - [unPrefix](#unPrefix)
 * - [format](#format)
 */
 var stringMethods = module.exports = {
    firstUpperCase: firstUpperCase,
    firstLowerCase: firstLowerCase,
    toRegExp: toRegExp,
    toFunction: toFunction,
    toDate: toDate,
    toQueryString: toQueryString,
    fromQueryString: fromQueryString,
    jsonParse: jsonParse,
    hashCode: hashCode,
    unPrefix: unPrefix,
    format: format
};


/**
 * Returns string with the first character changed to upper case.
 *
 * @param {String} self A string that will have its first character replaced
 */
function firstUpperCase({{# def.oneArg }}) {
    {{# def.varSelf }}
    var str = self ? self[0].toUpperCase() + self.slice(1) : self;
    {{# def.return:str }}
}


/**
 * Returns string with the first character changed to lower case.
 *
 * @param {String} self A string that will have its first character replaced
 */
function firstLowerCase({{# def.oneArg }}) {
    {{# def.varSelf }}
    var str = self ? self[0].toLowerCase() + self.slice(1) : self;
    {{# def.return:str }}
}


/**
 * Converts string created by `toString` method of RegExp back to RegExp
 *
 * @param {String} self string containing regular expression including enclosing "/" symbols and flags
 * @return {RegExp}
 */
function toRegExp({{# def.oneArg }}) {
    {{# def.varSelf }}
    var rx = self.match(regexpStringPattern);
    if (rx) {
        var newRx = new RegExp(rx[1], rx[2]);
    }
    {{# def.return:newRx }}
}
var regexpStringPattern = /^\/(.*)\/([gimy]*)$/;


/**
 * Converts string created by `toString` method of function back to function
 *
 * @param {String} self string containing full function code
 * @return {Function}
 */
function toFunction({{# def.oneArg }}) {
    {{# def.varSelf }}
    var code = 'return ' + self + ';';
    var func;
    try { func = (new Function(code))(); } catch(e) {}
    {{# def.return:func }}
}


/**
 * Converts string to date in a safe way so that the result is undefined if date is invalid
 *
 * @param {String|Date} self string or date object to convert to VALID date
 * @return {Date|undefined}
 */
function toDate({{# def.oneArg }}) {
    {{# def.varSelf }}
    if (self) {
        try {
            var date = new Date(self);
        } catch (e) {}
        if (date && date.getTime && !isNaN(date.getTime())) {
            {{# def.return:date }}
        }
    }
    {{? it.mode == 'methods' }}
        {{# def.return:undefined }}
    {{?}}
}


/**
 * Convert params object to a url style query string (without "?")
 * 
 * @param {Object} self The object hash to be converted
 * @param {Function} encode optional function used to encode data, encodeURIComponent is used if not specified
 * @return {String} the resulting query string
 */
function toQueryString({{# def.arg }} encode) {
    {{## def.defToQueryString:
        qs += key + "=" + encode(params[key]) + "&";
    #}}

    {{# def.varSelf }}
    var qs = ''
        , params = self || {}
        , encode = encode || encodeURIComponent;

    {{ var opts = { obj: 'params', code: '{{# def.defToQueryString }}' }; }}
    {{# def.eachKeyAll:opts }}
    
    var str = qs.slice(0, -1);
    {{# def.return:str }}
}


/**
 * Convert url style query string (without "?") into object hash
 * 
 * @param {String} self The string to be converted
 * @param {Function} decode optional decode function, decodeURIComponent will be used if not supplied
 * @return {Object} The resulting object hash
 */
function fromQueryString({{# def.arg }} decode) {
    {{# def.varSelf }}
    var pairs = self.split('&')
        , results = {}
        , decode = decode || decodeURIComponent;

    {{# def.iter:pairs }} {
        var pair = pairs[i];
        var splitPair = pair.split('=');
        if (splitPair.length < 2) return;
        var key = splitPair[0]
            , value = decode(splitPair[1] || '');
        if (!key) return;
        results[key] = value;
    }

    {{# def.return:results }}
}


/**
 * Safe JSON.parse, returns undefined if JSON.parse throws an exception
 *
 * @param {String} self JSON string representation of object
 * @return {Object|undefined}
 */
function jsonParse({{# def.oneArg }}) {
    {{# def.varSelf }}
    try {
        var result = JSON.parse(self);
    } catch (e) {}
    {{# def.return:result }}
}


/**
 * Dan Bernstein's algorythm to create hash from string
 *
 * @param {String} self string to convert to hash
 * @return {Number}
 */
function hashCode({{# def.oneArg }}) {
    {{# def.varSelf }}
    var hash = 5381
        , str = self
        , len = str.length;
    for (var i = 0; i < len; i++) {
        var char = str.charCodeAt(i);
        hash = ((hash << 5) + hash) + char; /* hash * 33 + c */
    }
    {{# def.return:hash }}
}


/**
 * Removes given prefix from the string. If string does not begin from the prefix, returns undefined
 * 
 * @param {String} self
 * @return {String}
 */
function unPrefix({{# def.arg }} str) {
    {{# def.varSelf }}
    if (self.indexOf(str) == 0)
        var result = self.replace(str, '');
    {{# def.return:result }}
}


/**
 * Regex used to identify format vars
 * @type {RegExp}
 */
var formatRegexp = /\$[0-9]+|\$\$/g;

/**
 * String formatting utility to swap out tokens for variables.
 * @param  {String} this The string to be formatted 
 * @param  {Array}  args The values to be formatted
 * @return {String}      The formatted string
 */
function format({{# def.oneArg }}) { // , ... arguments
    {{# def.varSelf }}
    {{# def.varArguments }}
    var result = self.replace(formatRegexp, function (item) {
        if (item == '$$') return '$';
        item = item.slice(1);
        return args[item - 1];
    });
    {{# def.return:result }}
};