rangeimpl.java
来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,767 行 · 第 1/5 页
JAVA
1,767 行
Range range = fDocument.createRange(); range.setStart(fStartContainer, fStartOffset); range.setEnd(fEndContainer, fEndOffset); return range; } public String toString(){ if( fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); } Node node = fStartContainer; Node stopNode = fEndContainer; StringBuffer sb = new StringBuffer(); if (fStartContainer.getNodeType() == Node.TEXT_NODE || fStartContainer.getNodeType() == Node.CDATA_SECTION_NODE ) { if (fStartContainer == fEndContainer) { sb.append(fStartContainer.getNodeValue().substring(fStartOffset, fEndOffset)); return sb.toString(); } sb.append(fStartContainer.getNodeValue().substring(fStartOffset)); node=nextNode (node,true); //fEndContainer!=fStartContainer } else { //fStartContainer is not a TextNode node=node.getFirstChild(); if (fStartOffset>0) { //find a first node within a range, specified by fStartOffset int counter=0; while (counter<fStartOffset && node!=null) { node=node.getNextSibling(); counter++; } } if (node == null) { node = nextNode(fStartContainer,false); } } if ( fEndContainer.getNodeType()!= Node.TEXT_NODE && fEndContainer.getNodeType()!= 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() == Node.TEXT_NODE || node.getNodeType() == Node.CDATA_SECTION_NODE) { sb.append(node.getNodeValue()); } node = nextNode(node, true); } if (fEndContainer.getNodeType() == Node.TEXT_NODE || fEndContainer.getNodeType() == Node.CDATA_SECTION_NODE) { sb.append(fEndContainer.getNodeValue().substring(0,fEndOffset)); } return sb.toString(); } public void detach() { fDetach = true; fDocument.removeRange(this); } // // Mutation functions // /** Signal other Ranges to update their start/end * containers/offsets. The data has already been split * into the two Nodes. */ void signalSplitData(Node node, Node newNode, int offset) { fSplitNode = node; // notify document fDocument.splitData(node, newNode, offset); fSplitNode = null; } /** Fix up this Range if another Range has split a Text Node * into 2 Nodes. */ void receiveSplitData(Node node, Node newNode, int offset) { if (node == null || newNode == null) return; if (fSplitNode == node) return; if (node == fStartContainer && fStartContainer.getNodeType() == Node.TEXT_NODE) { if (fStartOffset > offset) { fStartOffset = fStartOffset - offset; fStartContainer = newNode; } } if (node == fEndContainer && fEndContainer.getNodeType() == Node.TEXT_NODE) { if (fEndOffset > offset) { fEndOffset = fEndOffset-offset; fEndContainer = newNode; } } } /** This function inserts text into a Node and invokes * a method to fix-up all other Ranges. */ void deleteData(CharacterData node, int offset, int count) { fDeleteNode = node; node.deleteData( offset, count); fDeleteNode = null; } /** This function is called from DOM. * The text has already beeen inserted. * Fix-up any offsets. */ void receiveDeletedText(Node node, int offset, int count) { if (node == null) return; if (fDeleteNode == node) return; if (node == fStartContainer && fStartContainer.getNodeType() == Node.TEXT_NODE) { if (fStartOffset > offset+count) { fStartOffset = offset+(fStartOffset-(offset+count)); } else if (fStartOffset > offset) { fStartOffset = offset; } } if (node == fEndContainer && fEndContainer.getNodeType() == Node.TEXT_NODE) { if (fEndOffset > offset+count) { fEndOffset = offset+(fEndOffset-(offset+count)); } else if (fEndOffset > offset) { fEndOffset = offset; } } } /** This function inserts text into a Node and invokes * a method to fix-up all other Ranges. */ void insertData(CharacterData node, int index, String insert) { fInsertNode = node; node.insertData( index, insert); fInsertNode = null; } /** This function is called from DOM. * The text has already beeen inserted. * Fix-up any offsets. */ void receiveInsertedText(Node node, int index, int len) { if (node == null) return; if (fInsertNode == node) return; if (node == fStartContainer && fStartContainer.getNodeType() == Node.TEXT_NODE) { if (index < fStartOffset) { fStartOffset = fStartOffset+len; } } if (node == fEndContainer && fEndContainer.getNodeType() == Node.TEXT_NODE) { if (index < fEndOffset) { fEndOffset = fEndOffset+len; } } } /** This function is called from DOM. * The text has already beeen replaced. * Fix-up any offsets. */ void receiveReplacedText(Node node) { if (node == null) return; if (node == fStartContainer && fStartContainer.getNodeType() == Node.TEXT_NODE) { fStartOffset = 0; } if (node == fEndContainer && fEndContainer.getNodeType() == Node.TEXT_NODE) { fEndOffset = 0; } } /** This function is called from the DOM. * This node has already been inserted into the DOM. * Fix-up any offsets. */ public void insertedNodeFromDOM(Node node) { if (node == null) return; if (fInsertNode == node) return; Node parent = node.getParentNode(); if (parent == fStartContainer) { int index = indexOf(node, fStartContainer); if (index < fStartOffset) { fStartOffset++; } } if (parent == fEndContainer) { int index = indexOf(node, fEndContainer); if (index < fEndOffset) { fEndOffset++; } } } /** This function is called within Range * instead of Node.removeChild, * so that the range can remember that it is actively * removing this child. */ Node fRemoveChild = null; Node removeChild(Node parent, Node child) { fRemoveChild = child; Node n = parent.removeChild(child); fRemoveChild = null; return n; } /** This function must be called by the DOM _BEFORE_ * a node is deleted, because at that time it is * connected in the DOM tree, which we depend on. */ void removeNode(Node node) { if (node == null) return; if (fRemoveChild == node) return; Node parent = node.getParentNode(); if (parent == fStartContainer) { int index = indexOf(node, fStartContainer); if (index < fStartOffset) { fStartOffset--; } } if (parent == fEndContainer) { int index = indexOf(node, fEndContainer); if (index < fEndOffset) { fEndOffset--; } } //startContainer or endContainer or both is/are the ancestor(s) of the Node to be deleted if (parent != fStartContainer || parent != fEndContainer) { if (isAncestorOf(node, fStartContainer)) { fStartContainer = parent; fStartOffset = indexOf( node, parent); } if (isAncestorOf(node, fEndContainer)) { fEndContainer = parent; fEndOffset = indexOf( node, parent); } } } // // Utility functions. // // parameters for traverseContents(int) //REVIST: use boolean, since there are only 2 now... static final int EXTRACT_CONTENTS = 1; static final int CLONE_CONTENTS = 2; static final int DELETE_CONTENTS = 3; /** * This is the master routine invoked to visit the nodes * selected by this range. For each such node, different * actions are taken depending on the value of the * <code>how</code> argument. * * @param how Specifies what type of traversal is being * requested (extract, clone, or delete). * Legal values for this argument are: * * <ol> * <li><code>EXTRACT_CONTENTS</code> - will produce * a document fragment containing the range's content. * Partially selected nodes are copied, but fully * selected nodes are moved. * * <li><code>CLONE_CONTENTS</code> - will leave the * context tree of the range undisturbed, but sill * produced cloned content in a document fragment * * <li><code>DELETE_CONTENTS</code> - will delete from * the context tree of the range, all fully selected * nodes. * </ol> * * @return Returns a document fragment containing any * copied or extracted nodes. If the <code>how</code> * parameter was <code>DELETE_CONTENTS</code>, the * return value is null. */ private DocumentFragment traverseContents( int how ) throws DOMException { if (fStartContainer == null || fEndContainer == null) { return null; // REVIST: Throw exception? } //Check for a detached range. if( fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); } /* Traversal is accomplished by first determining the relationship between the endpoints of the range. For each of four significant relationships, we will delegate the traversal call to a method that can make appropriate assumptions. */ // case 1: same container if ( fStartContainer == fEndContainer ) return traverseSameContainer( how ); // case 2: Child C of start container is ancestor of end container // This can be quickly tested by walking the parent chain of // end container int endContainerDepth = 0; for ( Node c = fEndContainer, p = c.getParentNode(); p != null; c = p, p = p.getParentNode()) { if (p == fStartContainer)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?