Fix ListBox UiBinder parsing.
Review at http://gwt-code-reviews.appspot.com/1629803
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10891 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/ListBoxParser.java b/user/src/com/google/gwt/uibinder/elementparsers/ListBoxParser.java
index 708f625..c8221e6 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/ListBoxParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/ListBoxParser.java
@@ -36,7 +36,8 @@
writer.die(elem, "Invalid ListBox child element: " + tagName);
}
String value = child.consumeStringAttribute("value");
- String innerText = child.consumeInnerTextEscapedAsHtmlStringLiteral(new TextInterpreter(writer));
+ String innerText = child.consumeInnerTextEscapedAsStringLiteral(
+ new TextInterpreter(writer));
if (value != null) {
writer.addStatement("%s.addItem(\"%s\", %s);", fieldName, innerText, value);
} else {
diff --git a/user/src/com/google/gwt/uibinder/rebind/GetInnerHtmlVisitor.java b/user/src/com/google/gwt/uibinder/rebind/GetInnerHtmlVisitor.java
index 4eae5dd..65eb141 100644
--- a/user/src/com/google/gwt/uibinder/rebind/GetInnerHtmlVisitor.java
+++ b/user/src/com/google/gwt/uibinder/rebind/GetInnerHtmlVisitor.java
@@ -20,7 +20,7 @@
import org.w3c.dom.Element;
-class GetInnerHtmlVisitor extends GetEscapedInnerTextVisitor {
+class GetInnerHtmlVisitor extends GetInnerTextVisitor {
/**
* Recursively gathers an HTML representation of the children of the given
diff --git a/user/src/com/google/gwt/uibinder/rebind/GetEscapedInnerTextVisitor.java b/user/src/com/google/gwt/uibinder/rebind/GetInnerTextVisitor.java
similarity index 63%
rename from user/src/com/google/gwt/uibinder/rebind/GetEscapedInnerTextVisitor.java
rename to user/src/com/google/gwt/uibinder/rebind/GetInnerTextVisitor.java
index 24cf27c..06d3202 100644
--- a/user/src/com/google/gwt/uibinder/rebind/GetEscapedInnerTextVisitor.java
+++ b/user/src/com/google/gwt/uibinder/rebind/GetInnerTextVisitor.java
@@ -23,7 +23,7 @@
import org.w3c.dom.Node;
import org.w3c.dom.Text;
-class GetEscapedInnerTextVisitor implements NodeVisitor {
+class GetInnerTextVisitor implements NodeVisitor {
/**
* Gathers a text representation of the children of the given Elem, and stuffs
@@ -33,19 +33,39 @@
public static void getEscapedInnerText(Element elem, StringBuffer buffer,
Interpreter<String> interpreter, XMLElementProvider writer)
throws UnableToCompleteException {
- new ChildWalker().accept(elem, new GetEscapedInnerTextVisitor(buffer,
- interpreter, writer));
+ new ChildWalker().accept(elem, new GetInnerTextVisitor(buffer,
+ interpreter, writer, false));
+ }
+
+ /**
+ * Gathers a text representation of the children of the given Elem, and stuffs
+ * it into the given StringBuffer. Applies the interpreter to each descendant,
+ * and uses the writer to report errors. Escapes HTML Entities.
+ */
+ public static void getHtmlEscapedInnerText(Element elem, StringBuffer buffer,
+ Interpreter<String> interpreter, XMLElementProvider writer)
+ throws UnableToCompleteException {
+ new ChildWalker().accept(elem, new GetInnerTextVisitor(buffer,
+ interpreter, writer, true));
}
protected final StringBuffer buffer;
protected final Interpreter<String> interpreter;
protected final XMLElementProvider elementProvider;
+ protected final boolean escapeHtmlEntities;
- protected GetEscapedInnerTextVisitor(StringBuffer buffer,
+ protected GetInnerTextVisitor(StringBuffer buffer,
Interpreter<String> interpreter, XMLElementProvider elementProvider) {
+ this(buffer, interpreter, elementProvider, true);
+ }
+
+ protected GetInnerTextVisitor(StringBuffer buffer,
+ Interpreter<String> interpreter, XMLElementProvider elementProvider,
+ boolean escapeHtmlEntities) {
this.buffer = buffer;
this.interpreter = interpreter;
this.elementProvider = elementProvider;
+ this.escapeHtmlEntities = escapeHtmlEntities;
}
public void visitCData(CDATASection d) {
@@ -61,8 +81,18 @@
}
public void visitText(Text t) {
- String escaped = UiBinderWriter.escapeText(t.getTextContent(),
+ String escaped;
+ if (escapeHtmlEntities) {
+ escaped = UiBinderWriter.escapeText(t.getTextContent(),
preserveWhiteSpace(t));
+ } else {
+ escaped = t.getTextContent();
+ if (!preserveWhiteSpace(t)) {
+ escaped = escaped.replaceAll("\\s+", " ");
+ }
+ escaped = UiBinderWriter.escapeTextForJavaStringLiteral(escaped);
+ }
+
buffer.append(escaped);
}
diff --git a/user/src/com/google/gwt/uibinder/rebind/XMLElement.java b/user/src/com/google/gwt/uibinder/rebind/XMLElement.java
index 99680f3..07bee2c 100644
--- a/user/src/com/google/gwt/uibinder/rebind/XMLElement.java
+++ b/user/src/com/google/gwt/uibinder/rebind/XMLElement.java
@@ -417,36 +417,35 @@
/**
* Consumes all child text nodes, and asserts that this element held only
* text. Trailing and leading whitespace is trimmed, and escaped for use as a
- * string literal. Notice that HTML entities in the text are also escaped--is
- * this a source of errors?
+ * string literal. Notice that HTML entities in the text are also escaped
* <p>
* This call requires an interpreter to make sense of any special children.
* The odds are you want to use
* {@link com.google.gwt.uibinder.elementparsers.TextInterpreter}
- *
+ *
* @throws UnableToCompleteException If any elements present are not consumed
* by the interpreter
*/
public String consumeInnerTextEscapedAsHtmlStringLiteral(Interpreter<String> interpreter)
throws UnableToCompleteException {
- if (interpreter == null) {
- throw new NullPointerException("interpreter must not be null");
- }
- StringBuffer buf = new StringBuffer();
+ return consumeInnerTextEscapedAsHtmlStringLiteral(interpreter, true);
+ }
- GetEscapedInnerTextVisitor.getEscapedInnerText(elem, buf, interpreter, provider);
-
- // Make sure there are no children left but empty husks
- for (XMLElement child : consumeChildElementsNoEmptyCheck()) {
- if (child.hasChildNodes() || child.getAttributeCount() > 0) {
- logger.die(this, "Illegal child %s in a text-only context. "
- + "Perhaps you are trying to use unescaped HTML "
- + "where text is required, as in a HasText widget?", child);
- }
- }
-
- clearChildren(elem);
- return buf.toString().trim();
+ /**
+ * Consumes all child text nodes, and asserts that this element held only
+ * text. Trailing and leading whitespace is trimmed, and escaped for use as a
+ * string literal. Notice that HTML entities in the text are NOT escaped
+ * <p>
+ * This call requires an interpreter to make sense of any special children.
+ * The odds are you want to use
+ * {@link com.google.gwt.uibinder.elementparsers.TextInterpreter}
+ *
+ * @throws UnableToCompleteException If any elements present are not consumed
+ * by the interpreter
+ */
+ public String consumeInnerTextEscapedAsStringLiteral(Interpreter<String> interpreter)
+ throws UnableToCompleteException {
+ return consumeInnerTextEscapedAsHtmlStringLiteral(interpreter, false);
}
/**
@@ -819,6 +818,45 @@
}
}
+ /**
+ * Consumes all child text nodes, and asserts that this element held only
+ * text. Trailing and leading whitespace is trimmed, and escaped for use as a
+ * string literal. If escapeHtmlEntities is true, HTML Entities are also escaped.
+ * <p>
+ * This call requires an interpreter to make sense of any special children.
+ * The odds are you want to use
+ * {@link com.google.gwt.uibinder.elementparsers.TextInterpreter}
+ *
+ * @throws UnableToCompleteException If any elements present are not consumed
+ * by the interpreter
+ */
+ private String consumeInnerTextEscapedAsHtmlStringLiteral(Interpreter<String> interpreter,
+ boolean escapeHtmlEntities)
+ throws UnableToCompleteException {
+ if (interpreter == null) {
+ throw new NullPointerException("interpreter must not be null");
+ }
+ StringBuffer buf = new StringBuffer();
+
+ if (escapeHtmlEntities) {
+ GetInnerTextVisitor.getHtmlEscapedInnerText(elem, buf, interpreter, provider);
+ } else {
+ GetInnerTextVisitor.getEscapedInnerText(elem, buf, interpreter, provider);
+ }
+
+ // Make sure there are no children left but empty husks
+ for (XMLElement child : consumeChildElementsNoEmptyCheck()) {
+ if (child.hasChildNodes() || child.getAttributeCount() > 0) {
+ logger.die(this, "Illegal child %s in a text-only context. "
+ + "Perhaps you are trying to use unescaped HTML "
+ + "where text is required, as in a HasText widget?", child);
+ }
+ }
+
+ clearChildren(elem);
+ return buf.toString().trim();
+ }
+
private void failRequired(String name) throws UnableToCompleteException {
logger.die(this, "Missing required attribute \"%s\"", name);
}