@Override public int getLength(T textNode) { return inner.getLength(textNode); }
/** * Useful argument checking method for validating that an offset lies * within a text node * * @param doc * @param textNode * @param offset * @param msgPrefix string to prepend to exception, if thrown */ public static <N, T extends N> void checkOffset( ReadableDocument<N, ?, T> doc, T textNode, int offset, String msgPrefix) { Preconditions.checkNotNull(textNode, "Container must not be null"); if (offset < 0 || offset > doc.getLength(textNode)) { throw new IllegalArgumentException( msgPrefix + ": offset '" + offset + "' is not inside text node, " + "length " + doc.getLength(textNode) + ", text: '" + doc.getData(textNode) + "'"); } }
/** * @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()); } }
/** * 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; } }
/** * 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; } } }
/** * Normalizes a point so that it is biased towards text nodes, and node ends * rather than node start. * * @param <N> * @param <E> * @param <T> * @param point * @param doc */ public static <N, E extends N, T extends N> Point<N> normalizePoint(Point<N> point, ReadableDocument<N, E, T> doc) { N previous = null; if (!point.isInTextNode()) { previous = Point.nodeBefore(doc, point.asElementPoint()); T nodeAfterAsText = doc.asText(point.getNodeAfter()); if (nodeAfterAsText != null) { point = Point.<N>inText(nodeAfterAsText, 0); } } else if (point.getTextOffset() == 0) { previous = doc.getPreviousSibling(point.getContainer()); } T previousAsText = doc.asText(previous); if (previous != null && previousAsText != null) { point = Point.inText(previous, doc.getLength(previousAsText)); } return point; }
/** * 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; } }