/** * 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; }
/** * 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; }