rangeimpl.java

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

JAVA
1,767
字号
     * Traverses the "right boundary" of this range and     * operates on each "boundary node" according to the     * <code>how</code> parameter.  It is a-priori assumed     * by this method that the right boundary does     * not contain the range's start container.     * <p>     * A "right boundary" is best visualized by thinking     * of a sample tree:<pre>     *                 A     *                /|\     *               / | \     *              /  |  \     *             B   C   D     *            /|\     /|\     *           E F G   H I J     * </pre>     * Imagine first a range that begins between the     * "E" and "F" nodes and ends between the     * "I" and "J" nodes.  The start container is     * "B" and the end container is "D".  Given this setup,     * the following applies:     * <p>     * Partially Selected Nodes: B, D<br>     * Fully Selected Nodes: F, G, C, H, I     * <p>     * The "right boundary" is the highest subtree node     * that contains the ending container.  The root of     * this subtree is always partially selected.     * <p>     * In this example, the nodes that are traversed     * as "right boundary" nodes are: H, I, and D.     *      * @param root   The node that is the root of the "right boundary" subtree.     *      * @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 node containing the boundaries 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 will     *               produced cloned content.     *                    *               <li><code>DELETE_CONTENTS</code> - will delete from     *               the context tree of the range, all fully selected     *               nodes within the boundary.     *               </ol>     *      * @return Returns a node that is the result of visiting nodes.     *         If the traversal operation is     *         <code>DELETE_CONTENTS</code> the return value is null.     */    private Node traverseRightBoundary( Node root, int how )    {        Node next = getSelectedNode( fEndContainer, fEndOffset-1 );        boolean isFullySelected = ( next!=fEndContainer );        if ( next==root )            return traverseNode( next, isFullySelected, false, how );        Node parent = next.getParentNode();        Node clonedParent = traverseNode( parent, false, false, how );        while( parent!=null )        {            while( next!=null )            {                Node prevSibling = next.getPreviousSibling();                Node clonedChild =                     traverseNode( next, isFullySelected, false, how );                if ( how!=DELETE_CONTENTS )                {                    clonedParent.insertBefore(                         clonedChild,                         clonedParent.getFirstChild()                     );                }                isFullySelected = true;                next = prevSibling;            }            if ( parent==root )                return clonedParent;            next = parent.getPreviousSibling();            parent = parent.getParentNode();            Node clonedGrandParent = traverseNode( parent, false, false, how );            if ( how!=DELETE_CONTENTS )                clonedGrandParent.appendChild( clonedParent );            clonedParent = clonedGrandParent;        }         // should never occur        return null;    }    /**     * Traverses the "left boundary" of this range and     * operates on each "boundary node" according to the     * <code>how</code> parameter.  It is a-priori assumed     * by this method that the left boundary does     * not contain the range's end container.     * <p>     * A "left boundary" is best visualized by thinking     * of a sample tree:<pre>     *      *                 A     *                /|\     *               / | \     *              /  |  \     *             B   C   D     *            /|\     /|\     *           E F G   H I J     * </pre>     * Imagine first a range that begins between the     * "E" and "F" nodes and ends between the     * "I" and "J" nodes.  The start container is     * "B" and the end container is "D".  Given this setup,     * the following applies:     * <p>     * Partially Selected Nodes: B, D<br>     * Fully Selected Nodes: F, G, C, H, I     * <p>     * The "left boundary" is the highest subtree node     * that contains the starting container.  The root of     * this subtree is always partially selected.     * <p>     * In this example, the nodes that are traversed     * as "left boundary" nodes are: F, G, and B.     *      * @param root   The node that is the root of the "left boundary" subtree.     *      * @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 node containing the boundaries 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 will     *               produced cloned content.     *                    *               <li><code>DELETE_CONTENTS</code> - will delete from     *               the context tree of the range, all fully selected     *               nodes within the boundary.     *               </ol>     *      * @return Returns a node that is the result of visiting nodes.     *         If the traversal operation is     *         <code>DELETE_CONTENTS</code> the return value is null.     */    private Node traverseLeftBoundary( Node root, int how )    {        Node next = getSelectedNode( getStartContainer(), getStartOffset() );        boolean isFullySelected = ( next!=getStartContainer() );        if ( next==root )            return traverseNode( next, isFullySelected, true, how );        Node parent = next.getParentNode();        Node clonedParent = traverseNode( parent, false, true, how );        while( parent!=null )        {            while( next!=null )            {                Node nextSibling = next.getNextSibling();                Node clonedChild =                     traverseNode( next, isFullySelected, true, how );                if ( how!=DELETE_CONTENTS )                    clonedParent.appendChild(clonedChild);                isFullySelected = true;                next = nextSibling;            }            if ( parent==root )                return clonedParent;            next = parent.getNextSibling();            parent = parent.getParentNode();            Node clonedGrandParent = traverseNode( parent, false, true, how );            if ( how!=DELETE_CONTENTS )                clonedGrandParent.appendChild( clonedParent );            clonedParent = clonedGrandParent;        }         // should never occur        return null;    }    /**     * Utility method for traversing a single node.     * Does not properly handle a text node containing both the     * start and end offsets.  Such nodes should     * have been previously detected and been routed to traverseTextNode.     *      * @param n      The node to be traversed.     *      * @param isFullySelected     *               Set to true if the node is fully selected.  Should be      *               false otherwise.     *               Note that although the DOM 2 specification says that a      *               text node that is boththe start and end container is not     *               selected, we treat it here as if it were partially      *               selected.     *      * @param isLeft Is true if we are traversing the node as part of navigating     *               the "left boundary" of the range.  If this value is false,     *               it implies we are navigating the "right boundary" of the     *               range.     *      * @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 simply     *               return the original node.     *                    *               <li><code>CLONE_CONTENTS</code> - will leave the     *               context tree of the range undisturbed, but will     *               return a cloned node.     *                    *               <li><code>DELETE_CONTENTS</code> - will delete the     *               node from it's parent, but will return null.     *               </ol>     *      * @return Returns a node that is the result of visiting the node.     *         If the traversal operation is     *         <code>DELETE_CONTENTS</code> the return value is null.     */    private Node traverseNode( Node n, boolean isFullySelected, boolean isLeft, int how )    {        if ( isFullySelected )            return traverseFullySelected( n, how );        if ( n.getNodeType()==Node.TEXT_NODE )            return traverseTextNode( n, isLeft, how );        return traversePartiallySelected( n, how );    }    /**     * Utility method for traversing a single node when     * we know a-priori that the node if fully     * selected.     *      * @param n      The node to be traversed.     *      * @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 simply     *               return the original node.     *                    *               <li><code>CLONE_CONTENTS</code> - will leave the     *               context tree of the range undisturbed, but will     *               return a cloned node.     *                    *               <li><code>DELETE_CONTENTS</code> - will delete the     *               node from it's parent, but will return null.     *               </ol>     *      * @return Returns a node that is the result of visiting the node.     *         If the traversal operation is     *         <code>DELETE_CONTENTS</code> the return value is null.     */    private Node traverseFullySelected( Node n, int how )    {        switch( how )        {        case CLONE_CONTENTS:            return n.cloneNode( true );        case EXTRACT_CONTENTS:            if ( n.getNodeType()==Node.DOCUMENT_TYPE_NODE )            {                // TBD: This should be a HIERARCHY_REQUEST_ERR                throw new RangeExceptionImpl(    		RangeException.INVALID_NODE_TYPE_ERR,                 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_NODE_TYPE_ERR", null));            }            return n;        case DELETE_CONTENTS:            n.getParentNode().removeChild(n);            return null;        }        return null;    }    /**     * Utility method for traversing a single node when     * we know a-priori that the node if partially     * selected and is not a text node.     *      * @param n      The node to be traversed.     *      * @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 simply     *               return the original node.     *                    *               <li><code>CLONE_CONTENTS</code> - will leave the     *               context tree of the range undisturbed, but will     *               return a cloned node.     *                    *               <li><code>DELETE_CONTENTS</code> - will delete the     *               node from it's parent, but will return null.     *               </ol>     *      * @return Returns a node that is the result of visiting the node.     *         If the traversal operation is     *         <code>DELETE_CONTENTS</code> the return value is null.     */    private Node traversePartiallySelected( Node n, int how )    {        switch( how )        {        case DELETE_CONTENTS:            return null;        case CLONE_CONTENTS:        case EXTRACT_CONTENTS:            return n.cloneNode( false );        }        return null;    }    /**     * Utility method for traversing a text node that we know     * a-priori to be on a left or right boundary of the range.     * This method does not properly handle text nodes that contain     * both the start and end points of the range.     *      * @param n      The node to be traversed.     *      * @param isLeft Is true if we are traversing the node as part of navigating     *               the "left boundary" of the range.  If this value is false,     *               it implies we are navigating the "right boundary" of the     *             

⌨️ 快捷键说明

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