stopAt = doc.getDocumentElement(); E element = doc.asElement(start); if (element != null) { next = rightwards ? doc.getFirstChild(element) : doc.getLastChild(element); if (next != null) { return next; while (start != null && !doc.isSameNode(start, stopAt)) { next = rightwards ? doc.getNextSibling(start) : doc.getPreviousSibling(start); if (doc.isSameNode(next, stopAt)) { return null; return next; start = doc.getParentElement(start);
/** Performs a walk against an iterable collection of nodes, returns true if all checks pass. */ public boolean checkWalk(ReadableDocument<N, E, T> doc, Iterable<N> nodes) { try { for (N node : nodes) { E elt = doc.asElement(node); if (elt != null) { checkElement(doc.getTagName(elt), doc.getAttributes(elt)); } else { checkTextNode(doc.getData(doc.asText(node))); } } return checkComplete(); } catch (IllegalStateException e) { return false; // assertion failed. } }
/** * Appends element's attributes * * @param doc * @param element */ private <E extends N, T extends N> void appendAttributes( ReadableDocument<N, E, T> doc, E element) { try { Map<String, String> attributes = doc.getAttributes(element); for (Map.Entry<String, String> attribute : attributes.entrySet()) { append(" " + attribute.getKey() + "='" + attribute.getValue() + "'"); } } catch (Exception e) { // TODO(user): remove this when + if HtmlViewImpl implements getAttributes for (String name : new String[] {"class", "src", "id", "type", "name", "for", "href", "target"}) { String value = doc.getAttribute(element, name); if (value != null && value.length() > 0) { append(" " + name + "='" + value + "'"); } } } }
/** * Same as {@link #enclosingElement(ReadableDocument, Point)}, except * does it for a node. So if it is an element, return it, if it is * a text node, return its parent. */ public static <N, E extends N, T extends N> E enclosingElement( ReadableDocument<N,E,T> doc, N node) { E el = doc.asElement(node); return el == null ? doc.getParentElement(node) : el; }
/** * 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; }
/** * 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; }
Element container = doc.getFirstChild(doc.getDocumentElement()).asElement(); assertNull(DocHelper.getLastElementWithTagName(doc, "x", container)); Element expectedY = doc.getFirstChild(container).asElement(); assertSame(expectedY, DocHelper.getLastElementWithTagName(doc, "y", container)); Element container = doc.getFirstChild(doc.getDocumentElement()).asElement(); Element expectedY = doc.getFirstChild(container).asElement(); assertSame(expectedY, DocHelper.getLastElementWithTagName(doc, "y")); Element container = doc.getFirstChild(doc.getDocumentElement()).asElement(); Element y = doc.getFirstChild(container).asElement(); assertNull(DocHelper.getLastElementWithTagName(doc, "x", y)); Element x = doc.getLastChild(doc.getDocumentElement()).asElement(); assertNull(DocHelper.getLastElementWithTagName(doc, "z", x)); Element expectedX = doc.getFirstChild(doc.getLastChild( doc.getDocumentElement())).asElement(); assertSame(expectedX, DocHelper.getLastElementWithTagName(doc, "x"));
@Override public <N, E extends N, T extends N> boolean apply(ReadableDocument<N, E, T> doc, N node) { return node == doc.getDocumentElement(); } };
/** * Worker for appendNode * @param node * @return item length of node */ private int addNode(N node) { E element = view.asElement(node); if (element != null) { boolean selfClosing = isSelfClosing(element) && view.getFirstChild(element) == null; builder.append(startTag(element, selfClosing)); int len = 2; if (!selfClosing) { len += addChildXmlFragment(element); builder.append(endTag(element)); } return len; } else { String data = view.getData(view.asText(node)); return addText(permittedChars.coerceString(data)); } }
/** * @return true if the node is an element with the given tag name */ public static <N, E extends N> boolean isMatchingElement( final ReadableDocument<N, E, ?> doc, N node, String tagName) { E el = doc.asElement(node); return el != null && doc.getTagName(el).equals(tagName); }
/** * @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; }
public void testNodeAtEnd() { TestDocumentContext<Node, Element, Text> cxt = createAnnotationContext(); MutableDocument<Node, Element, Text> doc = cxt.document(); Element e = doc.createChildElement(doc.getDocumentElement(), "p", Attributes.EMPTY_MAP); doc.insertText(Point.<Node>inElement(e, null), "Hi"); doc.setAnnotation(3, 4, "x", "1"); timerService.tick(100); ReadableDocument<Node, Element, Text> fullDoc = cxt.getFullRawDoc(); Element boundary = fullDoc.asElement(fullDoc.getLastChild(e)); assertNotNull(boundary); assertEquals("l:b", boundary.getTagName()); doc.setAnnotation(3, 4, "x", null); timerService.tick(100); boundary = fullDoc.asElement(fullDoc.getLastChild(e)); assertNull(boundary); }
/** * 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 node * @return true if node prefers to be output inline */ private <E extends N, T extends N> boolean isInline( ReadableDocument<N, E, T> doc, N node) { E element = doc.asElement(node); T text = doc.asText(node); return text != null || "|b|u|i|".contains("|" + doc.getTagName(element).toLowerCase() + "|"); }
@Override public E asElement(N node) { return inner.asElement(node); }
/** * Construct a point at the end of either an element or text node. * @param doc Document containing the node * @param node The node to get the start of * @return The Point.El end if node is an element, otherwise the position at the last text offset. */ public static <N, E extends N, T extends N> Point<N> textOrElementEnd( ReadableDocument<N,E,T> doc, N node) { E elt = doc.asElement(node); return elt == null ? inText(node, doc.getData(doc.asText(node)).length()) : end(node); }
@Override public N getFirstChild(N node) { return inner.getFirstChild(node); }
/** * @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()); } }
/** * Checks whether the current walk is the correct type of element. * @throws IllegalStateException if the element does not match the expected state. * @return the checked element. */ public E checkElement(String tagName, Map<String, String> attributes) { Preconditions.checkState(nodeWalker.hasNext(), "Tree Walker: no more nodes to walk, element expected"); progress(); E element = document.asElement(currentNode); Preconditions.checkState(element != null, "Tree Walker: At text node, element expected"); Preconditions.checkState(document.getTagName(element).equals(tagName), "Tree Walker: Incorrect tag name"); Preconditions.checkState(ValueUtils.equal(document.getAttributes(element), attributes), "Tree Walker: Incorrect attributes"); return element; }