Parent should provide the child node at the given offset.
Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ParentTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ParentTest.java
index 26d3bab..58e58e1 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ParentTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ParentTest.java
@@ -10,6 +10,7 @@
import java.util.Iterator;
import java.util.List;
+import org.eclipse.core.runtime.AssertionFailedException;
import org.junit.Before;
import org.junit.Test;
@@ -375,6 +376,52 @@
assertTextNodeEquals(" World", 23, 28, childNodes.get(3));
}
+ @Test
+ public void shouldProvideSelfOnOwnBoundaries() throws Exception {
+ assertSame(parent, parent.getChildNodeAt(parent.getStartOffset()));
+ assertSame(parent, parent.getChildNodeAt(parent.getEndOffset()));
+ }
+
+ @Test
+ public void shouldReturnTextWithinBoundaries() throws Exception {
+ content.insertText(parent.getEndOffset(), "Hello World");
+ final Node text = parent.getChildNodes().get(0);
+ assertTextNodeEquals("Hello World", text.getStartOffset(), text.getEndOffset(), parent.getChildNodeAt(text.getStartOffset()));
+ assertTextNodeEquals("Hello World", text.getStartOffset(), text.getEndOffset(), parent.getChildNodeAt(text.getStartOffset() + 1));
+ assertTextNodeEquals("Hello World", text.getStartOffset(), text.getEndOffset(), parent.getChildNodeAt(text.getEndOffset() - 1));
+ assertTextNodeEquals("Hello World", text.getStartOffset(), text.getEndOffset(), parent.getChildNodeAt(text.getEndOffset()));
+ }
+
+ @Test
+ public void shouldReturnTextWithinChildBoundaries() throws Exception {
+ final int offset = parent.getEndOffset();
+ content.insertElementMarker(offset);
+ content.insertElementMarker(offset);
+ final Element child = new Element("child");
+ parent.addChild(child);
+ child.associate(content, offset, offset + 1);
+ content.insertText(child.getEndOffset(), "Hello World");
+ final Node text = child.getChildNodes().get(0);
+ assertTextNodeEquals("Hello World", text.getStartOffset(), text.getEndOffset(), parent.getChildNodeAt(text.getStartOffset()));
+ assertTextNodeEquals("Hello World", text.getStartOffset(), text.getEndOffset(), parent.getChildNodeAt(text.getStartOffset() + 1));
+ assertTextNodeEquals("Hello World", text.getStartOffset(), text.getEndOffset(), parent.getChildNodeAt(text.getEndOffset() - 1));
+ assertTextNodeEquals("Hello World", text.getStartOffset(), text.getEndOffset(), parent.getChildNodeAt(text.getEndOffset()));
+ }
+
+ @Test(expected = AssertionFailedException.class)
+ public void shouldNotProvideChildNodeBeforeStartOffset() throws Exception {
+ content.insertText(parent.getStartOffset(), "prefix");
+ parent.getChildNodeAt(parent.getStartOffset() - 1);
+
+ }
+
+ @Test(expected = AssertionFailedException.class)
+ public void shouldNotProvideChildNodeAfterEndOffset() throws Exception {
+ content.insertText(parent.getEndOffset() + 1, "suffix");
+ parent.getChildNodeAt(parent.getEndOffset() + 1);
+
+ }
+
private static void assertTextNodeEquals(final String text, final int startOffset, final int endOffset, final Node actualNode) {
assertTrue(actualNode instanceof Text);
assertEquals(text, actualNode.getText());
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Parent.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Parent.java
index e007fcf..6e44949 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Parent.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Parent.java
@@ -15,6 +15,8 @@
import java.util.Iterator;
import java.util.List;
+import org.eclipse.core.runtime.Assert;
+
/**
* A Parent node is a Node which can contain other nodes as children. This class defines the tree-like structure of the
* DOM. It handles the mergin of the child nodes and the textual content of one node within the structure of the
@@ -159,6 +161,28 @@
}
/**
+ * Returns the node at the given offset.
+ *
+ * @param offset
+ * the offset
+ * @return the node at the given offset
+ */
+ public Node getChildNodeAt(final int offset) {
+ Assert.isTrue(containsOffset(offset));
+ final List<Node> childNodes = getChildNodes();
+ for (final Node child : childNodes) {
+ if (child.containsOffset(offset)) {
+ if (child instanceof Parent) {
+ return ((Parent) child).getChildNodeAt(offset);
+ } else {
+ return child;
+ }
+ }
+ }
+ return this;
+ }
+
+ /**
* Indicates if this parent node has child nodes. Text nodes are ignored, i.e. this method will return false if this
* parent node contains only text.
*