123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- /*
- *+------------------------------------------------------------------------+
- *| 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 <span>Node label</span>
- *
- */
- 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<span> 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);
- }
- };
|