rangeimpl.java
来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,767 行 · 第 1/5 页
JAVA
1,767 行
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( 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( 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( fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_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? 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)); } int type = newNode.getNodeType(); 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; //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(); int i = 0; for(i = 0; i < fStartOffset && current != null; i++) { current=current.getNextSibling(); } if (current != null) { fStartContainer.insertBefore(newNode, current); } else { fStartContainer.appendChild(newNode); } //update fEndOffset. ex:<body><p/></body>. Range(start;end): body,0; body,1 // insert <h1>: <body></h1><p/></body>. Range(start;end): body,0; body,2 if ( fEndContainer == fStartContainer ) { //update fEndOffset fEndOffset += (fEndContainer.getChildNodes().getLength() - currentChildren); } } } public void surroundContents(Node newParent) throws DOMException, RangeException { if (newParent==null) return; if( fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); } int type = newParent.getNodeType(); if (type == Node.ATTRIBUTE_NODE || type == Node.ENTITY_NODE || type == Node.NOTATION_NODE || type == Node.DOCUMENT_TYPE_NODE || type == Node.DOCUMENT_NODE || type == Node.DOCUMENT_FRAGMENT_NODE) { throw new RangeExceptionImpl( RangeException.INVALID_NODE_TYPE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_NODE_TYPE_ERR", null)); } Node root = getCommonAncestorContainer(); Node realStart = fStartContainer; Node realEnd = fEndContainer; if (fStartContainer.getNodeType() == Node.TEXT_NODE) { realStart = fStartContainer.getParentNode(); } if (fEndContainer.getNodeType() == Node.TEXT_NODE) { realEnd = fEndContainer.getParentNode(); } if (realStart != realEnd) { throw new RangeExceptionImpl( RangeException.BAD_BOUNDARYPOINTS_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "BAD_BOUNDARYPOINTS_ERR", null)); } DocumentFragment frag = extractContents(); insertNode(newParent); newParent.appendChild(frag); selectNode(newParent); } public Range cloneRange(){ if( fDetach) { throw new DOMException( DOMException.INVALID_STATE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null)); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?