baja/nav/NavNode.js

/**
 * @copyright 2015 Tridium, Inc. All Rights Reserved.
 * @author Gareth Johnson
 */

/**
 * Defines {@link baja.NavNode}.
 * @module baja/nav/NavNode
 */
define([ "bajaScript/sys",
        "bajaScript/baja/comm/Callback",
        "bajaScript/baja/nav/NavContainer",
        "bajaPromises" ], function (
        baja, 
        Callback, 
        NavContainer,
        bajaPromises) {
  
  "use strict";
  
  var subclass = baja.subclass,
      callSuper = baja.callSuper,
      objectify = baja.objectify;
  
  /**
   * A Space Nav Node Container. Used to represent BINavNode objects.
   *
   * @class
   * @alias baja.NavNode
   * @extends baja.NavContainer
   */
  var NavNode = function NavNode(obj) {
    callSuper(NavNode, this, arguments); 
  };
  
  subclass(NavNode, NavContainer);

  NavNode.prototype.getType = function () {
    return baja.lt("baja:INavNode");
  };

  function findContainerNode(node) {
    if (!node) {
      return null;
    }

    if (!(node instanceof NavNode)) {
      return node;
    }

    return findContainerNode(node.getNavParent());
  }
        
  /**
   * Access the Nav Children.
   *
   * @param {Object} obj the Object Literal for the method's arguments.
   * @param {Function} [obj.ok] (Deprecated: use Promise) called when we have
   * the Nav Children. An array of Nav Children is passed as an argument into
   * this function.
   * @param {Function} [obj.fail] (Deprecated: use Promise) called if the
   * function fails to complete.
   * @returns {Promise.<Array.<baja.NavNode>>} a promise that will be resolved
   * once the nav children have been retrieved.
   * 
   * @example
   *   node.getNavChildren()
   *     .then(function (kids) {
   *       baja.outln('retrieved nav children: ' + kids.join());
   *     })
   *     .catch(function (err) {
   *       baja.error('failed to retrieve nav children: ' + err);
   *     });
   */
  NavNode.prototype.getNavChildren = function (obj) {
    var that = this,
        cb,
        containerNode;

    obj = objectify(obj, "ok");
    cb = new Callback(obj.ok, obj.fail, obj.batch);

    cb.addOk(function (ok, fail, resp) {
      let i,
        x,
        node,
        kids = [],
        oldKids = [ ...that.$navKids ];

      for (i = 0; i < resp.length; ++i) {
        node = null;
        for (x = 0; x < oldKids.length; ++x) {
          const oldKid = oldKids[x];
          if (oldKid && oldKid.getNavName() === resp[i].navName) {
            node = oldKids[x];
            oldKids[x] = undefined;
            node.$update(resp[i]);
          }
        }
        kids.push(that.$addChildNode(node || new NavNode(resp[i])));
      }

      //cleanup any kids that need to be removed
      for (x = 0; x < oldKids.length; ++x) {
        const oldKid = oldKids[x];
        if (oldKid) {
          that.$removeChildNode(oldKid);
        }
      }

      ok(kids);
    });

    containerNode = findContainerNode(that);
    if (containerNode) {
      return containerNode.$send("navChildren", that.getNavOrd().toString(), cb);
    } else {
      return bajaPromises.resolve([]);
    }
  };
    
  return NavNode;
});