Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Thienel2016-01-13 12:55:48 -0500
committerFlorian Thienel2016-01-13 12:55:48 -0500
commit93bebe038de6800e04f9b6a51ec1c4285db1c5bd (patch)
tree555efd64a9eb63fc9ba0b55f12e3d13b883381ad
parent4b683d12b48ebdb79bb1404eedc6bc3655ae34c8 (diff)
downloadorg.eclipse.mylyn.docs.vex-93bebe038de6800e04f9b6a51ec1c4285db1c5bd.tar.gz
org.eclipse.mylyn.docs.vex-93bebe038de6800e04f9b6a51ec1c4285db1c5bd.tar.xz
org.eclipse.mylyn.docs.vex-93bebe038de6800e04f9b6a51ec1c4285db1c5bd.zip
extract the editing part of IVexWidget into a separate interface
Signed-off-by: Florian Thienel <florian@thienel.org>
-rw-r--r--org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2CommentEditingTest.java275
-rw-r--r--org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2DocumentPositionTest.java41
-rw-r--r--org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2ProcessingInstructionEditingTest.java133
-rw-r--r--org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SelectionTest.java492
-rw-r--r--org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SimpleEditingTest.java2281
-rw-r--r--org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2XIncludeEditingTest.java258
-rw-r--r--org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java126
-rw-r--r--org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/BaseVexWidget.java5
-rw-r--r--org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/IDocumentEditor.java626
-rw-r--r--org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/IVexWidget.java592
-rw-r--r--org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/VexWidget.java115
-rw-r--r--org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/namespace/tests/EditNamespacesControllerTest.java345
-rw-r--r--org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/namespace/EditNamespacesController.java198
13 files changed, 2760 insertions, 2727 deletions
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2CommentEditingTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2CommentEditingTest.java
index 5e9339d8..029be518 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2CommentEditingTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2CommentEditingTest.java
@@ -1,138 +1,137 @@
-/*******************************************************************************
- * Copyright (c) 2013 Florian Thienel and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Florian Thienel - initial API and implementation
- *******************************************************************************/
-package org.eclipse.vex.core.internal.widget;
-
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PARA;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.TITLE;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.createDocumentWithDTD;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.getContentStructure;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.getCurrentXML;
-import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
-import static org.junit.Assert.assertEquals;
-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.provisional.dom.IComment;
-import org.eclipse.vex.core.provisional.dom.IDocumentFragment;
-import org.eclipse.vex.core.provisional.dom.IElement;
-import org.eclipse.vex.core.provisional.dom.INode;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * @author Florian Thienel
- */
-public class L2CommentEditingTest {
-
- private IVexWidget widget;
- private IElement rootElement;
-
- @Before
- public void setUp() throws Exception {
- widget = new BaseVexWidget(new MockHostComponent());
- widget.setDocument(createDocumentWithDTD(TEST_DTD, "section"), StyleSheet.NULL);
- rootElement = widget.getDocument().getRootElement();
- }
-
- @Test
- public void givenAnElement_whenInsertingAComment_elementShouldContainComment() throws Exception {
- final IComment comment = widget.insertComment();
- assertTrue(rootElement.getRange().contains(comment.getRange()));
- assertSame(rootElement, comment.getParent());
- assertEquals(comment.getEndPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void givenAnElementWithComment_whenInsertingTextWithinComment_shouldAddTextToComment() throws Exception {
- final IComment comment = widget.insertComment();
- widget.insertText("Hello World");
- assertEquals("Hello World", comment.getText());
- }
-
- @Test
- public void givenAnEmptyComment_whenCaretInCommentAndHittingBackspace_shouldDeleteComment() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- final IComment comment = widget.insertComment();
- widget.deletePreviousChar();
- assertFalse(titleElement.hasChildren());
- assertFalse(comment.isAssociated());
- assertNull(comment.getParent());
- }
-
- @Test
- public void givenAnEmptyComment_whenCaretInCommentAndHittingDelete_shouldDeleteComment() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- final IComment comment = widget.insertComment();
- widget.deleteNextChar();
- assertFalse(titleElement.hasChildren());
- assertFalse(comment.isAssociated());
- assertNull(comment.getParent());
- }
-
- @Test
- public void givenAComment_whenCaretInComment_shouldNotAllowToInsertAComment() throws Exception {
- widget.insertComment();
- assertFalse("can insert comment within comment", widget.canInsertComment());
- }
-
- @Test
- public void undoRemoveCommentTag() throws Exception {
- widget.insertElement(TITLE);
- widget.insertText("1text before comment1");
- widget.insertComment();
- final INode comment = widget.getDocument().getChildAt(widget.getCaretPosition());
- widget.insertText("2comment text2");
- widget.moveBy(1);
- widget.insertText("3text after comment3");
-
- final String expectedContentStructure = getContentStructure(widget.getDocument().getRootElement());
-
- widget.doWork(new Runnable() {
- @Override
- public void run() {
- widget.moveTo(comment.getStartPosition().moveBy(1), false);
- widget.moveTo(comment.getEndPosition().moveBy(-1), true);
- final IDocumentFragment fragment = widget.getSelectedFragment();
- widget.deleteSelection();
-
- widget.moveBy(-1, false);
- widget.moveBy(1, true);
- widget.deleteSelection();
-
- widget.insertFragment(fragment);
- }
- });
-
- widget.undo();
-
- assertEquals(expectedContentStructure, getContentStructure(widget.getDocument().getRootElement()));
- }
-
- @Test
- public void undoRedoInsertCommentWithSubsequentDelete() throws Exception {
- widget.insertElement(PARA);
- final String expectedXml = getCurrentXML(widget);
-
- final IComment comment = widget.insertComment();
- widget.moveTo(comment.getStartPosition());
- widget.moveTo(comment.getEndPosition(), true);
- widget.deleteSelection();
-
- widget.undo(); // delete
- widget.undo(); // insert comment
-
- assertEquals(expectedXml, getCurrentXML(widget));
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2013 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.widget;
+
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PARA;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.TITLE;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.createDocumentWithDTD;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.getContentStructure;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.getCurrentXML;
+import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
+import static org.junit.Assert.assertEquals;
+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.provisional.dom.IComment;
+import org.eclipse.vex.core.provisional.dom.IDocumentFragment;
+import org.eclipse.vex.core.provisional.dom.IElement;
+import org.eclipse.vex.core.provisional.dom.INode;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Florian Thienel
+ */
+public class L2CommentEditingTest {
+
+ private IDocumentEditor editor;
+ private IElement rootElement;
+
+ @Before
+ public void setUp() throws Exception {
+ editor = new BaseVexWidget(new MockHostComponent());
+ editor.setDocument(createDocumentWithDTD(TEST_DTD, "section"));
+ rootElement = editor.getDocument().getRootElement();
+ }
+
+ @Test
+ public void givenAnElement_whenInsertingAComment_elementShouldContainComment() throws Exception {
+ final IComment comment = editor.insertComment();
+ assertTrue(rootElement.getRange().contains(comment.getRange()));
+ assertSame(rootElement, comment.getParent());
+ assertEquals(comment.getEndPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenAnElementWithComment_whenInsertingTextWithinComment_shouldAddTextToComment() throws Exception {
+ final IComment comment = editor.insertComment();
+ editor.insertText("Hello World");
+ assertEquals("Hello World", comment.getText());
+ }
+
+ @Test
+ public void givenAnEmptyComment_whenCaretInCommentAndHittingBackspace_shouldDeleteComment() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ final IComment comment = editor.insertComment();
+ editor.deletePreviousChar();
+ assertFalse(titleElement.hasChildren());
+ assertFalse(comment.isAssociated());
+ assertNull(comment.getParent());
+ }
+
+ @Test
+ public void givenAnEmptyComment_whenCaretInCommentAndHittingDelete_shouldDeleteComment() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ final IComment comment = editor.insertComment();
+ editor.deleteNextChar();
+ assertFalse(titleElement.hasChildren());
+ assertFalse(comment.isAssociated());
+ assertNull(comment.getParent());
+ }
+
+ @Test
+ public void givenAComment_whenCaretInComment_shouldNotAllowToInsertAComment() throws Exception {
+ editor.insertComment();
+ assertFalse("can insert comment within comment", editor.canInsertComment());
+ }
+
+ @Test
+ public void undoRemoveCommentTag() throws Exception {
+ editor.insertElement(TITLE);
+ editor.insertText("1text before comment1");
+ editor.insertComment();
+ final INode comment = editor.getDocument().getChildAt(editor.getCaretPosition());
+ editor.insertText("2comment text2");
+ editor.moveBy(1);
+ editor.insertText("3text after comment3");
+
+ final String expectedContentStructure = getContentStructure(editor.getDocument().getRootElement());
+
+ editor.doWork(new Runnable() {
+ @Override
+ public void run() {
+ editor.moveTo(comment.getStartPosition().moveBy(1), false);
+ editor.moveTo(comment.getEndPosition().moveBy(-1), true);
+ final IDocumentFragment fragment = editor.getSelectedFragment();
+ editor.deleteSelection();
+
+ editor.moveBy(-1, false);
+ editor.moveBy(1, true);
+ editor.deleteSelection();
+
+ editor.insertFragment(fragment);
+ }
+ });
+
+ editor.undo();
+
+ assertEquals(expectedContentStructure, getContentStructure(editor.getDocument().getRootElement()));
+ }
+
+ @Test
+ public void undoRedoInsertCommentWithSubsequentDelete() throws Exception {
+ editor.insertElement(PARA);
+ final String expectedXml = getCurrentXML(editor);
+
+ final IComment comment = editor.insertComment();
+ editor.moveTo(comment.getStartPosition());
+ editor.moveTo(comment.getEndPosition(), true);
+ editor.deleteSelection();
+
+ editor.undo(); // delete
+ editor.undo(); // insert comment
+
+ assertEquals(expectedXml, getCurrentXML(editor));
+ }
+
+}
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2DocumentPositionTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2DocumentPositionTest.java
index 805ebec1..9951aec4 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2DocumentPositionTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2DocumentPositionTest.java
@@ -16,44 +16,41 @@ import static org.eclipse.vex.core.internal.widget.VexWidgetTest.createDocumentW
import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
import static org.junit.Assert.assertEquals;
-import org.eclipse.vex.core.internal.css.StyleSheet;
import org.eclipse.vex.core.provisional.dom.IElement;
import org.junit.Before;
import org.junit.Test;
public class L2DocumentPositionTest {
- private IVexWidget widget;
- private MockHostComponent hostComponent;
+ private IDocumentEditor editor;
@Before
public void setUp() throws Exception {
- hostComponent = new MockHostComponent();
- widget = new BaseVexWidget(hostComponent);
- widget.setDocument(createDocumentWithDTD(TEST_DTD, "section"), StyleSheet.NULL);
+ editor = new BaseVexWidget(new MockHostComponent());
+ editor.setDocument(createDocumentWithDTD(TEST_DTD, "section"));
}
@Test
public void moveToNextWord() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.insertText("Test Word Another Word");
- widget.moveTo(paraElement.getStartPosition().moveBy(1));
- widget.moveToNextWord(false);
- assertEquals(paraElement.getStartPosition().moveBy(5), widget.getCaretPosition());
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.insertText("Test Word Another Word");
+ editor.moveTo(paraElement.getStartPosition().moveBy(1));
+ editor.moveToNextWord(false);
+ assertEquals(paraElement.getStartPosition().moveBy(5), editor.getCaretPosition());
}
@Test
public void moveToPreviousWord() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.insertText("Test Word Another Word");
- widget.moveTo(paraElement.getEndPosition().moveBy(1));
- widget.moveToPreviousWord(false);
- assertEquals(paraElement.getStartPosition().moveBy(19), widget.getCaretPosition());
- widget.moveToPreviousWord(false);
- assertEquals(paraElement.getStartPosition().moveBy(11), widget.getCaretPosition());
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.insertText("Test Word Another Word");
+ editor.moveTo(paraElement.getEndPosition().moveBy(1));
+ editor.moveToPreviousWord(false);
+ assertEquals(paraElement.getStartPosition().moveBy(19), editor.getCaretPosition());
+ editor.moveToPreviousWord(false);
+ assertEquals(paraElement.getStartPosition().moveBy(11), editor.getCaretPosition());
}
}
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2ProcessingInstructionEditingTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2ProcessingInstructionEditingTest.java
index 3232c3f4..371507c9 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2ProcessingInstructionEditingTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2ProcessingInstructionEditingTest.java
@@ -19,7 +19,6 @@ import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import org.eclipse.vex.core.internal.css.StyleSheet;
import org.eclipse.vex.core.internal.undo.CannotApplyException;
import org.eclipse.vex.core.provisional.dom.IDocumentFragment;
import org.eclipse.vex.core.provisional.dom.INode;
@@ -29,22 +28,22 @@ import org.junit.Test;
public class L2ProcessingInstructionEditingTest {
- private IVexWidget widget;
+ private IDocumentEditor editor;
@Before
public void setUp() throws Exception {
- widget = new BaseVexWidget(new MockHostComponent());
- widget.setDocument(createDocumentWithDTD(TEST_DTD, "section"), StyleSheet.NULL);
+ editor = new BaseVexWidget(new MockHostComponent());
+ editor.setDocument(createDocumentWithDTD(TEST_DTD, "section"));
}
@Test
public void insertProcessingInstruction() throws Exception {
- widget.insertElement(TITLE);
- widget.insertProcessingInstruction("target");
- widget.insertText("data");
+ editor.insertElement(TITLE);
+ editor.insertProcessingInstruction("target");
+ editor.insertText("data");
- widget.moveBy(-1);
- final INode node = widget.getCurrentNode();
+ editor.moveBy(-1);
+ final INode node = editor.getCurrentNode();
assertTrue(node instanceof IProcessingInstruction);
final IProcessingInstruction pi = (IProcessingInstruction) node;
assertEquals("target", pi.getTarget());
@@ -53,69 +52,69 @@ public class L2ProcessingInstructionEditingTest {
@Test(expected = CannotApplyException.class)
public void shouldNotInsertInvalidProcessingInstruction() throws Exception {
- widget.insertElement(TITLE);
- widget.insertProcessingInstruction(" tar get");
+ editor.insertElement(TITLE);
+ editor.insertProcessingInstruction(" tar get");
}
@Test
public void undoInsertProcessingInstructionWithSubsequentDelete() throws Exception {
- widget.insertElement(PARA);
- final String expectedXml = getCurrentXML(widget);
+ editor.insertElement(PARA);
+ final String expectedXml = getCurrentXML(editor);
- final IProcessingInstruction pi = widget.insertProcessingInstruction("target");
+ final IProcessingInstruction pi = editor.insertProcessingInstruction("target");
- widget.moveTo(pi.getStartPosition());
- widget.moveTo(pi.getEndPosition(), true);
- widget.deleteSelection();
+ editor.moveTo(pi.getStartPosition());
+ editor.moveTo(pi.getEndPosition(), true);
+ editor.deleteSelection();
- widget.undo(); // delete
- widget.undo(); // insert comment
+ editor.undo(); // delete
+ editor.undo(); // insert comment
- assertEquals(expectedXml, getCurrentXML(widget));
+ assertEquals(expectedXml, getCurrentXML(editor));
}
@Test
public void undoRemoveProcessingInstruction() throws Exception {
- widget.insertElement(TITLE);
- widget.insertText("1text before pi");
- final INode pi = widget.insertProcessingInstruction("target");
- widget.insertText("2pi text2");
- widget.moveBy(1);
- widget.insertText("3text after pi");
+ editor.insertElement(TITLE);
+ editor.insertText("1text before pi");
+ final INode pi = editor.insertProcessingInstruction("target");
+ editor.insertText("2pi text2");
+ editor.moveBy(1);
+ editor.insertText("3text after pi");
- final String expectedContentStructure = getContentStructure(widget.getDocument().getRootElement());
+ final String expectedContentStructure = getContentStructure(editor.getDocument().getRootElement());
- widget.doWork(new Runnable() {
+ editor.doWork(new Runnable() {
@Override
public void run() {
- widget.moveTo(pi.getStartPosition().moveBy(1), false);
- widget.moveTo(pi.getEndPosition().moveBy(-1), true);
- final IDocumentFragment fragment = widget.getSelectedFragment();
- widget.deleteSelection();
+ editor.moveTo(pi.getStartPosition().moveBy(1), false);
+ editor.moveTo(pi.getEndPosition().moveBy(-1), true);
+ final IDocumentFragment fragment = editor.getSelectedFragment();
+ editor.deleteSelection();
- widget.moveBy(-1, false);
- widget.moveBy(1, true);
- widget.deleteSelection();
+ editor.moveBy(-1, false);
+ editor.moveBy(1, true);
+ editor.deleteSelection();
- widget.insertFragment(fragment);
+ editor.insertFragment(fragment);
}
});
- widget.undo();
+ editor.undo();
- assertEquals(expectedContentStructure, getContentStructure(widget.getDocument().getRootElement()));
+ assertEquals(expectedContentStructure, getContentStructure(editor.getDocument().getRootElement()));
}
@Test
public void editProcessingInstruction() throws Exception {
- widget.insertElement(TITLE);
- widget.insertProcessingInstruction("target");
- widget.insertText("oldData");
+ editor.insertElement(TITLE);
+ editor.insertProcessingInstruction("target");
+ editor.insertText("oldData");
- widget.moveBy(-1);
- widget.editProcessingInstruction("new", "newData");
+ editor.moveBy(-1);
+ editor.editProcessingInstruction("new", "newData");
- final INode node = widget.getCurrentNode();
+ final INode node = editor.getCurrentNode();
assertTrue(node instanceof IProcessingInstruction);
final IProcessingInstruction pi = (IProcessingInstruction) node;
assertEquals("new", pi.getTarget());
@@ -124,32 +123,32 @@ public class L2ProcessingInstructionEditingTest {
@Test
public void undoEditProcessingInstruction() throws Exception {
- widget.insertElement(TITLE);
- widget.insertText("1text before pi");
- final IProcessingInstruction pi = widget.insertProcessingInstruction("target");
- widget.insertText("2data");
- widget.moveBy(1);
- widget.insertText("3text after pi");
+ editor.insertElement(TITLE);
+ editor.insertText("1text before pi");
+ final IProcessingInstruction pi = editor.insertProcessingInstruction("target");
+ editor.insertText("2data");
+ editor.moveBy(1);
+ editor.insertText("3text after pi");
- final String expectedContentStructure = getContentStructure(widget.getDocument().getRootElement());
+ final String expectedContentStructure = getContentStructure(editor.getDocument().getRootElement());
- widget.moveTo(pi.getStartPosition().moveBy(1));
- widget.editProcessingInstruction("new", "data");
- widget.undo();
+ editor.moveTo(pi.getStartPosition().moveBy(1));
+ editor.editProcessingInstruction("new", "data");
+ editor.undo();
- assertEquals(expectedContentStructure, getContentStructure(widget.getDocument().getRootElement()));
+ assertEquals(expectedContentStructure, getContentStructure(editor.getDocument().getRootElement()));
}
@Test
public void editProcessingInstruction_newTargetOnly() throws Exception {
- widget.insertElement(TITLE);
- widget.insertProcessingInstruction("target");
- widget.insertText("oldData");
+ editor.insertElement(TITLE);
+ editor.insertProcessingInstruction("target");
+ editor.insertText("oldData");
- widget.moveBy(-1);
- widget.editProcessingInstruction("new", null);
+ editor.moveBy(-1);
+ editor.editProcessingInstruction("new", null);
- final INode node = widget.getCurrentNode();
+ final INode node = editor.getCurrentNode();
assertTrue(node instanceof IProcessingInstruction);
final IProcessingInstruction pi = (IProcessingInstruction) node;
assertEquals("new", pi.getTarget());
@@ -158,14 +157,14 @@ public class L2ProcessingInstructionEditingTest {
@Test
public void editProcessingInstruction_newDataOnly() throws Exception {
- widget.insertElement(TITLE);
- widget.insertProcessingInstruction("target");
- widget.insertText("oldData");
+ editor.insertElement(TITLE);
+ editor.insertProcessingInstruction("target");
+ editor.insertText("oldData");
- widget.moveBy(-1);
- widget.editProcessingInstruction(null, "newData");
+ editor.moveBy(-1);
+ editor.editProcessingInstruction(null, "newData");
- final INode node = widget.getCurrentNode();
+ final INode node = editor.getCurrentNode();
assertTrue(node instanceof IProcessingInstruction);
final IProcessingInstruction pi = (IProcessingInstruction) node;
assertEquals("target", pi.getTarget());
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SelectionTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SelectionTest.java
index 24339961..defcbb05 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SelectionTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2SelectionTest.java
@@ -1,247 +1,245 @@
-/*******************************************************************************
- * Copyright (c) 2012, 2014 Florian Thienel and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Florian Thienel - initial API and implementation
- * Carsten Hiesserich - additional tests
- *******************************************************************************/
-package org.eclipse.vex.core.internal.widget;
-
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PARA;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PRE;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.TITLE;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.createDocumentWithDTD;
-import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.vex.core.internal.css.StyleSheet;
-import org.eclipse.vex.core.provisional.dom.IComment;
-import org.eclipse.vex.core.provisional.dom.IElement;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * @author Florian Thienel
- */
-public class L2SelectionTest {
-
- private IVexWidget widget;
- private MockHostComponent hostComponent;
-
- @Before
- public void setUp() throws Exception {
- hostComponent = new MockHostComponent();
- widget = new BaseVexWidget(hostComponent);
- widget.setDocument(createDocumentWithDTD(TEST_DTD, "section"), StyleSheet.NULL);
- }
-
- @Test
- public void givenCaretInElement_whenSelectionIncludesStartOffset_shouldExpandSelectionToEndOffset() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.moveBy(-1, true);
- assertTrue(widget.hasSelection());
- assertEquals(titleElement.getRange(), widget.getSelectedRange());
- assertEquals(titleElement.getStartPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretInElementWith_whenSelectionIncludesStartOffset_shouldExpandSelectionToEndOffset() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveBy(-5, false);
- widget.moveTo(titleElement.getStartPosition(), true);
- assertTrue(widget.hasSelection());
- assertEquals(titleElement.getRange(), widget.getSelectedRange());
- assertEquals(titleElement.getStartPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretInElementWith_whenSelectionForwardIncludesStartOffset_shouldExpandSelectionToEndOffset() throws Exception {
- widget.insertElement(PARA);
- widget.insertText("before");
- final IElement innerElement = widget.insertElement(PRE);
- widget.insertText("Selection");
- widget.moveTo(innerElement.getEndPosition().moveBy(1));
- widget.insertText("after");
-
- widget.moveTo(innerElement.getStartPosition().moveBy(-1));
- widget.moveTo(innerElement.getStartPosition().moveBy(1), true);
-
- assertTrue(widget.hasSelection());
- assertEquals(innerElement.getStartPosition().moveBy(-1), widget.getSelectedPositionRange().getStartPosition());
- assertEquals(innerElement.getEndPosition().moveBy(1), widget.getSelectedPositionRange().getEndPosition());
- assertEquals(innerElement.getEndPosition().moveBy(1), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretInElementWith_whenSelectionBackwardIncludesStartOffset_shouldExpandSelectionToEndOffset() throws Exception {
- widget.insertElement(PARA);
- final IElement innerElement = widget.insertElement(PRE);
- widget.insertText("Selection");
- widget.moveTo(innerElement.getEndPosition().moveBy(1));
- widget.insertText("after");
- widget.moveTo(innerElement.getEndPosition().moveBy(-1));
- widget.moveTo(innerElement.getStartPosition(), true);
-
- assertTrue(widget.hasSelection());
- assertEquals(innerElement.getRange(), widget.getSelectedRange());
- assertEquals(innerElement.getStartPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretInElementAtEndOffset_whenMovedByOneBehindEndOffset_shouldExpandSelectionToStartOffset() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveBy(1, true);
- assertTrue(widget.hasSelection());
- assertEquals(titleElement.getRange(), widget.getSelectedRange());
- assertEquals(titleElement.getEndPosition().moveBy(1), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretInElementAtEndOffset_whenMovedOneBehindStartOffset_shouldNotIncludeEndOffsetInSelectedRange() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveTo(titleElement.getStartPosition().moveBy(1), true);
- assertEquals(titleElement.getRange().resizeBy(1, -1), widget.getSelectedRange());
- assertEquals(titleElement.getStartPosition().moveBy(1), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretAtStartOffsetOfElementWithText_whenMovedByOneForward_shouldExpandSelectionBehindEndOffset() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveTo(titleElement.getStartPosition(), false);
- widget.moveBy(1, true);
- assertEquals(titleElement.getRange(), widget.getSelectedRange());
- assertEquals(titleElement.getEndPosition().moveBy(1), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretAtStartOffsetOfElementWithText_whenMovedOneForwardAndOneBackward_shouldSelectNothing() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveTo(titleElement.getStartPosition(), false);
- widget.moveBy(1, true);
- widget.moveBy(-1, true);
- assertEquals(titleElement.getStartPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretInElementWithText_whenMovedBehindFollowingElementAndMovedBackOnce_shouldSelectOnlyFirstElement() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.insertText("Hello Again");
- widget.moveTo(titleElement.getStartPosition().moveBy(3));
- widget.moveTo(paraElement.getEndPosition().moveBy(1), true);
- widget.moveBy(-1, true);
- assertEquals(titleElement.getRange(), widget.getSelectedRange());
- assertEquals(titleElement.getEndPosition().moveBy(1), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretInElementWithText_whenMovedBehindFollowingElementAndMovedBackTwice_shouldSelectOnlyTextFragementOfFirstElement() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.insertText("Hello Again");
- widget.moveTo(titleElement.getStartPosition().moveBy(3));
- widget.moveTo(paraElement.getEndPosition().moveBy(1), true);
- widget.moveBy(-1, true);
- widget.moveBy(-1, true);
- assertEquals(titleElement.getRange().resizeBy(3, -1), widget.getSelectedRange());
- assertEquals(titleElement.getEndPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretInElementWithText_whenMovedBeforePrecedingElementAndMovedForwardOnce_shouldSelectOnlySecondElement() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.insertText("Hello Again");
- widget.moveTo(paraElement.getEndPosition().moveBy(-3));
- widget.moveTo(titleElement.getStartPosition(), true);
- widget.moveBy(1, true);
- assertEquals(paraElement.getRange(), widget.getSelectedRange());
- assertEquals(paraElement.getStartPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void givenCaretInElementWithText_whenMovedBeforePrecedingElementAndMovedForwardTwice_shouldSelectOnlyTextFragementOfSecondElement() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.insertText("Hello Again");
- widget.moveTo(paraElement.getEndPosition().moveBy(-3));
- widget.moveTo(titleElement.getStartPosition(), true);
- widget.moveBy(1, true);
- widget.moveBy(1, true);
- assertEquals(paraElement.getRange().resizeBy(1, -4), widget.getSelectedRange());
- assertEquals(paraElement.getStartPosition().moveBy(+1), widget.getCaretPosition());
- }
-
- @Test
- public void givenCarentInEmptyComment_whenMovedBeforeComment_shouldExpandSelectionToIncludeEndOffset() throws Exception {
- final IComment comment = widget.insertComment();
- widget.moveBy(-1, true);
- assertTrue(widget.hasSelection());
- assertEquals(comment.getRange(), widget.getSelectedRange());
- assertEquals(comment.getStartPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void givenNodeInDocument_whenNodeHasContent_shouldSelectContentOfNode() throws Exception {
- final IElement title = widget.insertElement(TITLE);
- widget.insertText("Hello World");
-
- widget.selectContentOf(title);
-
- assertEquals(title.getRange().resizeBy(1, -1), widget.getSelectedRange());
- assertTrue(widget.hasSelection());
- }
-
- @Test
- public void givenNodeInDocument_whenNodeIsEmpty_shouldMoveCaretIntoNode() throws Exception {
- final IElement title = widget.insertElement(TITLE);
-
- widget.selectContentOf(title);
-
- assertEquals(title.getEndPosition(), widget.getCaretPosition());
- assertFalse(widget.hasSelection());
- }
-
- @Test
- public void givenNodeInDocument_shouldSelectCompleteNodeWithStartAndEndTags() throws Exception {
- final IElement title = widget.insertElement(TITLE);
- widget.insertText("Hello World");
-
- widget.select(title);
-
- assertEquals(title.getRange(), widget.getSelectedRange());
- assertTrue(widget.hasSelection());
- }
-
- @Test
- public void givenWorkBlockStarted_whenWorkBlockNotEnded_shouldNotFireSelectionChangedEvent() throws Exception {
- hostComponent.selectionChanged = false;
- widget.beginWork();
- final IElement title = widget.insertElement(TITLE);
- widget.moveTo(title.getStartPosition());
- widget.moveTo(title.getEndPosition(), true);
- final boolean selectionChangedWhileWorking = hostComponent.selectionChanged;
- widget.endWork(true);
-
- assertFalse(selectionChangedWhileWorking);
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Florian Thienel - initial API and implementation
+ * Carsten Hiesserich - additional tests
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.widget;
+
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PARA;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PRE;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.TITLE;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.createDocumentWithDTD;
+import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.vex.core.provisional.dom.IComment;
+import org.eclipse.vex.core.provisional.dom.IElement;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Florian Thienel
+ */
+public class L2SelectionTest {
+
+ private IDocumentEditor editor;
+
+ @Before
+ public void setUp() throws Exception {
+ editor = new BaseVexWidget(new MockHostComponent());
+ editor.setDocument(createDocumentWithDTD(TEST_DTD, "section"));
+ }
+
+ @Test
+ public void givenCaretInElement_whenSelectionIncludesStartOffset_shouldExpandSelectionToEndOffset() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.moveBy(-1, true);
+ assertTrue(editor.hasSelection());
+ assertEquals(titleElement.getRange(), editor.getSelectedRange());
+ assertEquals(titleElement.getStartPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretInElementWith_whenSelectionIncludesStartOffset_shouldExpandSelectionToEndOffset() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveBy(-5, false);
+ editor.moveTo(titleElement.getStartPosition(), true);
+ assertTrue(editor.hasSelection());
+ assertEquals(titleElement.getRange(), editor.getSelectedRange());
+ assertEquals(titleElement.getStartPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretInElementWith_whenSelectionForwardIncludesStartOffset_shouldExpandSelectionToEndOffset() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("before");
+ final IElement innerElement = editor.insertElement(PRE);
+ editor.insertText("Selection");
+ editor.moveTo(innerElement.getEndPosition().moveBy(1));
+ editor.insertText("after");
+
+ editor.moveTo(innerElement.getStartPosition().moveBy(-1));
+ editor.moveTo(innerElement.getStartPosition().moveBy(1), true);
+
+ assertTrue(editor.hasSelection());
+ assertEquals(innerElement.getStartPosition().moveBy(-1), editor.getSelectedPositionRange().getStartPosition());
+ assertEquals(innerElement.getEndPosition().moveBy(1), editor.getSelectedPositionRange().getEndPosition());
+ assertEquals(innerElement.getEndPosition().moveBy(1), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretInElementWith_whenSelectionBackwardIncludesStartOffset_shouldExpandSelectionToEndOffset() throws Exception {
+ editor.insertElement(PARA);
+ final IElement innerElement = editor.insertElement(PRE);
+ editor.insertText("Selection");
+ editor.moveTo(innerElement.getEndPosition().moveBy(1));
+ editor.insertText("after");
+ editor.moveTo(innerElement.getEndPosition().moveBy(-1));
+ editor.moveTo(innerElement.getStartPosition(), true);
+
+ assertTrue(editor.hasSelection());
+ assertEquals(innerElement.getRange(), editor.getSelectedRange());
+ assertEquals(innerElement.getStartPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretInElementAtEndOffset_whenMovedByOneBehindEndOffset_shouldExpandSelectionToStartOffset() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveBy(1, true);
+ assertTrue(editor.hasSelection());
+ assertEquals(titleElement.getRange(), editor.getSelectedRange());
+ assertEquals(titleElement.getEndPosition().moveBy(1), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretInElementAtEndOffset_whenMovedOneBehindStartOffset_shouldNotIncludeEndOffsetInSelectedRange() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveTo(titleElement.getStartPosition().moveBy(1), true);
+ assertEquals(titleElement.getRange().resizeBy(1, -1), editor.getSelectedRange());
+ assertEquals(titleElement.getStartPosition().moveBy(1), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretAtStartOffsetOfElementWithText_whenMovedByOneForward_shouldExpandSelectionBehindEndOffset() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveTo(titleElement.getStartPosition(), false);
+ editor.moveBy(1, true);
+ assertEquals(titleElement.getRange(), editor.getSelectedRange());
+ assertEquals(titleElement.getEndPosition().moveBy(1), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretAtStartOffsetOfElementWithText_whenMovedOneForwardAndOneBackward_shouldSelectNothing() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveTo(titleElement.getStartPosition(), false);
+ editor.moveBy(1, true);
+ editor.moveBy(-1, true);
+ assertEquals(titleElement.getStartPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretInElementWithText_whenMovedBehindFollowingElementAndMovedBackOnce_shouldSelectOnlyFirstElement() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.insertText("Hello Again");
+ editor.moveTo(titleElement.getStartPosition().moveBy(3));
+ editor.moveTo(paraElement.getEndPosition().moveBy(1), true);
+ editor.moveBy(-1, true);
+ assertEquals(titleElement.getRange(), editor.getSelectedRange());
+ assertEquals(titleElement.getEndPosition().moveBy(1), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretInElementWithText_whenMovedBehindFollowingElementAndMovedBackTwice_shouldSelectOnlyTextFragementOfFirstElement() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.insertText("Hello Again");
+ editor.moveTo(titleElement.getStartPosition().moveBy(3));
+ editor.moveTo(paraElement.getEndPosition().moveBy(1), true);
+ editor.moveBy(-1, true);
+ editor.moveBy(-1, true);
+ assertEquals(titleElement.getRange().resizeBy(3, -1), editor.getSelectedRange());
+ assertEquals(titleElement.getEndPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretInElementWithText_whenMovedBeforePrecedingElementAndMovedForwardOnce_shouldSelectOnlySecondElement() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.insertText("Hello Again");
+ editor.moveTo(paraElement.getEndPosition().moveBy(-3));
+ editor.moveTo(titleElement.getStartPosition(), true);
+ editor.moveBy(1, true);
+ assertEquals(paraElement.getRange(), editor.getSelectedRange());
+ assertEquals(paraElement.getStartPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCaretInElementWithText_whenMovedBeforePrecedingElementAndMovedForwardTwice_shouldSelectOnlyTextFragementOfSecondElement() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.insertText("Hello Again");
+ editor.moveTo(paraElement.getEndPosition().moveBy(-3));
+ editor.moveTo(titleElement.getStartPosition(), true);
+ editor.moveBy(1, true);
+ editor.moveBy(1, true);
+ assertEquals(paraElement.getRange().resizeBy(1, -4), editor.getSelectedRange());
+ assertEquals(paraElement.getStartPosition().moveBy(+1), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenCarentInEmptyComment_whenMovedBeforeComment_shouldExpandSelectionToIncludeEndOffset() throws Exception {
+ final IComment comment = editor.insertComment();
+ editor.moveBy(-1, true);
+ assertTrue(editor.hasSelection());
+ assertEquals(comment.getRange(), editor.getSelectedRange());
+ assertEquals(comment.getStartPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenNodeInDocument_whenNodeHasContent_shouldSelectContentOfNode() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+
+ editor.selectContentOf(title);
+
+ assertEquals(title.getRange().resizeBy(1, -1), editor.getSelectedRange());
+ assertTrue(editor.hasSelection());
+ }
+
+ @Test
+ public void givenNodeInDocument_whenNodeIsEmpty_shouldMoveCaretIntoNode() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+
+ editor.selectContentOf(title);
+
+ assertEquals(title.getEndPosition(), editor.getCaretPosition());
+ assertFalse(editor.hasSelection());
+ }
+
+ @Test
+ public void givenNodeInDocument_shouldSelectCompleteNodeWithStartAndEndTags() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+
+ editor.select(title);
+
+ assertEquals(title.getRange(), editor.getSelectedRange());
+ assertTrue(editor.hasSelection());
+ }
+
+ @Test
+ public void givenWorkBlockStarted_whenWorkBlockNotEnded_shouldNotFireSelectionChangedEvent() throws Exception {
+ // TODO should IDocumentEditor implement ISelectionProvider?
+ // hostComponent.selectionChanged = false;
+ // editor.beginWork();
+ // final IElement title = editor.insertElement(TITLE);
+ // editor.moveTo(title.getStartPosition());
+ // editor.moveTo(title.getEndPosition(), true);
+ // final boolean selectionChangedWhileWorking = hostComponent.selectionChanged;
+ // editor.endWork(true);
+ //
+ // assertFalse(selectionChangedWhileWorking);
+ }
+}
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 c6fe5676..bf305984 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
@@ -1,1140 +1,1141 @@
-/*******************************************************************************
- * Copyright (c) 2012, 2013 Florian Thienel and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Florian Thienel - initial API and implementation
- * Carsten Hiesserich - additional tests (bug 407827, 409032)
- *******************************************************************************/
-package org.eclipse.vex.core.internal.widget;
-
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PARA;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PRE;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.SECTION;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.TITLE;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.assertCanMorphOnlyTo;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.assertXmlEquals;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.createDocumentWithDTD;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.getCurrentXML;
-import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
-import static org.junit.Assert.assertEquals;
-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 java.io.IOException;
-import java.util.List;
-
-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.undo.CannotApplyException;
-import org.eclipse.vex.core.provisional.dom.DocumentValidationException;
-import org.eclipse.vex.core.provisional.dom.IComment;
-import org.eclipse.vex.core.provisional.dom.IDocumentFragment;
-import org.eclipse.vex.core.provisional.dom.IElement;
-import org.eclipse.vex.core.provisional.dom.INode;
-import org.eclipse.vex.core.provisional.dom.IParent;
-import org.eclipse.vex.core.provisional.dom.IText;
-import org.eclipse.vex.core.tests.TestResources;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * @author Florian Thienel
- */
-public class L2SimpleEditingTest {
-
- private IVexWidget widget;
- private IElement rootElement;
-
- @Before
- public void setUp() throws Exception {
- widget = new BaseVexWidget(new MockHostComponent());
- widget.setDocument(createDocumentWithDTD(TEST_DTD, "section"), readTestStyleSheet());
- widget.setWhitespacePolicy(new CssWhitespacePolicy(widget.getStyleSheet()));
- rootElement = widget.getDocument().getRootElement();
- }
-
- @Test
- public void shouldStartInRootElement() throws Exception {
- assertSame(rootElement, widget.getCurrentElement());
- assertEquals(rootElement.getEndPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void shouldMoveCaretIntoInsertedElement() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- assertEquals(titleElement.getEndPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void shouldProvideInsertionElementAsCurrentElement() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.moveBy(-1);
- assertEquals(titleElement.getStartPosition(), widget.getCaretPosition());
- assertSame(rootElement, widget.getCurrentElement());
- }
-
- @Test
- public void givenAnElementWithText_whenAtEndOfTextAndHittingBackspace_shouldDeleteLastCharacter() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello");
- widget.deletePreviousChar();
- assertEquals("Hell", titleElement.getText());
- assertEquals(titleElement.getEndPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void givenAnElementWithText_whenAtBeginningOfTextAndHittingDelete_shouldDeleteFirstCharacter() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello");
- widget.moveBy(-5);
- widget.deleteNextChar();
- assertEquals("ello", titleElement.getText());
- assertEquals(titleElement.getStartPosition().moveBy(1), widget.getCaretPosition());
- }
-
- @Test
- public void givenAnEmptyElement_whenCaretBetweenStartAndEndTagAndHittingBackspace_shouldDeleteEmptyElement() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.deletePreviousChar();
- assertEquals(1, rootElement.children().count());
- assertNull(paraElement.getParent());
- assertFalse(paraElement.isAssociated());
- }
-
- @Test
- public void givenAnEmptyElement_whenCaretBetweenStartAndEndTagAndHittingDelete_shouldDeleteEmptyElement() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.deleteNextChar();
- assertEquals(1, rootElement.children().count());
- assertNull(paraElement.getParent());
- assertFalse(paraElement.isAssociated());
- }
-
- @Test
- public void givenAnEmptyElement_whenCaretAfterEndTagAndHittingDelete_shouldDeleteEmptyElement() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.moveBy(1);
- widget.deletePreviousChar();
- assertEquals(1, rootElement.children().count());
- assertNull(paraElement.getParent());
- assertFalse(paraElement.isAssociated());
- }
-
- @Test
- public void givenAnEmptyElement_whenCaretBeforeStartTagAndHittingDelete_shouldDeleteEmptyElement() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement paraElement = widget.insertElement(PARA);
- widget.moveBy(-1);
- widget.deleteNextChar();
- assertEquals(1, rootElement.children().count());
- assertNull(paraElement.getParent());
- assertFalse(paraElement.isAssociated());
- }
-
- @Test
- public void givenTwoMatchingElements_whenCaretBetweenEndAndStartTagAndHittingBackspace_shouldJoinElements() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement para1 = widget.insertElement(PARA);
- widget.insertText("Hello");
- widget.moveBy(1);
- final IElement para2 = widget.insertElement(PARA);
- widget.insertText("World");
-
- widget.moveTo(para2.getStartPosition());
- widget.deletePreviousChar();
-
- assertEquals(2, rootElement.children().count());
- 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 IElement para1 = widget.insertElement(PARA);
- widget.insertText("Hello");
- widget.moveBy(1);
- final IElement para2 = widget.insertElement(PARA);
- widget.insertText("World");
-
- widget.moveTo(para2.getStartPosition());
- widget.deleteNextChar();
-
- assertEquals(2, rootElement.children().count());
- 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 IElement para1 = widget.insertElement(PARA);
- widget.insertText("Hello");
- widget.moveBy(1);
- final IElement para2 = widget.insertElement(PARA);
- widget.insertText("World");
-
- widget.moveTo(para2.getStartPosition().moveBy(1));
- widget.deletePreviousChar();
-
- assertEquals(2, rootElement.children().count());
- 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 IElement para1 = widget.insertElement(PARA);
- widget.insertText("Hello");
- widget.moveBy(1);
- final IElement para2 = widget.insertElement(PARA);
- widget.insertText("World");
-
- widget.moveTo(para1.getEndPosition());
- widget.deleteNextChar();
-
- assertEquals(2, rootElement.children().count());
- assertSame(rootElement, para1.getParent());
- assertTrue(para1.isAssociated());
- assertEquals("HelloWorld", para1.getText());
- assertNull(para2.getParent());
- assertFalse(para2.isAssociated());
- }
-
- @Test
- public void givenElementWithText_whenAllTextSelectedAndInsertingACharacter_shouldReplaceAllTextWithNewCharacter() throws Exception {
- final IElement titleElement = widget.insertElement(TITLE);
- widget.insertText("Hello World");
-
- widget.selectContentOf(titleElement);
- widget.insertChar('A');
-
- assertEquals("A", titleElement.getText());
- }
-
- @Test(expected = ReadOnlyException.class)
- public void whenReadOnly_shouldNotInsertText() throws Exception {
- widget.insertElement(TITLE); // need an element where text would be valid
- widget.setReadOnly(true);
- assertFalse(widget.canInsertText());
- widget.insertText("Hello World");
- }
-
- @Test(expected = ReadOnlyException.class)
- public void whenReadOnly_shouldNotInsertChar() throws Exception {
- widget.insertElement(TITLE); // need an element where text would be valid
- widget.setReadOnly(true);
- assertFalse(widget.canInsertText());
- widget.insertChar('H');
- }
-
- @Test(expected = ReadOnlyException.class)
- public void whenReadOnly_shouldNotInsertElement() throws Exception {
- widget.setReadOnly(true);
- assertTrue(widget.getValidInsertElements().length == 0);
- widget.insertElement(TITLE);
- }
-
- @Test(expected = ReadOnlyException.class)
- public void whenReadOnly_shouldNotInsertComment() throws Exception {
- widget.setReadOnly(true);
- assertFalse(widget.canInsertComment());
- widget.insertComment();
- }
-
- @Test(expected = ReadOnlyException.class)
- public void whenReadOnly_shouldNotInsertFragment() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement para = widget.insertElement(PARA);
- final IDocumentFragment fragment = widget.getDocument().getFragment(para.getRange());
- widget.moveTo(rootElement.getEndPosition());
-
- widget.setReadOnly(true);
- assertFalse(widget.canInsertFragment(fragment));
- widget.insertFragment(fragment);
- }
-
- @Test
- public void givenNonPreElement_whenInsertingNewline_shouldSplitElement() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement para1 = widget.insertElement(PARA);
- widget.insertText("Hello");
- widget.moveTo(para1.getEndPosition());
- widget.insertText("\n");
- assertEquals("Hello", para1.getText());
- assertEquals(3, rootElement.children().count());
- }
-
- @Test
- public void givenPreElement_whenInsertingNewline_shouldInsertNewline() throws Exception {
- final IElement para = widget.insertElement(PARA);
- final IElement preElement = widget.insertElement(PRE);
- assertEquals(preElement.getEndPosition(), widget.getCaretPosition());
- widget.insertText("line1");
- widget.insertText("\n");
- assertEquals(1, para.children().count());
- assertEquals("line1\n", preElement.getText());
- }
-
- @Test
- public void insertingTextAtInvalidPosition_shouldNotAlterDocument() throws Exception {
- final IElement para1 = widget.insertElement(PARA);
- widget.moveBy(1);
- final IElement para2 = widget.insertElement(PARA);
- widget.moveTo(para1.getEndPosition());
- widget.insertText("Para1");
- widget.moveTo(para2.getEndPosition());
- widget.insertText("Para2");
-
- // Insert position is invalid
- widget.moveTo(para1.getEndPosition().moveBy(1));
- try {
- widget.insertText("Test");
- } catch (final Exception ex) {
- } finally {
- assertEquals("Para1", para1.getText());
- assertEquals("Para2", para2.getText());
- }
- }
-
- @Test
- public void insertingElementAtInvalidPosition_shouldNotAlterDocument() throws Exception {
- final IElement para1 = widget.insertElement(PARA);
- widget.moveBy(1);
- final IElement para2 = widget.insertElement(PARA);
- widget.moveTo(para1.getEndPosition());
- widget.insertText("Para1");
- widget.moveTo(para2.getEndPosition());
- widget.insertText("Para2");
-
- // Insert position is invalid
- widget.moveTo(para1.getEndPosition());
- try {
- widget.insertElement(PARA);
- } catch (final Exception ex) {
- } finally {
- assertEquals("Para1", para1.getText());
- assertEquals("Para2", para2.getText());
- }
- }
-
- @Test
- public void givenPreElement_whenInsertingTextWithNewline_shouldInsertNewline() throws Exception {
- widget.insertElement(PARA);
- final IElement preElement = widget.insertElement(PRE);
- assertEquals(preElement.getEndPosition(), widget.getCaretPosition());
- widget.insertText("line1\nline2");
- assertEquals("line1\nline2", preElement.getText());
- }
-
- @Test
- public void givenPreElement_whenInsertingText_shouldKeepWhitespace() throws Exception {
- widget.insertElement(PARA);
- final IElement preElement = widget.insertElement(PRE);
-
- widget.moveTo(preElement.getEndPosition());
- widget.insertText("line1\nline2 end");
-
- final List<? extends INode> children = preElement.children().asList();
- assertTrue("Expecting IText", children.get(0) instanceof IText);
- assertEquals("line1\nline2 end", children.get(0).getText());
- }
-
- @Test
- public void givenNonPreElement_whenInsertingText_shouldCompressWhitespace() throws Exception {
- final IElement para = widget.insertElement(PARA);
- widget.moveTo(para.getEndPosition());
- widget.insertText("line1\nline2 \t end");
-
- final List<? extends INode> children = rootElement.children().after(para.getStartPosition().getOffset()).asList();
- assertEquals("two para elements", 2, children.size());
- assertTrue("original para element", children.get(0) instanceof IParent);
- assertTrue("splitted para element", children.get(1) instanceof IParent);
- assertEquals("first line", "line1", children.get(0).getText());
- assertEquals("second line with compressed whitespace", "line2 end", children.get(1).getText());
- }
-
- @Test
- public void givenNonPreElement_whenInsertingText_shouldCompressNewlines() throws Exception {
- final IElement para = widget.insertElement(PARA);
- widget.moveTo(para.getEndPosition());
- widget.insertText("line1\n\nline2");
-
- final List<? extends INode> children = rootElement.children().after(para.getStartPosition().getOffset()).asList();
- assertEquals("two para elements", 2, children.size());
- assertTrue("original para element", children.get(0) instanceof IParent);
- assertTrue("splitted para element", children.get(1) instanceof IParent);
- assertEquals("first line", "line1", children.get(0).getText());
- assertEquals("second line", "line2", children.get(1).getText());
- }
-
- @Test
- public void givenNonPreElement_whenSplitting_shouldSplitIntoTwoElements() throws Exception {
- final IElement para = widget.insertElement(PARA);
- widget.moveTo(para.getEndPosition());
- widget.insertText("line1line2");
- widget.moveBy(-5);
-
- widget.split();
-
- final List<? extends INode> children = rootElement.children().after(para.getStartPosition().getOffset()).asList();
- assertEquals("two para elements", 2, children.size());
- assertTrue("original para element", children.get(0) instanceof IParent);
- assertTrue("splitted para element", children.get(1) instanceof IParent);
- assertEquals("first line element", PARA, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("second line element", PARA, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("first line", "line1", children.get(0).getText());
- assertEquals("second line", "line2", children.get(1).getText());
- }
-
- @Test
- public void givenPreElement_whenSplitting_shouldSplitIntoTwoElements() throws Exception {
- final IElement para = widget.insertElement(PARA);
- final IElement preElement = widget.insertElement(PRE);
- widget.moveTo(preElement.getEndPosition());
- widget.insertText("line1line2");
- widget.moveBy(-5);
-
- widget.split();
-
- final List<? extends INode> children = para.children().after(preElement.getStartPosition().getOffset()).asList();
- assertEquals("two para elements", 2, children.size());
- assertTrue("original pre element", children.get(0) instanceof IParent);
- assertTrue("splitted pre element", children.get(1) instanceof IParent);
- assertEquals("first line element", PRE, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("second line element", PRE, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("first line", "line1", children.get(0).getText());
- assertEquals("second line", "line2", children.get(1).getText());
- }
-
- @Test
- public void givenElementWithMultipleOccurrence_canSplitElement() throws Exception {
- widget.insertElement(PARA);
- assertTrue(widget.canSplit());
- }
-
- @Test
- public void givenElementWithMultipleOccurrence_whenAnythingIsSelected_canSplitElement() throws Exception {
- widget.insertElement(PARA);
- widget.insertText("12345");
- widget.moveBy(-3, true);
- assertTrue(widget.canSplit());
- }
-
- @Test
- public void givenElementWithMultipleOccurrence_whenSplittingWithAnythingSelected_shouldDeleteSelectionAndSplit() throws Exception {
- widget.insertElement(PARA);
- widget.insertText("12345");
- widget.moveBy(-3, true);
- widget.split();
-
- final List<? extends INode> children = rootElement.children().asList();
- assertEquals("two para elements", 2, children.size());
- assertTrue("original para element", children.get(0) instanceof IParent);
- assertTrue("splitted para element", children.get(1) instanceof IParent);
- assertEquals("first line element", PARA, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("second line element", PARA, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("first line", "12", children.get(0).getText());
- assertEquals("second line", "", children.get(1).getText());
- }
-
- @Test
- public void givenElementWithMultipleOccurrence_whenCaretRightAfterStartIndex_shouldSplit() throws Exception {
- final IElement para = widget.insertElement(PARA);
- widget.insertText("12345");
- widget.moveTo(para.getStartPosition().moveBy(1));
- widget.split();
-
- final List<? extends INode> children = rootElement.children().asList();
- assertEquals("two para elements", 2, children.size());
- assertTrue("original para element", children.get(0) instanceof IParent);
- assertTrue("splitted para element", children.get(1) instanceof IParent);
- assertEquals("first line element", PARA, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("second line element", PARA, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("first line", "", children.get(0).getText());
- assertEquals("second line", "12345", children.get(1).getText());
- }
-
- @Test
- public void givenElementWithMultipleOccurrenceAndInlineElement_whenCaretAtInlineStartOffset_shouldSplit() throws Exception {
- widget.insertElement(PARA);
- widget.insertText("12");
- widget.insertElement(PRE);
- widget.insertText("34");
- widget.moveBy(1);
- widget.insertText("56");
- widget.moveBy(-6);
- widget.split();
-
- final List<? extends INode> children = rootElement.children().asList();
- assertEquals("two para elements", 2, children.size());
- assertTrue("original para element", children.get(0) instanceof IParent);
- assertTrue("splitted para element", children.get(1) instanceof IParent);
- assertEquals("first line element", PARA, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("second line element", PARA, ((IElement) children.get(0)).getQualifiedName());
- assertEquals("first line", "12", children.get(0).getText());
- assertEquals("second line", "3456", children.get(1).getText());
- assertEquals("pre in second line", PRE, ((IElement) ((IElement) children.get(1)).children().get(0)).getQualifiedName());
- }
-
- @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);
-
- widget.moveBy(-4);
- widget.split();
-
- widget.moveBy(-1);
- widget.split();
-
- widget.undo();
- widget.undo();
-
- assertXmlEquals(expectedXml, widget);
- }
-
- @Test
- public void givenElementWithSingleOccurrence_cannotSplitElement() throws Exception {
- widget.insertElement(TITLE);
- assertFalse(widget.canSplit());
- }
-
- @Test(expected = CannotApplyException.class)
- public void givenElementWithSingleOccurrence_whenSplitting_shouldThrowCannotRedoException() throws Exception {
- widget.insertElement(TITLE);
- widget.split();
- }
-
- @Test
- public void givenComment_cannotSplit() throws Exception {
- widget.insertComment();
- assertFalse(widget.canSplit());
- }
-
- @Test(expected = DocumentValidationException.class)
- public void givenComment_whenSplitting_shouldThrowDocumentValidationException() throws Exception {
- widget.insertComment();
- widget.split();
- }
-
- @Test
- public void givenBeforeRootElement_cannotSplitElement() throws Exception {
- widget.moveTo(rootElement.getStartPosition());
- assertFalse(widget.canSplit());
- }
-
- @Test(expected = DocumentValidationException.class)
- public void givenBeforeRootElement_whenSplitting_shouldThrowDocumentValidationException() throws Exception {
- widget.moveTo(rootElement.getStartPosition());
- widget.split();
- }
-
- @Test
- public void undoRedoChangeNamespaceWithSubsequentDelete() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement para = widget.insertElement(PARA);
- final String expectedXml = getCurrentXML(widget);
-
- widget.declareNamespace("ns1", "nsuri1");
- widget.select(para);
- widget.deleteSelection();
-
- widget.undo(); // delete
- widget.undo(); // declare namespace
-
- assertXmlEquals(expectedXml, widget);
- }
-
- @Test
- public void undoRedoChangeAttributeWithSubsequentDelete() throws Exception {
- widget.insertElement(TITLE);
- widget.moveBy(1);
- final IElement para = widget.insertElement(PARA);
- final String expectedXml = getCurrentXML(widget);
-
- widget.setAttribute("id", "newParaElement");
- widget.select(para);
- widget.deleteSelection();
-
- widget.undo(); // delete
- widget.undo(); // set attribute
-
- assertXmlEquals(expectedXml, widget);
- }
-
- @Test
- public void whenReadOnly_cannotMorph() throws Exception {
- widget.insertElement(TITLE);
- widget.setReadOnly(true);
- assertFalse(widget.canMorph(PARA));
- }
-
- @Test(expected = ReadOnlyException.class)
- public void whenReadOnly_shouldNotMorph() throws Exception {
- widget.insertElement(TITLE);
- widget.setReadOnly(true);
- widget.morph(PARA);
- }
-
- @Test
- public void cannotMorphRootElement() throws Exception {
- assertFalse(widget.canMorph(TITLE));
- }
-
- @Test
- public void morphEmptyElement() throws Exception {
- widget.insertElement(TITLE);
-
- assertTrue(widget.canMorph(PARA));
- assertCanMorphOnlyTo(widget, PARA);
- widget.morph(PARA);
- }
-
- @Test
- public void givenElementWithText_whenMorphing_shouldPreserveText() throws Exception {
- widget.insertElement(TITLE);
- widget.insertText("text");
-
- assertTrue(widget.canMorph(PARA));
- widget.morph(PARA);
-
- widget.selectAll();
- assertXmlEquals("<section><para>text</para></section>", widget);
- }
-
- @Test
- public void givenElementWithChildren_whenStructureIsInvalidAfterMorphing_cannotMorph() throws Exception {
- widget.insertElement(PARA);
- widget.insertText("before");
- widget.insertElement(PRE);
- widget.insertText("within");
- widget.moveBy(1);
- widget.insertText("after");
-
- assertFalse(widget.canMorph(TITLE));
- }
-
- @Test
- public void givenElementWithChildren_whenStructureIsInvalidAfterMorphing_shouldNotProvideElementToMorph() throws Exception {
- widget.insertElement(PARA);
- widget.insertText("before");
- widget.insertElement(PRE);
- widget.insertText("within");
- widget.moveBy(1);
- widget.insertText("after");
-
- assertCanMorphOnlyTo(widget /* nothing */);
- }
-
- @Test(expected = CannotApplyException.class)
- public void givenElementWithChildren_whenStructureIsInvalidAfterMorphing_shouldNotMorph() throws Exception {
- widget.insertElement(PARA);
- widget.insertText("before");
- widget.insertElement(PRE);
- widget.insertText("within");
- widget.moveBy(1);
- widget.insertText("after");
-
- widget.morph(TITLE);
- }
-
- @Test
- public void givenAlternativeElement_whenElementIsNotAllowedAtCurrentInsertionPosition_cannotMorph() throws Exception {
- widget.insertElement(PARA);
- widget.moveBy(1);
- widget.insertElement(PARA);
-
- assertFalse(widget.canMorph(TITLE));
- }
-
- @Test
- public void givenAlternativeElement_whenElementIsNotAllowedAtCurrentInsertionPosition_shouldNotProvideElementToMorph() throws Exception {
- widget.insertElement(PARA);
- widget.moveBy(1);
- widget.insertElement(PARA);
-
- assertCanMorphOnlyTo(widget /* nothing */);
- }
-
- public void givenElementWithAttributes_whenUndoMorph_shouldPreserveAttributes() throws Exception {
- widget.insertElement(PARA);
- widget.setAttribute("id", "idValue");
- widget.morph(TITLE);
- widget.undo();
-
- assertEquals("idValue", widget.getCurrentElement().getAttribute("id").getValue());
- }
-
- public void whenReadOnly_cannotUnwrap() throws Exception {
- widget.insertElement(PARA);
- widget.insertElement(PRE);
- widget.insertText("text");
- widget.setReadOnly(true);
- assertFalse(widget.canUnwrap());
- }
-
- @Test(expected = ReadOnlyException.class)
- public void whenReadOnly_shouldNotUnwrap() throws Exception {
- widget.insertElement(PARA);
- widget.insertElement(PRE);
- widget.insertText("text");
- widget.setReadOnly(true);
- widget.unwrap();
- }
-
- @Test
- public void cannotUnwrapRootElement() throws Exception {
- assertFalse(widget.canUnwrap());
- }
-
- @Test
- public void unwrapEmptyElement() throws Exception {
- widget.insertElement(PARA);
- widget.unwrap();
-
- widget.selectAll();
- assertXmlEquals("<section></section>", widget);
- }
-
- @Test
- public void givenInlineElementWithText_shouldUnwrapInlineElement() throws Exception {
- final IElement para = widget.insertElement(PARA);
- widget.insertElement(PRE);
- widget.insertText("text");
- widget.unwrap();
-
- assertSame(para, widget.getCurrentElement());
- widget.selectAll();
- assertXmlEquals("<section><para>text</para></section>", widget);
- }
-
- @Test
- public void givenElementWithText_whenParentDoesNotAllowText_cannotUnwrap() throws Exception {
- widget.insertElement(PARA);
- widget.insertText("text");
-
- assertFalse(widget.canUnwrap());
- }
-
- @Test(expected = CannotApplyException.class)
- public void givenElementWithText_whenParentDoesNotAllowText_shouldNotUnwrap() throws Exception {
- widget.insertElement(PARA);
- widget.insertText("text");
- widget.unwrap();
- }
-
- @Test
- public void givenElementWithChildren_whenParentDoesNotAllowChildren_cannotUnwrap() throws Exception {
- widget.insertElement(PARA);
- widget.insertElement(PRE);
- widget.moveBy(1);
-
- assertFalse(widget.canUnwrap());
- }
-
- @Test(expected = CannotApplyException.class)
- public void givenElementWithChildren_whenParentDoesNotAllowChildren_shouldNotUnwrap() throws Exception {
- widget.insertElement(PARA);
- widget.insertElement(PRE);
- widget.moveBy(1);
- widget.unwrap();
- }
-
- @Test
- public void givenElementWithAttributes_whenUndoUnwrap_shouldPreserveAttributes() throws Exception {
- widget.insertElement(PARA);
- widget.insertElement(PRE);
- widget.setAttribute("id", "idValue");
-
- widget.unwrap();
- widget.undo();
-
- assertEquals(PRE, widget.getCurrentElement().getQualifiedName());
- assertEquals("idValue", widget.getCurrentElement().getAttributeValue("id"));
- }
-
- @Test
- public void givenMultipleElementsOfSameTypeSelected_canJoin() throws Exception {
- final IElement firstPara = widget.insertElement(PARA);
- widget.insertText("1");
- widget.moveBy(1);
- widget.insertElement(PARA);
- widget.insertText("2");
- widget.moveBy(1);
- final IElement lastPara = widget.insertElement(PARA);
- widget.insertText("3");
- widget.moveBy(1);
-
- widget.moveTo(firstPara.getStartPosition());
- widget.moveTo(lastPara.getEndPosition(), true);
-
- assertTrue(widget.canJoin());
- }
-
- @Test
- public void givenMultipleElementsOfSameTypeSelected_shouldJoin() throws Exception {
- final IElement firstPara = widget.insertElement(PARA);
- widget.insertText("1");
- widget.moveBy(1);
- widget.insertElement(PARA);
- widget.insertText("2");
- widget.moveBy(1);
- final IElement lastPara = widget.insertElement(PARA);
- widget.insertText("3");
- widget.moveBy(1);
-
- widget.moveTo(firstPara.getStartPosition());
- widget.moveTo(lastPara.getEndPosition(), true);
-
- widget.join();
-
- assertXmlEquals("<section><para>123</para></section>", widget);
- }
-
- @Test
- public void givenMultipleElementsOfSameKindSelected_whenJoining_shouldPreserveAttributesOfFirstElement() throws Exception {
- final IElement firstPara = widget.insertElement(PARA);
- widget.insertText("1");
- widget.moveBy(1);
- widget.insertElement(PARA);
- widget.insertText("2");
- widget.moveBy(1);
- final IElement lastPara = widget.insertElement(PARA);
- widget.insertText("3");
- firstPara.setAttribute("id", "para1");
- lastPara.setAttribute("id", "para3");
-
- widget.moveTo(firstPara.getStartPosition());
- widget.moveTo(lastPara.getEndPosition(), true);
-
- widget.join();
-
- assertXmlEquals("<section><para id=\"para1\">123</para></section>", widget);
- }
-
- @Test
- public void givenMultipleElementsOfSameKindSelected_whenJoinUndone_shouldRestoreAttributesOfAllElements() throws Exception {
- final IElement firstPara = widget.insertElement(PARA);
- widget.insertText("1");
- widget.moveBy(1);
- widget.insertElement(PARA);
- widget.insertText("2");
- widget.moveBy(1);
- final IElement lastPara = widget.insertElement(PARA);
- widget.insertText("3");
- firstPara.setAttribute("id", "para1");
- lastPara.setAttribute("id", "para3");
-
- widget.moveTo(firstPara.getStartPosition());
- widget.moveTo(lastPara.getEndPosition(), true);
-
- widget.join();
- widget.undo();
-
- assertXmlEquals("<section><para id=\"para1\">1</para><para>2</para><para id=\"para3\">3</para></section>", widget);
- }
-
- @Test
- public void givenMultipleElementsOfSameKindSelected_whenStructureAfterJoinWouldBeInvalid_cannotJoin() throws Exception {
- widget.setDocument(createDocumentWithDTD(TEST_DTD, "one-kind-of-child"), readTestStyleSheet());
- rootElement = widget.getDocument().getRootElement();
-
- final IElement firstSection = widget.insertElement(SECTION);
- widget.insertElement(TITLE);
- widget.moveBy(2);
- widget.insertElement(SECTION);
- widget.insertElement(TITLE);
- widget.moveBy(2);
- final IElement lastSection = widget.insertElement(SECTION);
- widget.insertElement(TITLE);
-
- widget.moveTo(firstSection.getStartPosition());
- widget.moveTo(lastSection.getEndPosition(), true);
-
- assertFalse(widget.canJoin());
- }
-
- @Test(expected = CannotApplyException.class)
- public void givenMultipleElementsOfSameKindSelected_whenStructureAfterJoinWouldBeInvalid_shouldJoin() throws Exception {
- widget.setDocument(createDocumentWithDTD(TEST_DTD, "one-kind-of-child"), readTestStyleSheet());
- rootElement = widget.getDocument().getRootElement();
-
- final IElement firstSection = widget.insertElement(SECTION);
- widget.insertElement(TITLE);
- widget.moveBy(2);
- widget.insertElement(SECTION);
- widget.insertElement(TITLE);
- widget.moveBy(2);
- final IElement lastSection = widget.insertElement(SECTION);
- widget.insertElement(TITLE);
-
- widget.moveTo(firstSection.getStartPosition());
- widget.moveTo(lastSection.getEndPosition(), true);
-
- widget.join();
- }
-
- @Test
- public void givenMultipleElementsOfDifferentTypeSelected_cannotJoin() throws Exception {
- final IElement title = widget.insertElement(TITLE);
- widget.insertText("1");
- widget.moveBy(1);
- widget.insertElement(PARA);
- widget.insertText("2");
- widget.moveBy(1);
- final IElement lastPara = widget.insertElement(PARA);
- widget.insertText("3");
- widget.moveBy(1);
-
- widget.moveTo(title.getStartPosition());
- widget.moveTo(lastPara.getEndPosition(), true);
-
- assertFalse(widget.canJoin());
- }
-
- @Test(expected = DocumentValidationException.class)
- public void givenMultipleElementsOfDifferentTypeSelected_shouldNotJoin() throws Exception {
- final IElement title = widget.insertElement(TITLE);
- widget.insertText("1");
- widget.moveBy(1);
- widget.insertElement(PARA);
- widget.insertText("2");
- widget.moveBy(1);
- final IElement lastPara = widget.insertElement(PARA);
- widget.insertText("3");
- widget.moveBy(1);
-
- widget.moveTo(title.getStartPosition());
- widget.moveTo(lastPara.getEndPosition(), true);
-
- widget.join();
- }
-
- @Test
- public void givenSelectionIsEmpty_cannotJoin() throws Exception {
- assertFalse(widget.canJoin());
- }
-
- @Test
- public void givenSelectionIsEmpty_whenRequestedToJoin_shouldIgnoreGracefully() throws Exception {
- final String expectedXml = getCurrentXML(widget);
-
- widget.join();
-
- assertXmlEquals(expectedXml, widget);
- }
-
- @Test
- public void givenOnlyTextSelected_cannotJoin() throws Exception {
- final IElement title = widget.insertElement(TITLE);
- widget.insertText("title text");
- widget.moveTo(title.getStartPosition().moveBy(1), true);
-
- assertFalse(widget.canJoin());
- }
-
- @Test
- public void givenOnlyTextSelected_whenRequestedToJoin_shouldIgnoreGracefully() throws Exception {
- final IElement title = widget.insertElement(TITLE);
- widget.insertText("title text");
- widget.selectContentOf(title);
- final String expectedXml = getCurrentXML(widget);
-
- widget.join();
-
- assertXmlEquals(expectedXml, widget);
- }
-
- @Test
- public void givenOnlySingleElementSelected_cannotJoin() throws Exception {
- final IElement title = widget.insertElement(TITLE);
- widget.moveTo(title.getStartPosition(), true);
-
- assertFalse(widget.canJoin());
- }
-
- @Test
- public void givenOnlySingleElementSelected_whenRequestedToJoin_shouldIgnoreGracefully() throws Exception {
- final IElement title = widget.insertElement(TITLE);
- widget.moveTo(title.getStartPosition(), true);
- final String expectedXml = getCurrentXML(widget);
-
- widget.join();
-
- assertXmlEquals(expectedXml, widget);
- }
-
- @Test
- public void givenMultipleCommentsSelected_canJoin() throws Exception {
- final IComment firstComment = widget.insertComment();
- widget.insertText("comment1");
- widget.moveBy(1);
- widget.insertComment();
- widget.insertText("comment2");
- widget.moveBy(1);
- final IComment lastComment = widget.insertComment();
- widget.insertText("comment3");
-
- widget.moveTo(firstComment.getStartPosition());
- widget.moveTo(lastComment.getEndPosition(), true);
-
- assertTrue(widget.canJoin());
- }
-
- @Test
- public void givenMultipleCommentsSelected_shouldJoin() throws Exception {
- final IComment firstComment = widget.insertComment();
- widget.insertText("comment1");
- widget.moveBy(1);
- widget.insertComment();
- widget.insertText("comment2");
- widget.moveBy(1);
- final IComment lastComment = widget.insertComment();
- widget.insertText("comment3");
-
- widget.moveTo(firstComment.getStartPosition());
- widget.moveTo(lastComment.getEndPosition(), true);
-
- widget.join();
-
- assertXmlEquals("<section><!--comment1comment2comment3--></section>", widget);
- }
-
- @Test
- public void givenMultipleInlineElementsOfSameKindSelected_whenTextEndsWithSpace_shouldJoin() throws Exception {
- widget.insertElement(PARA);
- final IElement firstElement = widget.insertElement(PRE);
- widget.insertText("1");
- widget.moveBy(1);
- final IElement lastElement = widget.insertElement(PRE);
- widget.insertText("2 ");
-
- widget.moveTo(firstElement.getStartPosition());
- widget.moveTo(lastElement.getEndPosition(), true);
-
- widget.join();
-
- assertXmlEquals("<section><para><pre>12 </pre></para></section>", widget);
- }
-
- @Test
- public void givenMultipleInlineElementsOfSameKindSelected_whenTextBetweenElements_cannotJoin() throws Exception {
- widget.insertElement(PARA);
- final IElement firstElement = widget.insertElement(PRE);
- widget.insertText("1");
- widget.moveBy(1);
- widget.insertText("text between elements");
- final IElement lastElement = widget.insertElement(PRE);
- widget.insertText("2 ");
-
- widget.moveTo(firstElement.getStartPosition());
- widget.moveTo(lastElement.getEndPosition(), true);
-
- assertFalse(widget.canJoin());
- }
-
- @Test(expected = DocumentValidationException.class)
- public void givenMultipleInlineElementsOfSameKindSelected_whenTextBetweenElements_shouldNotJoin() throws Exception {
- widget.insertElement(PARA);
- final IElement firstElement = widget.insertElement(PRE);
- widget.insertText("1");
- widget.moveBy(1);
- widget.insertText("text between elements");
- final IElement lastElement = widget.insertElement(PRE);
- widget.insertText("2 ");
-
- widget.moveTo(firstElement.getStartPosition());
- widget.moveTo(lastElement.getEndPosition(), true);
-
- widget.join();
- }
-
- @Test
- public void givenDeletedText_whenDeleteUndone_shouldSetCaretToEndOfRecoveredText() throws Exception {
- final IElement title = widget.insertElement(TITLE);
- widget.insertText("Hello World");
- widget.moveTo(title.getStartPosition().moveBy(1));
- widget.moveBy(5, true);
- final int expectedCaretPosition = widget.getSelectedRange().getEndOffset() + 1;
-
- widget.deleteSelection();
- widget.undo();
-
- assertEquals(expectedCaretPosition, widget.getCaretPosition().getOffset());
- }
-
- @Test
- public void afterDeletingSelection_CaretPositionShouldBeValid() throws Exception {
- final IElement para = widget.insertElement(PARA);
- widget.moveTo(para.getEndPosition());
- final IElement pre = widget.insertElement(PRE);
- widget.insertText("Hello World");
- widget.moveTo(pre.getStartPosition());
- widget.moveTo(pre.getEndPosition().moveBy(-1), true);
-
- widget.deleteSelection();
- assertEquals(para.getEndPosition(), widget.getCaretPosition());
- }
-
- @Test
- public void undoAndRedoDelete() throws Exception {
- final IElement para = widget.insertElement(PARA);
- widget.moveTo(para.getEndPosition());
- final IElement pre = widget.insertElement(PRE);
- widget.insertText("Hello World");
- final String beforeDeleteXml = getCurrentXML(widget);
-
- widget.moveTo(pre.getStartPosition());
- widget.moveTo(pre.getEndPosition().moveBy(-1), true);
- widget.deleteSelection();
-
- final String beforeUndoXml = getCurrentXML(widget);
- widget.undo();
- assertXmlEquals(beforeDeleteXml, widget);
-
- widget.redo();
- assertXmlEquals(beforeUndoXml, widget);
- }
-
- private static StyleSheet readTestStyleSheet() throws IOException {
- return new StyleSheetReader().read(TestResources.get("test.css"));
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Florian Thienel - initial API and implementation
+ * Carsten Hiesserich - additional tests (bug 407827, 409032)
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.widget;
+
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PARA;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.PRE;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.SECTION;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.TITLE;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.assertCanMorphOnlyTo;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.assertXmlEquals;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.createDocumentWithDTD;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.getCurrentXML;
+import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
+import static org.junit.Assert.assertEquals;
+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 java.io.IOException;
+import java.util.List;
+
+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.undo.CannotApplyException;
+import org.eclipse.vex.core.provisional.dom.DocumentValidationException;
+import org.eclipse.vex.core.provisional.dom.IComment;
+import org.eclipse.vex.core.provisional.dom.IDocumentFragment;
+import org.eclipse.vex.core.provisional.dom.IElement;
+import org.eclipse.vex.core.provisional.dom.INode;
+import org.eclipse.vex.core.provisional.dom.IParent;
+import org.eclipse.vex.core.provisional.dom.IText;
+import org.eclipse.vex.core.tests.TestResources;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Florian Thienel
+ */
+public class L2SimpleEditingTest {
+
+ private IDocumentEditor editor;
+ private IElement rootElement;
+
+ @Before
+ public void setUp() throws Exception {
+ editor = new BaseVexWidget(new MockHostComponent());
+ editor.setDocument(createDocumentWithDTD(TEST_DTD, "section"));
+ // TODO move dependency to whitespace policy into a BaseVexWidget specific set-up method
+ ((BaseVexWidget) editor).setWhitespacePolicy(new CssWhitespacePolicy(readTestStyleSheet()));
+ rootElement = editor.getDocument().getRootElement();
+ }
+
+ @Test
+ public void shouldStartInRootElement() throws Exception {
+ assertSame(rootElement, editor.getCurrentElement());
+ assertEquals(rootElement.getEndPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void shouldMoveCaretIntoInsertedElement() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ assertEquals(titleElement.getEndPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void shouldProvideInsertionElementAsCurrentElement() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.moveBy(-1);
+ assertEquals(titleElement.getStartPosition(), editor.getCaretPosition());
+ assertSame(rootElement, editor.getCurrentElement());
+ }
+
+ @Test
+ public void givenAnElementWithText_whenAtEndOfTextAndHittingBackspace_shouldDeleteLastCharacter() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello");
+ editor.deletePreviousChar();
+ assertEquals("Hell", titleElement.getText());
+ assertEquals(titleElement.getEndPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenAnElementWithText_whenAtBeginningOfTextAndHittingDelete_shouldDeleteFirstCharacter() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello");
+ editor.moveBy(-5);
+ editor.deleteNextChar();
+ assertEquals("ello", titleElement.getText());
+ assertEquals(titleElement.getStartPosition().moveBy(1), editor.getCaretPosition());
+ }
+
+ @Test
+ public void givenAnEmptyElement_whenCaretBetweenStartAndEndTagAndHittingBackspace_shouldDeleteEmptyElement() throws Exception {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.deletePreviousChar();
+ assertEquals(1, rootElement.children().count());
+ assertNull(paraElement.getParent());
+ assertFalse(paraElement.isAssociated());
+ }
+
+ @Test
+ public void givenAnEmptyElement_whenCaretBetweenStartAndEndTagAndHittingDelete_shouldDeleteEmptyElement() throws Exception {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.deleteNextChar();
+ assertEquals(1, rootElement.children().count());
+ assertNull(paraElement.getParent());
+ assertFalse(paraElement.isAssociated());
+ }
+
+ @Test
+ public void givenAnEmptyElement_whenCaretAfterEndTagAndHittingDelete_shouldDeleteEmptyElement() throws Exception {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.moveBy(1);
+ editor.deletePreviousChar();
+ assertEquals(1, rootElement.children().count());
+ assertNull(paraElement.getParent());
+ assertFalse(paraElement.isAssociated());
+ }
+
+ @Test
+ public void givenAnEmptyElement_whenCaretBeforeStartTagAndHittingDelete_shouldDeleteEmptyElement() throws Exception {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement paraElement = editor.insertElement(PARA);
+ editor.moveBy(-1);
+ editor.deleteNextChar();
+ assertEquals(1, rootElement.children().count());
+ assertNull(paraElement.getParent());
+ assertFalse(paraElement.isAssociated());
+ }
+
+ @Test
+ public void givenTwoMatchingElements_whenCaretBetweenEndAndStartTagAndHittingBackspace_shouldJoinElements() throws Exception {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement para1 = editor.insertElement(PARA);
+ editor.insertText("Hello");
+ editor.moveBy(1);
+ final IElement para2 = editor.insertElement(PARA);
+ editor.insertText("World");
+
+ editor.moveTo(para2.getStartPosition());
+ editor.deletePreviousChar();
+
+ assertEquals(2, rootElement.children().count());
+ 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 {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement para1 = editor.insertElement(PARA);
+ editor.insertText("Hello");
+ editor.moveBy(1);
+ final IElement para2 = editor.insertElement(PARA);
+ editor.insertText("World");
+
+ editor.moveTo(para2.getStartPosition());
+ editor.deleteNextChar();
+
+ assertEquals(2, rootElement.children().count());
+ 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 {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement para1 = editor.insertElement(PARA);
+ editor.insertText("Hello");
+ editor.moveBy(1);
+ final IElement para2 = editor.insertElement(PARA);
+ editor.insertText("World");
+
+ editor.moveTo(para2.getStartPosition().moveBy(1));
+ editor.deletePreviousChar();
+
+ assertEquals(2, rootElement.children().count());
+ 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 {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement para1 = editor.insertElement(PARA);
+ editor.insertText("Hello");
+ editor.moveBy(1);
+ final IElement para2 = editor.insertElement(PARA);
+ editor.insertText("World");
+
+ editor.moveTo(para1.getEndPosition());
+ editor.deleteNextChar();
+
+ assertEquals(2, rootElement.children().count());
+ assertSame(rootElement, para1.getParent());
+ assertTrue(para1.isAssociated());
+ assertEquals("HelloWorld", para1.getText());
+ assertNull(para2.getParent());
+ assertFalse(para2.isAssociated());
+ }
+
+ @Test
+ public void givenElementWithText_whenAllTextSelectedAndInsertingACharacter_shouldReplaceAllTextWithNewCharacter() throws Exception {
+ final IElement titleElement = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+
+ editor.selectContentOf(titleElement);
+ editor.insertChar('A');
+
+ assertEquals("A", titleElement.getText());
+ }
+
+ @Test(expected = ReadOnlyException.class)
+ public void whenReadOnly_shouldNotInsertText() throws Exception {
+ editor.insertElement(TITLE); // need an element where text would be valid
+ editor.setReadOnly(true);
+ assertFalse(editor.canInsertText());
+ editor.insertText("Hello World");
+ }
+
+ @Test(expected = ReadOnlyException.class)
+ public void whenReadOnly_shouldNotInsertChar() throws Exception {
+ editor.insertElement(TITLE); // need an element where text would be valid
+ editor.setReadOnly(true);
+ assertFalse(editor.canInsertText());
+ editor.insertChar('H');
+ }
+
+ @Test(expected = ReadOnlyException.class)
+ public void whenReadOnly_shouldNotInsertElement() throws Exception {
+ editor.setReadOnly(true);
+ assertTrue(editor.getValidInsertElements().length == 0);
+ editor.insertElement(TITLE);
+ }
+
+ @Test(expected = ReadOnlyException.class)
+ public void whenReadOnly_shouldNotInsertComment() throws Exception {
+ editor.setReadOnly(true);
+ assertFalse(editor.canInsertComment());
+ editor.insertComment();
+ }
+
+ @Test(expected = ReadOnlyException.class)
+ public void whenReadOnly_shouldNotInsertFragment() throws Exception {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement para = editor.insertElement(PARA);
+ final IDocumentFragment fragment = editor.getDocument().getFragment(para.getRange());
+ editor.moveTo(rootElement.getEndPosition());
+
+ editor.setReadOnly(true);
+ assertFalse(editor.canInsertFragment(fragment));
+ editor.insertFragment(fragment);
+ }
+
+ @Test
+ public void givenNonPreElement_whenInsertingNewline_shouldSplitElement() throws Exception {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement para1 = editor.insertElement(PARA);
+ editor.insertText("Hello");
+ editor.moveTo(para1.getEndPosition());
+ editor.insertText("\n");
+ assertEquals("Hello", para1.getText());
+ assertEquals(3, rootElement.children().count());
+ }
+
+ @Test
+ public void givenPreElement_whenInsertingNewline_shouldInsertNewline() throws Exception {
+ final IElement para = editor.insertElement(PARA);
+ final IElement preElement = editor.insertElement(PRE);
+ assertEquals(preElement.getEndPosition(), editor.getCaretPosition());
+ editor.insertText("line1");
+ editor.insertText("\n");
+ assertEquals(1, para.children().count());
+ assertEquals("line1\n", preElement.getText());
+ }
+
+ @Test
+ public void insertingTextAtInvalidPosition_shouldNotAlterDocument() throws Exception {
+ final IElement para1 = editor.insertElement(PARA);
+ editor.moveBy(1);
+ final IElement para2 = editor.insertElement(PARA);
+ editor.moveTo(para1.getEndPosition());
+ editor.insertText("Para1");
+ editor.moveTo(para2.getEndPosition());
+ editor.insertText("Para2");
+
+ // Insert position is invalid
+ editor.moveTo(para1.getEndPosition().moveBy(1));
+ try {
+ editor.insertText("Test");
+ } catch (final Exception ex) {
+ } finally {
+ assertEquals("Para1", para1.getText());
+ assertEquals("Para2", para2.getText());
+ }
+ }
+
+ @Test
+ public void insertingElementAtInvalidPosition_shouldNotAlterDocument() throws Exception {
+ final IElement para1 = editor.insertElement(PARA);
+ editor.moveBy(1);
+ final IElement para2 = editor.insertElement(PARA);
+ editor.moveTo(para1.getEndPosition());
+ editor.insertText("Para1");
+ editor.moveTo(para2.getEndPosition());
+ editor.insertText("Para2");
+
+ // Insert position is invalid
+ editor.moveTo(para1.getEndPosition());
+ try {
+ editor.insertElement(PARA);
+ } catch (final Exception ex) {
+ } finally {
+ assertEquals("Para1", para1.getText());
+ assertEquals("Para2", para2.getText());
+ }
+ }
+
+ @Test
+ public void givenPreElement_whenInsertingTextWithNewline_shouldInsertNewline() throws Exception {
+ editor.insertElement(PARA);
+ final IElement preElement = editor.insertElement(PRE);
+ assertEquals(preElement.getEndPosition(), editor.getCaretPosition());
+ editor.insertText("line1\nline2");
+ assertEquals("line1\nline2", preElement.getText());
+ }
+
+ @Test
+ public void givenPreElement_whenInsertingText_shouldKeepWhitespace() throws Exception {
+ editor.insertElement(PARA);
+ final IElement preElement = editor.insertElement(PRE);
+
+ editor.moveTo(preElement.getEndPosition());
+ editor.insertText("line1\nline2 end");
+
+ final List<? extends INode> children = preElement.children().asList();
+ assertTrue("Expecting IText", children.get(0) instanceof IText);
+ assertEquals("line1\nline2 end", children.get(0).getText());
+ }
+
+ @Test
+ public void givenNonPreElement_whenInsertingText_shouldCompressWhitespace() throws Exception {
+ final IElement para = editor.insertElement(PARA);
+ editor.moveTo(para.getEndPosition());
+ editor.insertText("line1\nline2 \t end");
+
+ final List<? extends INode> children = rootElement.children().after(para.getStartPosition().getOffset()).asList();
+ assertEquals("two para elements", 2, children.size());
+ assertTrue("original para element", children.get(0) instanceof IParent);
+ assertTrue("splitted para element", children.get(1) instanceof IParent);
+ assertEquals("first line", "line1", children.get(0).getText());
+ assertEquals("second line with compressed whitespace", "line2 end", children.get(1).getText());
+ }
+
+ @Test
+ public void givenNonPreElement_whenInsertingText_shouldCompressNewlines() throws Exception {
+ final IElement para = editor.insertElement(PARA);
+ editor.moveTo(para.getEndPosition());
+ editor.insertText("line1\n\nline2");
+
+ final List<? extends INode> children = rootElement.children().after(para.getStartPosition().getOffset()).asList();
+ assertEquals("two para elements", 2, children.size());
+ assertTrue("original para element", children.get(0) instanceof IParent);
+ assertTrue("splitted para element", children.get(1) instanceof IParent);
+ assertEquals("first line", "line1", children.get(0).getText());
+ assertEquals("second line", "line2", children.get(1).getText());
+ }
+
+ @Test
+ public void givenNonPreElement_whenSplitting_shouldSplitIntoTwoElements() throws Exception {
+ final IElement para = editor.insertElement(PARA);
+ editor.moveTo(para.getEndPosition());
+ editor.insertText("line1line2");
+ editor.moveBy(-5);
+
+ editor.split();
+
+ final List<? extends INode> children = rootElement.children().after(para.getStartPosition().getOffset()).asList();
+ assertEquals("two para elements", 2, children.size());
+ assertTrue("original para element", children.get(0) instanceof IParent);
+ assertTrue("splitted para element", children.get(1) instanceof IParent);
+ assertEquals("first line element", PARA, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("second line element", PARA, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("first line", "line1", children.get(0).getText());
+ assertEquals("second line", "line2", children.get(1).getText());
+ }
+
+ @Test
+ public void givenPreElement_whenSplitting_shouldSplitIntoTwoElements() throws Exception {
+ final IElement para = editor.insertElement(PARA);
+ final IElement preElement = editor.insertElement(PRE);
+ editor.moveTo(preElement.getEndPosition());
+ editor.insertText("line1line2");
+ editor.moveBy(-5);
+
+ editor.split();
+
+ final List<? extends INode> children = para.children().after(preElement.getStartPosition().getOffset()).asList();
+ assertEquals("two para elements", 2, children.size());
+ assertTrue("original pre element", children.get(0) instanceof IParent);
+ assertTrue("splitted pre element", children.get(1) instanceof IParent);
+ assertEquals("first line element", PRE, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("second line element", PRE, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("first line", "line1", children.get(0).getText());
+ assertEquals("second line", "line2", children.get(1).getText());
+ }
+
+ @Test
+ public void givenElementWithMultipleOccurrence_canSplitElement() throws Exception {
+ editor.insertElement(PARA);
+ assertTrue(editor.canSplit());
+ }
+
+ @Test
+ public void givenElementWithMultipleOccurrence_whenAnythingIsSelected_canSplitElement() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("12345");
+ editor.moveBy(-3, true);
+ assertTrue(editor.canSplit());
+ }
+
+ @Test
+ public void givenElementWithMultipleOccurrence_whenSplittingWithAnythingSelected_shouldDeleteSelectionAndSplit() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("12345");
+ editor.moveBy(-3, true);
+ editor.split();
+
+ final List<? extends INode> children = rootElement.children().asList();
+ assertEquals("two para elements", 2, children.size());
+ assertTrue("original para element", children.get(0) instanceof IParent);
+ assertTrue("splitted para element", children.get(1) instanceof IParent);
+ assertEquals("first line element", PARA, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("second line element", PARA, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("first line", "12", children.get(0).getText());
+ assertEquals("second line", "", children.get(1).getText());
+ }
+
+ @Test
+ public void givenElementWithMultipleOccurrence_whenCaretRightAfterStartIndex_shouldSplit() throws Exception {
+ final IElement para = editor.insertElement(PARA);
+ editor.insertText("12345");
+ editor.moveTo(para.getStartPosition().moveBy(1));
+ editor.split();
+
+ final List<? extends INode> children = rootElement.children().asList();
+ assertEquals("two para elements", 2, children.size());
+ assertTrue("original para element", children.get(0) instanceof IParent);
+ assertTrue("splitted para element", children.get(1) instanceof IParent);
+ assertEquals("first line element", PARA, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("second line element", PARA, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("first line", "", children.get(0).getText());
+ assertEquals("second line", "12345", children.get(1).getText());
+ }
+
+ @Test
+ public void givenElementWithMultipleOccurrenceAndInlineElement_whenCaretAtInlineStartOffset_shouldSplit() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("12");
+ editor.insertElement(PRE);
+ editor.insertText("34");
+ editor.moveBy(1);
+ editor.insertText("56");
+ editor.moveBy(-6);
+ editor.split();
+
+ final List<? extends INode> children = rootElement.children().asList();
+ assertEquals("two para elements", 2, children.size());
+ assertTrue("original para element", children.get(0) instanceof IParent);
+ assertTrue("splitted para element", children.get(1) instanceof IParent);
+ assertEquals("first line element", PARA, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("second line element", PARA, ((IElement) children.get(0)).getQualifiedName());
+ assertEquals("first line", "12", children.get(0).getText());
+ assertEquals("second line", "3456", children.get(1).getText());
+ assertEquals("pre in second line", PRE, ((IElement) ((IElement) children.get(1)).children().get(0)).getQualifiedName());
+ }
+
+ @Test
+ public void undoSubsequentSplitsOfInlineAndBlock() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("12");
+ editor.insertElement(PRE);
+ editor.insertText("34");
+ editor.moveBy(1);
+ editor.insertText("56");
+ final String expectedXml = getCurrentXML(editor);
+
+ editor.moveBy(-4);
+ editor.split();
+
+ editor.moveBy(-1);
+ editor.split();
+
+ editor.undo();
+ editor.undo();
+
+ assertXmlEquals(expectedXml, editor);
+ }
+
+ @Test
+ public void givenElementWithSingleOccurrence_cannotSplitElement() throws Exception {
+ editor.insertElement(TITLE);
+ assertFalse(editor.canSplit());
+ }
+
+ @Test(expected = CannotApplyException.class)
+ public void givenElementWithSingleOccurrence_whenSplitting_shouldThrowCannotRedoException() throws Exception {
+ editor.insertElement(TITLE);
+ editor.split();
+ }
+
+ @Test
+ public void givenComment_cannotSplit() throws Exception {
+ editor.insertComment();
+ assertFalse(editor.canSplit());
+ }
+
+ @Test(expected = DocumentValidationException.class)
+ public void givenComment_whenSplitting_shouldThrowDocumentValidationException() throws Exception {
+ editor.insertComment();
+ editor.split();
+ }
+
+ @Test
+ public void givenBeforeRootElement_cannotSplitElement() throws Exception {
+ editor.moveTo(rootElement.getStartPosition());
+ assertFalse(editor.canSplit());
+ }
+
+ @Test(expected = DocumentValidationException.class)
+ public void givenBeforeRootElement_whenSplitting_shouldThrowDocumentValidationException() throws Exception {
+ editor.moveTo(rootElement.getStartPosition());
+ editor.split();
+ }
+
+ @Test
+ public void undoRedoChangeNamespaceWithSubsequentDelete() throws Exception {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement para = editor.insertElement(PARA);
+ final String expectedXml = getCurrentXML(editor);
+
+ editor.declareNamespace("ns1", "nsuri1");
+ editor.select(para);
+ editor.deleteSelection();
+
+ editor.undo(); // delete
+ editor.undo(); // declare namespace
+
+ assertXmlEquals(expectedXml, editor);
+ }
+
+ @Test
+ public void undoRedoChangeAttributeWithSubsequentDelete() throws Exception {
+ editor.insertElement(TITLE);
+ editor.moveBy(1);
+ final IElement para = editor.insertElement(PARA);
+ final String expectedXml = getCurrentXML(editor);
+
+ editor.setAttribute("id", "newParaElement");
+ editor.select(para);
+ editor.deleteSelection();
+
+ editor.undo(); // delete
+ editor.undo(); // set attribute
+
+ assertXmlEquals(expectedXml, editor);
+ }
+
+ @Test
+ public void whenReadOnly_cannotMorph() throws Exception {
+ editor.insertElement(TITLE);
+ editor.setReadOnly(true);
+ assertFalse(editor.canMorph(PARA));
+ }
+
+ @Test(expected = ReadOnlyException.class)
+ public void whenReadOnly_shouldNotMorph() throws Exception {
+ editor.insertElement(TITLE);
+ editor.setReadOnly(true);
+ editor.morph(PARA);
+ }
+
+ @Test
+ public void cannotMorphRootElement() throws Exception {
+ assertFalse(editor.canMorph(TITLE));
+ }
+
+ @Test
+ public void morphEmptyElement() throws Exception {
+ editor.insertElement(TITLE);
+
+ assertTrue(editor.canMorph(PARA));
+ assertCanMorphOnlyTo(editor, PARA);
+ editor.morph(PARA);
+ }
+
+ @Test
+ public void givenElementWithText_whenMorphing_shouldPreserveText() throws Exception {
+ editor.insertElement(TITLE);
+ editor.insertText("text");
+
+ assertTrue(editor.canMorph(PARA));
+ editor.morph(PARA);
+
+ editor.selectAll();
+ assertXmlEquals("<section><para>text</para></section>", editor);
+ }
+
+ @Test
+ public void givenElementWithChildren_whenStructureIsInvalidAfterMorphing_cannotMorph() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("before");
+ editor.insertElement(PRE);
+ editor.insertText("within");
+ editor.moveBy(1);
+ editor.insertText("after");
+
+ assertFalse(editor.canMorph(TITLE));
+ }
+
+ @Test
+ public void givenElementWithChildren_whenStructureIsInvalidAfterMorphing_shouldNotProvideElementToMorph() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("before");
+ editor.insertElement(PRE);
+ editor.insertText("within");
+ editor.moveBy(1);
+ editor.insertText("after");
+
+ assertCanMorphOnlyTo(editor /* nothing */);
+ }
+
+ @Test(expected = CannotApplyException.class)
+ public void givenElementWithChildren_whenStructureIsInvalidAfterMorphing_shouldNotMorph() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("before");
+ editor.insertElement(PRE);
+ editor.insertText("within");
+ editor.moveBy(1);
+ editor.insertText("after");
+
+ editor.morph(TITLE);
+ }
+
+ @Test
+ public void givenAlternativeElement_whenElementIsNotAllowedAtCurrentInsertionPosition_cannotMorph() throws Exception {
+ editor.insertElement(PARA);
+ editor.moveBy(1);
+ editor.insertElement(PARA);
+
+ assertFalse(editor.canMorph(TITLE));
+ }
+
+ @Test
+ public void givenAlternativeElement_whenElementIsNotAllowedAtCurrentInsertionPosition_shouldNotProvideElementToMorph() throws Exception {
+ editor.insertElement(PARA);
+ editor.moveBy(1);
+ editor.insertElement(PARA);
+
+ assertCanMorphOnlyTo(editor /* nothing */);
+ }
+
+ public void givenElementWithAttributes_whenUndoMorph_shouldPreserveAttributes() throws Exception {
+ editor.insertElement(PARA);
+ editor.setAttribute("id", "idValue");
+ editor.morph(TITLE);
+ editor.undo();
+
+ assertEquals("idValue", editor.getCurrentElement().getAttribute("id").getValue());
+ }
+
+ public void whenReadOnly_cannotUnwrap() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertElement(PRE);
+ editor.insertText("text");
+ editor.setReadOnly(true);
+ assertFalse(editor.canUnwrap());
+ }
+
+ @Test(expected = ReadOnlyException.class)
+ public void whenReadOnly_shouldNotUnwrap() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertElement(PRE);
+ editor.insertText("text");
+ editor.setReadOnly(true);
+ editor.unwrap();
+ }
+
+ @Test
+ public void cannotUnwrapRootElement() throws Exception {
+ assertFalse(editor.canUnwrap());
+ }
+
+ @Test
+ public void unwrapEmptyElement() throws Exception {
+ editor.insertElement(PARA);
+ editor.unwrap();
+
+ editor.selectAll();
+ assertXmlEquals("<section></section>", editor);
+ }
+
+ @Test
+ public void givenInlineElementWithText_shouldUnwrapInlineElement() throws Exception {
+ final IElement para = editor.insertElement(PARA);
+ editor.insertElement(PRE);
+ editor.insertText("text");
+ editor.unwrap();
+
+ assertSame(para, editor.getCurrentElement());
+ editor.selectAll();
+ assertXmlEquals("<section><para>text</para></section>", editor);
+ }
+
+ @Test
+ public void givenElementWithText_whenParentDoesNotAllowText_cannotUnwrap() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("text");
+
+ assertFalse(editor.canUnwrap());
+ }
+
+ @Test(expected = CannotApplyException.class)
+ public void givenElementWithText_whenParentDoesNotAllowText_shouldNotUnwrap() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertText("text");
+ editor.unwrap();
+ }
+
+ @Test
+ public void givenElementWithChildren_whenParentDoesNotAllowChildren_cannotUnwrap() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertElement(PRE);
+ editor.moveBy(1);
+
+ assertFalse(editor.canUnwrap());
+ }
+
+ @Test(expected = CannotApplyException.class)
+ public void givenElementWithChildren_whenParentDoesNotAllowChildren_shouldNotUnwrap() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertElement(PRE);
+ editor.moveBy(1);
+ editor.unwrap();
+ }
+
+ @Test
+ public void givenElementWithAttributes_whenUndoUnwrap_shouldPreserveAttributes() throws Exception {
+ editor.insertElement(PARA);
+ editor.insertElement(PRE);
+ editor.setAttribute("id", "idValue");
+
+ editor.unwrap();
+ editor.undo();
+
+ assertEquals(PRE, editor.getCurrentElement().getQualifiedName());
+ assertEquals("idValue", editor.getCurrentElement().getAttributeValue("id"));
+ }
+
+ @Test
+ public void givenMultipleElementsOfSameTypeSelected_canJoin() throws Exception {
+ final IElement firstPara = editor.insertElement(PARA);
+ editor.insertText("1");
+ editor.moveBy(1);
+ editor.insertElement(PARA);
+ editor.insertText("2");
+ editor.moveBy(1);
+ final IElement lastPara = editor.insertElement(PARA);
+ editor.insertText("3");
+ editor.moveBy(1);
+
+ editor.moveTo(firstPara.getStartPosition());
+ editor.moveTo(lastPara.getEndPosition(), true);
+
+ assertTrue(editor.canJoin());
+ }
+
+ @Test
+ public void givenMultipleElementsOfSameTypeSelected_shouldJoin() throws Exception {
+ final IElement firstPara = editor.insertElement(PARA);
+ editor.insertText("1");
+ editor.moveBy(1);
+ editor.insertElement(PARA);
+ editor.insertText("2");
+ editor.moveBy(1);
+ final IElement lastPara = editor.insertElement(PARA);
+ editor.insertText("3");
+ editor.moveBy(1);
+
+ editor.moveTo(firstPara.getStartPosition());
+ editor.moveTo(lastPara.getEndPosition(), true);
+
+ editor.join();
+
+ assertXmlEquals("<section><para>123</para></section>", editor);
+ }
+
+ @Test
+ public void givenMultipleElementsOfSameKindSelected_whenJoining_shouldPreserveAttributesOfFirstElement() throws Exception {
+ final IElement firstPara = editor.insertElement(PARA);
+ editor.insertText("1");
+ editor.moveBy(1);
+ editor.insertElement(PARA);
+ editor.insertText("2");
+ editor.moveBy(1);
+ final IElement lastPara = editor.insertElement(PARA);
+ editor.insertText("3");
+ firstPara.setAttribute("id", "para1");
+ lastPara.setAttribute("id", "para3");
+
+ editor.moveTo(firstPara.getStartPosition());
+ editor.moveTo(lastPara.getEndPosition(), true);
+
+ editor.join();
+
+ assertXmlEquals("<section><para id=\"para1\">123</para></section>", editor);
+ }
+
+ @Test
+ public void givenMultipleElementsOfSameKindSelected_whenJoinUndone_shouldRestoreAttributesOfAllElements() throws Exception {
+ final IElement firstPara = editor.insertElement(PARA);
+ editor.insertText("1");
+ editor.moveBy(1);
+ editor.insertElement(PARA);
+ editor.insertText("2");
+ editor.moveBy(1);
+ final IElement lastPara = editor.insertElement(PARA);
+ editor.insertText("3");
+ firstPara.setAttribute("id", "para1");
+ lastPara.setAttribute("id", "para3");
+
+ editor.moveTo(firstPara.getStartPosition());
+ editor.moveTo(lastPara.getEndPosition(), true);
+
+ editor.join();
+ editor.undo();
+
+ assertXmlEquals("<section><para id=\"para1\">1</para><para>2</para><para id=\"para3\">3</para></section>", editor);
+ }
+
+ @Test
+ public void givenMultipleElementsOfSameKindSelected_whenStructureAfterJoinWouldBeInvalid_cannotJoin() throws Exception {
+ editor.setDocument(createDocumentWithDTD(TEST_DTD, "one-kind-of-child"));
+ rootElement = editor.getDocument().getRootElement();
+
+ final IElement firstSection = editor.insertElement(SECTION);
+ editor.insertElement(TITLE);
+ editor.moveBy(2);
+ editor.insertElement(SECTION);
+ editor.insertElement(TITLE);
+ editor.moveBy(2);
+ final IElement lastSection = editor.insertElement(SECTION);
+ editor.insertElement(TITLE);
+
+ editor.moveTo(firstSection.getStartPosition());
+ editor.moveTo(lastSection.getEndPosition(), true);
+
+ assertFalse(editor.canJoin());
+ }
+
+ @Test(expected = CannotApplyException.class)
+ public void givenMultipleElementsOfSameKindSelected_whenStructureAfterJoinWouldBeInvalid_shouldJoin() throws Exception {
+ editor.setDocument(createDocumentWithDTD(TEST_DTD, "one-kind-of-child"));
+ rootElement = editor.getDocument().getRootElement();
+
+ final IElement firstSection = editor.insertElement(SECTION);
+ editor.insertElement(TITLE);
+ editor.moveBy(2);
+ editor.insertElement(SECTION);
+ editor.insertElement(TITLE);
+ editor.moveBy(2);
+ final IElement lastSection = editor.insertElement(SECTION);
+ editor.insertElement(TITLE);
+
+ editor.moveTo(firstSection.getStartPosition());
+ editor.moveTo(lastSection.getEndPosition(), true);
+
+ editor.join();
+ }
+
+ @Test
+ public void givenMultipleElementsOfDifferentTypeSelected_cannotJoin() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+ editor.insertText("1");
+ editor.moveBy(1);
+ editor.insertElement(PARA);
+ editor.insertText("2");
+ editor.moveBy(1);
+ final IElement lastPara = editor.insertElement(PARA);
+ editor.insertText("3");
+ editor.moveBy(1);
+
+ editor.moveTo(title.getStartPosition());
+ editor.moveTo(lastPara.getEndPosition(), true);
+
+ assertFalse(editor.canJoin());
+ }
+
+ @Test(expected = DocumentValidationException.class)
+ public void givenMultipleElementsOfDifferentTypeSelected_shouldNotJoin() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+ editor.insertText("1");
+ editor.moveBy(1);
+ editor.insertElement(PARA);
+ editor.insertText("2");
+ editor.moveBy(1);
+ final IElement lastPara = editor.insertElement(PARA);
+ editor.insertText("3");
+ editor.moveBy(1);
+
+ editor.moveTo(title.getStartPosition());
+ editor.moveTo(lastPara.getEndPosition(), true);
+
+ editor.join();
+ }
+
+ @Test
+ public void givenSelectionIsEmpty_cannotJoin() throws Exception {
+ assertFalse(editor.canJoin());
+ }
+
+ @Test
+ public void givenSelectionIsEmpty_whenRequestedToJoin_shouldIgnoreGracefully() throws Exception {
+ final String expectedXml = getCurrentXML(editor);
+
+ editor.join();
+
+ assertXmlEquals(expectedXml, editor);
+ }
+
+ @Test
+ public void givenOnlyTextSelected_cannotJoin() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+ editor.insertText("title text");
+ editor.moveTo(title.getStartPosition().moveBy(1), true);
+
+ assertFalse(editor.canJoin());
+ }
+
+ @Test
+ public void givenOnlyTextSelected_whenRequestedToJoin_shouldIgnoreGracefully() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+ editor.insertText("title text");
+ editor.selectContentOf(title);
+ final String expectedXml = getCurrentXML(editor);
+
+ editor.join();
+
+ assertXmlEquals(expectedXml, editor);
+ }
+
+ @Test
+ public void givenOnlySingleElementSelected_cannotJoin() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+ editor.moveTo(title.getStartPosition(), true);
+
+ assertFalse(editor.canJoin());
+ }
+
+ @Test
+ public void givenOnlySingleElementSelected_whenRequestedToJoin_shouldIgnoreGracefully() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+ editor.moveTo(title.getStartPosition(), true);
+ final String expectedXml = getCurrentXML(editor);
+
+ editor.join();
+
+ assertXmlEquals(expectedXml, editor);
+ }
+
+ @Test
+ public void givenMultipleCommentsSelected_canJoin() throws Exception {
+ final IComment firstComment = editor.insertComment();
+ editor.insertText("comment1");
+ editor.moveBy(1);
+ editor.insertComment();
+ editor.insertText("comment2");
+ editor.moveBy(1);
+ final IComment lastComment = editor.insertComment();
+ editor.insertText("comment3");
+
+ editor.moveTo(firstComment.getStartPosition());
+ editor.moveTo(lastComment.getEndPosition(), true);
+
+ assertTrue(editor.canJoin());
+ }
+
+ @Test
+ public void givenMultipleCommentsSelected_shouldJoin() throws Exception {
+ final IComment firstComment = editor.insertComment();
+ editor.insertText("comment1");
+ editor.moveBy(1);
+ editor.insertComment();
+ editor.insertText("comment2");
+ editor.moveBy(1);
+ final IComment lastComment = editor.insertComment();
+ editor.insertText("comment3");
+
+ editor.moveTo(firstComment.getStartPosition());
+ editor.moveTo(lastComment.getEndPosition(), true);
+
+ editor.join();
+
+ assertXmlEquals("<section><!--comment1comment2comment3--></section>", editor);
+ }
+
+ @Test
+ public void givenMultipleInlineElementsOfSameKindSelected_whenTextEndsWithSpace_shouldJoin() throws Exception {
+ editor.insertElement(PARA);
+ final IElement firstElement = editor.insertElement(PRE);
+ editor.insertText("1");
+ editor.moveBy(1);
+ final IElement lastElement = editor.insertElement(PRE);
+ editor.insertText("2 ");
+
+ editor.moveTo(firstElement.getStartPosition());
+ editor.moveTo(lastElement.getEndPosition(), true);
+
+ editor.join();
+
+ assertXmlEquals("<section><para><pre>12 </pre></para></section>", editor);
+ }
+
+ @Test
+ public void givenMultipleInlineElementsOfSameKindSelected_whenTextBetweenElements_cannotJoin() throws Exception {
+ editor.insertElement(PARA);
+ final IElement firstElement = editor.insertElement(PRE);
+ editor.insertText("1");
+ editor.moveBy(1);
+ editor.insertText("text between elements");
+ final IElement lastElement = editor.insertElement(PRE);
+ editor.insertText("2 ");
+
+ editor.moveTo(firstElement.getStartPosition());
+ editor.moveTo(lastElement.getEndPosition(), true);
+
+ assertFalse(editor.canJoin());
+ }
+
+ @Test(expected = DocumentValidationException.class)
+ public void givenMultipleInlineElementsOfSameKindSelected_whenTextBetweenElements_shouldNotJoin() throws Exception {
+ editor.insertElement(PARA);
+ final IElement firstElement = editor.insertElement(PRE);
+ editor.insertText("1");
+ editor.moveBy(1);
+ editor.insertText("text between elements");
+ final IElement lastElement = editor.insertElement(PRE);
+ editor.insertText("2 ");
+
+ editor.moveTo(firstElement.getStartPosition());
+ editor.moveTo(lastElement.getEndPosition(), true);
+
+ editor.join();
+ }
+
+ @Test
+ public void givenDeletedText_whenDeleteUndone_shouldSetCaretToEndOfRecoveredText() throws Exception {
+ final IElement title = editor.insertElement(TITLE);
+ editor.insertText("Hello World");
+ editor.moveTo(title.getStartPosition().moveBy(1));
+ editor.moveBy(5, true);
+ final int expectedCaretPosition = editor.getSelectedRange().getEndOffset() + 1;
+
+ editor.deleteSelection();
+ editor.undo();
+
+ assertEquals(expectedCaretPosition, editor.getCaretPosition().getOffset());
+ }
+
+ @Test
+ public void afterDeletingSelection_CaretPositionShouldBeValid() throws Exception {
+ final IElement para = editor.insertElement(PARA);
+ editor.moveTo(para.getEndPosition());
+ final IElement pre = editor.insertElement(PRE);
+ editor.insertText("Hello World");
+ editor.moveTo(pre.getStartPosition());
+ editor.moveTo(pre.getEndPosition().moveBy(-1), true);
+
+ editor.deleteSelection();
+ assertEquals(para.getEndPosition(), editor.getCaretPosition());
+ }
+
+ @Test
+ public void undoAndRedoDelete() throws Exception {
+ final IElement para = editor.insertElement(PARA);
+ editor.moveTo(para.getEndPosition());
+ final IElement pre = editor.insertElement(PRE);
+ editor.insertText("Hello World");
+ final String beforeDeleteXml = getCurrentXML(editor);
+
+ editor.moveTo(pre.getStartPosition());
+ editor.moveTo(pre.getEndPosition().moveBy(-1), true);
+ editor.deleteSelection();
+
+ final String beforeUndoXml = getCurrentXML(editor);
+ editor.undo();
+ assertXmlEquals(beforeDeleteXml, editor);
+
+ editor.redo();
+ assertXmlEquals(beforeUndoXml, editor);
+ }
+
+ private static StyleSheet readTestStyleSheet() throws IOException {
+ return new StyleSheetReader().read(TestResources.get("test.css"));
+ }
+
+}
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2XIncludeEditingTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2XIncludeEditingTest.java
index 5a1f1566..602a7a5b 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2XIncludeEditingTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/L2XIncludeEditingTest.java
@@ -1,132 +1,126 @@
-/*******************************************************************************
- * Copyright (c) 2014 Carsten Hiesserich and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Carsten Hiesserich - initial API and implementation
- *******************************************************************************/
-package org.eclipse.vex.core.internal.widget;
-
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.createDocumentWithDTD;
-import static org.eclipse.vex.core.internal.widget.VexWidgetTest.getCurrentXML;
-import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.vex.core.internal.css.CssWhitespacePolicy;
-import org.eclipse.vex.core.internal.css.StyleSheet;
-import org.eclipse.vex.core.internal.io.XMLFragment;
-import org.eclipse.vex.core.provisional.dom.IElement;
-import org.eclipse.vex.core.provisional.dom.IIncludeNode;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * @author Florian Thienel
- */
-public class L2XIncludeEditingTest {
-
- private final String includeXml = "<para>12<xi:include xmlns:xi=\"http://www.w3.org/2001/XInclude\" href=\"test\" />34</para>";
- private final String includeInlineXml = "<para>12<xi:include xmlns:xi=\"http://www.w3.org/2001/XInclude\" href=\"test\" parse=\"text\" />34</para>";
-
- private IVexWidget widget;
- private IElement rootElement;
- private IElement para;
- private IIncludeNode includeNode;
-
- @Before
- public void setUp() throws Exception {
- widget = new BaseVexWidget(new MockHostComponent());
- widget.setDocument(createDocumentWithDTD(TEST_DTD, "section"), StyleSheet.NULL);
- widget.setWhitespacePolicy(new CssWhitespacePolicy(widget.getStyleSheet()));
- }
-
- @Test
- public void whenCaretAfterEmptyInclude_BackspaceShouldDeleteInclude() throws Exception {
- createIncludeElement(includeXml);
- widget.moveTo(includeNode.getEndPosition().moveBy(1));
- widget.deletePreviousChar();
-
- assertTrue(para.children().withoutText().isEmpty());
- assertFalse(includeNode.isAssociated());
- assertNull(includeNode.getReference().getParent());
- }
-
- @Test
- public void whenIncludeSelected_ShouldDeleteInclude() throws Exception {
- createIncludeElement(includeXml);
- widget.moveTo(includeNode.getStartPosition());
- widget.moveTo(includeNode.getEndPosition(), true);
- widget.deleteSelection();
-
- final String currentXml = getCurrentXML(widget);
- assertEquals("<section><para>1234</para></section>", currentXml);
-
- assertTrue(para.children().withoutText().isEmpty());
- assertFalse(includeNode.isAssociated());
- assertNull(includeNode.getReference().getParent());
- }
-
- @Test
- public void deleteInlineIncludeWithSurroundingContent() throws Exception {
- createIncludeElement(includeInlineXml);
-
- widget.moveTo(includeNode.getStartPosition());
- widget.moveTo(para.getEndPosition().moveBy(-1), true);
- widget.deleteSelection();
-
- final String currentXml = getCurrentXML(widget);
- assertEquals("<section><para>124</para></section>", currentXml);
-
- assertTrue(para.children().withoutText().isEmpty());
- assertFalse(includeNode.isAssociated());
- assertNull(includeNode.getReference().getParent());
- }
-
- @Test
- public void deleteInlineIncludeWithSurroundingContent_selectingBackwards() throws Exception {
- createIncludeElement(includeInlineXml);
-
- // Yes, the direction of the selection makes a difference
- widget.moveTo(para.getEndPosition().moveBy(-1));
- widget.moveTo(includeNode.getStartPosition(), true);
-
- widget.deleteSelection();
-
- final String currentXml = getCurrentXML(widget);
- assertEquals("<section><para>124</para></section>", currentXml);
-
- assertTrue(para.children().withoutText().isEmpty());
- assertFalse(includeNode.isAssociated());
- assertNull(includeNode.getReference().getParent());
- }
-
- @Test
- public void undoDeleteInclude() throws Exception {
- createIncludeElement(includeXml);
- widget.moveTo(includeNode.getStartPosition());
- widget.moveTo(includeNode.getEndPosition(), true);
- final String exepctedXml = getCurrentXML(widget);
- widget.deleteSelection();
- widget.undo();
- assertEquals(exepctedXml, getCurrentXML(widget));
-
- para = (IElement) rootElement.children().get(0);
- includeNode = (IIncludeNode) para.children().withoutText().get(0);
- assertTrue(includeNode.isAssociated());
- assertEquals(para, includeNode.getReference().getParent());
- }
-
- private void createIncludeElement(final String xml) {
- widget.insertFragment(new XMLFragment(xml).getDocumentFragment());
- rootElement = widget.getDocument().getRootElement();
- para = (IElement) rootElement.children().get(0);
- includeNode = (IIncludeNode) para.children().withoutText().get(0);
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2014 Carsten Hiesserich and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Carsten Hiesserich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.widget;
+
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.createDocumentWithDTD;
+import static org.eclipse.vex.core.internal.widget.VexWidgetTest.getCurrentXML;
+import static org.eclipse.vex.core.tests.TestResources.TEST_DTD;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.vex.core.internal.io.XMLFragment;
+import org.eclipse.vex.core.provisional.dom.IElement;
+import org.eclipse.vex.core.provisional.dom.IIncludeNode;
+import org.junit.Before;
+import org.junit.Test;
+
+public class L2XIncludeEditingTest {
+
+ private final String includeXml = "<para>12<xi:include xmlns:xi=\"http://www.w3.org/2001/XInclude\" href=\"test\" />34</para>";
+ private final String includeInlineXml = "<para>12<xi:include xmlns:xi=\"http://www.w3.org/2001/XInclude\" href=\"test\" parse=\"text\" />34</para>";
+
+ private IDocumentEditor editor;
+ private IElement rootElement;
+ private IElement para;
+ private IIncludeNode includeNode;
+
+ @Before
+ public void setUp() throws Exception {
+ editor = new BaseVexWidget(new MockHostComponent());
+ editor.setDocument(createDocumentWithDTD(TEST_DTD, "section"));
+ }
+
+ @Test
+ public void whenCaretAfterEmptyInclude_BackspaceShouldDeleteInclude() throws Exception {
+ createIncludeElement(includeXml);
+ editor.moveTo(includeNode.getEndPosition().moveBy(1));
+ editor.deletePreviousChar();
+
+ assertTrue(para.children().withoutText().isEmpty());
+ assertFalse(includeNode.isAssociated());
+ assertNull(includeNode.getReference().getParent());
+ }
+
+ @Test
+ public void whenIncludeSelected_ShouldDeleteInclude() throws Exception {
+ createIncludeElement(includeXml);
+ editor.moveTo(includeNode.getStartPosition());
+ editor.moveTo(includeNode.getEndPosition(), true);
+ editor.deleteSelection();
+
+ final String currentXml = getCurrentXML(editor);
+ assertEquals("<section><para>1234</para></section>", currentXml);
+
+ assertTrue(para.children().withoutText().isEmpty());
+ assertFalse(includeNode.isAssociated());
+ assertNull(includeNode.getReference().getParent());
+ }
+
+ @Test
+ public void deleteInlineIncludeWithSurroundingContent() throws Exception {
+ createIncludeElement(includeInlineXml);
+
+ editor.moveTo(includeNode.getStartPosition());
+ editor.moveTo(para.getEndPosition().moveBy(-1), true);
+ editor.deleteSelection();
+
+ final String currentXml = getCurrentXML(editor);
+ assertEquals("<section><para>124</para></section>", currentXml);
+
+ assertTrue(para.children().withoutText().isEmpty());
+ assertFalse(includeNode.isAssociated());
+ assertNull(includeNode.getReference().getParent());
+ }
+
+ @Test
+ public void deleteInlineIncludeWithSurroundingContent_selectingBackwards() throws Exception {
+ createIncludeElement(includeInlineXml);
+
+ // Yes, the direction of the selection makes a difference
+ editor.moveTo(para.getEndPosition().moveBy(-1));
+ editor.moveTo(includeNode.getStartPosition(), true);
+
+ editor.deleteSelection();
+
+ final String currentXml = getCurrentXML(editor);
+ assertEquals("<section><para>124</para></section>", currentXml);
+
+ assertTrue(para.children().withoutText().isEmpty());
+ assertFalse(includeNode.isAssociated());
+ assertNull(includeNode.getReference().getParent());
+ }
+
+ @Test
+ public void undoDeleteInclude() throws Exception {
+ createIncludeElement(includeXml);
+ editor.moveTo(includeNode.getStartPosition());
+ editor.moveTo(includeNode.getEndPosition(), true);
+ final String exepctedXml = getCurrentXML(editor);
+ editor.deleteSelection();
+ editor.undo();
+ assertEquals(exepctedXml, getCurrentXML(editor));
+
+ para = (IElement) rootElement.children().get(0);
+ includeNode = (IIncludeNode) para.children().withoutText().get(0);
+ assertTrue(includeNode.isAssociated());
+ assertEquals(para, includeNode.getReference().getParent());
+ }
+
+ private void createIncludeElement(final String xml) {
+ editor.insertFragment(new XMLFragment(xml).getDocumentFragment());
+ rootElement = editor.getDocument().getRootElement();
+ para = (IElement) rootElement.children().get(0);
+ includeNode = (IIncludeNode) para.children().withoutText().get(0);
+ }
+
+}
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java
index 81599546..7e699d08 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/widget/VexWidgetTest.java
@@ -18,7 +18,6 @@ import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.vex.core.internal.css.StyleSheet;
import org.eclipse.vex.core.internal.dom.Document;
import org.eclipse.vex.core.internal.io.XMLFragment;
import org.eclipse.vex.core.internal.validator.WTPVEXValidator;
@@ -39,101 +38,100 @@ public class VexWidgetTest {
public static final QualifiedName PARA = new QualifiedName(null, "para");
public static final QualifiedName PRE = new QualifiedName(null, "pre");
- private IVexWidget widget;
+ private IDocumentEditor editor;
@Before
public void setUp() throws Exception {
- widget = new BaseVexWidget(new MockHostComponent());
+ editor = new BaseVexWidget(new MockHostComponent());
}
@Test
public void provideOnlyAllowedElementsFromDtd() throws Exception {
- widget.setDocument(createDocumentWithDTD(TEST_DTD, "section"), StyleSheet.NULL);
- assertCanInsertOnly(widget, "title", "para");
- widget.insertElement(new QualifiedName(null, "title"));
- assertCanInsertOnly(widget);
- widget.moveBy(1);
- assertCanInsertOnly(widget, "para");
- widget.insertElement(new QualifiedName(null, "para"));
- widget.moveBy(1);
- assertCanInsertOnly(widget, "para");
+ editor.setDocument(createDocumentWithDTD(TEST_DTD, "section"));
+ assertCanInsertOnly(editor, "title", "para");
+ editor.insertElement(new QualifiedName(null, "title"));
+ assertCanInsertOnly(editor);
+ editor.moveBy(1);
+ assertCanInsertOnly(editor, "para");
+ editor.insertElement(new QualifiedName(null, "para"));
+ editor.moveBy(1);
+ assertCanInsertOnly(editor, "para");
}
@Test
public void provideOnlyAllowedElementsFromSimpleSchema() throws Exception {
- widget.setDocument(createDocument(CONTENT_NS, "p"), StyleSheet.NULL);
- assertCanInsertOnly(widget, "b", "i");
- widget.insertElement(new QualifiedName(CONTENT_NS, "b"));
- assertCanInsertOnly(widget, "b", "i");
- widget.moveBy(1);
- assertCanInsertOnly(widget, "b", "i");
+ editor.setDocument(createDocument(CONTENT_NS, "p"));
+ assertCanInsertOnly(editor, "b", "i");
+ editor.insertElement(new QualifiedName(CONTENT_NS, "b"));
+ assertCanInsertOnly(editor, "b", "i");
+ editor.moveBy(1);
+ assertCanInsertOnly(editor, "b", "i");
}
@Test
public void provideOnlyAllowedElementFromComplexSchema() throws Exception {
- widget.setDocument(createDocument(STRUCTURE_NS, "chapter"), StyleSheet.NULL);
- assertCanInsertOnly(widget, "title", "chapter", "p");
- widget.insertElement(new QualifiedName(STRUCTURE_NS, "title"));
- assertCanInsertOnly(widget);
- widget.moveBy(1);
+ editor.setDocument(createDocument(STRUCTURE_NS, "chapter"));
+ assertCanInsertOnly(editor, "title", "chapter", "p");
+ editor.insertElement(new QualifiedName(STRUCTURE_NS, "title"));
+ assertCanInsertOnly(editor);
+ editor.moveBy(1);
// assertCanInsertOnly(widget, "chapter", "p");
- widget.insertElement(new QualifiedName(CONTENT_NS, "p"));
- assertCanInsertOnly(widget, "b", "i");
- widget.moveBy(1);
+ editor.insertElement(new QualifiedName(CONTENT_NS, "p"));
+ assertCanInsertOnly(editor, "b", "i");
+ editor.moveBy(1);
// assertCanInsertOnly(widget, "p");
// FIXME: maybe the schema is still not what I mean
}
@Test
public void provideNoAllowedElementsForInsertionInComment() throws Exception {
- final BaseVexWidget widget = new BaseVexWidget(new MockHostComponent());
final IDocument document = createDocument(STRUCTURE_NS, "chapter");
- widget.setDocument(document, StyleSheet.NULL);
- widget.insertElement(new QualifiedName(STRUCTURE_NS, "title"));
- widget.moveBy(1);
- widget.insertElement(new QualifiedName(CONTENT_NS, "p"));
- widget.insertComment();
+ editor.setDocument(document);
+ editor.insertElement(new QualifiedName(STRUCTURE_NS, "title"));
+ editor.moveBy(1);
+ editor.insertElement(new QualifiedName(CONTENT_NS, "p"));
+ editor.insertComment();
- assertCannotInsertAnything(widget);
+ assertCannotInsertAnything(editor);
}
@Test
public void undoRemoveCommentTag() throws Exception {
- final BaseVexWidget widget = new BaseVexWidget(new MockHostComponent());
- widget.setDocument(createDocument(STRUCTURE_NS, "chapter"), StyleSheet.NULL);
- widget.insertElement(new QualifiedName(CONTENT_NS, "p"));
- widget.insertText("1text before comment1");
- final INode comment = widget.insertComment();
- widget.insertText("2comment text2");
- widget.moveBy(1);
- widget.insertText("3text after comment3");
+ editor.setDocument(createDocument(STRUCTURE_NS, "chapter"));
+ editor.insertElement(new QualifiedName(CONTENT_NS, "p"));
+ editor.insertText("1text before comment1");
+ final INode comment = editor.insertComment();
+ editor.insertText("2comment text2");
+ editor.moveBy(1);
+ editor.insertText("3text after comment3");
- final String expectedContentStructure = getContentStructure(widget.getDocument().getRootElement());
+ final String expectedContentStructure = getContentStructure(editor.getDocument().getRootElement());
- widget.doWork(new Runnable() {
+ editor.doWork(new Runnable() {
@Override
public void run() {
- widget.selectContentOf(comment);
- final IDocumentFragment fragment = widget.getSelectedFragment();
- widget.deleteSelection();
+ editor.selectContentOf(comment);
+ final IDocumentFragment fragment = editor.getSelectedFragment();
+ editor.deleteSelection();
- widget.select(comment);
- widget.deleteSelection();
+ editor.select(comment);
+ editor.deleteSelection();
- widget.insertFragment(fragment);
+ editor.insertFragment(fragment);
}
});
- widget.undo();
+ editor.undo();
- assertEquals(expectedContentStructure, getContentStructure(widget.getDocument().getRootElement()));
+ assertEquals(expectedContentStructure, getContentStructure(editor.getDocument().getRootElement()));
}
/* bug 421401 */
@Test
public void whenClickedRightToLineEnd_shouldSetCursorToLineEnd() throws Exception {
- final IDocument document = createDocument(STRUCTURE_NS, "chapter");
- widget.setDocument(document, StyleSheet.NULL);
+ // TODO move to a separate test class that is specific to BaseVexWidget, this here is not editing but mouse handling
+ final BaseVexWidget widget = new BaseVexWidget(new MockHostComponent());
+ widget.setDocument(createDocument(STRUCTURE_NS, "chapter"));
widget.insertElement(new QualifiedName(CONTENT_NS, "p"));
widget.insertText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris.");
widget.setLayoutWidth(200); // breaks after "amet, "
@@ -148,13 +146,13 @@ public class VexWidgetTest {
@Test
public void whenMovingCursorUp_shouldNotGetStuckInHigherLevelElement() throws Exception {
final IDocument document = createDocument(STRUCTURE_NS, "chapter");
- widget.setDocument(document, StyleSheet.NULL);
- widget.insertElement(new QualifiedName(CONTENT_NS, "p"));
- widget.insertText("para 1");
- widget.moveTo(new ContentPosition(document, 1));
+ editor.setDocument(document);
+ editor.insertElement(new QualifiedName(CONTENT_NS, "p"));
+ editor.insertText("para 1");
+ editor.moveTo(new ContentPosition(document, 1));
- widget.moveToNextLine(false);
- assertEquals(2, widget.getCaretPosition().getOffset());
+ editor.moveToNextLine(false);
+ assertEquals(2, editor.getCaretPosition().getOffset());
}
public static IDocument createDocumentWithDTD(final String dtdIdentifier, final String rootElementName) {
@@ -171,19 +169,19 @@ public class VexWidgetTest {
return document;
}
- public static void assertCanInsertOnly(final IVexWidget widget, final Object... elementNames) {
+ public static void assertCanInsertOnly(final IDocumentEditor widget, final Object... elementNames) {
final String[] expected = sortedCopyOf(elementNames);
final String[] actual = sortedCopyOf(widget.getValidInsertElements());
assertEquals(Arrays.toString(expected), Arrays.toString(actual));
}
- public static void assertCanMorphOnlyTo(final IVexWidget widget, final Object... elementNames) {
+ public static void assertCanMorphOnlyTo(final IDocumentEditor widget, final Object... elementNames) {
final String[] expected = sortedCopyOf(elementNames);
final String[] actual = sortedCopyOf(widget.getValidMorphElements());
assertEquals(Arrays.toString(expected), Arrays.toString(actual));
}
- public static void assertCannotInsertAnything(final IVexWidget widget) {
+ public static void assertCannotInsertAnything(final IDocumentEditor widget) {
assertCanInsertOnly(widget /* nothing */);
}
@@ -221,11 +219,11 @@ public class VexWidgetTest {
return result.toString();
}
- public static String getCurrentXML(final IVexWidget widget) {
+ public static String getCurrentXML(final IDocumentEditor widget) {
return new XMLFragment(widget.getDocument().getFragment(widget.getDocument().getRootElement().getRange())).getXML();
}
- public static void assertXmlEquals(final String expected, final IVexWidget widget) {
+ public static void assertXmlEquals(final String expected, final IDocumentEditor widget) {
assertEquals(expected, getCurrentXML(widget));
}
}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/BaseVexWidget.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/BaseVexWidget.java
index a0737e38..f973c8ff 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/BaseVexWidget.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/BaseVexWidget.java
@@ -1710,6 +1710,11 @@ public class BaseVexWidget implements IVexWidget {
this.document.addDocumentListener(documentListener);
}
+ @Override
+ public void setDocument(final IDocument document) {
+ setDocument(document, StyleSheet.NULL);
+ }
+
/**
* Called by the host component when it gains or loses focus.
*
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/IDocumentEditor.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/IDocumentEditor.java
new file mode 100644
index 00000000..a2980fac
--- /dev/null
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/IDocumentEditor.java
@@ -0,0 +1,626 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.widget;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.vex.core.internal.core.ElementName;
+import org.eclipse.vex.core.internal.undo.CannotApplyException;
+import org.eclipse.vex.core.internal.undo.CannotUndoException;
+import org.eclipse.vex.core.provisional.dom.ContentPosition;
+import org.eclipse.vex.core.provisional.dom.ContentPositionRange;
+import org.eclipse.vex.core.provisional.dom.ContentRange;
+import org.eclipse.vex.core.provisional.dom.DocumentValidationException;
+import org.eclipse.vex.core.provisional.dom.IComment;
+import org.eclipse.vex.core.provisional.dom.IDocument;
+import org.eclipse.vex.core.provisional.dom.IDocumentFragment;
+import org.eclipse.vex.core.provisional.dom.IElement;
+import org.eclipse.vex.core.provisional.dom.INode;
+import org.eclipse.vex.core.provisional.dom.IProcessingInstruction;
+
+public interface IDocumentEditor {
+
+ /*
+ * Configuration
+ */
+
+ /**
+ * Returns the document associated with this editor.
+ */
+ IDocument getDocument();
+
+ /**
+ * Sets a new document for editing.
+ *
+ * @param document
+ * new Document to edit
+ */
+ void setDocument(IDocument document);
+
+ /**
+ * @return true if this editor is read-only
+ */
+ boolean isReadOnly();
+
+ /**
+ * Make this editor read-only.
+ *
+ * @param readOnly
+ * set to true if this editor should be read-only
+ */
+ void setReadOnly(boolean readOnly);
+
+ /*
+ * Undo/Redo
+ */
+
+ /**
+ * Returns true if a redo can be performed.
+ */
+ boolean canRedo();
+
+ /**
+ * Redoes the last action on the redo stack.
+ *
+ * @throws CannotApplyException
+ * if the last action cannot be re-done, or if there is nothing to redo.
+ */
+ void redo() throws CannotApplyException;
+
+ /**
+ * Returns true if an undo can be performed.
+ */
+ boolean canUndo();
+
+ /**
+ * Undoes the last action on the undo stack.
+ *
+ * @throws CannotUndoException
+ * if the last action cannot be undone, or if there's nothing left to undo.
+ */
+ void undo() throws CannotUndoException;
+
+ /*
+ * Transaction Handling
+ */
+
+ /**
+ * Signals the start of a set of operations that should be considered a single unit for undo/redo purposes.
+ *
+ * <p>
+ * <b>It is <i>strongly</i> recommended to use the {@link #doWork(IRunnable)} method instead of manually
+ * implementing beginWork/endWork.</b>
+ * </p>
+ *
+ * <p>
+ * Each call to beginWork should be matched with a call to {@link #endWork(boolean)}. The following pattern can be
+ * used to enforce this rules even in the face of exceptions.
+ * </p>
+ *
+ * <pre>
+ * VexComponent c = ...;
+ * boolean success = false;
+ * try {
+ * c.beginWork();
+ * // do multiple inserts/deletes
+ * success = true;
+ * } finally {
+ * c.endWork(success);
+ * }
+ * </pre>
+ *
+ * <p>
+ * In the case of nested beginWork/endWork calls, only the outermost results in an undoable event.
+ * </p>
+ *
+ * @see endWork(boolean)
+ */
+ void beginWork();
+
+ /**
+ * Perform the runnable's run method within a beginWork/endWork pair. All operations in the runnable are treated as
+ * a single unit of work, and can be undone in one operation by the user. Also, if a later operation fails, all
+ * earlier operations are also undone.
+ *
+ * @param runnable
+ * Runnable implementing the work to be done.
+ */
+ void doWork(Runnable runnable);
+
+ /**
+ * Perform the runnable's run method within a beginWork/endWork pair. All operations in the runnable are treated as
+ * a single unit of work, and can be undone in one operation by the user. Also, if a later operation fails, all
+ * earlier operations are also undone.
+ *
+ * @param runnable
+ * Runnable implementing the work to be done.
+ * @param savePosition
+ * If true, the current caret position is saved and restored once the operation is complete.
+ */
+ void doWork(Runnable runnable, boolean savePosition);
+
+ /**
+ * Signals the end of a set of operations that should be treated as a single unit for undo/redo purposes.
+ *
+ * @param success
+ * If true, an edit is added to the undo stack. If false, all the changes since the matching beginWork
+ * call are undone.
+ *
+ * @see #beginWork()
+ */
+ void endWork(boolean success);
+
+ /**
+ * Execute a Runnable, restoring the caret position to its original position afterward.
+ *
+ * @param runnable
+ * Runnable to be invoked.
+ */
+ void savePosition(Runnable runnable);
+
+ /*
+ * Clipboard cut/copy/paste
+ */
+
+ /**
+ * Cuts the current selection to the clipboard.
+ */
+ void cutSelection();
+
+ /**
+ * Copy the current selection to the clipboard.
+ */
+ void copySelection();
+
+ /**
+ * Returns true if the clipboard has content that can be pasted. Used to enable/disable the paste action of a
+ * containing application.
+ */
+ boolean canPaste();
+
+ /**
+ * Paste the current clipboard contents into the document at the current caret position.
+ */
+ void paste() throws DocumentValidationException;
+
+ /**
+ * Returns true if the clipboard has plain text content that can be pasted. Used to enable/disable the "paste text"
+ * action of a containing application.
+ */
+ boolean canPasteText();
+
+ /**
+ * Paste the current clipboard contents as plain text into the document at the current caret position.
+ */
+ void pasteText() throws DocumentValidationException;
+
+ /*
+ * Caret and Selection
+ */
+
+ /**
+ * Return the offset into the document represented by the caret.
+ */
+ ContentPosition getCaretPosition();
+
+ /**
+ * Returns the element at the current caret offset.
+ */
+ IElement getCurrentElement();
+
+ /**
+ * Returns the node a the current caret offset.
+ */
+ INode getCurrentNode();
+
+ /**
+ * Returns the offset range in the content which is selected.
+ */
+ ContentRange getSelectedRange();
+
+ /**
+ * Returns the {@link ContentPositionRange} which is selected.
+ */
+ ContentPositionRange getSelectedPositionRange();
+
+ /**
+ * Returns the currently selected document fragment, or null if there is no current selection.
+ */
+ IDocumentFragment getSelectedFragment();
+
+ /**
+ * Returns the currently selected string, or an empty string if there is no current selection.
+ */
+ String getSelectedText();
+
+ /**
+ * Returns true if the user currently has some text selected.
+ */
+ boolean hasSelection();
+
+ /**
+ * Selects all content in the document.
+ */
+ void selectAll();
+
+ /**
+ * Selects the word at the current caret offset.
+ */
+ void selectWord();
+
+ /**
+ * Selects the content of the given node.
+ *
+ * @param node
+ * the node
+ */
+ void selectContentOf(INode node);
+
+ /**
+ * Selects the given node.
+ *
+ * @param node
+ * the node to select
+ */
+ void select(INode node);
+
+ /**
+ * @return true if the current selection can be deleted. Returns false if there is no selection.
+ */
+ boolean canDeleteSelection();
+
+ /**
+ * Delete the current selection. Does nothing if there is no current selection.
+ */
+ void deleteSelection();
+
+ /*
+ * Caret Movement
+ */
+
+ /**
+ * Moves the caret a given distance relative to the current caret offset.
+ *
+ * @param distance
+ * Amount by which to alter the caret offset. Positive values increase the caret offset.
+ */
+ void moveBy(int distance);
+
+ /**
+ * Moves the caret a given distance relative to the current caret offset.
+ *
+ * @param distance
+ * Amount by which to alter the caret offset. Positive values increase the caret offset.
+ * @param select
+ * if true, the current selection is extended to match the new caret offset
+ */
+ void moveBy(int distance, boolean select);
+
+ /**
+ * Moves the caret to a new offset. The selection is not extended. This is equivalent to
+ * <code>moveTo(offset, false)</code>.
+ *
+ * @param int
+ * new offset for the caret. The offset must be >= 1 and less than the document size; if not, it is
+ * silently ignored.
+ */
+ void moveTo(final ContentPosition position);
+
+ /**
+ * Moves the caret to the new offset, possibly changing the selection.
+ *
+ * @param int
+ * new offset for the caret. The offset must be >= 1 and less than the document size; if not, it is
+ * silently ignored.
+ * @param select
+ * if true, the current selection is extended to match the new caret offset.
+ */
+ void moveTo(final ContentPosition position, boolean select);
+
+ /**
+ * Move the caret to the end of the current line.
+ *
+ * @param select
+ * If true, the selection is extended.
+ */
+ void moveToLineEnd(boolean select);
+
+ /**
+ * Move the caret to the start of the current line.
+ *
+ * @param select
+ * If true, the selection is extended.
+ */
+ void moveToLineStart(boolean select);
+
+ /**
+ * Move the caret down to the next line. Attempts to preserve the same distance from the left edge of the control.
+ *
+ * @param select
+ * If true, the selection is extended.
+ */
+ void moveToNextLine(boolean select);
+
+ /**
+ * Move the caret down to the next page. Attempts to preserve the same distance from the left edge of the control.
+ *
+ * @param select
+ * If true, the selection is extended.
+ */
+ void moveToNextPage(boolean select);
+
+ /**
+ * Moves the caret to the end of the current or next word.
+ *
+ * @param select
+ * If true, the selection is extended.
+ */
+ void moveToNextWord(boolean select);
+
+ /**
+ * Moves the caret up to the previous line.
+ *
+ * @param select
+ * If true, the selection is extended
+ */
+ void moveToPreviousLine(boolean select);
+
+ /**
+ * Moves the caret up to the previous page.
+ *
+ * @param select
+ * If true, the selection is extended
+ */
+ void moveToPreviousPage(boolean select);
+
+ /**
+ * Moves the caret to the start of the current or previous word.
+ *
+ * @param select
+ * If true, the selection is extended.
+ */
+ void moveToPreviousWord(boolean select);
+
+ /*
+ * Namespaces
+ */
+
+ void declareNamespace(final String namespacePrefix, final String namespaceURI);
+
+ void removeNamespace(final String namespacePrefix);
+
+ void declareDefaultNamespace(final String namespaceURI);
+
+ void removeDefaultNamespace();
+
+ /*
+ * Attributes
+ */
+
+ /**
+ * @param attributeName
+ * local name of the attribute being changed.
+ * @param value
+ * New value for the attribute. If null, the attribute is removed from the element.
+ * @return true if the given value is valid for the attribute with the given name
+ */
+ boolean canSetAttribute(String attributeName, String value);
+
+ /**
+ * Sets the value of an attribute in the current element. Attributes set in this manner (as opposed to calling
+ * Element.setAttribute directly) will be subject to undo/redo.
+ *
+ * @param attributeName
+ * local name of the attribute being changed.
+ * @param value
+ * New value for the attribute. If null, the attribute is removed from the element.
+ */
+ void setAttribute(String attributeName, String value);
+
+ /**
+ * @param attributeName
+ * the local name of the attribute to remove
+ * @return true if it is valid to remove the attribute with the given name
+ */
+ boolean canRemoveAttribute(String attributeName);
+
+ /**
+ * Removes an attribute from the current element. Attributes removed in this manner (as opposed to calling
+ * Element.setAttribute directly) will be subject to undo/redo.
+ *
+ * @param attributeName
+ * local name of the attribute to remove.
+ */
+ void removeAttribute(String attributeName);
+
+ /*
+ * Content
+ */
+
+ /**
+ * Returns true if text can be inserted at the current position.
+ */
+ boolean canInsertText();
+
+ /**
+ * Inserts the given character at the current caret position. Any selected content is deleted. The main difference
+ * between this method and insertText is that this method does not use beginWork/endWork, so consecutive calls to
+ * insertChar are collapsed into a single IUndoableEdit. This method should normally only be called in response to a
+ * user typing a key.
+ *
+ * @param c
+ * Character to insert.
+ */
+ void insertChar(char c) throws DocumentValidationException;
+
+ /**
+ * Deletes the character to the right of the caret.
+ */
+ void deleteNextChar() throws DocumentValidationException;
+
+ /**
+ * Deletes the character to the left of the caret.
+ */
+ void deletePreviousChar() throws DocumentValidationException;
+
+ /**
+ * Inserts the given text at the current caret position. Any selected content is first deleted.
+ *
+ * @param text
+ * String to insert.
+ */
+ void insertText(String text) throws DocumentValidationException;
+
+ /*
+ * Structure
+ */
+
+ /**
+ * Returns an array of names of elements that are valid to insert at the given caret offset and selection
+ */
+ ElementName[] getValidInsertElements();
+
+ /**
+ * Returns an array of names of elements to which the element at the current caret location can be morphed.
+ */
+ ElementName[] getValidMorphElements();
+
+ /**
+ * @param elementName
+ * the qualified name of the element to insert
+ * @return true if an element with the given name can be inserted at the current caret position/instead of the
+ * current selection
+ */
+ boolean canInsertElement(QualifiedName elementName);
+
+ /**
+ * Inserts the given element at the current caret position. Any selected content becomes the new contents of the
+ * element.
+ *
+ * @param elementName
+ * Qualified name of the element to insert.
+ * @return the newly inserted element
+ */
+ IElement insertElement(QualifiedName elementName) throws DocumentValidationException;
+
+ /**
+ * @return true if a comment can be inserted at the current caret position/instead of the current selection
+ */
+ boolean canInsertComment();
+
+ /**
+ * Inserts a comment a the current caret position. Any selected content is first deleted.
+ *
+ * @return the new comment
+ */
+ IComment insertComment() throws DocumentValidationException;
+
+ /**
+ * @return true if a processing instruction can be inserted at the current caret position/instead of the current
+ * selection
+ */
+ boolean canInsertProcessingInstruction();
+
+ /**
+ * Inserts a processing instruction at the current caret position. Any selected content is first deleted.
+ *
+ * @return the new comment
+ */
+ IProcessingInstruction insertProcessingInstruction(final String target) throws CannotApplyException, ReadOnlyException;
+
+ /**
+ * Edits the processing instruction at the current caret position. Updates target and data with the given Strings.
+ *
+ * @param target
+ * The target to set. may be null to keep the old target.
+ * @param data
+ * The data to set. May be null to keep the old value.
+ */
+ void editProcessingInstruction(final String target, final String data) throws CannotApplyException, ReadOnlyException;
+
+ /**
+ * Inserts the given XML fragment at the current caret position. Any selected content is first deleted.
+ *
+ * @param xml
+ * XML to insert
+ * @throws DocumentValidationException
+ */
+ public void insertXML(String xml) throws DocumentValidationException;
+
+ /**
+ * Returns true if the given fragment can be inserted at the current caret position.
+ *
+ * @param fragment
+ * DocumentFragment to be inserted.
+ */
+ boolean canInsertFragment(final IDocumentFragment fragment);
+
+ /**
+ * Inserts the given document fragment at the current caret position. Any selected content is deleted.
+ *
+ * @param frag
+ * DocumentFragment to insert.
+ */
+ void insertFragment(IDocumentFragment frag) throws DocumentValidationException;
+
+ /**
+ * Returns true if the current element can be unwrapped, i.e. replaced with its content.
+ */
+ boolean canUnwrap();
+
+ void unwrap() throws DocumentValidationException;
+
+ /**
+ * Indicates whether the current element can be morphed into the given element.
+ *
+ * @param elementName
+ * Qualified name of the element to morph the current element into.
+ * @return true if the current element can be morphed
+ */
+ boolean canMorph(QualifiedName elementName);
+
+ /**
+ * Replaces the current element with an element with the given name. The content of the element is preserved.
+ *
+ * @param elementName
+ * Qualified name of the element to replace the current element with.
+ * @throws DocumentValidationException
+ * if the given element is not valid at this place in the document, or if the current element's content
+ * is not compatible with the given element.
+ */
+ void morph(QualifiedName elementName) throws DocumentValidationException;
+
+ /**
+ * Indiciates whether the caret is at a position between adjacent nodes that can be joined.
+ *
+ * @return true if the nodes adjacent to the caret can be joined
+ */
+ boolean canJoin();
+
+ /**
+ * Joins the nodes adjacent to the caret.
+ *
+ * @throws DocumentValidationException
+ */
+ void join() throws DocumentValidationException;
+
+ /**
+ * Indicates whether the current element can be splitted into two elements at the current caret position.
+ *
+ * @return true if the current element can be splitted
+ */
+ boolean canSplit();
+
+ /**
+ * Splits the element at the current caret offset.
+ */
+ void split() throws DocumentValidationException;
+
+}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/IVexWidget.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/IVexWidget.java
index f52936e5..bb2f0dc1 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/IVexWidget.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/IVexWidget.java
@@ -11,39 +11,22 @@
*******************************************************************************/
package org.eclipse.vex.core.internal.widget;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.vex.core.internal.core.ElementName;
import org.eclipse.vex.core.internal.css.IWhitespacePolicy;
import org.eclipse.vex.core.internal.css.StyleSheet;
-import org.eclipse.vex.core.internal.undo.CannotApplyException;
-import org.eclipse.vex.core.internal.undo.CannotUndoException;
import org.eclipse.vex.core.provisional.dom.ContentPosition;
-import org.eclipse.vex.core.provisional.dom.ContentPositionRange;
-import org.eclipse.vex.core.provisional.dom.ContentRange;
-import org.eclipse.vex.core.provisional.dom.DocumentValidationException;
-import org.eclipse.vex.core.provisional.dom.IComment;
import org.eclipse.vex.core.provisional.dom.IDocument;
-import org.eclipse.vex.core.provisional.dom.IDocumentFragment;
-import org.eclipse.vex.core.provisional.dom.IElement;
-import org.eclipse.vex.core.provisional.dom.INode;
-import org.eclipse.vex.core.provisional.dom.IProcessingInstruction;
/**
* Methods implemented by implementations of the Vex widget on all platforms. This interface is more important as a
* place to gather common Javadoc than as a way to enforce a contract.
*/
-public interface IVexWidget {
+public interface IVexWidget extends IDocumentEditor {
/*
* Configuration
*/
/**
- * Returns the document associated with this component.
- */
- IDocument getDocument();
-
- /**
* Sets a new document for this control.
*
* @param document
@@ -68,18 +51,9 @@ public interface IVexWidget {
*/
void setStyleSheet(StyleSheet styleSheet);
- /**
- * @return true if this widget is read-only
- */
- boolean isReadOnly();
+ public void setWhitespacePolicy(IWhitespacePolicy whitespacePolicy);
- /**
- * Make this widget read-only.
- *
- * @param readOnly
- * set to true if this widget should be read-only
- */
- void setReadOnly(boolean readOnly);
+ public IWhitespacePolicy getWhitespacePolicy();
/**
* Returns the value of the debugging flag.
@@ -119,564 +93,4 @@ public interface IVexWidget {
*/
ContentPosition viewToModel(int x, int y);
- /*
- * Undo/Redo
- */
-
- /**
- * Returns true if a redo can be performed.
- */
- boolean canRedo();
-
- /**
- * Redoes the last action on the redo stack.
- *
- * @throws CannotApplyException
- * if the last action cannot be re-done, or if there is nothing to redo.
- */
- void redo() throws CannotApplyException;
-
- /**
- * Returns true if an undo can be performed.
- */
- boolean canUndo();
-
- /**
- * Undoes the last action on the undo stack.
- *
- * @throws CannotUndoException
- * if the last action cannot be undone, or if there's nothing left to undo.
- */
- void undo() throws CannotUndoException;
-
- /*
- * Transaction Handling
- */
-
- /**
- * Signals the start of a set of operations that should be considered a single unit for undo/redo purposes.
- *
- * <p>
- * <b>It is <i>strongly</i> recommended to use the {@link #doWork(IRunnable)} method instead of manually
- * implementing beginWork/endWork.</b>
- * </p>
- *
- * <p>
- * Each call to beginWork should be matched with a call to {@link #endWork(boolean)}. The following pattern can be
- * used to enforce this rules even in the face of exceptions.
- * </p>
- *
- * <pre>
- * VexComponent c = ...;
- * boolean success = false;
- * try {
- * c.beginWork();
- * // do multiple inserts/deletes
- * success = true;
- * } finally {
- * c.endWork(success);
- * }
- * </pre>
- *
- * <p>
- * In the case of nested beginWork/endWork calls, only the outermost results in an undoable event.
- * </p>
- *
- * @see endWork(boolean)
- */
- void beginWork();
-
- /**
- * Perform the runnable's run method within a beginWork/endWork pair. All operations in the runnable are treated as
- * a single unit of work, and can be undone in one operation by the user. Also, if a later operation fails, all
- * earlier operations are also undone.
- *
- * @param runnable
- * Runnable implementing the work to be done.
- */
- void doWork(Runnable runnable);
-
- /**
- * Perform the runnable's run method within a beginWork/endWork pair. All operations in the runnable are treated as
- * a single unit of work, and can be undone in one operation by the user. Also, if a later operation fails, all
- * earlier operations are also undone.
- *
- * @param runnable
- * Runnable implementing the work to be done.
- * @param savePosition
- * If true, the current caret position is saved and restored once the operation is complete.
- */
- void doWork(Runnable runnable, boolean savePosition);
-
- /**
- * Signals the end of a set of operations that should be treated as a single unit for undo/redo purposes.
- *
- * @param success
- * If true, an edit is added to the undo stack. If false, all the changes since the matching beginWork
- * call are undone.
- *
- * @see #beginWork()
- */
- void endWork(boolean success);
-
- /**
- * Execute a Runnable, restoring the caret position to its original position afterward.
- *
- * @param runnable
- * Runnable to be invoked.
- */
- void savePosition(Runnable runnable);
-
- /*
- * Clipboard cut/copy/paste
- */
-
- /**
- * Cuts the current selection to the clipboard.
- */
- void cutSelection();
-
- /**
- * Copy the current selection to the clipboard.
- */
- void copySelection();
-
- /**
- * Returns true if the clipboard has content that can be pasted. Used to enable/disable the paste action of a
- * containing application.
- */
- boolean canPaste();
-
- /**
- * Paste the current clipboard contents into the document at the current caret position.
- */
- void paste() throws DocumentValidationException;
-
- /**
- * Returns true if the clipboard has plain text content that can be pasted. Used to enable/disable the "paste text"
- * action of a containing application.
- */
- boolean canPasteText();
-
- /**
- * Paste the current clipboard contents as plain text into the document at the current caret position.
- */
- void pasteText() throws DocumentValidationException;
-
- /*
- * Caret and Selection
- */
-
- /**
- * Return the offset into the document represented by the caret.
- */
- ContentPosition getCaretPosition();
-
- /**
- * Returns the element at the current caret offset.
- */
- IElement getCurrentElement();
-
- /**
- * Returns the node a the current caret offset.
- */
- INode getCurrentNode();
-
- /**
- * Returns the offset range in the content which is selected.
- */
- ContentRange getSelectedRange();
-
- /**
- * Returns the {@link ContentPositionRange} which is selected.
- */
- ContentPositionRange getSelectedPositionRange();
-
- /**
- * Returns the currently selected document fragment, or null if there is no current selection.
- */
- IDocumentFragment getSelectedFragment();
-
- /**
- * Returns the currently selected string, or an empty string if there is no current selection.
- */
- String getSelectedText();
-
- /**
- * Returns true if the user currently has some text selected.
- */
- boolean hasSelection();
-
- /**
- * Selects all content in the document.
- */
- void selectAll();
-
- /**
- * Selects the word at the current caret offset.
- */
- void selectWord();
-
- /**
- * Selects the content of the given node.
- *
- * @param node
- * the node
- */
- void selectContentOf(INode node);
-
- /**
- * Selects the given node.
- *
- * @param node
- * the node to select
- */
- void select(INode node);
-
- /**
- * @return true if the current selection can be deleted. Returns false if there is no selection.
- */
- boolean canDeleteSelection();
-
- /**
- * Delete the current selection. Does nothing if there is no current selection.
- */
- void deleteSelection();
-
- /*
- * Caret Movement
- */
-
- /**
- * Moves the caret a given distance relative to the current caret offset.
- *
- * @param distance
- * Amount by which to alter the caret offset. Positive values increase the caret offset.
- */
- void moveBy(int distance);
-
- /**
- * Moves the caret a given distance relative to the current caret offset.
- *
- * @param distance
- * Amount by which to alter the caret offset. Positive values increase the caret offset.
- * @param select
- * if true, the current selection is extended to match the new caret offset
- */
- void moveBy(int distance, boolean select);
-
- /**
- * Moves the caret to a new offset. The selection is not extended. This is equivalent to
- * <code>moveTo(offset, false)</code>.
- *
- * @param int
- * new offset for the caret. The offset must be >= 1 and less than the document size; if not, it is
- * silently ignored.
- */
- void moveTo(final ContentPosition position);
-
- /**
- * Moves the caret to the new offset, possibly changing the selection.
- *
- * @param int
- * new offset for the caret. The offset must be >= 1 and less than the document size; if not, it is
- * silently ignored.
- * @param select
- * if true, the current selection is extended to match the new caret offset.
- */
- void moveTo(final ContentPosition position, boolean select);
-
- /**
- * Move the caret to the end of the current line.
- *
- * @param select
- * If true, the selection is extended.
- */
- void moveToLineEnd(boolean select);
-
- /**
- * Move the caret to the start of the current line.
- *
- * @param select
- * If true, the selection is extended.
- */
- void moveToLineStart(boolean select);
-
- /**
- * Move the caret down to the next line. Attempts to preserve the same distance from the left edge of the control.
- *
- * @param select
- * If true, the selection is extended.
- */
- void moveToNextLine(boolean select);
-
- /**
- * Move the caret down to the next page. Attempts to preserve the same distance from the left edge of the control.
- *
- * @param select
- * If true, the selection is extended.
- */
- void moveToNextPage(boolean select);
-
- /**
- * Moves the caret to the end of the current or next word.
- *
- * @param select
- * If true, the selection is extended.
- */
- void moveToNextWord(boolean select);
-
- /**
- * Moves the caret up to the previous line.
- *
- * @param select
- * If true, the selection is extended
- */
- void moveToPreviousLine(boolean select);
-
- /**
- * Moves the caret up to the previous page.
- *
- * @param select
- * If true, the selection is extended
- */
- void moveToPreviousPage(boolean select);
-
- /**
- * Moves the caret to the start of the current or previous word.
- *
- * @param select
- * If true, the selection is extended.
- */
- void moveToPreviousWord(boolean select);
-
- /*
- * Namespaces
- */
-
- void declareNamespace(final String namespacePrefix, final String namespaceURI);
-
- void removeNamespace(final String namespacePrefix);
-
- void declareDefaultNamespace(final String namespaceURI);
-
- void removeDefaultNamespace();
-
- /*
- * Attributes
- */
-
- /**
- * @param attributeName
- * local name of the attribute being changed.
- * @param value
- * New value for the attribute. If null, the attribute is removed from the element.
- * @return true if the given value is valid for the attribute with the given name
- */
- boolean canSetAttribute(String attributeName, String value);
-
- /**
- * Sets the value of an attribute in the current element. Attributes set in this manner (as opposed to calling
- * Element.setAttribute directly) will be subject to undo/redo.
- *
- * @param attributeName
- * local name of the attribute being changed.
- * @param value
- * New value for the attribute. If null, the attribute is removed from the element.
- */
- void setAttribute(String attributeName, String value);
-
- /**
- * @param attributeName
- * the local name of the attribute to remove
- * @return true if it is valid to remove the attribute with the given name
- */
- boolean canRemoveAttribute(String attributeName);
-
- /**
- * Removes an attribute from the current element. Attributes removed in this manner (as opposed to calling
- * Element.setAttribute directly) will be subject to undo/redo.
- *
- * @param attributeName
- * local name of the attribute to remove.
- */
- void removeAttribute(String attributeName);
-
- /*
- * Content
- */
-
- /**
- * Returns true if text can be inserted at the current position.
- */
- boolean canInsertText();
-
- /**
- * Inserts the given character at the current caret position. Any selected content is deleted. The main difference
- * between this method and insertText is that this method does not use beginWork/endWork, so consecutive calls to
- * insertChar are collapsed into a single IUndoableEdit. This method should normally only be called in response to a
- * user typing a key.
- *
- * @param c
- * Character to insert.
- */
- void insertChar(char c) throws DocumentValidationException;
-
- /**
- * Deletes the character to the right of the caret.
- */
- void deleteNextChar() throws DocumentValidationException;
-
- /**
- * Deletes the character to the left of the caret.
- */
- void deletePreviousChar() throws DocumentValidationException;
-
- /**
- * Inserts the given text at the current caret position. Any selected content is first deleted.
- *
- * @param text
- * String to insert.
- */
- void insertText(String text) throws DocumentValidationException;
-
- /*
- * Structure
- */
-
- /**
- * Returns an array of names of elements that are valid to insert at the given caret offset and selection
- */
- ElementName[] getValidInsertElements();
-
- /**
- * Returns an array of names of elements to which the element at the current caret location can be morphed.
- */
- ElementName[] getValidMorphElements();
-
- /**
- * @param elementName
- * the qualified name of the element to insert
- * @return true if an element with the given name can be inserted at the current caret position/instead of the
- * current selection
- */
- boolean canInsertElement(QualifiedName elementName);
-
- /**
- * Inserts the given element at the current caret position. Any selected content becomes the new contents of the
- * element.
- *
- * @param elementName
- * Qualified name of the element to insert.
- * @return the newly inserted element
- */
- IElement insertElement(QualifiedName elementName) throws DocumentValidationException;
-
- /**
- * @return true if a comment can be inserted at the current caret position/instead of the current selection
- */
- boolean canInsertComment();
-
- /**
- * Inserts a comment a the current caret position. Any selected content is first deleted.
- *
- * @return the new comment
- */
- IComment insertComment() throws DocumentValidationException;
-
- /**
- * @return true if a processing instruction can be inserted at the current caret position/instead of the current
- * selection
- */
- boolean canInsertProcessingInstruction();
-
- /**
- * Inserts a processing instruction at the current caret position. Any selected content is first deleted.
- *
- * @return the new comment
- */
- IProcessingInstruction insertProcessingInstruction(final String target) throws CannotApplyException, ReadOnlyException;
-
- /**
- * Edits the processing instruction at the current caret position. Updates target and data with the given Strings.
- *
- * @param target
- * The target to set. may be null to keep the old target.
- * @param data
- * The data to set. May be null to keep the old value.
- */
- void editProcessingInstruction(final String target, final String data) throws CannotApplyException, ReadOnlyException;
-
- /**
- * Inserts the given XML fragment at the current caret position. Any selected content is first deleted.
- *
- * @param xml
- * XML to insert
- * @throws DocumentValidationException
- */
- public void insertXML(String xml) throws DocumentValidationException;
-
- /**
- * Returns true if the given fragment can be inserted at the current caret position.
- *
- * @param fragment
- * DocumentFragment to be inserted.
- */
- boolean canInsertFragment(final IDocumentFragment fragment);
-
- /**
- * Inserts the given document fragment at the current caret position. Any selected content is deleted.
- *
- * @param frag
- * DocumentFragment to insert.
- */
- void insertFragment(IDocumentFragment frag) throws DocumentValidationException;
-
- /**
- * Returns true if the current element can be unwrapped, i.e. replaced with its content.
- */
- boolean canUnwrap();
-
- void unwrap() throws DocumentValidationException;
-
- /**
- * Indicates whether the current element can be morphed into the given element.
- *
- * @param elementName
- * Qualified name of the element to morph the current element into.
- * @return true if the current element can be morphed
- */
- boolean canMorph(QualifiedName elementName);
-
- /**
- * Replaces the current element with an element with the given name. The content of the element is preserved.
- *
- * @param elementName
- * Qualified name of the element to replace the current element with.
- * @throws DocumentValidationException
- * if the given element is not valid at this place in the document, or if the current element's content
- * is not compatible with the given element.
- */
- void morph(QualifiedName elementName) throws DocumentValidationException;
-
- boolean canJoin();
-
- void join() throws DocumentValidationException;
-
- public void setWhitespacePolicy(IWhitespacePolicy whitespacePolicy);
-
- public IWhitespacePolicy getWhitespacePolicy();
-
- /**
- * Indicates whether the current element can be splitted into two elements at the current caret position.
- *
- * @return true if the current element can be splitted
- */
- boolean canSplit();
-
- /**
- * Split the element at the current caret offset. This is the normal behaviour when the user presses Enter.
- */
- void split() throws DocumentValidationException;
-
}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/VexWidget.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/VexWidget.java
index f324a252..c01ba9eb 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/VexWidget.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/VexWidget.java
@@ -66,6 +66,7 @@ import org.eclipse.vex.core.internal.css.IWhitespacePolicy;
import org.eclipse.vex.core.internal.css.StyleSheet;
import org.eclipse.vex.core.internal.io.XMLFragment;
import org.eclipse.vex.core.internal.widget.BaseVexWidget;
+import org.eclipse.vex.core.internal.widget.IDocumentEditor;
import org.eclipse.vex.core.internal.widget.IHostComponent;
import org.eclipse.vex.core.internal.widget.IVexWidget;
import org.eclipse.vex.core.internal.widget.ReadOnlyException;
@@ -155,9 +156,6 @@ public class VexWidget extends Canvas implements IVexWidget, ISelectionProvider
return false;
}
- /**
- * @see org.eclipse.vex.core.internal.widget.IVexWidget#canPasteText()
- */
@Override
public boolean canPasteText() {
// TODO Auto-generated method stub
@@ -562,6 +560,11 @@ public class VexWidget extends Canvas implements IVexWidget, ISelectionProvider
}
@Override
+ public void setDocument(final IDocument document) {
+ impl.setDocument(document);
+ }
+
+ @Override
public void setLayoutWidth(final int width) {
impl.setLayoutWidth(width);
}
@@ -778,7 +781,7 @@ public class VexWidget extends Canvas implements IVexWidget, ISelectionProvider
runEx(widget);
}
- public abstract void runEx(IVexWidget w) throws ExecutionException;
+ public abstract void runEx(IDocumentEditor editor) throws ExecutionException;
}
@@ -901,83 +904,83 @@ public class VexWidget extends Canvas implements IVexWidget, ISelectionProvider
// arrows: (Shift) Up/Down, {-, Shift, Ctrl, Shift+Ctrl} + Left/Right
addKey(CHAR_NONE, SWT.ARROW_DOWN, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToNextLine(false);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToNextLine(false);
}
});
addKey(CHAR_NONE, SWT.ARROW_DOWN, SWT.SHIFT, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToNextLine(true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToNextLine(true);
}
});
addKey(CHAR_NONE, SWT.ARROW_UP, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToPreviousLine(false);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToPreviousLine(false);
}
});
addKey(CHAR_NONE, SWT.ARROW_UP, SWT.SHIFT, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToPreviousLine(true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToPreviousLine(true);
}
});
addKey(CHAR_NONE, SWT.ARROW_LEFT, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveBy(-1);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveBy(-1);
}
});
addKey(CHAR_NONE, SWT.ARROW_LEFT, SWT.SHIFT, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveBy(-1, true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveBy(-1, true);
}
});
addKey(CHAR_NONE, SWT.ARROW_LEFT, SWT.CONTROL, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToPreviousWord(false);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToPreviousWord(false);
}
});
addKey(CHAR_NONE, SWT.ARROW_LEFT, SWT.SHIFT | SWT.CONTROL, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToPreviousWord(true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToPreviousWord(true);
}
});
addKey(CHAR_NONE, SWT.ARROW_RIGHT, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveBy(+1);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveBy(+1);
}
});
addKey(CHAR_NONE, SWT.ARROW_RIGHT, SWT.SHIFT, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveBy(+1, true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveBy(+1, true);
}
});
addKey(CHAR_NONE, SWT.ARROW_RIGHT, SWT.CONTROL, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToNextWord(false);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToNextWord(false);
}
});
addKey(CHAR_NONE, SWT.ARROW_RIGHT, SWT.SHIFT | SWT.CONTROL, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToNextWord(true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToNextWord(true);
}
});
// Delete/Backspace
addKey(SWT.BS, SWT.BS, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) throws ExecutionException {
+ public void runEx(final IDocumentEditor editor) throws ExecutionException {
try {
- w.deletePreviousChar();
+ editor.deletePreviousChar();
} catch (final DocumentValidationException e) {
throw new ExecutionException(e.getMessage(), e);
}
@@ -985,9 +988,9 @@ public class VexWidget extends Canvas implements IVexWidget, ISelectionProvider
});
addKey(SWT.DEL, SWT.DEL, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) throws ExecutionException {
+ public void runEx(final IDocumentEditor editor) throws ExecutionException {
try {
- w.deleteNextChar();
+ editor.deleteNextChar();
} catch (final DocumentValidationException e) {
throw new ExecutionException(e.getMessage(), e);
}
@@ -997,76 +1000,76 @@ public class VexWidget extends Canvas implements IVexWidget, ISelectionProvider
// {-, Shift, Ctrl, Shift+Ctrl} + Home/End
addKey(CHAR_NONE, SWT.END, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToLineEnd(false);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToLineEnd(false);
}
});
addKey(CHAR_NONE, SWT.END, SWT.SHIFT, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToLineEnd(true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToLineEnd(true);
}
});
addKey(CHAR_NONE, SWT.END, SWT.CONTROL, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveTo(w.getDocument().getEndPosition().moveBy(-1));
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveTo(editor.getDocument().getEndPosition().moveBy(-1));
}
});
addKey(CHAR_NONE, SWT.END, SWT.SHIFT | SWT.CONTROL, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveTo(w.getDocument().getEndPosition().moveBy(-1));
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveTo(editor.getDocument().getEndPosition().moveBy(-1));
}
});
addKey(CHAR_NONE, SWT.HOME, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToLineStart(false);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToLineStart(false);
}
});
addKey(CHAR_NONE, SWT.HOME, SWT.SHIFT, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToLineStart(true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToLineStart(true);
}
});
addKey(CHAR_NONE, SWT.HOME, SWT.CONTROL, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveTo(w.getDocument().getStartPosition().moveBy(1));
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveTo(editor.getDocument().getStartPosition().moveBy(1));
}
});
addKey(CHAR_NONE, SWT.HOME, SWT.SHIFT | SWT.CONTROL, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveTo(w.getDocument().getStartPosition().moveBy(1), true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveTo(editor.getDocument().getStartPosition().moveBy(1), true);
}
});
// (Shift) Page Up/Down
addKey(CHAR_NONE, SWT.PAGE_DOWN, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToNextPage(false);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToNextPage(false);
}
});
addKey(CHAR_NONE, SWT.PAGE_DOWN, SWT.SHIFT, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToNextPage(true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToNextPage(true);
}
});
addKey(CHAR_NONE, SWT.PAGE_UP, SWT.NONE, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToPreviousPage(false);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToPreviousPage(false);
}
});
addKey(CHAR_NONE, SWT.PAGE_UP, SWT.SHIFT, new Action() {
@Override
- public void runEx(final IVexWidget w) {
- w.moveToPreviousPage(true);
+ public void runEx(final IDocumentEditor editor) {
+ editor.moveToPreviousPage(true);
}
});
}
diff --git a/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/namespace/tests/EditNamespacesControllerTest.java b/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/namespace/tests/EditNamespacesControllerTest.java
index f8ddc958..d497a7b2 100644
--- a/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/namespace/tests/EditNamespacesControllerTest.java
+++ b/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/namespace/tests/EditNamespacesControllerTest.java
@@ -1,173 +1,172 @@
-/*******************************************************************************
- * Copyright (c) 2011 Florian Thienel and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Florian Thienel - initial API and implementation
- *******************************************************************************/
-package org.eclipse.vex.ui.internal.namespace.tests;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.vex.core.internal.css.StyleSheet;
-import org.eclipse.vex.core.internal.dom.Document;
-import org.eclipse.vex.core.internal.widget.BaseVexWidget;
-import org.eclipse.vex.core.internal.widget.IVexWidget;
-import org.eclipse.vex.core.internal.widget.MockHostComponent;
-import org.eclipse.vex.core.provisional.dom.IElement;
-import org.eclipse.vex.ui.internal.namespace.EditNamespacesController;
-import org.eclipse.vex.ui.internal.namespace.EditableNamespaceDefinition;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * @author Florian Thienel
- */
-public class EditNamespacesControllerTest {
-
- private IVexWidget widget;
-
- @Before
- public void setUp() throws Exception {
- widget = new BaseVexWidget(new MockHostComponent());
- widget.setDocument(new Document(new QualifiedName(null, "root")), StyleSheet.NULL);
- }
-
- @Test
- public void populateFromElement() throws Exception {
- final IElement element = widget.insertElement(new QualifiedName("http://namespace/uri/default", "element"));
- element.declareDefaultNamespace("http://namespace/uri/default");
- element.declareNamespace("ns1", "http://namespace/uri/1");
- element.declareNamespace("ns2", "http://namespace/uri/2");
- final EditNamespacesController controller = new EditNamespacesController(widget);
-
- assertEquals("http://namespace/uri/default", controller.getDefaultNamespaceURI());
-
- final List<EditableNamespaceDefinition> namespaces = controller.getNamespaceDefinitions();
- assertEquals(2, namespaces.size());
- assertContainsNamespaceDefinition(new EditableNamespaceDefinition("ns1", "http://namespace/uri/1"), namespaces);
- assertContainsNamespaceDefinition(new EditableNamespaceDefinition("ns2", "http://namespace/uri/2"), namespaces);
- }
-
- @Test
- public void defaultNamespaceNotNull() throws Exception {
- final EditNamespacesController controller = new EditNamespacesController(widget);
- assertNotNull(controller.getDefaultNamespaceURI());
- }
-
- @Test
- public void editDefaultNamespace() throws Exception {
- final IElement element = widget.insertElement(new QualifiedName(null, "element"));
- final EditNamespacesController controller = new EditNamespacesController(widget);
- controller.setDefaultNamespaceURI("http://namespace/uri/default");
- assertEquals("http://namespace/uri/default", controller.getDefaultNamespaceURI());
- assertNull(element.getDeclaredDefaultNamespaceURI());
-
- controller.applyToElement();
- assertEquals("http://namespace/uri/default", element.getDefaultNamespaceURI());
- assertNull(element.getQualifiedName().getQualifier());
- }
-
- @Test
- public void removeDefaultNamespace() throws Exception {
- final IElement element = widget.insertElement(new QualifiedName("http://namespace/uri/default", "element"));
- element.declareDefaultNamespace("http://namespace/uri/default");
- final EditNamespacesController controller = new EditNamespacesController(widget);
-
- controller.setDefaultNamespaceURI("");
- controller.applyToElement();
- assertNull(element.getDeclaredDefaultNamespaceURI());
- assertEquals("http://namespace/uri/default", element.getQualifiedName().getQualifier());
- }
-
- @Test
- public void addNamespaceDefinition() throws Exception {
- final IElement element = widget.insertElement(new QualifiedName(null, "element"));
- final EditNamespacesController controller = new EditNamespacesController(widget);
-
- assertTrue(controller.getNamespaceDefinitions().isEmpty());
- assertTrue(element.getDeclaredNamespacePrefixes().isEmpty());
-
- final EditableNamespaceDefinition newDefinition = controller.addNamespaceDefinition();
- assertNotNull(newDefinition);
-
- assertEquals(1, controller.getNamespaceDefinitions().size());
- assertSame(newDefinition, controller.getNamespaceDefinitions().get(0));
- assertTrue(element.getDeclaredNamespacePrefixes().isEmpty());
-
- newDefinition.setPrefix("ns1");
- newDefinition.setUri("http://namespace/uri/1");
-
- controller.applyToElement();
- assertEquals(1, element.getDeclaredNamespacePrefixes().size());
- }
-
- @Test
- public void removeNamespaceDefinition() throws Exception {
- final IElement element = widget.insertElement(new QualifiedName(null, "element"));
- element.declareNamespace("ns1", "http://namespace/uri/1");
- final EditNamespacesController controller = new EditNamespacesController(widget);
-
- controller.removeNamespaceDefinition(controller.getNamespaceDefinitions().get(0));
-
- assertTrue(controller.getNamespaceDefinitions().isEmpty());
- assertTrue(element.getDeclaredNamespacePrefixes().contains("ns1"));
-
- controller.applyToElement();
- assertTrue(element.getDeclaredNamespacePrefixes().isEmpty());
- }
-
- @Test
- public void editNamespacePrefix() throws Exception {
- final IElement element = widget.insertElement(new QualifiedName(null, "element"));
- element.declareNamespace("ns1", "http://namespace/uri/1");
- final EditNamespacesController controller = new EditNamespacesController(widget);
- final EditableNamespaceDefinition definition = controller.getNamespaceDefinitions().get(0);
-
- definition.setPrefix("ns2");
- assertTrue(element.getDeclaredNamespacePrefixes().contains("ns1"));
- assertEquals(1, element.getDeclaredNamespacePrefixes().size());
-
- controller.applyToElement();
- assertFalse(element.getDeclaredNamespacePrefixes().contains("ns1"));
- assertTrue(element.getDeclaredNamespacePrefixes().contains("ns2"));
- assertEquals(1, element.getDeclaredNamespacePrefixes().size());
- }
-
- @Test
- public void editNamespaceUri() throws Exception {
- final IElement element = widget.insertElement(new QualifiedName(null, "element"));
- element.declareNamespace("ns1", "http://namespace/uri/1");
- final EditNamespacesController controller = new EditNamespacesController(widget);
- final EditableNamespaceDefinition definition = controller.getNamespaceDefinitions().get(0);
-
- definition.setUri("http://namespace/uri/2");
- assertEquals("http://namespace/uri/1", element.getNamespaceURI("ns1"));
-
- controller.applyToElement();
- assertEquals("http://namespace/uri/2", element.getNamespaceURI("ns1"));
- assertEquals(1, element.getDeclaredNamespacePrefixes().size());
- }
-
- private static void assertContainsNamespaceDefinition(final EditableNamespaceDefinition expected, final List<EditableNamespaceDefinition> actualList) {
- for (final EditableNamespaceDefinition definition : actualList) {
- if (expected.getPrefix().equals(definition.getPrefix()) && expected.getUri().equals(definition.getUri())) {
- return;
- }
- }
- fail("namespace definition not found: " + expected.getPrefix() + "=" + expected.getUri());
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2011 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.ui.internal.namespace.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.vex.core.internal.dom.Document;
+import org.eclipse.vex.core.internal.widget.BaseVexWidget;
+import org.eclipse.vex.core.internal.widget.IDocumentEditor;
+import org.eclipse.vex.core.internal.widget.MockHostComponent;
+import org.eclipse.vex.core.provisional.dom.IElement;
+import org.eclipse.vex.ui.internal.namespace.EditNamespacesController;
+import org.eclipse.vex.ui.internal.namespace.EditableNamespaceDefinition;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Florian Thienel
+ */
+public class EditNamespacesControllerTest {
+
+ private IDocumentEditor editor;
+
+ @Before
+ public void setUp() throws Exception {
+ editor = new BaseVexWidget(new MockHostComponent());
+ editor.setDocument(new Document(new QualifiedName(null, "root")));
+ }
+
+ @Test
+ public void populateFromElement() throws Exception {
+ final IElement element = editor.insertElement(new QualifiedName("http://namespace/uri/default", "element"));
+ element.declareDefaultNamespace("http://namespace/uri/default");
+ element.declareNamespace("ns1", "http://namespace/uri/1");
+ element.declareNamespace("ns2", "http://namespace/uri/2");
+ final EditNamespacesController controller = new EditNamespacesController(editor);
+
+ assertEquals("http://namespace/uri/default", controller.getDefaultNamespaceURI());
+
+ final List<EditableNamespaceDefinition> namespaces = controller.getNamespaceDefinitions();
+ assertEquals(2, namespaces.size());
+ assertContainsNamespaceDefinition(new EditableNamespaceDefinition("ns1", "http://namespace/uri/1"), namespaces);
+ assertContainsNamespaceDefinition(new EditableNamespaceDefinition("ns2", "http://namespace/uri/2"), namespaces);
+ }
+
+ @Test
+ public void defaultNamespaceNotNull() throws Exception {
+ final EditNamespacesController controller = new EditNamespacesController(editor);
+ assertNotNull(controller.getDefaultNamespaceURI());
+ }
+
+ @Test
+ public void editDefaultNamespace() throws Exception {
+ final IElement element = editor.insertElement(new QualifiedName(null, "element"));
+ final EditNamespacesController controller = new EditNamespacesController(editor);
+ controller.setDefaultNamespaceURI("http://namespace/uri/default");
+ assertEquals("http://namespace/uri/default", controller.getDefaultNamespaceURI());
+ assertNull(element.getDeclaredDefaultNamespaceURI());
+
+ controller.applyToElement();
+ assertEquals("http://namespace/uri/default", element.getDefaultNamespaceURI());
+ assertNull(element.getQualifiedName().getQualifier());
+ }
+
+ @Test
+ public void removeDefaultNamespace() throws Exception {
+ final IElement element = editor.insertElement(new QualifiedName("http://namespace/uri/default", "element"));
+ element.declareDefaultNamespace("http://namespace/uri/default");
+ final EditNamespacesController controller = new EditNamespacesController(editor);
+
+ controller.setDefaultNamespaceURI("");
+ controller.applyToElement();
+ assertNull(element.getDeclaredDefaultNamespaceURI());
+ assertEquals("http://namespace/uri/default", element.getQualifiedName().getQualifier());
+ }
+
+ @Test
+ public void addNamespaceDefinition() throws Exception {
+ final IElement element = editor.insertElement(new QualifiedName(null, "element"));
+ final EditNamespacesController controller = new EditNamespacesController(editor);
+
+ assertTrue(controller.getNamespaceDefinitions().isEmpty());
+ assertTrue(element.getDeclaredNamespacePrefixes().isEmpty());
+
+ final EditableNamespaceDefinition newDefinition = controller.addNamespaceDefinition();
+ assertNotNull(newDefinition);
+
+ assertEquals(1, controller.getNamespaceDefinitions().size());
+ assertSame(newDefinition, controller.getNamespaceDefinitions().get(0));
+ assertTrue(element.getDeclaredNamespacePrefixes().isEmpty());
+
+ newDefinition.setPrefix("ns1");
+ newDefinition.setUri("http://namespace/uri/1");
+
+ controller.applyToElement();
+ assertEquals(1, element.getDeclaredNamespacePrefixes().size());
+ }
+
+ @Test
+ public void removeNamespaceDefinition() throws Exception {
+ final IElement element = editor.insertElement(new QualifiedName(null, "element"));
+ element.declareNamespace("ns1", "http://namespace/uri/1");
+ final EditNamespacesController controller = new EditNamespacesController(editor);
+
+ controller.removeNamespaceDefinition(controller.getNamespaceDefinitions().get(0));
+
+ assertTrue(controller.getNamespaceDefinitions().isEmpty());
+ assertTrue(element.getDeclaredNamespacePrefixes().contains("ns1"));
+
+ controller.applyToElement();
+ assertTrue(element.getDeclaredNamespacePrefixes().isEmpty());
+ }
+
+ @Test
+ public void editNamespacePrefix() throws Exception {
+ final IElement element = editor.insertElement(new QualifiedName(null, "element"));
+ element.declareNamespace("ns1", "http://namespace/uri/1");
+ final EditNamespacesController controller = new EditNamespacesController(editor);
+ final EditableNamespaceDefinition definition = controller.getNamespaceDefinitions().get(0);
+
+ definition.setPrefix("ns2");
+ assertTrue(element.getDeclaredNamespacePrefixes().contains("ns1"));
+ assertEquals(1, element.getDeclaredNamespacePrefixes().size());
+
+ controller.applyToElement();
+ assertFalse(element.getDeclaredNamespacePrefixes().contains("ns1"));
+ assertTrue(element.getDeclaredNamespacePrefixes().contains("ns2"));
+ assertEquals(1, element.getDeclaredNamespacePrefixes().size());
+ }
+
+ @Test
+ public void editNamespaceUri() throws Exception {
+ final IElement element = editor.insertElement(new QualifiedName(null, "element"));
+ element.declareNamespace("ns1", "http://namespace/uri/1");
+ final EditNamespacesController controller = new EditNamespacesController(editor);
+ final EditableNamespaceDefinition definition = controller.getNamespaceDefinitions().get(0);
+
+ definition.setUri("http://namespace/uri/2");
+ assertEquals("http://namespace/uri/1", element.getNamespaceURI("ns1"));
+
+ controller.applyToElement();
+ assertEquals("http://namespace/uri/2", element.getNamespaceURI("ns1"));
+ assertEquals(1, element.getDeclaredNamespacePrefixes().size());
+ }
+
+ private static void assertContainsNamespaceDefinition(final EditableNamespaceDefinition expected, final List<EditableNamespaceDefinition> actualList) {
+ for (final EditableNamespaceDefinition definition : actualList) {
+ if (expected.getPrefix().equals(definition.getPrefix()) && expected.getUri().equals(definition.getUri())) {
+ return;
+ }
+ }
+ fail("namespace definition not found: " + expected.getPrefix() + "=" + expected.getUri());
+ }
+
+}
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/namespace/EditNamespacesController.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/namespace/EditNamespacesController.java
index d48f22c4..8de1d71f 100644
--- a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/namespace/EditNamespacesController.java
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/namespace/EditNamespacesController.java
@@ -1,99 +1,99 @@
-/*******************************************************************************
- * Copyright (c) 2011 Florian Thienel and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Florian Thienel - initial API and implementation
- *******************************************************************************/
-package org.eclipse.vex.ui.internal.namespace;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.vex.core.internal.widget.IVexWidget;
-import org.eclipse.vex.core.provisional.dom.IElement;
-
-/**
- * @author Florian Thienel
- */
-public class EditNamespacesController {
-
- private final IVexWidget widget;
- private final IElement element;
-
- private String defaultNamespaceURI;
-
- private final List<EditableNamespaceDefinition> namespaceDefinitions;
-
- public EditNamespacesController(final IVexWidget widget) {
- this.widget = widget;
- element = widget.getCurrentElement();
- Assert.isNotNull(element, "There is no current element available. Namespaces can only be edited in elements.");
- defaultNamespaceURI = getDefaultNamespaceURI(element);
- namespaceDefinitions = getNamespaceDefinitions(element);
- }
-
- private static String getDefaultNamespaceURI(final IElement element) {
- final String result = element.getDeclaredDefaultNamespaceURI();
- if (result == null) {
- return "";
- }
- return result;
- }
-
- private static List<EditableNamespaceDefinition> getNamespaceDefinitions(final IElement element) {
- final ArrayList<EditableNamespaceDefinition> result = new ArrayList<EditableNamespaceDefinition>();
- for (final String prefix : element.getDeclaredNamespacePrefixes()) {
- result.add(new EditableNamespaceDefinition(prefix, element.getNamespaceURI(prefix)));
- }
- return result;
- }
-
- public String getDefaultNamespaceURI() {
- return defaultNamespaceURI;
- }
-
- public void setDefaultNamespaceURI(final String defaultNamespaceURI) {
- this.defaultNamespaceURI = defaultNamespaceURI;
- }
-
- public List<EditableNamespaceDefinition> getNamespaceDefinitions() {
- return namespaceDefinitions;
- }
-
- public EditableNamespaceDefinition addNamespaceDefinition() {
- final EditableNamespaceDefinition result = new EditableNamespaceDefinition();
- namespaceDefinitions.add(result);
- return result;
- }
-
- public void removeNamespaceDefinition(final EditableNamespaceDefinition namespaceDefinition) {
- namespaceDefinitions.remove(namespaceDefinition);
- }
-
- public void applyToElement() {
- if (defaultNamespaceURI == null || "".equals(defaultNamespaceURI)) {
- widget.removeDefaultNamespace();
- } else {
- widget.declareDefaultNamespace(defaultNamespaceURI);
- }
-
- final HashSet<String> declaredPrefixes = new HashSet<String>();
- for (final EditableNamespaceDefinition definition : namespaceDefinitions) {
- widget.declareNamespace(definition.getPrefix(), definition.getUri());
- declaredPrefixes.add(definition.getPrefix());
- }
-
- for (final String prefix : element.getDeclaredNamespacePrefixes()) {
- if (!declaredPrefixes.contains(prefix)) {
- widget.removeNamespace(prefix);
- }
- }
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2011 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.ui.internal.namespace;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.vex.core.internal.widget.IDocumentEditor;
+import org.eclipse.vex.core.provisional.dom.IElement;
+
+/**
+ * @author Florian Thienel
+ */
+public class EditNamespacesController {
+
+ private final IDocumentEditor editor;
+ private final IElement element;
+
+ private String defaultNamespaceURI;
+
+ private final List<EditableNamespaceDefinition> namespaceDefinitions;
+
+ public EditNamespacesController(final IDocumentEditor editor) {
+ this.editor = editor;
+ element = editor.getCurrentElement();
+ Assert.isNotNull(element, "There is no current element available. Namespaces can only be edited in elements.");
+ defaultNamespaceURI = getDefaultNamespaceURI(element);
+ namespaceDefinitions = getNamespaceDefinitions(element);
+ }
+
+ private static String getDefaultNamespaceURI(final IElement element) {
+ final String result = element.getDeclaredDefaultNamespaceURI();
+ if (result == null) {
+ return "";
+ }
+ return result;
+ }
+
+ private static List<EditableNamespaceDefinition> getNamespaceDefinitions(final IElement element) {
+ final ArrayList<EditableNamespaceDefinition> result = new ArrayList<EditableNamespaceDefinition>();
+ for (final String prefix : element.getDeclaredNamespacePrefixes()) {
+ result.add(new EditableNamespaceDefinition(prefix, element.getNamespaceURI(prefix)));
+ }
+ return result;
+ }
+
+ public String getDefaultNamespaceURI() {
+ return defaultNamespaceURI;
+ }
+
+ public void setDefaultNamespaceURI(final String defaultNamespaceURI) {
+ this.defaultNamespaceURI = defaultNamespaceURI;
+ }
+
+ public List<EditableNamespaceDefinition> getNamespaceDefinitions() {
+ return namespaceDefinitions;
+ }
+
+ public EditableNamespaceDefinition addNamespaceDefinition() {
+ final EditableNamespaceDefinition result = new EditableNamespaceDefinition();
+ namespaceDefinitions.add(result);
+ return result;
+ }
+
+ public void removeNamespaceDefinition(final EditableNamespaceDefinition namespaceDefinition) {
+ namespaceDefinitions.remove(namespaceDefinition);
+ }
+
+ public void applyToElement() {
+ if (defaultNamespaceURI == null || "".equals(defaultNamespaceURI)) {
+ editor.removeDefaultNamespace();
+ } else {
+ editor.declareDefaultNamespace(defaultNamespaceURI);
+ }
+
+ final HashSet<String> declaredPrefixes = new HashSet<String>();
+ for (final EditableNamespaceDefinition definition : namespaceDefinitions) {
+ editor.declareNamespace(definition.getPrefix(), definition.getUri());
+ declaredPrefixes.add(definition.getPrefix());
+ }
+
+ for (final String prefix : element.getDeclaredNamespacePrefixes()) {
+ if (!declaredPrefixes.contains(prefix)) {
+ editor.removeNamespace(prefix);
+ }
+ }
+ }
+
+}

Back to the top