rangeimpl.java
来自「JAVA 所有包」· Java 代码 · 共 1,729 行 · 第 1/5 页
JAVA
1,729 行
public void setEndAfter(Node refNode) throws RangeException { if (fDocument.errorChecking) { if( fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); } if ( !hasLegalRootContainer(refNode) || !isLegalContainedNode(refNode)) { throw new RangeExceptionImpl( RangeException.INVALID_NODE_TYPE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_NODE_TYPE_ERR", null)); } if ( fDocument != refNode.getOwnerDocument() && fDocument != refNode) { throw new DOMException( DOMException.WRONG_DOCUMENT_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null)); } } fEndContainer = refNode.getParentNode(); int i = 0; for (Node n = refNode; n!=null; n = n.getPreviousSibling()) { i++; } fEndOffset = i; // If one boundary-point of a Range is set to have a root container // other // than the current one for the Range, the Range should be collapsed to // the new position. // The start position of a Range should never be after the end position. if (getCommonAncestorContainer() == null || (fStartContainer == fEndContainer && fEndOffset < fStartOffset)) { collapse(false); } } public void collapse(boolean toStart) { if( fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); } if (toStart) { fEndContainer = fStartContainer; fEndOffset = fStartOffset; } else { fStartContainer = fEndContainer; fStartOffset = fEndOffset; } } public void selectNode(Node refNode) throws RangeException { if (fDocument.errorChecking) { if (fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); } if ( !isLegalContainer( refNode.getParentNode() ) || !isLegalContainedNode( refNode ) ) { throw new RangeExceptionImpl( RangeException.INVALID_NODE_TYPE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_NODE_TYPE_ERR", null)); } if ( fDocument != refNode.getOwnerDocument() && fDocument != refNode) { throw new DOMException( DOMException.WRONG_DOCUMENT_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null)); } } Node parent = refNode.getParentNode(); if (parent != null ) // REVIST: what to do if it IS null? { fStartContainer = parent; fEndContainer = parent; int i = 0; for (Node n = refNode; n!=null; n = n.getPreviousSibling()) { i++; } fStartOffset = i-1; fEndOffset = fStartOffset+1; } } public void selectNodeContents(Node refNode) throws RangeException { if (fDocument.errorChecking) { if( fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); } if ( !isLegalContainer(refNode)) { throw new RangeExceptionImpl( RangeException.INVALID_NODE_TYPE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_NODE_TYPE_ERR", null)); } if ( fDocument != refNode.getOwnerDocument() && fDocument != refNode) { throw new DOMException( DOMException.WRONG_DOCUMENT_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null)); } } fStartContainer = refNode; fEndContainer = refNode; Node first = refNode.getFirstChild(); fStartOffset = 0; if (first == null) { fEndOffset = 0; } else { int i = 0; for (Node n = first; n!=null; n = n.getNextSibling()) { i++; } fEndOffset = i; } } public short compareBoundaryPoints(short how, Range sourceRange) throws DOMException { if (fDocument.errorChecking) { if( fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); } // WRONG_DOCUMENT_ERR: Raised if the two Ranges are not in the same Document or DocumentFragment. if ((fDocument != sourceRange.getStartContainer().getOwnerDocument() && fDocument != sourceRange.getStartContainer() && sourceRange.getStartContainer() != null) || (fDocument != sourceRange.getEndContainer().getOwnerDocument() && fDocument != sourceRange.getEndContainer() && sourceRange.getStartContainer() != null)) { throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, DOMMessageFormatter.formatMessage( DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null)); } } Node endPointA; Node endPointB; int offsetA; int offsetB; if (how == START_TO_START) { endPointA = sourceRange.getStartContainer(); endPointB = fStartContainer; offsetA = sourceRange.getStartOffset(); offsetB = fStartOffset; } else if (how == START_TO_END) { endPointA = sourceRange.getStartContainer(); endPointB = fEndContainer; offsetA = sourceRange.getStartOffset(); offsetB = fEndOffset; } else if (how == END_TO_START) { endPointA = sourceRange.getEndContainer(); endPointB = fStartContainer; offsetA = sourceRange.getEndOffset(); offsetB = fStartOffset; } else { endPointA = sourceRange.getEndContainer(); endPointB = fEndContainer; offsetA = sourceRange.getEndOffset(); offsetB = fEndOffset; } // The DOM Spec outlines four cases that need to be tested // to compare two range boundary points: // case 1: same container // case 2: Child C of container A is ancestor of B // case 3: Child C of container B is ancestor of A // case 4: preorder traversal of context tree. // case 1: same container if (endPointA == endPointB) { if (offsetA < offsetB) return 1; if (offsetA == offsetB) return 0; return -1; } // case 2: Child C of container A is ancestor of B // This can be quickly tested by walking the parent chain of B for ( Node c = endPointB, p = c.getParentNode(); p != null; c = p, p = p.getParentNode()) { if (p == endPointA) { int index = indexOf(c, endPointA); if (offsetA <= index) return 1; return -1; } } // case 3: Child C of container B is ancestor of A // This can be quickly tested by walking the parent chain of A for ( Node c = endPointA, p = c.getParentNode(); p != null; c = p, p = p.getParentNode()) { if (p == endPointB) { int index = indexOf(c, endPointB); if (index < offsetB) return 1; return -1; } } // case 4: preorder traversal of context tree. // Instead of literally walking the context tree in pre-order, // we use relative node depth walking which is usually faster int depthDiff = 0; for ( Node n = endPointA; n != null; n = n.getParentNode() ) depthDiff++; for ( Node n = endPointB; n != null; n = n.getParentNode() ) depthDiff--; while (depthDiff > 0) { endPointA = endPointA.getParentNode(); depthDiff--; } while (depthDiff < 0) { endPointB = endPointB.getParentNode(); depthDiff++; } for (Node pA = endPointA.getParentNode(), pB = endPointB.getParentNode(); pA != pB; pA = pA.getParentNode(), pB = pB.getParentNode() ) { endPointA = pA; endPointB = pB; } for ( Node n = endPointA.getNextSibling(); n != null; n = n.getNextSibling() ) { if (n == endPointB) { return 1; } } return -1; } public void deleteContents() throws DOMException { traverseContents(DELETE_CONTENTS); } public DocumentFragment extractContents() throws DOMException { return traverseContents(EXTRACT_CONTENTS); } public DocumentFragment cloneContents() throws DOMException { return traverseContents(CLONE_CONTENTS); } public void insertNode(Node newNode) throws DOMException, RangeException { if ( newNode == null ) return; //throw exception? int type = newNode.getNodeType(); if (fDocument.errorChecking) { if (fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); } if ( fDocument != newNode.getOwnerDocument() ) { throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null)); } if (type == Node.ATTRIBUTE_NODE || type == Node.ENTITY_NODE || type == Node.NOTATION_NODE || type == Node.DOCUMENT_NODE) { throw new RangeExceptionImpl( RangeException.INVALID_NODE_TYPE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_NODE_TYPE_ERR", null)); } } Node cloneCurrent; Node current; int currentChildren = 0; fInsertedFromRange = true; //boolean MULTIPLE_MODE = false; if (fStartContainer.getNodeType() == Node.TEXT_NODE) { Node parent = fStartContainer.getParentNode(); currentChildren = parent.getChildNodes().getLength(); //holds number of kids before insertion // split text node: results is 3 nodes.. cloneCurrent = fStartContainer.cloneNode(false); ((TextImpl)cloneCurrent).setNodeValueInternal( (cloneCurrent.getNodeValue()).substring(fStartOffset)); ((TextImpl)fStartContainer).setNodeValueInternal( (fStartContainer.getNodeValue()).substring(0,fStartOffset)); Node next = fStartContainer.getNextSibling(); if (next != null) { if (parent != null) { parent.insertBefore(newNode, next); parent.insertBefore(cloneCurrent, next); } } else { if (parent != null) { parent.appendChild(newNode); parent.appendChild(cloneCurrent); } } //update ranges after the insertion if ( fEndContainer == fStartContainer) { fEndContainer = cloneCurrent; //endContainer is the new Node created fEndOffset -= fStartOffset; } else if ( fEndContainer == parent ) { //endContainer was not a text Node. //endOffset + = number_of_children_added fEndOffset += (parent.getChildNodes().getLength() - currentChildren); } // signal other Ranges to update their start/end containers/offsets signalSplitData(fStartContainer, cloneCurrent, fStartOffset); } else { // ! TEXT_NODE if ( fEndContainer == fStartContainer ) //need to remember number of kids currentChildren= fEndContainer.getChildNodes().getLength(); current = fStartContainer.getFirstChild();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?