join adjacent elements when deleting tags in between

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SimpleEditingTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SimpleEditingTest.java
index f65fb59..a655af2 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SimpleEditingTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SimpleEditingTest.java
@@ -18,6 +18,7 @@
 import static org.junit.Assert.assertFalse;

 import static org.junit.Assert.assertNull;

 import static org.junit.Assert.assertSame;

+import static org.junit.Assert.assertTrue;

 

 import org.eclipse.vex.core.internal.css.StyleSheet;

 import org.eclipse.vex.core.internal.dom.Element;

@@ -124,4 +125,87 @@
 		assertFalse(paraElement.isAssociated());

 	}

 

+	@Test

+	public void givenTwoMatchingElements_whenCaretBetweenEndAndStartTagAndHittingBackspace_shouldJoinElements() throws Exception {

+		widget.insertElement(TITLE);

+		widget.moveBy(1);

+		final Element para1 = widget.insertElement(PARA);

+		widget.insertText("Hello");

+		widget.moveBy(1);

+		final Element para2 = widget.insertElement(PARA);

+		widget.insertText("World");

+

+		widget.moveTo(para2.getStartOffset());

+		widget.deletePreviousChar();

+

+		assertEquals(2, rootElement.getChildCount());

+		assertSame(rootElement, para1.getParent());

+		assertTrue(para1.isAssociated());

+		assertEquals("HelloWorld", para1.getText());

+		assertNull(para2.getParent());

+		assertFalse(para2.isAssociated());

+	}

+

+	@Test

+	public void givenTwoMatchingElements_whenCaretBetweenEndAndStartTagAndHittingDelete_shouldJoinElements() throws Exception {

+		widget.insertElement(TITLE);

+		widget.moveBy(1);

+		final Element para1 = widget.insertElement(PARA);

+		widget.insertText("Hello");

+		widget.moveBy(1);

+		final Element para2 = widget.insertElement(PARA);

+		widget.insertText("World");

+

+		widget.moveTo(para2.getStartOffset());

+		widget.deleteNextChar();

+

+		assertEquals(2, rootElement.getChildCount());

+		assertSame(rootElement, para1.getParent());

+		assertTrue(para1.isAssociated());

+		assertEquals("HelloWorld", para1.getText());

+		assertNull(para2.getParent());

+		assertFalse(para2.isAssociated());

+	}

+

+	@Test

+	public void givenTwoMatchingElements_whenCaretAfterStartTagOfSecondElementAndHittingBackspace_shouldJoinElements() throws Exception {

+		widget.insertElement(TITLE);

+		widget.moveBy(1);

+		final Element para1 = widget.insertElement(PARA);

+		widget.insertText("Hello");

+		widget.moveBy(1);

+		final Element para2 = widget.insertElement(PARA);

+		widget.insertText("World");

+

+		widget.moveTo(para2.getStartOffset() + 1);

+		widget.deletePreviousChar();

+

+		assertEquals(2, rootElement.getChildCount());

+		assertSame(rootElement, para1.getParent());

+		assertTrue(para1.isAssociated());

+		assertEquals("HelloWorld", para1.getText());

+		assertNull(para2.getParent());

+		assertFalse(para2.isAssociated());

+	}

+

+	@Test

+	public void givenTwoMatchingElements_whenCaretBeforeEndTagOfFirstElementAndHittingDelete_shouldJoinElements() throws Exception {

+		widget.insertElement(TITLE);

+		widget.moveBy(1);

+		final Element para1 = widget.insertElement(PARA);

+		widget.insertText("Hello");

+		widget.moveBy(1);

+		final Element para2 = widget.insertElement(PARA);

+		widget.insertText("World");

+

+		widget.moveTo(para1.getEndOffset());

+		widget.deleteNextChar();

+

+		assertEquals(2, rootElement.getChildCount());

+		assertSame(rootElement, para1.getParent());

+		assertTrue(para1.isAssociated());

+		assertEquals("HelloWorld", para1.getText());

+		assertNull(para2.getParent());

+		assertFalse(para2.isAssociated());

+	}

 }

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java
index 7d54c28..08b9c35 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/VexWidgetImpl.java
@@ -1478,12 +1478,11 @@
 			final boolean moveContent = !element.isEmpty();
 			DocumentFragment frag = null;
 			if (moveContent) {
-				this.moveTo(element.getEndOffset(), true);
+				this.moveTo(element.getEndOffset() - 1, true);
 				frag = getSelectedFragment();
 				deleteSelection();
 			}
-			this.moveBy(-1);
-			this.moveBy(2, true);
+			this.moveBy(-1, true);
 			deleteSelection();
 			this.moveBy(-1);
 			if (moveContent) {