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 + -
显示快捷键?