@Override public N getNextSibling(N node) { return inner.getNextSibling(node); }
/** * Gets the next sibling of an element that is also an element itself. * * @param doc document accessor * @param element an element * @return the next element sibling of {@code element} if there is one, * otherwise {@code null}. */ public static <N, E extends N> E getNextSiblingElement(ReadableDocument<N, E, ?> doc, E element) { return getNextElementInclusive(doc, doc.getNextSibling(element), true); }
/** * Counts how many children a particular element in a document has. * * @param doc The doc that the element is in. * @param elem An element. * @return Number of children the specified element has. */ public static <N, E extends N, T extends N> int countChildren( ReadableDocument<Node, Element, Text> doc, Element elem) { int children = 0; Node currentChild = doc.getFirstChild(elem); while (currentChild != null) { children++; currentChild = doc.getNextSibling(currentChild); } return children; }
/** * Construct a point after the given node */ public static <N, E extends N, T extends N> El<N> after( ReadableDocument<N,E,T> doc, N node) { return new El<N>(doc.getParentElement(node), doc.getNextSibling(node)); }
private void getInnerTextOfElement(E element, StringBuilder builder) { N child = document.getFirstChild(element); while (child != null) { getInnerTextOfNode(child, builder); child = document.getNextSibling(child); } } }
/** * Worker * @param element * @return XML fragment describing children */ private int addChildXmlFragment(E element) { int size = 0; for (N n = view.getFirstChild(element); n != null; n = view.getNextSibling(n)) { size += addNode(n); } return size; }
/** * Similar to {@link #inElement(Object, Object)} * * @param element Parent * @param nodeBefore The node BEFORE the point, or null for the START of parent * @return point */ public static <N, E extends N, T extends N> El<N> inElementReverse( ReadableDocument<N,E,T> doc, E element, N nodeBefore) { return new El<N>(element, nodeBefore == null ? doc.getFirstChild(element) : doc.getNextSibling(nodeBefore)); }
/** * Apply action to a node and its descendants. * * @param doc view for traversing * @param node reference node * @param nodeAction action to apply to node and its descendants */ public static <N, E extends N, T extends N> void traverse(ReadableDocument<N, E, T> doc, N node, NodeAction<N> nodeAction) { for (; node != null; node = doc.getNextSibling(node)) { nodeAction.apply(node); traverse(doc, doc.getFirstChild(node), nodeAction); } }
/** * Returns a node as an element if it is one; otherwise, finds the next * sibling of that node that is an element. * * @param doc document accessor * @param node reference node * @return the next element in the inclusive sibling chain from {@code node}. */ public static <N, E extends N> E getNextElementInclusive(ReadableDocument<N, E, ?> doc, N node, boolean forward) { E asElement = doc.asElement(node); while (node != null && asElement == null) { node = forward ? doc.getNextSibling(node) : doc.getPreviousSibling(node); asElement = doc.asElement(node); } return asElement; }
/** * @param doc * @return true if the given document is an old-style-paragraph document */ @Deprecated private static <N, E extends N, T extends N> boolean isUnsupportedParagraphDocument( ReadableDocument<N, E, T> doc) { if (doc.getFirstChild(doc.getDocumentElement()) == null) { // If the document is empty, check what the default global option is return !USE_LINE_CONTAINERS_BY_DEFAULT; } // Testing all children in the case of special <input> tags N root = doc.getDocumentElement(); for (N child = doc.getFirstChild(root); child != null; child = doc.getNextSibling(child)) { if (isUnsupportedParagraphElement(doc, child)) { return true; } } return false; }
/** * Step out of end tags, so we get something that is either in a text node, * or the node after our point in a pre-order traversal */ private static <N, E extends N, T extends N> void getNodeAfterOutwards( ReadableDocument<N, E, T> doc, Point<N> point, NodeOffset<N> output) { N node; int startOffset; if (point.isInTextNode()) { node = point.getContainer(); startOffset = point.getTextOffset(); } else { node = point.getNodeAfter(); if (node == null) { N parent = point.getContainer(); while (parent != null) { node = doc.getNextSibling(parent); if (node != null) { break; } parent = doc.getParentElement(parent); } } startOffset = 0; } output.node = node; output.offset = startOffset; }
/** * Writes an element's information out to an initialization cursor, optionally recursing * to do likewise for its children. * * @param doc Document the node resides within. * @param element Element containing information to be written. * @param cursor Cursor to write results out to. * @param recurse Whether or not to write children to the operation. */ public static <N, E extends N, T extends N> void buildDomInitializationFromElement( ReadableDocument<N, E, T> doc, E element, DocInitializationCursor cursor, boolean recurse) { cursor.elementStart(doc.getTagName(element), new AttributesImpl(doc.getAttributes(element))); if (recurse) { for (N child = doc.getFirstChild(element); child != null; child = doc.getNextSibling(child)) { buildDomInitializationFromSubtree(doc, child, cursor); } } cursor.elementEnd(); } }
/** * @param doc * @param point * @return Node before the given point */ @SuppressWarnings("unchecked") public static <N, E extends N, T extends N> E elementAfter( ReadableDocument<N,E,T> doc, Point<N> point) { if (point.isInTextNode()) { if (point.getTextOffset() < doc.getLength((T) point.getContainer())) { return null; } else { return doc.asElement(doc.getNextSibling(point.getContainer())); } } else { return doc.asElement(point.getNodeAfter()); } }
/** * This method returns the last point in a sequence of text node in the given direction. * * We guarantee that the return value is non-null and inside a text node. * * @return the last point in the text sequence as a text point. */ private static <N, E extends N, T extends N> Tx<N> lastPointInTextSequence( ReadableDocument<N, E, T> doc, Tx<N> start, boolean forward) { Tx<N> ret; if (forward) { T t = doc.asText(start.getCanonicalNode()); T next = doc.asText(doc.getNextSibling(t)); while (next != null) { t = next; next = doc.asText(doc.getNextSibling(t)); } ret = Point.<N> inText(t, doc.getLength(t)); } else { T t = doc.asText(start.getCanonicalNode()); T prev = doc.asText(doc.getPreviousSibling(t)); while (prev != null) { t = prev; prev = doc.asText(doc.getPreviousSibling(t)); } ret = Point.<N> inText(t, 0); } return ret; } }
if (direction == RoundDirection.RIGHT) { // round to the right N nodeAfter = point.isInTextNode() ? doc.getNextSibling(point.getContainer()) : point.getNodeAfter(); while (nodeAfter != null && !isLineElement(doc, nodeAfter)) { nodeAfter = doc.getNextSibling(nodeAfter);
/** * If the given point is equivalent to the end of the inside of an element, * return that element, otherwise null. */ @SuppressWarnings("unchecked") public static <N, E extends N, T extends N> E elementEndingAt( ReadableDocument<N,E,T> doc, Point<N> point) { if (point.isInTextNode()) { if (point.getTextOffset() < doc.getLength((T) point.getContainer())) { return null; } else if (doc.getNextSibling(point.getContainer()) == null) { return doc.getParentElement(point.getContainer()); } else { return null; } } else { return point.getNodeAfter() == null ? (E) point.getContainer() : null; } }
if (location.isInTextNode()) { el = doc.getParentElement(location.getContainer()); nodeAfter = doc.getNextSibling(location.getContainer()); if (predicate.apply(doc, el)) { return location; nodeAfter = doc.getNextSibling(el); el = doc.getParentElement(el);
next = rightwards ? doc.getNextSibling(start) : doc.getPreviousSibling(start); if (doc.isSameNode(next, stopAt)) { return null;
/** * Locates characters in contiguous of text nodes. * * Returns location when given locator matches with the data in a text node, * Returns null if not found. * * @param doc * @param start * @param locator * @param forward */ private static <N, E extends N, T extends N> Tx<N> locateCharacters( ReadableDocument<N, E, T> doc, Tx<N> start, CharacterLocator locator, boolean forward) { Tx<N> current = start; N node = start.getContainer(); Tx<N> found = null; while (true) { found = findCharacterInNode(doc, current.asTextPoint(), locator, forward); if (found != null) { return found; } node = forward ? doc.getNextSibling(node) : doc.getPreviousSibling(node); if (doc.asText(node) != null) { current = forward ? Point.inText(node, 0) : Point.inText(node, doc.getLength(doc.asText(node))); } else { return null; } } }
/** * Ensures the given point is at a node boundary, possibly splitting a text * node in order to do so, in which case a new point is returned. * * @param point * @return a point at the same place as the input point, guaranteed to be at * a node boundary. */ public static <N, T extends N> Point.El<N> ensureNodeBoundary(Point<N> point, ReadableDocument<N, ?, T> doc, TextNodeOrganiser<T> textNodeOrganiser) { Point.Tx<N> textPoint = point.asTextPoint(); if (textPoint != null) { T textNode = doc.asText(textPoint.getContainer()); N maybeSecond = textNodeOrganiser.splitText(textNode, textPoint.getTextOffset()); if (maybeSecond != null) { return Point.inElement(doc.getParentElement(maybeSecond), maybeSecond); } else { return Point.inElement(doc.getParentElement(textNode), doc.getNextSibling(textNode)); } } else { return point.asElementPoint(); } }