[ 218070] whitespace preservation during region formatting
[218030] XML Formatter Throws NPE Formatting a Selected Region
diff --git a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/DefaultXMLPartitionFormatter.java b/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/DefaultXMLPartitionFormatter.java
index a09a4e0..35354ea 100644
--- a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/DefaultXMLPartitionFormatter.java
+++ b/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/DefaultXMLPartitionFormatter.java
@@ -142,15 +142,13 @@
DOMRegion domRegion = new DOMRegion();
domRegion.documentRegion = currentRegion;
domRegion.domNode = currentDOMNode;
-
- // determine parent constraint information by trying to
- // determine child constraint for parent node
- DOMRegion parentDOMRegion = new DOMRegion();
- parentDOMRegion.domNode = (IDOMNode) currentDOMNode.getParentNode();
- parentDOMRegion.documentRegion = parentDOMRegion.domNode.getFirstStructuredDocumentRegion();
- XMLFormattingConstraints parentConstraints = new XMLFormattingConstraints();
- updateFormattingConstraints(null, null, parentConstraints, parentDOMRegion);
-
+
+ XMLFormattingConstraints parentConstraints = getRegionConstraints(currentDOMNode);
+
+ /* if the whitespace strategy is declared as default, get it from the preferences */
+ if(parentConstraints.getWhitespaceStrategy() == XMLFormattingConstraints.DEFAULT)
+ parentConstraints.setWhitespaceStrategy(preferences.getElementWhitespaceStrategy());
+
// TODO: initialize indentLevel
// initialize available line width
int lineWidth = getFormattingPreferences().getMaxLineWidth();
@@ -173,6 +171,75 @@
}
/**
+ * Determines the formatting constraints for a specified node based on
+ * its ancestors' formatting. In particular, if any ancestor node either
+ * explicitly defines whitespace preservation or ignorance, that
+ * whitespace strategy should be used for <code>currentNode</code> and
+ * all of its descendants.
+ *
+ * @param currentNode the node to investigate the ancestry of to determine
+ * formatting constraints
+ *
+ * @return formatting constraints defined by an ancestor
+ */
+ private XMLFormattingConstraints getRegionConstraints(IDOMNode currentNode) {
+ IDOMNode iterator = currentNode;
+ XMLFormattingConstraints result = new XMLFormattingConstraints();
+ DOMRegion region = new DOMRegion();
+ XMLFormattingConstraints parentConstraints = new XMLFormattingConstraints();
+ boolean parent = true;
+
+ /* Iterate through the ancestry to find if any explicit whitespace strategy has
+ * been defined
+ */
+ while(iterator != null && iterator.getNodeType() != Node.DOCUMENT_NODE) {
+ iterator = (IDOMNode) iterator.getParentNode();
+ region.domNode = iterator;
+ region.documentRegion = iterator.getFirstStructuredDocumentRegion();
+
+ updateFormattingConstraints(null, null, result, region);
+
+ /* If this is the parent of the current node, keep the constraints
+ * in case no other constraints are identified
+ */
+ if(parent) {
+ parentConstraints.copyConstraints(result);
+ parent = false;
+ }
+
+ /* A parent who has defined a specific whitespace strategy was found */
+ if(XMLFormattingConstraints.PRESERVE == result.getWhitespaceStrategy() || XMLFormattingConstraints.DEFAULT == result.getWhitespaceStrategy())
+ return result;
+ }
+
+ return parentConstraints;
+ }
+// private XMLFormattingConstraints getRegionConstraints(IDOMNode currentNode) {
+// IDOMNode iterator = (IDOMNode) currentNode.getParentNode();
+// XMLFormattingConstraints result = new XMLFormattingConstraints();
+// DOMRegion region = new DOMRegion();
+//
+// /* Iterate through the ancestry to find if any explicit whitespace strategy has
+// * been defined
+// */
+// while(iterator != null && iterator.getNodeType() != Node.DOCUMENT_NODE) {
+
+// region.domNode = iterator;
+// region.documentRegion = iterator.getFirstStructuredDocumentRegion();
+//
+// updateFormattingConstraints(null, null, result, region);
+//
+// /* A parent who has defined a specific whitespace strategy was found */
+// if(XMLFormattingConstraints.PRESERVE == result.getWhitespaceStrategy() || XMLFormattingConstraints.DEFAULT == result.getWhitespaceStrategy())
+// return result;
+//
+// iterator = (IDOMNode) iterator.getParentNode();
+// }
+//
+// return null;
+// }
+
+ /**
* Formats the given xml content region
*
* @param textEdit
@@ -398,6 +465,9 @@
XMLFormattingConstraints childrenConstraints = new XMLFormattingConstraints();
updateFormattingConstraints(parentConstraints, thisConstraints, childrenConstraints, currentDOMRegion);
+ if(childrenConstraints.getWhitespaceStrategy() == XMLFormattingConstraints.DEFAULT)
+ childrenConstraints.setWhitespaceStrategy((new XMLFormattingPreferences()).getElementWhitespaceStrategy());
+
String whitespaceStrategy = thisConstraints.getWhitespaceStrategy();
String indentStrategy = thisConstraints.getIndentStrategy();
int availableLineWidth = thisConstraints.getAvailableLineWidth();
@@ -1163,8 +1233,8 @@
}
else {
// xml:space was found but it was not collapse, so
- // just null
- childConstraints.setWhitespaceStrategy(null);
+ // use default whitespace strategy
+ childConstraints.setWhitespaceStrategy(XMLFormattingConstraints.DEFAULT);
}
}
else {
@@ -1176,7 +1246,7 @@
boolean textNodeFound = false;
// BUG214516 - If the parent constraint is to preserve whitespace, child constraints should
// still reflect the parent constraints
- while (index < length && !textNodeFound && !XMLFormattingConstraints.PRESERVE.equals(parentConstraints.getWhitespaceStrategy())) {
+ while (index < length && !textNodeFound && parentConstraints != null && !XMLFormattingConstraints.PRESERVE.equals(parentConstraints.getWhitespaceStrategy())) {
Node childNode = nodeList.item(index);
if (childNode.getNodeType() == Node.TEXT_NODE) {
textNodeFound = !((IDOMText) childNode).isElementContentWhitespace();
@@ -1207,10 +1277,10 @@
// follow whitespace strategy preference for
// pcdata content
int contentType = elementDeclaration.getContentType();
- if (contentType == CMElementDeclaration.PCDATA && !XMLFormattingConstraints.PRESERVE.equals(parentConstraints.getWhitespaceStrategy())) {
+ if (contentType == CMElementDeclaration.PCDATA && parentConstraints != null && !XMLFormattingConstraints.PRESERVE.equals(parentConstraints.getWhitespaceStrategy())) {
childConstraints.setWhitespaceStrategy(preferences.getPCDataWhitespaceStrategy());
}
- else if (contentType == CMElementDeclaration.ELEMENT && !XMLFormattingConstraints.PRESERVE.equals(parentConstraints.getWhitespaceStrategy())) {
+ else if (contentType == CMElementDeclaration.ELEMENT && parentConstraints != null && !XMLFormattingConstraints.PRESERVE.equals(parentConstraints.getWhitespaceStrategy())) {
childConstraints.setWhitespaceStrategy(XMLFormattingConstraints.IGNORE);
childConstraints.setIndentStrategy(XMLFormattingConstraints.INDENT);
childConstraints.setIsWhitespaceStrategyAHint(true);
@@ -1249,11 +1319,15 @@
if(PRESERVE.equals(defaultValue))
childConstraints.setWhitespaceStrategy(XMLFormattingConstraints.PRESERVE);
else
- childConstraints.setWhitespaceStrategy(null);
+ childConstraints.setWhitespaceStrategy(XMLFormattingConstraints.DEFAULT);
}
// If the node has no attributes, inherit the parents whitespace strategy
- else
- childConstraints.setWhitespaceStrategy(parentConstraints.getWhitespaceStrategy());
+ else {
+ if(parentConstraints != null)
+ childConstraints.setWhitespaceStrategy(parentConstraints.getWhitespaceStrategy());
+ else
+ childConstraints.setWhitespaceStrategy(null);
+ }
}
}
}
diff --git a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/XMLFormattingConstraints.java b/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/XMLFormattingConstraints.java
index c375166..6bf3763 100644
--- a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/XMLFormattingConstraints.java
+++ b/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/formatter/XMLFormattingConstraints.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2008 IBM Corporation 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
@@ -15,6 +15,7 @@
public final static String PRESERVE = "PRESERVE"; //$NON-NLS-1$
public final static String COLLAPSE = "COLLAPSE"; //$NON-NLS-1$
public final static String IGNORE = "IGNORE"; //$NON-NLS-1$
+ public final static String DEFAULT = "DEFAULT"; //$NON-NLS-1$
public final static String INDENT = "INDENT"; //$NON-NLS-1$
public final static String NEW_LINE = "NEW_LINE"; //$NON-NLS-1$