/** * Visits the nodes selected by this range when we know * a-priori that the start and end containers are not the * same, but the end container is an ancestor of the start container * */ DOM_DocumentFragment RangeImpl::traverseCommonEndContainer( DOM_Node startAncestor, int how ) { DOM_DocumentFragment frag = null; if ( how!=DELETE_CONTENTS) frag = fDocument.createDocumentFragment(); DOM_Node n = traverseLeftBoundary( startAncestor, how ); if ( frag!=null ) frag.appendChild( n ); int startIdx = indexOf( startAncestor, fEndContainer ); ++startIdx; // Because we already traversed it.... int cnt = fEndOffset - startIdx; n = startAncestor.getNextSibling(); while( cnt > 0 ) { DOM_Node sibling = n.getNextSibling(); DOM_Node xferNode = traverseFullySelected( n, how ); if ( frag!=null ) frag.appendChild( xferNode ); --cnt; n = sibling; } if ( how != CLONE_CONTENTS ) { setStartAfter( startAncestor ); collapse( true ); } return frag; }
EppCommandCheckContact * EppCommandCheckContact::fromXML( const DOM_Node& root ) { EppCommandCheckContact * cmd = new EppCommandCheckContact(); DOM_NodeList list = root.getChildNodes(); for( unsigned int i = 0; i < list.getLength(); i++ ) { DOM_Node node = list.item(i); DOMString name = node.getLocalName(); if( name == null ) { name = node.getNodeName(); } if( name == null ) { continue; } if( name.equals("id") || name.equals("contact:id") ) { DOMString id = EppUtil::getText(node); cmd->addId(id); } } return cmd; }
/** * Utility method for traversing a text node that we know * a-priori to be on a left or right boundary of the range. * This method does not properly handle text nodes that contain * both the start and end points of the range. * */ DOM_Node RangeImpl::traverseTextNode( DOM_Node n, bool isLeft, int how ) { DOMString txtValue = n.getNodeValue(); DOMString newNodeValue; DOMString oldNodeValue; if ( isLeft ) { int offset = getStartOffset(); newNodeValue = txtValue.substringData( offset , fStartContainer.getNodeValue().length()-offset); oldNodeValue = txtValue.substringData( 0, offset ); } else { int offset = getEndOffset(); newNodeValue = txtValue.substringData( 0, offset ); oldNodeValue = txtValue.substringData( offset , fEndContainer.getNodeValue().length()-offset ); } if ( how != CLONE_CONTENTS ) n.setNodeValue( oldNodeValue ); if ( how==DELETE_CONTENTS ) return null; DOM_Node newNode = n.cloneNode( false ); newNode.setNodeValue( newNodeValue ); return newNode; }
void NodeIteratorImpl::removeNode (DOM_Node node) { if (fDetached) throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null); // Implementation note: Fix-up means setting the current node properly // after a remove. if (node.isNull()) return; DOM_Node deleted = matchNodeOrParent(node); if (deleted.isNull()) return; if (fForward) { fCurrentNode = previousNode(deleted); } else // if (!fForward) { DOM_Node next = nextNode(deleted, false); if (! next.isNull()) { // normal case: there _are_ nodes following this in the iterator. fCurrentNode = next; } else { // the last node in the iterator is to be removed, // so we set the current node to be the previous one. fCurrentNode = previousNode(deleted); fForward = true; } } }
EppResponseDataTransferContact * EppResponseDataTransferContact::fromXML( const DOM_Node& root ) { EppResponseDataTransferContact * res = null; DOM_NodeList list = root.getChildNodes(); for( unsigned int i = 0; i < list.getLength(); i++ ) { DOM_Node node = list.item(i); DOMString name = node.getLocalName(); if( name == null ) { name = node.getNodeName(); } if( name == null ) { continue; } // if( name.equals("id") ) if( name.equals("id") || name.equals("contact:id") ) { if( res == null ) { DOMString id = EppUtil::getText(node); res = new EppResponseDataTransferContact(id); } } else if( res != null ) { res->fromXMLCommon(node, name); } } return res; }
short TreeWalkerImpl::acceptNode (DOM_Node node) { if (fNodeFilter == 0) { if ( ( fWhatToShow & (1 << (node.getNodeType() - 1))) != 0) { return DOM_NodeFilter::FILTER_ACCEPT; } else { return DOM_NodeFilter::FILTER_SKIP; } } else { // REVISIT: This logic is unclear from the spec! if ((fWhatToShow & (1 << (node.getNodeType() - 1))) != 0 ) { return fNodeFilter->acceptNode(node); } else { // what to show has failed! if (fNodeFilter->acceptNode(node) == DOM_NodeFilter::FILTER_REJECT) { return DOM_NodeFilter::FILTER_REJECT; } else { return DOM_NodeFilter::FILTER_SKIP; } } } }
//====================================================================== //====================================================================== bool XMLDocument::doAttributesMatch(DOM_Node currNode, DataTypeAttribute** dtAttributes) { DOM_NamedNodeMap nnodeMap = currNode.getAttributes(); int len = nnodeMap.getLength(); int a = 0; DataTypeAttribute* dtAttribute; while ((dtAttribute = (DataTypeAttribute*)dtAttributes[a++]) != (DataTypeAttribute*)NULL) { bool isFound = false; for (int i = 0; i < len && !isFound; i++) { DOM_Node attNode = nnodeMap.item(i); char* tmp = attNode.getNodeName().transcode(); char* tmp1 = attNode.getNodeValue().transcode(); if (strcmp(dtAttribute->getName(), tmp) == 0 && strcmp(dtAttribute->getValue(), tmp1) == 0) { isFound = true; } delete[] tmp; delete[] tmp1; } if (!isFound) return false; } return true; }
EppCommandLogin * EppCommandLogin::fromXML( const DOM_Node& root ) { EppCommandLogin * cmd = null; DOM_NodeList list = root.getChildNodes(); for( unsigned int i = 0; i < list.getLength(); i++ ) { DOM_Node node = list.item(i); DOMString name = node.getLocalName(); if( name == null ) { name = node.getNodeName(); } if( name == null ) { continue; } if( name.equals("svcs") ) { EppServiceMenu * menu = EppServiceMenu::fromXML(node); if( menu != null ) { cmd = new EppCommandLogin(*menu); delete menu; return cmd; } } } return null; }
static OP_STATUS DOM_SetBoundaryPoint(DOM_EnvironmentImpl *environment, DOM_Document *document, DOM_Range::BoundaryPoint &bp, HTML_Element *elm, unsigned offset, BOOL place_after) { OP_ASSERT(elm); DOM_Node *node; RETURN_IF_ERROR(environment->ConstructNode(node, elm, document)); if (!node->IsA(DOM_TYPE_CHARACTERDATA) && !elm->FirstChildActual()) { HTML_Element *parent = elm->ParentActual(); if (parent) { RETURN_IF_ERROR(environment->ConstructNode(bp.node, parent, document)); bp.offset = DOM_Range::CalculateOffset(elm); if (place_after) { bp.offset++; bp.unit = NULL; } else bp.unit = node; return OpStatus::OK; } } bp.node = node; bp.offset = offset; bp.unit = NULL; return OpStatus::OK; }
void RangeImpl::checkIndex(const DOM_Node& node, unsigned int offset) const { if (offset < 0) { throw DOM_DOMException( DOM_DOMException::INDEX_SIZE_ERR, null ); } short type = node.getNodeType(); if((type == DOM_Node::TEXT_NODE || type == DOM_Node::CDATA_SECTION_NODE || type == DOM_Node::COMMENT_NODE || type == DOM_Node::PROCESSING_INSTRUCTION_NODE)) { if (offset > node.getNodeValue().length()) throw DOM_DOMException( DOM_DOMException::INDEX_SIZE_ERR, null ); else return; } DOM_Node child = node.getFirstChild(); unsigned int i = 0; for (; child != null; i++) { child = child.getNextSibling(); } if (i < offset) { throw DOM_DOMException( DOM_DOMException::INDEX_SIZE_ERR, null ); } }
/** Return node, if matches or any parent if matches. */ DOM_Node NodeIteratorImpl::matchNodeOrParent (DOM_Node node) { DOM_Node result; for (DOM_Node n = fCurrentNode; n != fRoot; n = n.getParentNode()) { if (node == n) return n; } return result; }
unsigned short RangeImpl::indexOf(const DOM_Node& child, const DOM_Node& parent) const { unsigned short i = 0; if (child.getParentNode() != parent) return (unsigned short)-1; for(DOM_Node node = child.getPreviousSibling(); node!= null; node=node.getPreviousSibling()) { i++; } return i; }
/** The node is accepted if it passes the whatToShow and the filter. */ bool NodeIteratorImpl::acceptNode (DOM_Node node) { if (fDetached) throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null); if (fNodeFilter == 0) { return ((fWhatToShow & (1 << (node.getNodeType() - 1))) != 0); } else { return ((fWhatToShow & (1 << (node.getNodeType() - 1))) != 0) && fNodeFilter->acceptNode(node) == DOM_NodeFilter::FILTER_ACCEPT; } }
bool RangeImpl::isValidAncestorType(const DOM_Node& node) const { for (DOM_Node aNode = node; aNode!=null; aNode = aNode.getParentNode()) { short type = aNode.getNodeType(); if ( type == DOM_Node::ENTITY_NODE || type == DOM_Node::NOTATION_NODE || type == DOM_Node::DOCUMENT_TYPE_NODE) return false; } return true; }
DOM_Node TreeWalkerImpl::nextSibling () { DOM_Node result; if (fCurrentNode.isNull()) return result; DOM_Node node = getNextSibling(fCurrentNode); if (! node.isNull()) { fCurrentNode = node; } return node; }
EppCommandInfoSvcsub * EppCommandInfoSvcsub::fromXML( const DOM_Node& root ) { EppCommandInfoSvcsub * cmd = null; EppAuthInfo * authInfo = null; DOMString userid = null; DOM_NodeList list = root.getChildNodes(); for( unsigned int i = 0; i < list.getLength(); i++ ) { DOM_Node node = list.item(i); DOMString name = node.getLocalName(); if( name == null ) { name = node.getNodeName(); } if( name == null ) { continue; } // if( name.equals("id") ) if( name.equals("id") || name.equals("svcsub:id") ) { DOMString id = EppUtil::getText(node); if( cmd == null ) { cmd = new EppCommandInfoSvcsub(id); } } // if( name.equals("userid") ) if( name.equals("userid") || name.equals("svcsub:userid") ) { userid = EppUtil::getText(node); } // else if( name.equals("authInfo") ) else if( name.equals("authInfo") || name.equals("svcsub:authInfo") ) { if( authInfo == null ) { authInfo = EppAuthInfo::fromXML(node); } } } if( cmd != null ) { cmd->authInfo = authInfo; cmd->userid = userid; } else if( authInfo != null ) { delete authInfo; } return cmd; }
/** Return the last child Node from the current node, * after applying filter, whatToshow. * If result is not null, set the current Node. */ DOM_Node TreeWalkerImpl::lastChild () { DOM_Node result; if (fCurrentNode.isNull()) return result; DOM_Node node = getLastChild(fCurrentNode); if (! node.isNull()) { fCurrentNode = node; } return node; }
EppContact * EppContact::fromXML( const DOM_Node& root ) { EppContact * contact = new EppContact(); DOM_NodeList list = root.getChildNodes(); for( unsigned int i = 0; i < list.getLength(); i++ ) { DOM_Node node = list.item(i); DOMString name = node.getLocalName(); if( name == null ) { name = node.getNodeName(); } if( name == null ) { continue; } if( name.substringData(0, 8).equals("contact:") ) { name = name.substringData(8, name.length() - 8); } if( name.equals("id") ) { contact->id = EppUtil::getText(node); } else if( name.equals("ascii") ) { contact->ascii = EppContactData::fromXML(node); } else if( name.equals("i15d") ) { contact->i15d = EppContactData::fromXML(node); } else if( name.equals("voice") ) { contact->voice = EppE164::fromXML(node); } else if( name.equals("fax") ) { contact->fax = EppE164::fromXML(node); } else if( name.equals("email") ) { contact->email = EppUtil::getText(node); } else { contact->fromXMLCommon(node, name); } } return contact; }
void RangeImpl::checkReadOnly(DOM_Node& start, DOM_Node& end, unsigned int startOffset, unsigned int endOffset) { if ((start == null) || (end == null) ) return; //if both start and end are text check and return if (start.getNodeType() == DOM_Node::TEXT_NODE) { if (start.fImpl->isReadOnly()) { throw DOM_DOMException( DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null); } if (start == end) return; } //set the start and end nodes to check DOM_Node sNode = start.getFirstChild(); for(unsigned int i = 0; i<startOffset; i++) sNode = sNode.getNextSibling(); DOM_Node eNode; if (end.getNodeType() == DOM_Node::TEXT_NODE) { eNode = end; //need to check only till this node } else { //need to check all the kids that fall before the end offset value eNode = end.getFirstChild(); for (unsigned int i = 0; i<endOffset-1; i++) eNode = eNode.getNextSibling(); } //recursivly search if any node is readonly recurseTreeAndCheck(sNode, eNode); }
DOM_Node XMLDocument::getNode(DOM_Node currNode, char* path, DataTypeAttribute** dtAttributes) { if (path == NULL) return NULL_DOM_Node; char* currName = currNode.getNodeName().transcode(); if (strcmp(currName, path) == 0 && (dtAttributes == NULL || doAttributesMatch(currNode, dtAttributes))) { delete[] currName; return currNode; } delete[] currName; char* cp = strchr(path, '.'); char pathName[256]; if (cp == NULL) strcpy(pathName, path); else { strncpy(pathName, path, cp - path); pathName[cp - path] = '\0'; } DOM_Node child = currNode.getFirstChild(); while (child != NULL) { char* childName = child.getNodeName().transcode(); if (child.getNodeType() != DOM_Node::ELEMENT_NODE) { child = child.getNextSibling(); delete[] childName; continue; } if (strcmp(pathName, childName) == 0) { if (cp != NULL) { delete[] childName; return getNode(child, cp+1, dtAttributes); } if (dtAttributes != NULL) { if (!doAttributesMatch(child, dtAttributes)) { child = child.getNextSibling(); delete[] childName; continue; } } delete[] childName; return child; } delete[] childName; child = child.getNextSibling(); } return NULL_DOM_Node; }
bool RangeImpl::hasLegalRootContainer(const DOM_Node& node) const { if ( node==null ) return false; DOM_Node rootContainer = node; for (; rootContainer.getParentNode()!=null; rootContainer = rootContainer.getParentNode()) ; switch( rootContainer.getNodeType() ) { case DOM_Node::ATTRIBUTE_NODE: case DOM_Node::DOCUMENT_NODE: case DOM_Node::DOCUMENT_FRAGMENT_NODE: return true; } return false; }
DOM_Node RangeImpl::removeChild(DOM_Node& parent, DOM_Node& child) { fRemoveChild = child; //only a precaution measure not to update this range data before removal DOM_Node n = parent.removeChild(child); fRemoveChild = null; return n; }
/* virtual */ ES_PutState DOM_HTMLDocument::PutNameRestart(OpAtom property_name, ES_Value* value, ES_Runtime* origining_runtime, ES_Object *restart_object) { if (property_name == OP_ATOM_body) return ((DOM_HTMLElement *) root)->PutChildElement(OP_ATOM_body, value, (DOM_Runtime *) origining_runtime, restart_object); else if (property_name == OP_ATOM_title) if (HTML_Element *element = GetElement(HE_TITLE)) { DOM_Node *node; PUT_FAILED_IF_ERROR(GetEnvironment()->ConstructNode(node, element, this)); return node->PutNameRestart(OP_ATOM_text, value, origining_runtime, restart_object); } else return PUT_SUCCESS; else return PUT_FAILED; }
DOM_Node TreeWalkerImpl::getParentNode (DOM_Node node) { DOM_Node result; if (node.isNull() || node == fRoot) return result; DOM_Node newNode = node.getParentNode(); if (newNode.isNull()) return result; short accept = acceptNode(newNode); if (accept == DOM_NodeFilter::FILTER_ACCEPT) return newNode; return getParentNode(newNode); }
/** * Utility method for traversing a single node. * Does not properly handle a text node containing both the * start and end offsets. Such nodes should * have been previously detected and been routed to traverseTextNode. * */ DOM_Node RangeImpl::traverseNode( DOM_Node n, bool isFullySelected, bool isLeft, int how ) { if ( isFullySelected ) return traverseFullySelected( n, how ); if ( n.getNodeType()== DOM_Node::TEXT_NODE ) return traverseTextNode( n, isLeft, how ); return traversePartiallySelected( n, how ); }
/** * Visits the nodes selected by this range when we know * a-priori that the start and end containers are the same. * */ DOM_DocumentFragment RangeImpl::traverseSameContainer( int how ) { DOM_DocumentFragment frag = null; if ( how!=DELETE_CONTENTS) frag = fDocument.createDocumentFragment(); // If selection is empty, just return the fragment if ( fStartOffset==fEndOffset ) return frag; DOM_Node current = fStartContainer; DOM_Node cloneCurrent = null; // Text node needs special case handling if ( fStartContainer.getNodeType()== DOM_Node::TEXT_NODE ) { cloneCurrent = fStartContainer.cloneNode(false); cloneCurrent.setNodeValue( cloneCurrent.getNodeValue().substringData(fStartOffset, fEndOffset - fStartOffset)); // set the original text node to its new value if ( how != CLONE_CONTENTS ) ((DOM_Text &)fStartContainer).deleteData(fStartOffset, fEndOffset-fStartOffset); if ( how != DELETE_CONTENTS) frag.appendChild(cloneCurrent); } else { // Copy nodes between the start/end offsets. DOM_Node n = getSelectedNode( fStartContainer, fStartOffset ); int cnt = fEndOffset - fStartOffset; while( cnt > 0 ) { DOM_Node sibling = n.getNextSibling(); DOM_Node xferNode = traverseFullySelected( n, how ); if ( frag!=null ) frag.appendChild( xferNode ); --cnt; n = sibling; } } // Nothing is partially selected, so collapse to start point if ( how != CLONE_CONTENTS ) collapse(true); return frag; }
const DOM_Node RangeImpl::commonAncestorOf(const DOM_Node& pointA, const DOM_Node& pointB) const { if (fDetached) throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null); if (pointA.getOwnerDocument() != pointB.getOwnerDocument()) throw DOM_DOMException( DOM_DOMException::WRONG_DOCUMENT_ERR, null ); //if the containers are same then it itself is its common ancestor. if (pointA == pointB) return pointA; typedef RefVectorOf<NodeImpl> VectorNodes; VectorNodes* startV= new (((DocumentImpl*)fDocument.fImpl)->getMemoryManager()) VectorNodes(1, false, ((DocumentImpl*)fDocument.fImpl)->getMemoryManager()); DOM_Node node; for (node=fStartContainer; node != null; node=node.getParentNode()) { startV->addElement(node.fImpl); } VectorNodes* endV = new (((DocumentImpl*)fDocument.fImpl)->getMemoryManager()) VectorNodes(1, false, ((DocumentImpl*)fDocument.fImpl)->getMemoryManager()); for (node=fEndContainer; node != null; node=node.getParentNode()) { endV->addElement(node.fImpl); } int s = startV->size()-1; int e = endV->size()-1; NodeImpl* commonAncestor = 0; while (s>=0 && e>=0) { if (startV->elementAt(s) == endV->elementAt(e)) { commonAncestor = startV->elementAt(s); } else break; --s; --e; } delete startV; delete endV; return DOM_Node(commonAncestor); }
void RangeImpl::surroundContents(DOM_Node& newParent) { if (newParent==null) return; //check for elimination criteria if( fDetached) { throw DOM_DOMException( DOM_DOMException::INVALID_STATE_ERR, null); } if (newParent.getOwnerDocument() !=fDocument) { throw DOM_DOMException( DOM_DOMException::WRONG_DOCUMENT_ERR, null); } int type = newParent.getNodeType(); if ( !isLegalContainedNode(newParent) || type == DOM_Node::DOCUMENT_TYPE_NODE) { throw DOM_RangeException( DOM_RangeException::INVALID_NODE_TYPE_ERR, null); } DOM_Node root = getCommonAncestorContainer(); DOM_Node realStart = fStartContainer; DOM_Node realEnd = fEndContainer; if (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) { realStart = fStartContainer.getParentNode(); } if (fEndContainer.getNodeType() == DOM_Node::TEXT_NODE) { realEnd = fEndContainer.getParentNode(); } if (realStart != realEnd) { throw DOM_RangeException( DOM_RangeException::BAD_BOUNDARYPOINTS_ERR, null); } DOM_DocumentFragment frag = extractContents(); insertNode(newParent); newParent.appendChild(frag); selectNode(newParent); }
DOM_Node NodeIteratorImpl::previousNode (DOM_Node node) { if (fDetached) throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null); DOM_Node result; // if we're at the root, return null. if (node == fRoot) return result; // get sibling result = node.getPreviousSibling(); if (result.isNull()) { //if 1st sibling, return parent result = node.getParentNode(); return result; } // if sibling has children, keep getting last child of child. if (result.hasChildNodes()) { while (result.hasChildNodes()) { result = result.getLastChild(); } } return result; }
//====================================================================== // CJM 4/17/03 ..Needed to update an attribute list... for ContentGuard //====================================================================== bool XMLDocument::setAttributeList(char* path, DataTypeAttribute** dtAttributes) { if (mDoc == NULL) return false; if (path == NULL) return false; DOM_Node child = getNode(mRootNode, path, NULL); char* value = getString(path); if (child == NULL) return false; short nType = child.getNodeType(); DOM_Node parent = child.getParentNode(); if (parent == NULL) return false; char* childName = child.getNodeName().transcode(); DOM_NamedNodeMap nnodeMap = child.getAttributes(); parent.removeChild(child); DOM_Element childElement = mDoc.createElement(childName); delete[] childName; int a = 0; DataTypeAttribute* dtAttribute; while ((dtAttribute = (DataTypeAttribute*)dtAttributes[a++]) != (DataTypeAttribute*)NULL) { childElement.setAttribute(dtAttribute->getName(), dtAttribute->getValue()); } if (nType == DOM_Node::TEXT_NODE) { DOM_Text childText = mDoc.createTextNode((value == NULL)?"":value); childElement.appendChild(childText); } else { if (nType == DOM_Node::CDATA_SECTION_NODE) { DOM_CDATASection childCData = mDoc.createCDATASection((value == NULL)?"":value); childElement.appendChild(childCData); } } parent.appendChild(childElement); return true; }