📄 dom2_rangeimpl.cpp
字号:
refNode.nodeType() == Node::ENTITY_NODE || refNode.nodeType() == Node::NOTATION_NODE ) throw RangeException( RangeException::INVALID_NODE_TYPE_ERR ); if( isDetached() ) throw DOMException( DOMException::INVALID_STATE_ERR ); try { setEnd( refNode.parentNode(), refNode.index() ); } catch( RangeException r ) { if( r.code == RangeException::INVALID_NODE_TYPE_ERR ) fprintf( stderr, "Exception: Invalid Node type\n" ); return; } catch( DOMException d ) { if( d.code == DOMException::NOT_FOUND_ERR ) fprintf( stderr, "Exception: Null Nodes not accepted\n" ); if( d.code == DOMException::INDEX_SIZE_ERR ) fprintf( stderr, "Exception: offset has wrong size\n" ); if( d.code == DOMException::INVALID_STATE_ERR ) fprintf( stderr, "Exception: detach() has been invoked\n" ); return; }}void RangeImpl::setEndAfter( const Node &refNode ){ Node _tempNode = refNode; if( _tempNode.isNull() ) throw DOMException( DOMException::NOT_FOUND_ERR ); _tempNode = refNode.parentNode(); while( !_tempNode.isNull() ) { if( _tempNode.nodeType() == Node::ATTRIBUTE_NODE || _tempNode.nodeType() == Node::ENTITY_NODE || _tempNode.nodeType() == Node::NOTATION_NODE || _tempNode.nodeType() == Node::DOCUMENT_TYPE_NODE ) throw RangeException( RangeException::INVALID_NODE_TYPE_ERR ); _tempNode = _tempNode.parentNode(); } if( refNode.nodeType() == Node::DOCUMENT_NODE || refNode.nodeType() == Node::DOCUMENT_FRAGMENT_NODE || refNode.nodeType() == Node::ATTRIBUTE_NODE || refNode.nodeType() == Node::ENTITY_NODE || refNode.nodeType() == Node::NOTATION_NODE ) throw RangeException( RangeException::INVALID_NODE_TYPE_ERR ); if( isDetached() ) throw DOMException( DOMException::INVALID_STATE_ERR ); try { setEnd( refNode.parentNode(), refNode.index()+1 ); } catch( RangeException r ) { if( r.code == RangeException::INVALID_NODE_TYPE_ERR ) fprintf( stderr, "Exception: Invalid Node type\n" ); return; } catch( DOMException d ) { if( d.code == DOMException::NOT_FOUND_ERR ) fprintf( stderr, "Exception: Null Nodes not accepted\n" ); if( d.code == DOMException::INDEX_SIZE_ERR ) fprintf( stderr, "Exception: offset has wrong size\n" ); if( d.code == DOMException::INVALID_STATE_ERR ) fprintf( stderr, "Exception: detach() has been invoked\n" ); return; }}void RangeImpl::collapse( bool toStart ){ if( isDetached() ) throw DOMException( DOMException::INVALID_STATE_ERR ); if( toStart ) // collapse to start { endContainer = startContainer; endOffset = startOffset; collapsed = true; commonAncestorContainer = startContainer; } else // collapse to end { startContainer = endContainer; startOffset = endOffset; collapsed = true; commonAncestorContainer = endContainer; }}void RangeImpl::selectNode( const Node &refNode ){ Node _tempNode = refNode; if( _tempNode.isNull() ) throw DOMException( DOMException::NOT_FOUND_ERR ); _tempNode = refNode.parentNode(); while( !_tempNode.isNull() ) { if( _tempNode.nodeType() == Node::ATTRIBUTE_NODE || _tempNode.nodeType() == Node::ENTITY_NODE || _tempNode.nodeType() == Node::NOTATION_NODE || _tempNode.nodeType() == Node::DOCUMENT_TYPE_NODE ) throw RangeException( RangeException::INVALID_NODE_TYPE_ERR ); _tempNode = _tempNode.parentNode(); } if( refNode.nodeType() == Node::DOCUMENT_NODE || refNode.nodeType() == Node::DOCUMENT_FRAGMENT_NODE || refNode.nodeType() == Node::ATTRIBUTE_NODE || refNode.nodeType() == Node::ENTITY_NODE || refNode.nodeType() == Node::NOTATION_NODE ) throw RangeException( RangeException::INVALID_NODE_TYPE_ERR ); if( isDetached() ) throw DOMException( DOMException::INVALID_STATE_ERR ); try { setStartBefore( refNode ); setEndAfter( refNode ); } catch( RangeException r ) { if( r.code == RangeException::INVALID_NODE_TYPE_ERR ) fprintf( stderr, "Exception: Invalid Node type\n" ); return; } catch( DOMException d ) { if( d.code == DOMException::NOT_FOUND_ERR ) fprintf( stderr, "Exception: Null Nodes not accepted\n" ); if( d.code == DOMException::INVALID_STATE_ERR ) fprintf( stderr, "Exception: detach() has been invoked\n" ); return; }}void RangeImpl::selectNodeContents( const Node &refNode ){ Node _tempNode = refNode; if( _tempNode.isNull() ) throw DOMException( DOMException::NOT_FOUND_ERR ); while( !_tempNode.isNull() ) { if( _tempNode.nodeType() == Node::ATTRIBUTE_NODE || _tempNode.nodeType() == Node::ENTITY_NODE || _tempNode.nodeType() == Node::NOTATION_NODE || _tempNode.nodeType() == Node::DOCUMENT_TYPE_NODE ) throw RangeException( RangeException::INVALID_NODE_TYPE_ERR ); _tempNode = _tempNode.parentNode(); } if( isDetached() ) throw DOMException( DOMException::INVALID_STATE_ERR ); try { setStartBefore( refNode.firstChild() ); setEndAfter( refNode.lastChild() ); } catch( RangeException r ) { if( r.code == RangeException::INVALID_NODE_TYPE_ERR ) fprintf( stderr, "Exception: Invalid Node type\n" ); return; } catch( DOMException d ) { if( d.code == DOMException::NOT_FOUND_ERR ) fprintf( stderr, "Exception: Null Nodes not accepted\n" ); if( d.code == DOMException::INVALID_STATE_ERR ) fprintf( stderr, "Exception: detach() has been invoked\n" ); return; }}short RangeImpl::compareBoundaryPoints( Range::CompareHow how, const Range &sourceRange ){ if( commonAncestorContainer.ownerDocument() != sourceRange.handle()->commonAncestorContainer.ownerDocument() ) throw DOMException( DOMException::WRONG_DOCUMENT_ERR ); if( isDetached() ) throw DOMException( DOMException::INVALID_STATE_ERR ); switch(how) { case Range::START_TO_START: return compareBoundaryPoints( getStartContainer(), getStartOffset(), sourceRange.startContainer(), sourceRange.startOffset() ); break; case Range::START_TO_END: return compareBoundaryPoints( getStartContainer(), getStartOffset(), sourceRange.endContainer(), sourceRange.endOffset() ); break; case Range::END_TO_END: return compareBoundaryPoints( getEndContainer(), getEndOffset(), sourceRange.endContainer(), sourceRange.endOffset() ); break; case Range::END_TO_START: return compareBoundaryPoints( getEndContainer(), getEndOffset(), sourceRange.startContainer(), sourceRange.startOffset() ); break; default: printf( "Function compareBoundaryPoints: Invalid CompareHow\n" ); return 2; // undocumented - should throw an exception here }}short RangeImpl::compareBoundaryPoints( Node containerA, long offsetA, Node containerB, long offsetB ){ if( offsetA < 0 || offsetB < 0 ) { printf( "Function compareBoundaryPoints: No negative offsets allowed\n" ); return 2; // undocumented - should throw an exception here } if( containerA == containerB ) { if( offsetA == offsetB ) return 0; // A is equal to B if( offsetA < offsetB ) return -1; // A is before B else return 1; // A is after B } Node n = containerA; while( n != 0 ) { if( n == containerB) return -1; // A is before B Node next; if( n == containerA ) next = n.childNodes().item( offsetA ); else next = n.firstChild(); if( next == 0 ) next = n.nextSibling(); while( n != 0 && next == 0 ) { n = n.parentNode(); next = n.nextSibling(); } n = next; } return 1; // A is after B}bool RangeImpl::boundaryPointsValid( ){ short valid = compareBoundaryPoints( getStartContainer(), getStartOffset(), getEndContainer(), getEndOffset() ); if( valid == 1 ) return false; else return true;}void RangeImpl::deleteContents( ){ Node cmnRoot = getCommonAncestorContainer(); printf("CommonAC: %s \n", cmnRoot.nodeName().string().ascii());// printf("end: %d, start: %d", startOffset, endOffset); if(startContainer == endContainer) { if(startOffset == endOffset) // we have a collapsed range {printf("collapsed\n");return;} // TODO: we need to delete the text Node if a whole text is selected!! if( startContainer.nodeType() == Node::TEXT_NODE ) { startContainer.nodeValue().remove(startOffset, endOffset); startContainer.applyChanges(); } else { printf("same but not a text node\n"); Node _tempParent = startContainer; Node _tempCurrent = startContainer.firstChild(); unsigned int i; for(i=0; i < startOffset; i++) // get the node given by the offset _tempCurrent = _tempCurrent.nextSibling(); /* now delete all nodes between the offsets */ unsigned int range = endOffset - startOffset; Node _nextCurrent = _tempCurrent; // to keep track of which node to take next for(i=0; i<range && !_tempCurrent.isNull(); i++) { if(_tempParent == _tempCurrent.parentNode() ) printf("like\n"); _nextCurrent = _tempCurrent.nextSibling(); printf("just before remove\n"); _tempParent.removeChild(_tempCurrent); printf("just after remove\n"); _tempCurrent = _nextCurrent; } _tempParent.applyChanges(); } return; }// END COMMON CONTAINER CASE!! printf("end common case\n"); Node _nextCurrent; Node _tempCurrent; // cleanup left side Node _leftParent = startContainer; if( startContainer.nodeType() == Node::TEXT_NODE ) { printf("left side text\n"); (void)startContainer.nodeValue().split(startOffset); // what about complete removals? } else { _tempCurrent = startContainer.firstChild(); unsigned int i; for(i=0; i < startOffset; i++) // get the node given by the offset _tempCurrent = _tempCurrent.nextSibling(); _nextCurrent = _tempCurrent; // to keep track of which node to take next while( !_tempCurrent.isNull() ) { _nextCurrent = _tempCurrent.nextSibling(); _leftParent.removeChild(_tempCurrent); _tempCurrent = _nextCurrent; } } _tempCurrent = _leftParent; _leftParent = _leftParent.parentNode(); while( _leftParent != cmnRoot ) { while( !_tempCurrent.isNull() ) { _nextCurrent = _tempCurrent.nextSibling(); _leftParent.removeChild(_tempCurrent); _tempCurrent = _nextCurrent; } _tempCurrent = _leftParent; _leftParent = _leftParent.parentNode(); } // cleanup right side Node _rightParent = endContainer; if( endContainer.nodeType() == Node::TEXT_NODE ) { endContainer.nodeValue().remove(0, endOffset); // what about complete removals? } else { Node _tempCurrent = endContainer.firstChild(); unsigned int i; for(i=0; i < endOffset; i++) // get the node given by the offset _tempCurrent = _tempCurrent.nextSibling(); Node _nextCurrent = _tempCurrent; // to keep track of which node to take next while( !_tempCurrent.isNull() ) { _nextCurrent = _tempCurrent.previousSibling(); _leftParent.removeChild(_tempCurrent); _tempCurrent = _nextCurrent; } } _tempCurrent = _rightParent; _rightParent = _rightParent.parentNode(); while( _rightParent != cmnRoot ) { while( !_tempCurrent.isNull() ) { _nextCurrent = _tempCurrent.previousSibling(); _rightParent.removeChild(_tempCurrent); _tempCurrent = _nextCurrent; } _tempCurrent = _rightParent; _rightParent = _rightParent.parentNode(); } // cleanup middle _leftParent = _leftParent.nextSibling(); while( _leftParent != _rightParent ) { cmnRoot.removeChild(_leftParent); _leftParent = _leftParent.nextSibling(); } // FIXME! this allways collapses to the front (see DOM specs) //collapse(true);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -