Java Code Examples for org.w3c.dom.Node#insertBefore()
The following examples show how to use
org.w3c.dom.Node#insertBefore() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DOMKeyInfo.java From openjdk-8 with GNU General Public License v2.0 | 6 votes |
private void marshal(Node parent, Element kiElem, Node nextSibling, String dsPrefix, DOMCryptoContext context) throws MarshalException { // create and append KeyInfoType elements for (XMLStructure kiType : keyInfoTypes) { if (kiType instanceof DOMStructure) { ((DOMStructure)kiType).marshal(kiElem, dsPrefix, context); } else { DOMUtils.appendChild(kiElem, ((javax.xml.crypto.dom.DOMStructure)kiType).getNode()); } } // append id attribute DOMUtils.setAttributeID(kiElem, "Id", id); parent.insertBefore(kiElem, nextSibling); }
Example 2
Source File: DOMKeyInfo.java From jdk8u-dev-jdk with GNU General Public License v2.0 | 6 votes |
private void marshal(Node parent, Element kiElem, Node nextSibling, String dsPrefix, DOMCryptoContext context) throws MarshalException { // create and append KeyInfoType elements for (XMLStructure kiType : keyInfoTypes) { if (kiType instanceof DOMStructure) { ((DOMStructure)kiType).marshal(kiElem, dsPrefix, context); } else { DOMUtils.appendChild(kiElem, ((javax.xml.crypto.dom.DOMStructure)kiType).getNode()); } } // append id attribute DOMUtils.setAttributeID(kiElem, "Id", id); parent.insertBefore(kiElem, nextSibling); }
Example 3
Source File: DOMKeyInfo.java From jdk8u_jdk with GNU General Public License v2.0 | 6 votes |
private void marshal(Node parent, Element kiElem, Node nextSibling, String dsPrefix, DOMCryptoContext context) throws MarshalException { // create and append KeyInfoType elements for (XMLStructure kiType : keyInfoTypes) { if (kiType instanceof DOMStructure) { ((DOMStructure)kiType).marshal(kiElem, dsPrefix, context); } else { DOMUtils.appendChild(kiElem, ((javax.xml.crypto.dom.DOMStructure)kiType).getNode()); } } // append id attribute DOMUtils.setAttributeID(kiElem, "Id", id); parent.insertBefore(kiElem, nextSibling); }
Example 4
Source File: TextImpl.java From TencentKona-8 with GNU General Public License v2.0 | 5 votes |
/** * Break a text node into two sibling nodes. (Note that if the current node * has no parent, they won't wind up as "siblings" -- they'll both be * orphans.) * * @param offset * The offset at which to split. If offset is at the end of the * available data, the second node will be empty. * * @return A reference to the new node (containing data after the offset * point). The original node will contain data up to that point. * * @throws DOMException(INDEX_SIZE_ERR) * if offset is <0 or >length. * * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) * if node is read-only. */ public Text splitText(int offset) throws DOMException { if (isReadOnly()) { throw new DOMException( DOMException.NO_MODIFICATION_ALLOWED_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null)); } if (needsSyncData()) { synchronizeData(); } if (offset < 0 || offset > data.length() ) { throw new DOMException(DOMException.INDEX_SIZE_ERR, DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INDEX_SIZE_ERR", null)); } // split text into two separate nodes Text newText = getOwnerDocument().createTextNode(data.substring(offset)); setNodeValue(data.substring(0, offset)); // insert new text node Node parentNode = getParentNode(); if (parentNode != null) { parentNode.insertBefore(newText, nextSibling); } return newText; }
Example 5
Source File: DOMTreeBuilder.java From caja with Apache License 2.0 | 5 votes |
@Override protected void insertFosterParentedCharacters(String text, Element table, Element stackParent) throws SAXException { try { Node child = document.createTextNode(text); Node parent = table.getParentNode(); if (parent != null) { // always an element if not null parent.insertBefore(child, table); } else { stackParent.appendChild(child); } } catch (DOMException e) { fatal(e); } }
Example 6
Source File: SAX2DOM.java From jdk8u60 with GNU General Public License v2.0 | 5 votes |
private void appendTextNode() { if (_textBuffer.length() > 0) { final Node last = (Node)_nodeStk.peek(); if (last == _root && _nextSiblingCache != null) { _lastSibling = last.insertBefore(_document.createTextNode(_textBuffer.toString()), _nextSiblingCache); } else { _lastSibling = last.appendChild(_document.createTextNode(_textBuffer.toString())); } _textBuffer.setLength(0); } }
Example 7
Source File: DOMNormalizer.java From openjdk-jdk8u-backup with GNU General Public License v2.0 | 5 votes |
protected final void expandEntityRef (Node parent, Node reference){ Node kid, next; for (kid = reference.getFirstChild(); kid != null; kid = next) { next = kid.getNextSibling(); parent.insertBefore(kid, reference); } }
Example 8
Source File: SAX2DOM.java From openjdk-jdk8u-backup with GNU General Public License v2.0 | 5 votes |
private void appendTextNode() { if (_textBuffer.length() > 0) { final Node last = (Node)_nodeStk.peek(); if (last == _root && _nextSiblingCache != null) { _lastSibling = last.insertBefore(_document.createTextNode(_textBuffer.toString()), _nextSiblingCache); } else { _lastSibling = last.appendChild(_document.createTextNode(_textBuffer.toString())); } _textBuffer.setLength(0); } }
Example 9
Source File: DOMNormalizer.java From openjdk-8 with GNU General Public License v2.0 | 5 votes |
protected final void expandEntityRef (Node parent, Node reference){ Node kid, next; for (kid = reference.getFirstChild(); kid != null; kid = next) { next = kid.getNextSibling(); parent.insertBefore(kid, reference); } }
Example 10
Source File: XmlNode.java From JsDroidCmd with Mozilla Public License 2.0 | 5 votes |
void insertChildAt(int index, XmlNode node) { Node parent = this.dom; Node child = parent.getOwnerDocument().importNode( node.dom, true ); if (parent.getChildNodes().getLength() < index) { // TODO Check ECMA for what happens here throw new IllegalArgumentException("index=" + index + " length=" + parent.getChildNodes().getLength()); } if (parent.getChildNodes().getLength() == index) { parent.appendChild(child); } else { parent.insertBefore(child, parent.getChildNodes().item(index)); } }
Example 11
Source File: DOMBuilder.java From openjdk-jdk8u-backup with GNU General Public License v2.0 | 4 votes |
/** * Append a node to the current container. * * @param newNode New node to append */ protected void append(Node newNode) throws org.xml.sax.SAXException { Node currentNode = m_currentNode; if (null != currentNode) { if (currentNode == m_root && m_nextSibling != null) currentNode.insertBefore(newNode, m_nextSibling); else currentNode.appendChild(newNode); // System.out.println(newNode.getNodeName()); } else if (null != m_docFrag) { if (m_nextSibling != null) m_docFrag.insertBefore(newNode, m_nextSibling); else m_docFrag.appendChild(newNode); } else { boolean ok = true; short type = newNode.getNodeType(); if (type == Node.TEXT_NODE) { String data = newNode.getNodeValue(); if ((null != data) && (data.trim().length() > 0)) { throw new org.xml.sax.SAXException( XMLMessages.createXMLMessage( XMLErrorResources.ER_CANT_OUTPUT_TEXT_BEFORE_DOC, null)); //"Warning: can't output text before document element! Ignoring..."); } ok = false; } else if (type == Node.ELEMENT_NODE) { if (m_doc.getDocumentElement() != null) { ok = false; throw new org.xml.sax.SAXException( XMLMessages.createXMLMessage( XMLErrorResources.ER_CANT_HAVE_MORE_THAN_ONE_ROOT, null)); //"Can't have more than one root on a DOM!"); } } if (ok) { if (m_nextSibling != null) m_doc.insertBefore(newNode, m_nextSibling); else m_doc.appendChild(newNode); } } }
Example 12
Source File: DOMBuilder.java From jdk8u60 with GNU General Public License v2.0 | 4 votes |
/** * Append a node to the current container. * * @param newNode New node to append */ protected void append(Node newNode) throws org.xml.sax.SAXException { Node currentNode = m_currentNode; if (null != currentNode) { if (currentNode == m_root && m_nextSibling != null) currentNode.insertBefore(newNode, m_nextSibling); else currentNode.appendChild(newNode); // System.out.println(newNode.getNodeName()); } else if (null != m_docFrag) { if (m_nextSibling != null) m_docFrag.insertBefore(newNode, m_nextSibling); else m_docFrag.appendChild(newNode); } else { boolean ok = true; short type = newNode.getNodeType(); if (type == Node.TEXT_NODE) { String data = newNode.getNodeValue(); if ((null != data) && (data.trim().length() > 0)) { throw new org.xml.sax.SAXException( XMLMessages.createXMLMessage( XMLErrorResources.ER_CANT_OUTPUT_TEXT_BEFORE_DOC, null)); //"Warning: can't output text before document element! Ignoring..."); } ok = false; } else if (type == Node.ELEMENT_NODE) { if (m_doc.getDocumentElement() != null) { ok = false; throw new org.xml.sax.SAXException( XMLMessages.createXMLMessage( XMLErrorResources.ER_CANT_HAVE_MORE_THAN_ONE_ROOT, null)); //"Can't have more than one root on a DOM!"); } } if (ok) { if (m_nextSibling != null) m_doc.insertBefore(newNode, m_nextSibling); else m_doc.appendChild(newNode); } } }
Example 13
Source File: CustomizationParser.java From cxf with Apache License 2.0 | 4 votes |
protected void copyAllJaxbDeclarations(final Node schemaNode, final Element jaxwsBindingNode) { if (isSchemaElement(schemaNode)) { appendJaxbVersion((Element)schemaNode); } Node[] embededNodes = getAnnotationNodes(schemaNode); Node annotationNode = embededNodes[0]; Node appinfoNode = embededNodes[1]; for (Node childNode = jaxwsBindingNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) { if (isSchemaElement(schemaNode)) { copyJaxbAttributes(childNode, (Element)schemaNode); } //TODO: check for valid extension namespaces if (!(childNode instanceof Element)) { //!isJaxbBindings(childNode)) { continue; } Element childEl = (Element)childNode; if (isJaxbBindings(childNode) && isJaxbBindingsElement(childEl)) { NodeList nlist = nodeSelector.queryNodes(schemaNode, childEl.getAttribute("node")); for (int i = 0; i < nlist.getLength(); i++) { Node node = nlist.item(i); copyAllJaxbDeclarations(node, childEl); } } else { Element cloneNode = (Element)ProcessorUtil.cloneNode(schemaNode.getOwnerDocument(), childEl, true); NamedNodeMap atts = cloneNode.getAttributes(); for (int x = 0; x < atts.getLength(); x++) { Attr attr = (Attr)atts.item(x); if (ToolConstants.NS_JAXB_BINDINGS.equals(attr.getNamespaceURI())) { cloneNode.removeAttributeNode(attr); atts = cloneNode.getAttributes(); x = -1; } } appinfoNode.appendChild(cloneNode); } } if (schemaNode.getFirstChild() != null) { schemaNode.insertBefore(annotationNode, schemaNode.getFirstChild()); } else { schemaNode.appendChild(annotationNode); } }
Example 14
Source File: SAX2DOM.java From openjdk-8 with GNU General Public License v2.0 | 4 votes |
public void startElement(String namespace, String localName, String qName, Attributes attrs) { appendTextNode(); if (needToSetDocumentInfo) { setDocumentInfo(); needToSetDocumentInfo = false; } final Element tmp = (Element)_document.createElementNS(namespace, qName); // Add namespace declarations first if (_namespaceDecls != null) { final int nDecls = _namespaceDecls.size(); for (int i = 0; i < nDecls; i++) { final String prefix = (String) _namespaceDecls.elementAt(i++); if (prefix == null || prefix.equals(EMPTYSTRING)) { tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, (String) _namespaceDecls.elementAt(i)); } else { tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, (String) _namespaceDecls.elementAt(i)); } } _namespaceDecls.clear(); } // Add attributes to element /* final int nattrs = attrs.getLength(); for (int i = 0; i < nattrs; i++) { if (attrs.getLocalName(i) == null) { tmp.setAttribute(attrs.getQName(i), attrs.getValue(i)); } else { tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i), attrs.getValue(i)); } } */ // Add attributes to element final int nattrs = attrs.getLength(); for (int i = 0; i < nattrs; i++) { // checking if Namespace processing is being done String attQName = attrs.getQName(i); String attURI = attrs.getURI(i); if (attrs.getLocalName(i).equals("")) { tmp.setAttribute(attQName, attrs.getValue(i)); if (attrs.getType(i).equals("ID")) { tmp.setIdAttribute(attQName, true); } } else { tmp.setAttributeNS(attURI, attQName, attrs.getValue(i)); if (attrs.getType(i).equals("ID")) { tmp.setIdAttributeNS(attURI, attrs.getLocalName(i), true); } } } // Append this new node onto current stack node Node last = (Node)_nodeStk.peek(); // If the SAX2DOM is created with a non-null next sibling node, // insert the result nodes before the next sibling under the root. if (last == _root && _nextSibling != null) last.insertBefore(tmp, _nextSibling); else last.appendChild(tmp); // Push this node onto stack _nodeStk.push(tmp); _lastSibling = null; }
Example 15
Source File: DOMBuilder.java From openjdk-jdk9 with GNU General Public License v2.0 | 4 votes |
/** * Append a node to the current container. * * @param newNode New node to append */ protected void append(Node newNode) throws org.xml.sax.SAXException { Node currentNode = m_currentNode; if (null != currentNode) { if (currentNode == m_root && m_nextSibling != null) currentNode.insertBefore(newNode, m_nextSibling); else currentNode.appendChild(newNode); // System.out.println(newNode.getNodeName()); } else if (null != m_docFrag) { if (m_nextSibling != null) m_docFrag.insertBefore(newNode, m_nextSibling); else m_docFrag.appendChild(newNode); } else { boolean ok = true; short type = newNode.getNodeType(); if (type == Node.TEXT_NODE) { String data = newNode.getNodeValue(); if ((null != data) && (data.trim().length() > 0)) { throw new org.xml.sax.SAXException( XMLMessages.createXMLMessage( XMLErrorResources.ER_CANT_OUTPUT_TEXT_BEFORE_DOC, null)); //"Warning: can't output text before document element! Ignoring..."); } ok = false; } else if (type == Node.ELEMENT_NODE) { if (m_doc.getDocumentElement() != null) { ok = false; throw new org.xml.sax.SAXException( XMLMessages.createXMLMessage( XMLErrorResources.ER_CANT_HAVE_MORE_THAN_ONE_ROOT, null)); //"Can't have more than one root on a DOM!"); } } if (ok) { if (m_nextSibling != null) m_doc.insertBefore(newNode, m_nextSibling); else m_doc.appendChild(newNode); } } }
Example 16
Source File: ManifestMerger.java From java-n-IDE-for-Android with Apache License 2.0 | 4 votes |
private static int insertSourceMarker(@NonNull Node parent, @NonNull Node node, @NonNull File file, boolean after) { int insertCount = 0; Document doc = parent.getNodeType() == Node.DOCUMENT_NODE ? (Document) parent : parent.getOwnerDocument(); String comment; try { comment = SdkUtils.createPathComment(file, true); } catch (MalformedURLException e) { return insertCount; } Node prev = node.getPreviousSibling(); String newline; if (prev != null && prev.getNodeType() == Node.TEXT_NODE) { // Duplicate indentation from previous line. Once we switch the merger // over to using the XmlPrettyPrinter, we won't need this. newline = prev.getNodeValue(); int index = newline.lastIndexOf('\n'); if (index != -1) { newline = newline.substring(index); } } else { newline = "\n"; } if (after) { node = node.getNextSibling(); } parent.insertBefore(doc.createComment(comment), node); insertCount++; // Can't add text nodes at the document level in Xerces, even though // it will happily parse these if (parent.getNodeType() != Node.DOCUMENT_NODE) { parent.insertBefore(doc.createTextNode(newline), node); insertCount++; } return insertCount; }
Example 17
Source File: RangeImpl.java From openjdk-8 with GNU General Public License v2.0 | 2 votes |
/** * 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; }
Example 18
Source File: RangeImpl.java From hottub with GNU General Public License v2.0 | 2 votes |
/** * 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; }
Example 19
Source File: RangeImpl.java From openjdk-jdk9 with GNU General Public License v2.0 | 2 votes |
/** * 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; }
Example 20
Source File: RangeImpl.java From openjdk-jdk8u-backup with GNU General Public License v2.0 | 2 votes |
/** * 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; }