#

API Docs for: v2.11.1
Show: Inherited Protected Private Deprecated

# File: node_modules/router_js/lib/router/utils.js

    var slice = Array.prototype.slice;

    var _isArray;
    if (!Array.isArray) {
      _isArray = function (x) {
        return Object.prototype.toString.call(x) === "[object Array]";
      };
    } else {
      _isArray = Array.isArray;
    }

    export var isArray = _isArray;

    /**
      Determines if an object is Promise by checking if it is "thenable".
    **/
    export function isPromise(obj) {
      return ((typeof obj === 'object' && obj !== null) || typeof obj === 'function') && typeof obj.then === 'function';
    }

    function merge(hash, other) {
      for (var prop in other) {
        if (other.hasOwnProperty(prop)) { hash[prop] = other[prop]; }
      }
    }

    export var oCreate = Object.create || function(proto) {
      function F() {}
      F.prototype = proto;
      return new F();
    };

    /**
      @private

      Extracts query params from the end of an array
    **/
    export function extractQueryParams(array) {
      var len = (array && array.length), head, queryParams;

      if(len && len > 0 && array[len - 1] && array[len - 1].hasOwnProperty('queryParams')) {
        queryParams = array[len - 1].queryParams;
        head = slice.call(array, 0, len - 1);
        return [head, queryParams];
      } else {
        return [array, null];
      }
    }

    /**
      @private

      Coerces query param properties and array elements into strings.
    **/
    function coerceQueryParamsToString(queryParams) {
      for (var key in queryParams) {
        if (typeof queryParams[key] === 'number') {
          queryParams[key] = '' + queryParams[key];
        } else if (isArray(queryParams[key])) {
          for (var i = 0, l = queryParams[key].length; i < l; i++) {
            queryParams[key][i] = '' + queryParams[key][i];
          }
        }
      }
    }
    /**
      @private
     */
    export function log(router, sequence, msg) {
      if (!router.log) { return; }

      if (arguments.length === 3) {
        router.log("Transition #" + sequence + ": " + msg);
      } else {
        msg = sequence;
        router.log(msg);
      }
    }

    export function bind(context, fn) {
      var boundArgs = arguments;
      return function(value) {
        var args = slice.call(boundArgs, 2);
        args.push(value);
        return fn.apply(context, args);
      };
    }

    function isParam(object) {
      return (typeof object === "string" || object instanceof String || typeof object === "number" || object instanceof Number);
    }

    export function forEach(array, callback) {
      for (var i=0, l=array.length; i < l && false !== callback(array[i]); i++) { }
    }

    export function trigger(router, handlerInfos, ignoreFailure, args) {
      if (router.triggerEvent) {
        router.triggerEvent(handlerInfos, ignoreFailure, args);
        return;
      }

      var name = args.shift();

      if (!handlerInfos) {
        if (ignoreFailure) { return; }
        throw new Error("Could not trigger event '" + name + "'. There are no active handlers");
      }

      var eventWasHandled = false;

      function delayedEvent(name, args, handler) {
        handler.events[name].apply(handler, args);
      }

      for (var i=handlerInfos.length-1; i>=0; i--) {
        var handlerInfo = handlerInfos[i],
            handler = handlerInfo.handler;

        // If there is no handler, it means the handler hasn't resolved yet which
        // means that we should trigger the event later when the handler is available
        if (!handler) {
          handlerInfo.handlerPromise.then(bind(null, delayedEvent, name, args));
          continue;
        }

        if (handler.events && handler.events[name]) {
          if (handler.events[name].apply(handler, args) === true) {
            eventWasHandled = true;
          } else {
            return;
          }
        }
      }

      // In the case that we got an UnrecognizedURLError as an event with no handler,
      // let it bubble up
      if (name === 'error' && args[0].name === 'UnrecognizedURLError') {
        throw args[0];
      } else if (!eventWasHandled && !ignoreFailure) {
        throw new Error("Nothing handled the event '" + name + "'.");
      }
    }

    export function getChangelist(oldObject, newObject) {
      var key;
      var results = {
        all: {},
        changed: {},
        removed: {}
      };

      merge(results.all, newObject);

      var didChange = false;
      coerceQueryParamsToString(oldObject);
      coerceQueryParamsToString(newObject);

      // Calculate removals
      for (key in oldObject) {
        if (oldObject.hasOwnProperty(key)) {
          if (!newObject.hasOwnProperty(key)) {
            didChange = true;
            results.removed[key] = oldObject[key];
          }
        }
      }

      // Calculate changes
      for (key in newObject) {
        if (newObject.hasOwnProperty(key)) {
          if (isArray(oldObject[key]) && isArray(newObject[key])) {
            if (oldObject[key].length !== newObject[key].length) {
              results.changed[key] = newObject[key];
              didChange = true;
            } else {
              for (var i = 0, l = oldObject[key].length; i < l; i++) {
                if (oldObject[key][i] !== newObject[key][i]) {
                  results.changed[key] = newObject[key];
                  didChange = true;
                }
              }
            }
          }
          else {
            if (oldObject[key] !== newObject[key]) {
              results.changed[key] = newObject[key];
              didChange = true;
            }
          }
        }
      }

      return didChange && results;
    }

    export function promiseLabel(label) {
      return 'Router: ' + label;
    }

    export function subclass(parentConstructor, proto) {
      function C(props) {
        parentConstructor.call(this, props || {});
      }
      C.prototype = oCreate(parentConstructor.prototype);
      merge(C.prototype, proto);
      return C;
    }

    function resolveHook(obj, hookName) {
      if (!obj) { return; }
      var underscored = "_" + hookName;
      return obj[underscored] && underscored ||
             obj[hookName] && hookName;
    }

    function callHook(obj, _hookName, arg1, arg2) {
      var hookName = resolveHook(obj, _hookName);
      return hookName && obj[hookName].call(obj, arg1, arg2);
    }

    function applyHook(obj, _hookName, args) {
      var hookName = resolveHook(obj, _hookName);
      if (hookName) {
        if (args.length === 0) {
          return obj[hookName].call(obj);
        } else if (args.length === 1) {
          return obj[hookName].call(obj, args[0]);
        } else if (args.length === 2) {
          return obj[hookName].call(obj, args[0], args[1]);
        } else {
          return obj[hookName].apply(obj, args);
        }
      }
    }

    export { merge, slice, isParam, coerceQueryParamsToString, callHook, resolveHook, applyHook };