/*
*+------------------------------------------------------------------------+
*| Licensed Materials - Property of IBM
*| BI and PM: prmt
*| (C) Copyright IBM Corp. 2002, 2017
*|
*| US Government Users Restricted Rights - Use, duplication or
*| disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*|
*+------------------------------------------------------------------------+
*/
//IOS TREE CONTROL: We subclass the tree class to handle the fact that iOS' Voiceover intercepts key events and doesn't support some aria attributes
// oPane: the HTML element where the tree will be rendered
// oSubmit: the form control to submit selections to the server
// bRequired: is this a required field [true|false]
// bMultiSelect: can the user pick more than one value [true|false]
// sRef: the name of this object
// oImgTest: the image object used for validation handling
// oErrorFeedback: object used to provide validation feedback
// sCVId
// sStyle
// sTextDir
// sPromptName: the name of the prompt associated with the tree. This is used as a cache key prefix
CInnerTreeIOS.prototype = new CInnerTree;
function CInnerTreeIOS(oPane, oSubmit, bRequired, bMultiSelect, sRef, oImgTest, oErrorFeedback, sCVId, sStyle, sTextDir, sPromptName, oPromptControl)
{
CInnerTree.call(this, oPane, oSubmit, bRequired, bMultiSelect, sRef, oImgTest, oErrorFeedback, sCVId, sStyle, sTextDir, sPromptName, oPromptControl);
if(this.m_sDirection != "RTL") // Mobile iOS a11y: Remove the expando image from the read order
{
this.m_oToggleIMG.setAttribute("role", "presentation");
}
}
// * CInnerTree.prototype = new CPromptControl();
// Set this to the tree's parameter name if this is a prompt control tree
// getPromptValues OM function will be called automatically if this is a prompting tree
CInnerTreeIOS.prototype.drawLoading = function(node, nodeId)
{
var theElement = document.getElementById(nodeId);
if (!theElement && node.getNodeType() == TREE_ROOT && this.getRootNodeShowing() == false)
{
theElement = this.m_oPane;
}
if (theElement != null)
{
var newDivContainer = document.createElement("DIV");
newDivContainer.className = CLS_TREE_LEVEL;
newDivContainer.id = this.getName() + node.getTreeRef() + "loading";
newDivContainer.style.width = "100%";
var newNobrContainer = document.createElement("NOBR");
this.drawTreeLines(node, newNobrContainer, node.getLevel() + 1);
if (!(node.getNodeType() == TREE_ROOT && node.getTree().getRootNodeShowing() == false && node.getMoreData() != true))
{
var newLIcon = document.createElement("IMG");
newLIcon.align = gsCTREE_middle;
newLIcon.src = (this.m_sDirection == "RTL" ? TREE_L_ONLY_RTL : TREE_L_ONLY);
//mobile a11y
if(this.m_sDirection != "RTL")
{
newLIcon.setAttribute("role", "presentation");
}
newNobrContainer.appendChild(newLIcon);
}
var newStateIcon = document.createElement("IMG");
newStateIcon.align = gsCTREE_middle;
newStateIcon.src = TREE_LOADING;
newNobrContainer.appendChild(newStateIcon);
var newLabelContainer = document.createElement("SPAN");
newLabelContainer.className = CLS_TREE_NODE_UNSELECTED + K_PRMT_sSP + CLS_TREE_TEXT;
//We need the localized string for "Loading..." here
if (typeof PMT_TRE_TREE_LOADING != K_PRMT_sUNDEFINED)
{
var newStateText = document.createTextNode(PMT_TRE_TREE_LOADING);
newLabelContainer.appendChild(newStateText);
newLabelContainer.title = PMT_TRE_TREE_LOADING;
}
newNobrContainer.appendChild(newLabelContainer);
newDivContainer.appendChild(newNobrContainer);
theElement.appendChild(newDivContainer);
}
};
CInnerTreeIOS.prototype.drawMoreData = function(node, nodeId)
{
var theElement = document.getElementById(nodeId);
if (!theElement && node.getNodeType() == TREE_ROOT && this.getRootNodeShowing() == false)
{
theElement = this.m_oPane;
}
var childrenContainer = (theElement.getAttribute("role") == "tree"? theElement : theElement.firstChild.nextSibling);
if (theElement != null && childrenContainer != null && (childrenContainer.getAttribute("role") == "group" || childrenContainer.getAttribute("role") == "tree"))
{
var newDivContainer = document.createElement("DIV");
newDivContainer.className = CLS_TREE_LEVEL;
newDivContainer.id = this.getName() + node.getTreeRef() + "moredata";
newDivContainer.style.width = "100%";
var newNobrContainer = document.createElement("NOBR");
this.drawTreeLines(node, newNobrContainer, node.getLevel() + 1);
var newLIcon = document.createElement("IMG");
newLIcon.align = gsCTREE_middle;
newLIcon.src = (this.m_sDirection == "RTL" ? TREE_L_ONLY_RTL : TREE_L_ONLY);
//mobile a11y
if(this.m_sDirection != "RTL")
{
newLIcon.setAttribute("role", "presentation");
}
newNobrContainer.appendChild(newLIcon);
var newStateIcon = document.createElement("IMG");
newStateIcon.align = gsCTREE_middle;
newStateIcon.src = TREE_MORE_DATA;
newStateIcon.setAttribute("role", "presentation");
newNobrContainer.appendChild(newStateIcon);
var newLabelContainer = document.createElement("SPAN");
newLabelContainer.className = CLS_TREE_NODE_UNSELECTED + K_PRMT_sSP + CLS_TREE_TEXT_LINK;
//We need the localized string for "More" here
if (typeof PMT_TRE_MORE != K_PRMT_sUNDEFINED)
{
var newStateText = document.createTextNode(PMT_TRE_MORE);
newLabelContainer.appendChild(newStateText);
newLabelContainer.title = PMT_TRE_MORE;
}
newLabelContainer.id = this.getName() + node.getTreeRef() + "moredatalabel";
newLabelContainer.setAttribute(gsCTREE_tree, this.getName());
newLabelContainer.setAttribute(gsCTREE_treeRef, node.getTreeRef());
newLabelContainer.tabIndex = 0;
PRMTUtils.f_addEvent(newLabelContainer, "click", getMoreDataForTreeNode);
PRMTUtils.f_addEvent(newLabelContainer, "keydown", getMoreDataForTreeNode);
PRMTUtils.f_addEvent(newLabelContainer, "keypress", getMoreDataForTreeNode);
newNobrContainer.appendChild(newLabelContainer);
newDivContainer.appendChild(newNobrContainer);
childrenContainer.appendChild(newDivContainer);
}
};
CInnerTreeIOS.prototype.draw = function(node, oParentElement)
{
if (node.getTree().getDisabled() == true)
{
return false;
}
var treeRef = node.getTreeRef();
var treeName = this.getName();
//if the node is the root node, removes the old root node so that the entire tree is redrawn
//this takes care of the case where a loading tree is replaced with real data
if (node.getNodeType() == TREE_ROOT)
{
var rootNode = document.getElementById(treeName);
if (rootNode != null) {
oParentElement.removeChild(rootNode);
}
oParentElement.setAttribute(gsCTREE_treeRef, treeRef);
oParentElement.setAttribute(gsCTREE_tree, treeName);
}
// clone outer container DIV (it's much faster than create a new one)
var nodeElement = this.m_oDIVnewElement.cloneNode(true);
PRMTUtils.f_addEvent( nodeElement, "dragstart", dragStartOnNode );
PRMTUtils.f_addEvent( nodeElement, "drag", dragOnNode );
PRMTUtils.f_addEvent( nodeElement, "dragend", dragEndOnNode );
nodeElement.setAttribute(gsCTREE_treeRef, treeRef);
nodeElement.setAttribute(gsCTREE_tree, treeName);
if (treeRef == K_PRMT_sEMPTY) {
nodeElement.setAttribute(K_PRMT_ARIA_ROLE, "listbox");
}
nodeElement.id = treeName + treeRef;
if (!(node.getNodeType() == TREE_ROOT && this.getRootNodeShowing() == false))
{
this.drawNode(node, nodeElement);
}
// ******************************************************************
// deal with children
// ******************************************************************
oParentElement.appendChild(nodeElement);
this.drawNodeChildren (node, nodeElement);
this.m_bHasBeenDrawn = true;
};
CInnerTreeIOS.prototype.detailToogleIcon = function(node, newToggleIcon) {
// text for high contrast
var newToggleText = this.m_oTextSPAN.cloneNode(true);
newToggleText.className= K_PRMT_TREE_TOGGLE_TEXT;
newToggleText.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
var toggleTextContent = "";
if (node.canHaveChildren() == true)
{
newToggleIcon.setAttribute("aria-labelledby", node.id);
if (node.isOpen() == true)
{
newToggleIcon.className = K_PRMT_TREE_TOGGLE_OPENED + this.m_sDirection;
newToggleIcon.title = PMT_TRE_COLLAPSE;
newToggleIcon.alt = PMT_TRE_COLLAPSE;
//newToggleIcon.setAttribute(K_PRMT_TREE_STATE_EXPANDED, true);
toggleTextContent = "-";
}
else
{
newToggleIcon.className= K_PRMT_TREE_TOGGLE_CLOSED + this.m_sDirection;
newToggleIcon.title = PMT_TRE_EXPAND;
newToggleIcon.alt = PMT_TRE_EXPAND;
toggleTextContent = "+";
}
newToggleIcon.tabIndex = -1;
newToggleIcon.onclick = this.toggle;
newToggleText.onclick = this.toggle;
}
else
{
newToggleIcon.className= K_PRMT_TREE_TOGGLE_LEAF;
newToggleIcon.src = PROMT_IMAGES + "blank.gif";
newToggleIcon.alt = "";
newToggleIcon.onclick = null;
newToggleIcon.removeAttribute("aria-labelledby");
newToggleIcon.removeAttribute("title");
newToggleIcon.removeAttribute("tabindex");
}
var toggleTextNode= document.createTextNode(toggleTextContent);
newToggleText.appendChild(toggleTextNode);
newToggleIcon.setAttribute(gsCTREE_treeRef, gsCTREE_img);
return [newToggleIcon, newToggleText];
};
/**
* Draws the checkbox
*
*/
CInnerTreeIOS.prototype.drawNodeCheckboxIcon = function(node) {
var checkBoxIcon = CInnerTree.prototype.drawNodeCheckboxIcon.call(this, node);
checkBoxIcon.setAttribute("aria-hidden", "true");
return checkBoxIcon;
};
/**
* Draws the label Node label
*
*/
CInnerTreeIOS.prototype.drawNodeLabel = function(node, treeName, treeRef) {
var nodeElementLabelContainer = this.m_oLabelSPAN.cloneNode(true);
nodeElementLabelContainer.id = treeName + treeRef + gsCTREE_labelText;
this.updateLabelClass(nodeElementLabelContainer, getClassName(node, this), node);
nodeElementLabelContainer.setAttribute(gsCTREE_treeRef, treeRef);
nodeElementLabelContainer.setAttribute(gsCTREE_dragRef, treeRef.toString());
nodeElementLabelContainer.setAttribute(gsCTREE_dragTree, treeName);
nodeElementLabelContainer.setAttribute(gsCTREE_tree, treeName);
node.m_oLabelText = nodeElementLabelContainer;
if (node.isFirst()) {
nodeElementLabelContainer.tabIndex = 0;
this.m_lastFocus = nodeElementLabelContainer;
}
var labelText = document.createTextNode( G_IsBidiEnabled && this.m_sTextDir ? PRMT_BidiUtils.enforceBidiDirection(node.getName(), this.m_sTextDir) : node.getName() );
nodeElementLabelContainer.appendChild(labelText);
var sStyle = this.getStyle();
nodeElementLabelContainer.style.color= cssParser(sStyle,"color",true);
nodeElementLabelContainer.style.backgroundColor= cssParser(sStyle,"background-color",true);
nodeElementLabelContainer.style.fontFamily= cssParser(sStyle,"font-family",true);
nodeElementLabelContainer.style.fontSize= cssParser(sStyle,"font-size",true);
nodeElementLabelContainer.style.fontWeight= cssParser(sStyle,"font-weight",true);
nodeElementLabelContainer.style.fontStyle= cssParser(sStyle,"font-style",true);
nodeElementLabelContainer.style.fontVariant= cssParser(sStyle,"font-variant",true);
nodeElementLabelContainer.style.textAlign= cssParser(sStyle,"text-align",true);
nodeElementLabelContainer.style.textVariant= cssParser(sStyle,"text-variant",true);
nodeElementLabelContainer.style.textIndent= cssParser(sStyle,"text-indent",true);
nodeElementLabelContainer.style.textTransform= cssParser(sStyle,"text-transform",true);
nodeElementLabelContainer.setAttribute(gsCTREE_treeRef, treeRef);
nodeElementLabelContainer.setAttribute(gsCTREE_dragRef, treeRef.toString());
nodeElementLabelContainer.setAttribute(gsCTREE_dragTree, treeName);
nodeElementLabelContainer.setAttribute(gsCTREE_tree, treeName);
nodeElementLabelContainer.setAttribute("onfocus","this.classname='" + CLS_TREE_NODE_HOVER + " " + CLS_TREE_TEXT + "';");
nodeElementLabelContainer.setAttribute("onblur","this.classname='" + CLS_TREE_NODE_UNSELECTED + " " + CLS_TREE_TEXT + "';");
return nodeElementLabelContainer;
};
/**
* Process event from click in Toggle icon
*/
CInnerTreeIOS.prototype.toggle = function(evt, uiNode)
{
//get the event in a cross-browser fashion
evt = (evt) ? evt : ((event) ? event : null);
//cancel any text selection
clearSelection();
//prevent the event from bubbling to other elements
PRMTUtils.F_StopEvent(evt);
//get UI Node
uiNode = (uiNode? getUINode(null, uiNode) : getUINode(evt));
var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
//get the tree object
var tree = uiNode.getAttribute(gsCTREE_tree).toString();
//get tree Node
var node = getTreeNode(tree, uiNodeTreeRef);
var v_oTree = node.getTree();
if (v_oTree && v_oTree.canToggleNode(node))
{
v_oTree.toggleExpandCollapse(uiNode, node, 0);
}
};
CInnerTreeIOS.prototype.toggleExpandCollapse = function(uiNode, node, toggleDirection)
{
var result = false;
var tree = uiNode.getAttribute(gsCTREE_tree).toString();
//toggle folders
var isExpanded = null;
if ( node.isClosed() && toggleDirection != K_PRMT_TREE_COLLAPSE )
{
isExpanded = true;
this.expandNode(uiNode, node);
result = true;
}
else if ( (node.isOpen()) && toggleDirection != K_PRMT_TREE_EXPAND )
{
isExpanded = false;
this.collapseNode(uiNode, node);
result = true;
}
if (isExpanded){
this.setCacheValue(this.getExpandedNodeCacheKey(node), "true");
}else{
this.removeCacheValue(this.getExpandedNodeCacheKey(node));
}
updateToggleIcon(node, tree);
// update aria-expanded
if ( isExpanded != null ) {
this.updateAriaLabelContainer(node, tree, isExpanded);
}
return result;
};
/**
* Update the label container aria-expanded attribute
*/
CInnerTreeIOS.prototype.updateAriaLabelContainer = function(oNode, sTreeName, ariaExpanded)
{
var labelContainer = document.getElementById(sTreeName + oNode.getTreeRef() + gsCTREE_labelText);
if (labelContainer && oNode.canHaveChildren())
{
labelContainer.setAttribute(K_PRMT_TREE_STATE_EXPANDED, ariaExpanded);
} else if(!oNode.canHaveChildren())
{
oNode.removeAttribute(K_PRMT_TREE_STATE_EXPANDED);
}
};