store element's ContentRange in InsertElementEdit

When an element is deleted, it gets dissociated from the document. While
it can still be referenced by an InsertElementEdit, it is useless for
undo/redo, because its ContentRange gets lost when it is dissociated.
Hence the ContentRange must also be stored in InsertElementEdit.

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 1907c93..abe06df 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
@@ -28,6 +28,7 @@
 import org.eclipse.vex.core.internal.css.CssWhitespacePolicy;

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

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

+import org.eclipse.vex.core.internal.io.XMLFragment;

 import org.eclipse.vex.core.internal.undo.CannotRedoException;

 import org.eclipse.vex.core.provisional.dom.DocumentValidationException;

 import org.eclipse.vex.core.provisional.dom.IDocumentFragment;

@@ -503,6 +504,28 @@
 	}

 

 	@Test

+	public void undoSubsequentSplitsOfInlineAndBlock() throws Exception {

+		widget.insertElement(PARA);

+		widget.insertText("12");

+		widget.insertElement(PRE);

+		widget.insertText("34");

+		widget.moveBy(1);

+		widget.insertText("56");

+		final String expectedXml = getCurrentXML();

+

+		widget.moveBy(-4);

+		widget.split();

+

+		widget.moveBy(-1);

+		widget.split();

+

+		widget.undo();

+		widget.undo();

+

+		assertEquals(expectedXml, getCurrentXML());

+	}

+

+	@Test

 	public void givenElementWithSingleOccurrence_cannotSplitElement() throws Exception {

 		widget.insertElement(TITLE);

 		assertFalse(widget.canSplit());

@@ -538,6 +561,10 @@
 		widget.split();

 	}

 

+	private String getCurrentXML() {

+		return new XMLFragment(widget.getDocument().getFragment(widget.getDocument().getRootElement().getRange())).getXML();

+	}

+

 	private static StyleSheet readTestStyleSheet() throws IOException {

 		return new StyleSheetReader().read(TestResources.get("test.css"));

 	}

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/DeleteEdit.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/DeleteEdit.java
index 35345a6..5c2d1f2 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/DeleteEdit.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/DeleteEdit.java
@@ -33,8 +33,8 @@
 		try {

 			document.insertFragment(range.getStartOffset(), fragment);

 			fragment = null;

-		} catch (final DocumentValidationException ex) {

-			throw new CannotUndoException(ex);

+		} catch (final DocumentValidationException e) {

+			throw new CannotUndoException(e);

 		}

 	}

 

@@ -43,8 +43,8 @@
 		try {

 			fragment = document.getFragment(range);

 			document.delete(range);

-		} catch (final DocumentValidationException ex) {

-			throw new CannotRedoException(ex);

+		} catch (final DocumentValidationException e) {

+			throw new CannotRedoException(e);

 		}

 	}

 

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/InsertElementEdit.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/InsertElementEdit.java
index be049b1..51fa64d 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/InsertElementEdit.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/undo/InsertElementEdit.java
@@ -12,6 +12,7 @@
 package org.eclipse.vex.core.internal.undo;

 

 import org.eclipse.core.runtime.QualifiedName;

+import org.eclipse.vex.core.provisional.dom.ContentRange;

 import org.eclipse.vex.core.provisional.dom.DocumentValidationException;

 import org.eclipse.vex.core.provisional.dom.IDocument;

 import org.eclipse.vex.core.provisional.dom.IElement;

@@ -21,22 +22,25 @@
 	private final IDocument document;

 	private final int offset;

 	private final QualifiedName elementName;

+	private ContentRange elementRange;

 	private IElement element;

 

 	public InsertElementEdit(final IDocument document, final int offset, final QualifiedName elementName) {

 		this.document = document;

 		this.offset = offset;

 		this.elementName = elementName;

+		elementRange = ContentRange.NULL;

 		element = null;

 	}

 

 	@Override

 	protected void performUndo() throws CannotUndoException {

 		try {

-			document.delete(element.getRange());

+			document.delete(elementRange);

+			elementRange = ContentRange.NULL;

 			element = null;

-		} catch (final DocumentValidationException ex) {

-			throw new CannotUndoException();

+		} catch (final DocumentValidationException e) {

+			throw new CannotUndoException(e);

 		}

 	}

 

@@ -44,8 +48,9 @@
 	protected void performRedo() throws CannotRedoException {

 		try {

 			element = document.insertElement(offset, elementName);

-		} catch (final DocumentValidationException ex) {

-			throw new CannotRedoException(ex);

+			elementRange = element.getRange();

+		} catch (final DocumentValidationException e) {

+			throw new CannotRedoException(e);

 		}

 	}

 

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IPosition.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IPosition.java
index 298cf9d..d8850ad 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IPosition.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IPosition.java
@@ -28,6 +28,11 @@
 		public boolean isValid() {
 			return false;
 		};
+
+		@Override
+		public String toString() {
+			return "NULL";
+		}
 	};
 
 	/**