/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Gareth Johnson
*/
/**
* Defines {@link baja.NavContainer}.
* @module baja/nav/NavContainer
*/
define([
"bajaScript/sys",
"bajaScript/baja/obj/Icon",
"bajaScript/baja/obj/Object",
"bajaScript/baja/comm/Callback" ], function (
baja,
Icon,
BObject,
Callback) {
"use strict";
var subclass = baja.subclass,
callSuper = baja.callSuper,
objectify = baja.objectify,
emptyObj = {};
/**
* `NavContainer` is a generic `NavNode`.
*
* @class
* @alias baja.NavContainer
* @extends baja.Object
*/
var NavContainer = function NavContainer(obj) {
var that = this;
callSuper(NavContainer, that, arguments);
that.$navKids = [];
that.$update(obj);
};
subclass(NavContainer, BObject);
/**
* Return the type spec of object this nav node navigates to.
*
* @return {String} The nav type spec.
*/
NavContainer.prototype.getNavTypeSpec = function () {
return this.$navTypeSpec;
};
/**
* Return the Nav Name.
*
* @returns {String}
*/
NavContainer.prototype.getNavName = function () {
return this.$navName;
};
/**
* Return the Nav Display Name.
*
* @returns {String}
*/
NavContainer.prototype.getNavDisplayName = function () {
return this.$navDisplayName;
};
/**
* Return the Nav Description.
*
* @returns {String}
*/
NavContainer.prototype.getNavDescription = function () {
return this.$navDescription;
};
/**
* Return the Nav ORD.
*
* If passing `sessionAware`, the returned ORD may return session information
* when BajaScript is running in Workbench (most commonly including the IP
* address and fox|foxs schemes). Note that a session-aware ORD is not safe
* to pass directly up to a station for resolution as in an RPC or servlet
* call, as a station won't know how to open a FOX session to itself.
*
* @param {object} [params]
* @param {boolean} [params.sessionAware] include session information if
* available
* @returns {baja.Ord}
* @example
* <caption>When running in Workbench, connected to a station at ip:1.2.3.4,
* session information can be retrieved.</caption>
* console.log(services.getNavOrd());
* // local:|station:|slot:/Services
* console.log(services.getNavOrd({ sessionAware: true });
* // ip:1.2.3.4|fox:|station:|slot:/Services
*
* @example
* <caption>When running in a browser, session information is never present.
* </caption>
* console.log(services.getNavOrd());
* // local:|station:|slot:/Services
* console.log(services.getNavOrd({ sessionAware: true });
* // local:|station:|slot:/Services
*/
NavContainer.prototype.getNavOrd = function (params) {
var sessionAware = baja.objectify(params).sessionAware;
if (sessionAware) {
if (!this.$sessionNavOrd) {
this.$sessionNavOrd = baja.Ord.make(this.$sessionNavOrdStr);
}
return this.$sessionNavOrd;
} else {
if (!this.$navOrd) {
this.$navOrd = baja.Ord.make(this.$navOrdStr);
}
return this.$navOrd;
}
};
/**
* Return the Nav Parent (or null if there's no parent).
*
* @returns {baja.NavContainer}
*/
NavContainer.prototype.getNavParent = function () {
return this.$navParent || null;
};
/**
* 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
* container.getNavChildren()
* .then(function (kids) {
* baja.outln('retrieved nav children: ' + kids.join());
* })
* .catch(function (err) {
* baja.error('failed to retrieve nav children: ' + err);
* });
*/
NavContainer.prototype.getNavChildren = function (obj) {
obj = objectify(obj, "ok");
var cb = new Callback(obj.ok);
cb.ok(this.$navKids);
return cb.promise();
};
/**
* Return the Nav Icon for this node.
*
* @returns {baja.Icon}
*/
NavContainer.prototype.getNavIcon = function () {
if (!this.$navIcon) {
this.$navIcon = Icon.make(this.$navIconStr);
}
return this.$navIcon;
};
/**
*
* @since Niagara 4.14
* @returns {baja.Permissions}
* @throws {Error} if this node is not a BIProtected
*/
NavContainer.prototype.getPermissions = function () {
if (!this.$permissionsStr) {
throw new Error(this.getNavOrd() + ": Cannot determine permissions on this node." +
"\nResolve and get permissions on the target instead.");
}
return baja.Permissions.make(this.$permissionsStr);
};
/**
* Add a child node to this container.
*
* Please note, this is a private method and should only be used by Tridium developers.
*
* @private
*
* @param node
* @returns node
*/
NavContainer.prototype.$addChildNode = function (node) {
node.$navParent = this;
this.$navKids.push(node);
return node;
};
/**
* Remove a child node from this container. If found and removed, the node is
* returned. If not found then null is returned.
*
* Please note, this is a private method and should only be used by Tridium developers.
*
* @private
*
* @param {string} name
* @returns node
*/
NavContainer.prototype.$removeChildNode = function (name) {
var i,
navKids = this.$navKids,
oldNode = null;
for (i = 0; i < navKids.length; ++i) {
if (navKids[i].getNavName() === name) {
oldNode = navKids[i];
oldNode.$navParent = null;
navKids.splice(i, 1);
break;
}
}
return oldNode;
};
/**
* Remove all the children from the container.
*
* Please note, this is a private method and should only be used by Tridium developers.
*
* @private
*
* @returns An array of the child nodes that were removed.
*/
NavContainer.prototype.$removeAllChildNodes = function () {
var i,
navKids = this.$navKids;
for (i = 0; i < navKids.length; ++i) {
navKids[i].$navParent = null;
}
this.$navKids = [];
return navKids;
};
/**
* Update the node with the new nav node information. This will not reset any children.
*
* @private
*
* @param {Object} [obj] An object literal that contains the updated information.
*/
NavContainer.prototype.$update = function (obj) {
obj = obj || emptyObj;
var that = this;
that.$navName = obj.navName || "";
that.$navDisplayName = (obj.displayName || obj.navName) || "";
that.$navDescription = obj.description || that.$navDisplayName;
that.$navOrdStr = obj.ord || "";
that.$navOrd = null;
that.$sessionNavOrdStr = obj.sessionOrd || that.$navOrdStr;
that.$sessionNavOrd = null;
that.$navIconStr = obj.icon || "";
that.$navIcon = "";
that.$navTypeSpec = obj.typeSpec || "baja:INavNode";
that.$permissionsStr = obj.hasOwnProperty('permissions') ? obj.permissions : null;
};
/**
* Updates and returns the child node.
*
* @private
*
* @param {String} name The name of the child to find.
* @param obj The object to update the nav node with.
* @returns The updated child node or null if it couldn't be found.
*/
NavContainer.prototype.$updateChildNode = function (name, obj) {
var i,
navKids = this.$navKids,
node = null;
for (i = 0; i < navKids.length; ++i) {
if (navKids[i].getNavName() === name) {
node = navKids[i];
node.$update(obj);
break;
}
}
return node;
};
/**
* NavNodes do not always fire renamed events. Use this method to make BajaScript nav event
* handlers behave as though this one did.
*
* @private
* @param {string} newName
* @param {object} [cx]
* @since Niagara 4.14
*/
NavContainer.prototype.$syntheticSetName = function (newName, cx = {}) {
const oldName = this.$navName;
this.$navName = newName;
const parent = this.getNavParent();
if (parent) {
baja.nav.fireHandlers('renamed', (err) => { throw err; }, baja.nav,
parent.getNavOrd(), this, oldName, cx);
}
};
/**
* Set the new nav display name, and trigger a "renamed" event on the same nav name. This should
* trigger event consumers to repaint this nav node with the new display name as needed.
*
* @private
* @param {string} newName
* @param {object} [cx]
* @since Niagara 4.14
*/
NavContainer.prototype.$syntheticSetDisplayName = function (newName, cx) {
this.$navDisplayName = newName;
this.$syntheticSetName(this.getNavName(), cx);
};
return NavContainer;
});