rangeimpl.java

来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,767 行 · 第 1/5 页

JAVA
1,767
字号
                return traverseCommonStartContainer( c, how );            ++endContainerDepth;        }        // case 3: Child C of container B is ancestor of A        // This can be quickly tested by walking the parent chain of A        int startContainerDepth = 0;        for ( Node c = fStartContainer, p = c.getParentNode();             p != null;             c = p, p = p.getParentNode())        {            if (p == fEndContainer)                return traverseCommonEndContainer( c, how );            ++startContainerDepth;        }        // case 4: There is a common ancestor container.  Find the        // ancestor siblings that are children of that container.        int depthDiff = startContainerDepth - endContainerDepth;        Node startNode = fStartContainer;        while (depthDiff > 0) {            startNode = startNode.getParentNode();            depthDiff--;        }        Node endNode = fEndContainer;        while (depthDiff < 0) {            endNode = endNode.getParentNode();            depthDiff++;        }        // ascend the ancestor hierarchy until we have a common parent.        for( Node sp = startNode.getParentNode(), ep = endNode.getParentNode();             sp!=ep;              sp = sp.getParentNode(), ep = ep.getParentNode() )        {            startNode = sp;            endNode = ep;        }        return traverseCommonAncestors( startNode, endNode, how );    }        /**     * Visits the nodes selected by this range when we know     * a-priori that the start and end containers are the same.     * This method is invoked by the generic <code>traverse</code>     * method.     *      * @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 traverseSameContainer( int how )    {        DocumentFragment frag = null;        if ( how!=DELETE_CONTENTS)            frag = fDocument.createDocumentFragment();        // If selection is empty, just return the fragment        if ( fStartOffset==fEndOffset )            return frag;        // Text node needs special case handling        if ( fStartContainer.getNodeType()==Node.TEXT_NODE )        {            // get the substring            String s = fStartContainer.getNodeValue();            String sub = s.substring( fStartOffset, fEndOffset );            // set the original text node to its new value            if ( how != CLONE_CONTENTS )            {                ((TextImpl)fStartContainer).deleteData(fStartOffset,                     fEndOffset-fStartOffset) ;                // Nothing is partially selected, so collapse to start point                collapse( true );            }            if ( how==DELETE_CONTENTS)                return null;            frag.appendChild( fDocument.createTextNode(sub) );            return frag;        }        // Copy nodes between the start/end offsets.        Node n = getSelectedNode( fStartContainer, fStartOffset );        int cnt = fEndOffset - fStartOffset;        while( cnt > 0 )        {            Node sibling = n.getNextSibling();            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;    }    /**     * Visits the nodes selected by this range when we know     * a-priori that the start and end containers are not the     * same, but the start container is an ancestor of the     * end container. This method is invoked by the generic      * <code>traverse</code> method.     *      * @param endAncestor     *               The ancestor of the end container that is a direct child     *               of the start container.     *      * @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         traverseCommonStartContainer( Node endAncestor, int how )    {        DocumentFragment frag = null;        if ( how!=DELETE_CONTENTS)            frag = fDocument.createDocumentFragment();        Node n = traverseRightBoundary( endAncestor, how );        if ( frag!=null )            frag.appendChild( n );        int endIdx = indexOf( endAncestor, fStartContainer );        int cnt = endIdx - fStartOffset;        if ( cnt <=0 )        {            // Collapse to just before the endAncestor, which             // is partially selected.            if ( how != CLONE_CONTENTS )            {                setEndBefore( endAncestor );                collapse( false );            }            return frag;        }        n = endAncestor.getPreviousSibling();        while( cnt > 0 )        {            Node sibling = n.getPreviousSibling();            Node xferNode = traverseFullySelected( n, how );            if ( frag!=null )                frag.insertBefore( xferNode, frag.getFirstChild() );            --cnt;            n = sibling;        }        // Collapse to just before the endAncestor, which         // is partially selected.        if ( how != CLONE_CONTENTS )        {            setEndBefore( endAncestor );            collapse( false );        }        return frag;    }        /**     * Visits the nodes selected by this range when we know     * a-priori that the start and end containers are not the     * same, but the end container is an ancestor of the     * start container. This method is invoked by the generic     * <code>traverse</code> method.     *      * @param startAncestor     *               The ancestor of the start container that is a direct     *               child of the end container.     *      * @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         traverseCommonEndContainer( Node startAncestor, int how )    {        DocumentFragment frag = null;        if ( how!=DELETE_CONTENTS)            frag = fDocument.createDocumentFragment();        Node n = traverseLeftBoundary( startAncestor, how );        if ( frag!=null )            frag.appendChild( n );        int startIdx = indexOf( startAncestor, fEndContainer );        ++startIdx;  // Because we already traversed it....        int cnt = fEndOffset - startIdx;        n = startAncestor.getNextSibling();        while( cnt > 0 )        {            Node sibling = n.getNextSibling();            Node xferNode = traverseFullySelected( n, how );            if ( frag!=null )                frag.appendChild( xferNode );            --cnt;            n = sibling;        }        if ( how != CLONE_CONTENTS )        {            setStartAfter( startAncestor );            collapse( true );        }        return frag;    }    /**     * Visits the nodes selected by this range when we know     * a-priori that the start and end containers are not     * the same, and we also know that neither the start     * nor end container is an ancestor of the other.     * This method is invoked by     * the generic <code>traverse</code> method.     *      * @param startAncestor     *               Given a common ancestor of the start and end containers,     *               this parameter is the ancestor (or self) of the start     *               container that is a direct child of the common ancestor.     *      * @param endAncestor     *               Given a common ancestor of the start and end containers,     *               this parameter is the ancestor (or self) of the end     *               container that is a direct child of the common ancestor.     *      * @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         traverseCommonAncestors( Node startAncestor, Node endAncestor, int how )    {        DocumentFragment frag = null;        if ( how!=DELETE_CONTENTS)            frag = fDocument.createDocumentFragment();        Node n = traverseLeftBoundary( startAncestor, how );        if ( frag!=null )            frag.appendChild( n );        Node commonParent = startAncestor.getParentNode();        int startOffset = indexOf( startAncestor, commonParent );        int endOffset = indexOf( endAncestor, commonParent );        ++startOffset;        int cnt = endOffset - startOffset;        Node sibling = startAncestor.getNextSibling();        while( cnt > 0 )        {            Node nextSibling = sibling.getNextSibling();            n = traverseFullySelected( sibling, how );            if ( frag!=null )                frag.appendChild( n );            sibling = nextSibling;            --cnt;        }        n = traverseRightBoundary( endAncestor, how );        if ( frag!=null )            frag.appendChild( n );        if ( how != CLONE_CONTENTS )        {            setStartAfter( startAncestor );            collapse( true );        }        return frag;    }    /**

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?