erikroyall/hilo

View on GitHub
src/util.js

Summary

Maintainability
F
6 days
Test Coverage

  // --------------------------------------------------
  // Utilities
  // --------------------------------------------------

  var boxedString = Object("a")
    , splitString = boxedString[0] !== "a" || !(0 in boxedString);

  var toObject = function toObject (o) {
    if (typeof o === "undefined") { // this matches both null and undefined
      throw new TypeError("can't convert "+o+" to object");
    }

    return Object(o);
  };

  var toInteger = function toInteger (value) {
    var number = +value;

    if (Number.isNaN(number)) {
      return 0;
    }

    if (number === 0 || !isFinite(number)) {
      return number;
    }

    return sign(number) * Math.floor(Math.abs(number));
  };

  var isPrimitive = function isPrimitive(input) {
    var type = typeof input;
    
    return (
      input === null ||
      type === "undefined" ||
      type === "boolean" ||
      type === "number" ||
      type === "string"
    );
  };

  var toPrimitive = function toPrimitive (input) {
    var val, valueOf, toString;

    if (isPrimitive(input)) {
      return input;
    }

    valueOf = input.valueOf;

    if (typeof valueOf === "function") {
      val = valueOf.call(input);

      if (isPrimitive(val)) {
        return val;
      }
    }
    toString = input.toString;
    
    if (typeof toString === "function") {
      val = toString.call(input);

      if (isPrimitive(val)) {
        return val;
      }
    }

    throw new TypeError();
  };

  var sign = function sign(value) {
    var number = +value;

    if (number === 0) {
      return number;
    }

    if (Number.isNaN(number)) {
      return number;
    }

    return number < 0 ? -1 : 1;
  };

  // --------------------------------------------------
  // Array Utilities
  // --------------------------------------------------

  // Executes a function on each of the element
  // in the array
  var each = function each (arr, fn, thisRef) {
    var _i, _l;

    // Use Array.prototype.forEach if available
    if (Array.prototype.forEach) {
      return Array.prototype.forEach.call(arr, fn);
    }

    // Throw an error if array and function are not provided
    if (!(arr && fn)) {
      throw new Error (
        "Not enough arguments provided for each()"
      );
    }

    // Make the this variable the array itself if not provided
    thisRef = thisRef || arr;

    for (_i = 0, _l = arr.length; _i < _l; _i += 1) {
      fn.call(thisRef, arr[_i]);
    }
  };

  // Iterate over an object and execute a function on each 'value'
  // of it
  var forIn = function forIn (obj, fn, thisRef) {
    var _i;

    // Throw an error if object and function are not provided
    if (!(obj && fn)) {
      throw new Error (
        "Not enough arguments provided for forIn()"
      );
    }

    // Make the given object as the `this` value if one is not provided
    thisRef = thisRef || obj;

    for (_i in obj) {
      if (own(obj, _i)) {
        fn.call(thisRef, _i);
      }
    }
  };

  // Append all the properties of the second object to the first
  var extend = function extend (obj, ext) {
    var _i;

    // Throw an error if object and extension are not provided
    if (!(obj && ext)) {
      throw new Error (
        "Not enough arguments provided for extend()"
      );
    }

    for (_i in ext) {
      if (own(ext, _i)) {
        obj[_i] = ext[_i];
      }
    }

    return obj;
  };

  // Check if every element in the object passes the test
  var every = function every (o, fun) {
    var t, len, thisp, _i;

    if (o === null) {
      throw new TypeError();
    }

    t = Object(o);
    len = t.length >>> 0;

    if (typeof fun !== "function") {
      throw new TypeError();
    }

    thisp = arguments[1];

    for (_i = 0; _i < len; _i++) {
      if (_i in t && !fun.call(thisp, t[_i], _i, t)) {
        return false;
      }
    }

    return true;
  };

  // --------------------------------------------------
  // String Utilities
  // --------------------------------------------------

  // Remove whitespace at the start and end of a string
  var trim = function trim (str) {
    var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + 
             "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + 
             "\u2029\uFEFF";

    ws = "[" + ws + "]";

    var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
      trimEndRegexp = new RegExp(ws + ws + "*$");

    if (str === void 0 || str === null) {
      throw new TypeError("can't convert "+ str +" to object");
    }

    return String(str).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
  };

  // Check if a string contains another string in it
  var contains = function contains (haystack, needle) {
    var position = arguments[1];

    return haystack.indexOf(needle, position) !== -1;
  };

  var indexOf = function indexOf(arr, sought /*, fromIndex */ ) {
    var self = splitString && arr.toString() === "[object String]" ?
            this.split("") :
            toObject(this)
      , length = self.length >>> 0;

    if (!length) {
        return -1;
    }

    var i = 0;

    if (arguments.length > 1) {
        i = toInteger(arguments[1]);
    }

    // handle negative indices
    i = i >= 0 ? i : Math.max(0, length + i);

    for (; i < length; i++) {
        if (i in self && self[i] === sought) {
            return i;
        }
    }
    
    return -1;
  };