canRemoveAttribute

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java
index 49d88dc..cfa54de 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java
@@ -133,6 +133,14 @@
 		return attribute.getValue();
 	}
 
+	public boolean canRemoveAttribute(final String localName) {
+		return canRemoveAttribute(qualify(localName));
+	}
+
+	public boolean canRemoveAttribute(final QualifiedName name) {
+		return true; // TODO implement validation for attribute values
+	}
+
 	public void removeAttribute(final String localName) throws DocumentValidationException {
 		removeAttribute(qualify(localName));
 	}
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 e8cea09..ba324df 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
@@ -1366,7 +1366,6 @@
 
 		final IElement element = getCurrentElement();
 		if (element == null) {
-			// TODO throw IllegalStateException("Not in element");
 			return;
 		}
 
@@ -1379,6 +1378,20 @@
 		}
 	}
 
+	public boolean canRemoveAttribute(final String attributeName) {
+		if (readOnly) {
+			return false;
+		}
+
+		final IElement element = getCurrentElement();
+		if (element == null) {
+			return false;
+		}
+
+		final QualifiedName qualifiedAttributeName = element.qualify(attributeName);
+		return element.canRemoveAttribute(qualifiedAttributeName);
+	}
+
 	public void removeAttribute(final String attributeName) throws ReadOnlyException {
 		if (readOnly) {
 			throw new ReadOnlyException(MessageFormat.format("Cannot remove attribute {0}, because the editor is read-only.", attributeName));
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 c76fe5b..aaf61c1 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
@@ -461,6 +461,13 @@
 	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.
 	 * 
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 8049b88..4e8e43f 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
@@ -384,6 +384,10 @@
 		impl.redo();
 	}
 
+	public boolean canRemoveAttribute(final String attributeName) {
+		return impl.canRemoveAttribute(attributeName);
+	}
+
 	public void removeAttribute(final String attributeName) {
 		impl.removeAttribute(attributeName);
 	}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IElement.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IElement.java
index 238d714..a25750f 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IElement.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IElement.java
@@ -92,6 +92,20 @@
 	String getAttributeValue(QualifiedName name);

 

 	/**

+	 * @param localName

+	 *            the local name of the attribute to remove

+	 * @return true if it is valid to remove the attribute with the given local name

+	 */

+	boolean canRemoveAttribute(String localName);

+

+	/**

+	 * @param name

+	 *            the qualified name of the attribute to remove

+	 * @return true if it is valid to remove the attribute with the given qualified name

+	 */

+	boolean canRemoveAttribute(QualifiedName name);

+

+	/**

 	 * Remove the attribute with the given local name.

 	 * 

 	 * @param localName