baja/comp/compUtil.js

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

define([ "bajaScript/comm",
        "bajaScript/baja/comm/Callback",
        "bajaPromises" ], function (baja, Callback, Promise) {
  
  "use strict";

  /**
   * API Status: **Private**
   * @exports module:baja/comp/compUtil
   */
  const exports = {};
    
  exports.setContextInOkCallback = function (comp, cb) {
    cb.addOk(function (ok, fail, resp) {
      ok.call(comp, resp);
    });
  };
  
  exports.setContextInFailCallback = function (comp, cb) {
    cb.addFail(function (ok, fail, err) {
      fail.call(comp, err);
    });
  };
  
  exports.unlease = function (comp) {
    // Reset lease
    comp.$lease = false;
    comp.$leaseTicket.cancel();
  
    if (comp.$subDf) {
      comp.$subDf.promise().finally(function () {
        if (exports.canUnsubscribe(comp)) {
          delete comp.$subDf;
          comp.$space.getCallbacks().unsubscribe([ "h:" + comp.$handle ], new Callback());
        } 
      });
    }
  };

  exports.canUnsubscribe = function (comp) {
    return comp.$subDf &&
           !Promise.isRejected(comp.$subDf.promise()) &&
           !comp.isSubscribed() &&
            comp.isMounted() &&
            comp.$space.hasCallbacks();
  };

  /**
   * @param {baja.Complex} comp
   * @param {string|baja.Slot|Array.<string|baja.Slot>|baja.SlotPath} slotPath the path of slots to follow
   * @returns {{complex: baja.Complex|null, slot: String}} the Complex found at the next-to-last slot
   * in the slot path (or the given Complex itself if the slot path length is 1), and the slot on
   * it. `complex` will be null if it could not be resolved from the slot path.
   * @since Niagara 4.15
   */
  exports.getComplexAndSlotFromPath = function (comp, slotPath) {
    slotPath = new baja.SlotPath(slotPath);

    comp = doBackup(comp, slotPath);
    const names = slotPath.getNames();

    const complex = names.slice(0, -1).reduce((comp, name) => {
      if (!isComplex(comp)) { return null; }
      switch (name) {
        case '..': return comp.getParent();
        case '.': return comp;
        default:
          return comp.get(name);
      }
    }, comp);

    const slot = names[names.length - 1];
    return { complex: isComplex(complex) ? complex : null, slot };
  };

  function isComplex(comp) {
    return baja.hasType(comp, 'baja:Complex');
  }

  function doBackup(comp, slotPath) {
    let depth = slotPath.getBackupDepth();
    while (depth--) { comp = comp.getParent(); }
    return comp;
  }

  return exports;
});