/** * Adds a tag to the document. * * @param tagName The name of the tag to add. */ public void addTag(String tagName) { if (tagName == null) { return; } tagElements.add(doc.appendXml(getXmlFor(tagName))); }
/** * Deletes a tag from the document by name. * * @param tagName the name of the tag to delete. */ public void deleteTag(String tagName) { N node = doc.getFirstChild(doc.getDocumentElement()); while (node != null) { E element = doc.asElement(node); if (element != null) { T textNode = doc.asText(doc.getFirstChild(node)); if (textNode != null && doc.getData(textNode).equals(tagName)) { doc.deleteNode(element); return; } } node = doc.getNextSibling(node); } }
public <N, E extends N, T extends N> void exec(MutableDocument<N, E, T> doc) { E anchor = Point.elementAfter(doc, doc.locate(location)); E anchorParent = doc.getParentElement(anchor); doc.createChildElement(anchorParent, doc.getTagName(anchor), doc.getAttributes(anchor)); } });
/** * @param index The index of the tag we are interested in. * @return The element that contains the desired tag. */ private E getNthTagNode(int index) { N node = doc.getFirstChild(doc.getDocumentElement()); for (int i = 0; i < index; i++) { if (node == null) { return null; } node = doc.getNextSibling(node); } return doc.asElement(node); }
/** * @param doc * @return true if the document's title is explicitly set */ public static boolean hasExplicitTitle(MutableDocument<?, ?, ?> doc) { int start = doc.firstAnnotationChange(0, doc.size(), TITLE_KEY, null); if (start != -1 && !doc.getAnnotation(start, TITLE_KEY).isEmpty()) { return true; } else { return false; } }
@Override public <N, E extends N, T extends N> void exec(MutableDocument<N, E, T> doc) { Point<N> point = doc.locate(location); doc.createElement(point, Blips.THREAD_INLINE_ANCHOR_TAGNAME, Collections.singletonMap(Blips.THREAD_INLINE_ANCHOR_ID_ATTR, threadId)); } });
/** * Test normalize points between an element and a text node <a>stuff</a>"hi" */ public void testNormalizePointElementFollowedByTextNode() { MutableDocument<Node, Element, Text> doc = initializeMutableDoc(); Element p = doc.asElement(doc.getFirstChild(doc.getDocumentElement())); assert p != null; Element aElement = doc.createElement(Point.start(doc, p), "a", Collections.<String, String> emptyMap()); doc.insertText(Point.start(doc, aElement), "stuff"); doc.insertText(Point.<Node> end(p), "hi"); Text hi = doc.asText(doc.getLastChild(p)); Text stuff = doc.asText(aElement.getFirstChild()); assertEquals(Point.inText(hi, 0), DocHelper.normalizePoint(Point.<Node> inText(hi, 0), doc)); assertEquals(Point.inText(hi, 0), DocHelper.normalizePoint(Point.<Node>inElement(p, hi), doc)); // In the future, we might want to move the caret out from inline elements. assertEquals(Point.inText(stuff, stuff.getLength()), DocHelper.normalizePoint(Point .<Node> inText(stuff, stuff.getLength()), doc)); }
/** Tests bug 1839733 */ public void testNestedPaintNodes() { 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(doc.locate(1), "A"); doc.insertText(doc.locate(2), "B"); doc.setAnnotation(2, 3, "a", "1"); timerService.tick(100); checkXml("<p>A<l:p a=\"1\">B</l:p></p>", XmlStringBuilder.innerXml(cxt.getFullRawDoc())); doc.insertText(doc.locate(3), "C"); doc.setAnnotation(3, 4, "b", "2"); timerService.tick(100); checkXml("<p>A<l:p a=\"1\">B</l:p><l:p a=\"1\" b=\"2\">C</l:p></p>", XmlStringBuilder.innerXml(cxt.getFullRawDoc())); doc.insertText(doc.locate(4), "D"); doc.setAnnotation(4, 5, "a", null); timerService.tick(100); checkXml("<p>A<l:p a=\"1\">B</l:p><l:p a=\"1\" b=\"2\">C</l:p><l:p b=\"2\">D</l:p></p>", XmlStringBuilder.innerXml(cxt.getFullRawDoc())); doc.insertText(doc.locate(5), "E"); doc.setAnnotation(5, 6, "b", null); timerService.tick(100); checkXml("<p>A<l:p a=\"1\">B</l:p><l:p a=\"1\" b=\"2\">C</l:p><l:p b=\"2\">D</l:p>E</p>", XmlStringBuilder.innerXml(cxt.getFullRawDoc())); }
public <N, E extends N, T extends N> void exec(MutableDocument<N, E, T> doc) { Point<N> startText = doc.locate(locateAfterLineElement(doc)); doc.insertText(startText, "cd"); // Insert reply between c|d. N bodyNode = DocHelper.getElementWithTagName(doc, Blips.BODY_TAGNAME); N textNode = doc.getFirstChild(bodyNode); textNode = doc.getNextSibling(textNode); int replyLocation = doc.getLocation(Point.inText(textNode, 1)); ConversationThread replyThread = blip.addReplyThread(replyLocation); // Delete text and anchor. doc.deleteRange(Point.before(doc, textNode), Point.inElement(bodyNode, null)); int newLocation = blip.locateReplyThreads().iterator().next().getLocation(); assertEquals(Blips.INVALID_INLINE_LOCATION, newLocation); } });
public void testFindingImplicitTitleClearsFromInvalidDocuments() { getDoc("<body><line/>Some text.<line/>Some more text</body>"); TitleHelper.maybeFindAndSetImplicitTitle(doc); assertEquals("Some text.", TitleHelper.extractTitle(doc)); doc.emptyElement(doc.getDocumentElement()); doc.appendXml(XmlStringBuilder.createText("Blah. Blah").wrap("x")); TitleHelper.maybeFindAndSetImplicitTitle(doc); assertEquals("", TitleHelper.extractTitle(doc)); assertFalse(TitleHelper.hasExplicitTitle(doc)); assertEquals(-1, doc.firstAnnotationChange(0, doc.size(), TitleHelper.TITLE_KEY, null)); }
boolean afterPunctuation = false; int start = -1, end = doc.size() -1; E firstLineReached = null; E el = doc.asElement(node); if (el == null) { if (firstLineReached != null) { String text = doc.getData(doc.asText(node)); end = doc.getLocation(node) + textIndex; break outer; } else { if (doc.getTagName(el).equals(LineContainers.LINE_TAGNAME)) { if (firstLineReached != null) { end = doc.getLocation(node); break; } else { start = doc.getLocation(node); firstLineReached = el;
String tag, Expectation expectation) { N firstNode = doc.locate(0).getNodeAfter(); if (expectation == Expectation.PRESENT && firstNode == null) { throw new IllegalArgumentException("Document has no top-level element"); return doc.createChildElement(doc.getDocumentElement(), tag, Attributes.EMPTY_MAP); } else { E firstElement = doc.asElement(firstNode); if (firstElement == null) { throw new IllegalArgumentException("First node is not an element: " + firstNode); String actualTag = doc.getTagName(firstElement); if (!tag.equals(actualTag)) { throw new RuntimeException("Document already has non-matching top-level element: "
for (E el : DocIterate.deepElementsReverse(doc, doc.getDocumentElement(), null)) { if (isLineContainer(doc, el)) { lc = el; lc = doc.appendXml(XmlStringBuilder.createEmpty().wrap(LINE_TAGNAME).wrap( topLevelContainerTagname())); doc.insertXml(Point.<N>end(lc), content); E line = doc.asElement(doc.getFirstChild(lc)); assert line != null; if (attributes != null) { doc.setElementAttributes(line, attributes);
@Override public <N, E extends N, T extends N> Object exec(MutableDocument<N, E, T> doc) { return doc.createChildElement(doc.getDocumentElement(), "foreign", Attributes.EMPTY_MAP); } });
@Override public <N, E extends N, T extends N> void exec(MutableDocument<N, E, T> doc) { N rootThreadNode = doc.getFirstChild(doc.getDocumentElement()); E rootThread = doc.asElement(rootThreadNode); doc.createChildElement(rootThread, "blip", Collections.singletonMap( "id", idGenerator.newBlipId())); } });
Element top = (Element) doc.getDocumentElement().getFirstChild(); Node n1 = doc.getFirstChild(top); Node n2 = doc.getLastChild(top); List<Element> all = elementsInner(doc, top); List<Element> els = Arrays.asList(all.get(0), all.get(1)); ci(doc.asElement(top.getFirstChild())), ti(14, moreText), cd(23, 10, dl(st("p", attrs("x", "y")), tt("abc"), st("b", attrs("a", "b")),
doc.firstAnnotationChange(0, doc.size(), TitleHelper.TITLE_KEY, null)); assertEquals("", TitleHelper.extractTitle(doc)); assertEquals(firstLineLocation, doc.firstAnnotationChange(0, doc.size(), TitleHelper.TITLE_KEY, null)); assertEquals(firstLineLocation + 2, doc.lastAnnotationChange(0, doc.size(), TitleHelper.TITLE_KEY, null)); DocHelper.ensureNodeBoundary(doc.locate(startText + i), doc, cxt.textNodeOrganiser()); TitleHelper.maybeFindAndSetImplicitTitle(doc); assertEquals("Some 5.5 text!?.!", TitleHelper.extractTitle(doc)); DocHelper.ensureNodeBoundary(doc.locate(startText + i), doc, cxt.textNodeOrganiser()); DocHelper.ensureNodeBoundary(doc.locate(startText + j), doc, cxt.textNodeOrganiser()); TitleHelper.maybeFindAndSetImplicitTitle(doc); assertEquals("Some 5.5 text!?.!", TitleHelper.extractTitle(doc)); doc.firstAnnotationChange(0, doc.size(), TitleHelper.TITLE_KEY, null)); assertFalse(TitleHelper.hasExplicitTitle(doc));
@Override public <N, E extends N, T extends N> void exec(MutableDocument<N, E, T> doc) { List<E> elementsToDelete = CollectionUtils.newArrayList(); for (E el : DocIterate.deepElements(doc, doc.getDocumentElement(), null)) { if (Blips.THREAD_INLINE_ANCHOR_TAGNAME.equals(doc.getTagName(el))) { String elId = doc.getAttribute(el, Blips.THREAD_INLINE_ANCHOR_ID_ATTR); if (threadIds.contains(elId)) { elementsToDelete.add(el); } } } // Reverse elements to delete so we always delete bottom up if one // contains another (which would be really weird anyway). Collections.reverse(elementsToDelete); for (E el : elementsToDelete) { doc.deleteNode(el); } } });
E lc = doc.getParentElement(line); if (!isLineContainer(doc, lc)) { Preconditions.illegalArgument("Not a line container: " + lc); boolean isFirstLine = doc.getFirstChild(lc) == line; deleteStartPoint = Point.before(doc, line); } else { doc.emptyElement(line); deleteStartPoint = Point.after(doc, line); doc.deleteRange(deleteStartPoint, deleteEndPoint);
/** * Try to insert text into a new text node, by first inserting an element, and * then removing it after the new text is inserted. * * NOTE(user): We assume the document doesn't try to join the text nodes * after the dummy element is removed. * * @param <N> * @param at * @param text */ // TODO(user): Move somewhere common for TextLocatorTest static <N, E extends N, T extends N> void insertTextInNewTextNodeHelper( MutableDocument<N, E, T> doc, Point<N> at, String text) { E e = doc.createElement(at, "a", Collections.<String, String> emptyMap()); doc.insertText(Point.after(doc, e), text); doc.deleteNode(e); }