?? rangeimpl.cpp
字號:
return; } DOM_Node parent = refNode.getParentNode(); if (parent != null ) // REVIST: what to do if it IS null? { fStartContainer = parent; fEndContainer = parent; unsigned int i = 0; for (DOM_Node n = parent.getFirstChild(); n!=null, n!=refNode; n = n.getNextSibling()) { i++; } fStartOffset = i; fEndOffset = fStartOffset+1; }}void RangeImpl::selectNodeContents(const DOM_Node& node){ validateNode(node); fStartContainer = node; fEndContainer = node; fStartOffset = 0; if (node.getNodeType() == DOM_Node::TEXT_NODE ) { fEndOffset = ((DOM_Text &)node).getLength(); return; } DOM_Node first = node.getFirstChild(); if (first == null) { fEndOffset = 0; return; } unsigned int i = 0; for (DOM_Node n = first; n!=null; n = n.getNextSibling()) { i++; } fEndOffset = i;}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);}short RangeImpl::compareBoundaryPoints(DOM_Range::CompareHow how, RangeImpl* srcRange) const{ if (fDocument != srcRange->fDocument) { throw DOM_DOMException( DOM_DOMException::WRONG_DOCUMENT_ERR, null); } if( fDetached) { throw DOM_DOMException( DOM_DOMException::INVALID_STATE_ERR, null); } DOM_Node pointA, pointB; int offsetA, offsetB; switch (how) { case (DOM_Range::START_TO_START) : pointB = srcRange->getStartContainer(); pointA = fStartContainer; offsetB = srcRange->getStartOffset(); offsetA = fStartOffset; break; case (DOM_Range::START_TO_END) : pointB = srcRange->getStartContainer(); pointA = fEndContainer; offsetB = srcRange->getStartOffset(); offsetA = fEndOffset; break; case (DOM_Range::END_TO_START) : pointB = srcRange->getEndContainer(); pointA = fStartContainer; offsetB = srcRange->getEndOffset(); offsetA = fStartOffset; break; case (DOM_Range::END_TO_END) : pointB = srcRange->getEndContainer(); pointA = fEndContainer; offsetB = srcRange->getEndOffset(); offsetA = fEndOffset; break; } // case 1: same container if (pointA == pointB) { if (offsetA < offsetB) return -1; //A before B if (offsetA == offsetB) return 0; //A equal to B return 1; // A after B } // case 2: Child C of container A is ancestor of B for (DOM_Node node = pointA.getFirstChild(); node != null; node=node.getNextSibling()) { if (isAncestorOf(node, pointB)) { int index = indexOf(node, pointA); if (offsetA <= index) return -1; return 1; } } // case 3: Child C of container B is ancestor of A for (DOM_Node nd = pointB.getFirstChild(); nd != null; nd=nd.getNextSibling()) { if (isAncestorOf(nd, pointA)) { int index = indexOf(nd, pointB); if (index < offsetB ) return -1; return 1; //B strictly before A } } // case 4: preorder traversal of context tree. DOM_Node ancestor = commonAncestorOf(pointA, pointB); DOM_Node current = ancestor; do { if (current == pointA) return -1; if (current == pointB) return 1; current = nextNode(current, true); } while (current!=null && current!=ancestor); return -2; // this should never happen}void RangeImpl:: deleteContents(){ traverseContents(DELETE_CONTENTS);}DOM_DocumentFragment RangeImpl::extractContents(){ checkReadOnly(fStartContainer, fEndContainer, fStartOffset, fEndOffset); return traverseContents(EXTRACT_CONTENTS);}DOM_DocumentFragment RangeImpl::cloneContents() const{ // cast off const. return ((RangeImpl *)this)->traverseContents(CLONE_CONTENTS);}void RangeImpl::insertNode(DOM_Node& newNode){ if (newNode == null) return; //don't have to do anything for (DOM_Node aNode = fStartContainer; aNode!=null; aNode = aNode.getParentNode()) { if (aNode.fImpl->isReadOnly()) { throw DOM_DOMException( DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null); } } if (fDocument != newNode.getOwnerDocument()) { throw DOM_DOMException( DOM_DOMException::WRONG_DOCUMENT_ERR, null); } // Prevent cycles in the tree. //isKidOK() is not checked here as its taken care by insertBefore() function if (isAncestorOf( newNode, fStartContainer)) { throw DOM_DOMException( DOM_DOMException::HIERARCHY_REQUEST_ERR, null); } if( fDetached) { throw DOM_DOMException( DOM_DOMException::INVALID_STATE_ERR, null); } int type = newNode.getNodeType(); if (type == DOM_Node::ATTRIBUTE_NODE || type == DOM_Node::ENTITY_NODE || type == DOM_Node::NOTATION_NODE || type == DOM_Node::DOCUMENT_NODE) { throw DOM_RangeException( DOM_RangeException::INVALID_NODE_TYPE_ERR, null); } DOM_Node parent; DOM_Node next; if (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) { //set 'parent' and 'next' here parent = fStartContainer.getParentNode(); //split the text nodes if (fStartOffset > 0) ((DOM_Text &)fStartContainer).splitText(fStartOffset); //update the new start information later. After inserting the first newNode if (fStartOffset == 0) next = fStartContainer; else next = fStartContainer.getNextSibling(); } // end of text handling else { parent = fStartContainer; next = fStartContainer.getFirstChild(); for(unsigned int i = 0; (i < fStartOffset) && (next != null); i++) { next=next.getNextSibling(); } } if (parent != null) { if (next != null) parent.insertBefore(newNode, next); else parent.appendChild(newNode); }}RangeImpl* RangeImpl::cloneRange() const{ if( fDetached) { throw DOM_DOMException( DOM_DOMException::INVALID_STATE_ERR, null); } RangeImpl* range = ((DocumentImpl*)fDocument.fImpl)->createRange(); range->setStart(fStartContainer, fStartOffset); range->setEnd(fEndContainer, fEndOffset); return range;}DOMString RangeImpl::toString() const{ if( fDetached) { throw DOM_DOMException( DOM_DOMException::INVALID_STATE_ERR, null); } DOM_Node node = fStartContainer; DOM_Node stopNode = fEndContainer; DOMString tempString; if ( (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) || (fStartContainer.getNodeType() == DOM_Node::CDATA_SECTION_NODE) ) { if (fStartContainer == fEndContainer) { tempString.appendData(fStartContainer.getNodeValue().substringData(fStartOffset, fEndOffset-fStartOffset)); return tempString; } else { int length = fStartContainer.getNodeValue().length(); tempString.appendData(fStartContainer.getNodeValue().substringData(fStartOffset, length - fStartOffset)); node = nextNode(node, true); } }else { //fStartContainer is not a TextNode node=node.getFirstChild(); if (fStartOffset>0) { //find a first node within a range, specified by fStartOffset unsigned int counter = 0; while (counter<fStartOffset && node!=null) { node=node.getNextSibling(); counter++; } } if (node == null) { node = nextNode(fStartContainer,false); } } if ( fEndContainer.getNodeType()!= DOM_Node::TEXT_NODE && fEndContainer.getNodeType()!= DOM_Node::CDATA_SECTION_NODE ){ int i=fEndOffset; stopNode = fEndContainer.getFirstChild(); while( i>0 && stopNode!=null ){ --i; stopNode = stopNode.getNextSibling(); } if ( stopNode == null ) stopNode = nextNode( fEndContainer, false ); } while (node != stopNode) { //look into all kids of the Range if (node == null) break; if (node.getNodeType() == DOM_Node::TEXT_NODE || node.getNodeType() == DOM_Node::CDATA_SECTION_NODE) { tempString.appendData(node.getNodeValue()); } node = nextNode(node, true); } if (fEndContainer.getNodeType() == DOM_Node::TEXT_NODE || fEndContainer.getNodeType() == DOM_Node::CDATA_SECTION_NODE) { tempString.appendData(fEndContainer.getNodeValue().substringData(0,fEndOffset)); } return tempString;}DOM_Document RangeImpl::getDocument(){ return fDocument;}const DOM_Node RangeImpl::getCommonAncestorContainer() const{ return commonAncestorOf(fStartContainer, fEndContainer);}//---------------------//private functions//---------------------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;}bool RangeImpl::isAncestorOf(const DOM_Node& a, const DOM_Node& b) { for (DOM_Node node=b; node != null; node=node.getParentNode()) { if (node == a) return true; } return false;}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;}bool RangeImpl::isLegalContainedNode(const DOM_Node& node ) const { if ( node==null ) return false; switch( node.getNodeType() ) { case DOM_Node::DOCUMENT_NODE: case DOM_Node::DOCUMENT_FRAGMENT_NODE: case DOM_Node::ATTRIBUTE_NODE: case DOM_Node::ENTITY_NODE: case DOM_Node::NOTATION_NODE: return false; } return true;}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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -