UiBinderWriter#escapeTextForJavaStringLiteral correctly escapes \n and
", but forgets \.

Also, I couldn't see a reason for using replaceAll instead of replace.

Patch by tbroyer@gmail.com
Review by rjrjr@google.com

http://gwt-code-reviews.appspot.com/620804

Review by: robertvawter@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8356 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
index 3f42296..54a2b59 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
@@ -113,11 +113,12 @@
 
   /**
    * Escape characters that would mess up interpretation of this string as a
-   * string literal in generated code (that is, protect \n and " ).
+   * string literal in generated code (that is, protect \, \n and " ).
    */
   public static String escapeTextForJavaStringLiteral(String text) {
-    text = text.replaceAll("\"", "\\\\\"");
-    text = text.replaceAll("\n", "\\\\n");
+    text = text.replace("\\", "\\\\");
+    text = text.replace("\"", "\\\"");
+    text = text.replace("\n", "\\n");
 
     return text;
   }
diff --git a/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java b/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
index fbdf469..48b43ae 100644
--- a/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
+++ b/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
@@ -231,19 +231,19 @@
   public void testDomAttributeMessageWithFunnyChars() {
     ParagraphElement p = widgetUi.funnyCharsMessageDomAttributeParagraph;
     String t = p.getAttribute("title");
-    assertEquals("funny characters \" ' ' & < > > { }", t);
+    assertEquals("funny characters \\ \" ' ' & < > > { }", t);
   }
 
   public void testDomAttributeNoMessageWithFunnyChars() {
     ParagraphElement p = widgetUi.funnyCharsDomAttributeParagraph;
     String t = p.getAttribute("title");
-    assertEquals("funny characters \" ' ' & < > > { }", t);
+    assertEquals("funny characters \\ \" ' ' & < > > { }", t);
   }
 
   public void testDomTextMessageWithFunnyChars() {
     String t = widgetUi.funnyCharsMessageParagraph.getInnerText();
     assertEquals("They might show up in body text that has been marked for "
-        + "translation: funny characters \" \" ' ' & < > > { }", t);
+        + "translation: funny characters \\ \" \" ' ' & < > > { }", t);
   }
   
   public void testEmptyAttributesOkay() {
@@ -275,12 +275,12 @@
   public void testProtectedDomTextMessageWithFunnyChars() {
     String t = widgetUi.funnyCharsProtectedMessageParagraph.getInnerText();
     assertEquals("Don't forget about protected untranslatable blocks: "
-        + "funny characters \" \" ' ' & < > > { }", t);
+        + "funny characters \\ \" \" ' ' & < > > { }", t);
   }
 
   public void testDomTextInNamedElementMessageWithFunnyChars() {
     String t = widgetUi.funnyCharsMessageChildSpan.getInnerText();
-    assertEquals("funny characters \" \" ' ' & < > > { }", t);
+    assertEquals("funny characters \\ \" \" ' ' & < > > { }", t);
   }
 
   public void suppressedForSafari3Fail_testDomTextNoMessageWithFunnyChars() {
@@ -289,7 +289,7 @@
     String t = p.getInnerHTML().replace("\n", " ").toLowerCase();
     String expected = "Templates can be marked up for <b>localization</b>, which presents alls "
         + "kinds of exciting opportunities for bugs related to character escaping. "
-        + "Consider these funny characters \" \" ' ' &amp; &lt; &gt; &gt; { }, and "
+        + "Consider these funny characters \\ \" \" ' ' &amp; &lt; &gt; &gt; { }, and "
         + "the various places they might make your life miserable, like this "
         + "untranslated paragraph.";
     expected = expected.toLowerCase();
@@ -448,13 +448,13 @@
   public void testWidgetAttributeMessageWithFunnyChars() {
     ClickyLink clicky = widgetUi.funnyCharsMessageAttributeWidget;
     String t = clicky.getPopupText();
-    assertEquals("funny characters \" ' ' & < > > { }", t);
+    assertEquals("funny characters \\ \" ' ' & < > > { }", t);
   }
 
   public void testWidgetAttributeNoMessageWithFunnyChars() {
     ClickyLink clicky = widgetUi.funnyCharsAttributeWidget;
     String t = clicky.getPopupText();
-    assertEquals("funny characters \" ' ' & < > > { }", t);
+    assertEquals("funny characters \\ \" ' ' & < > > { }", t);
   }
 
   public void testCustomImageClass() {
diff --git a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
index 09fa323..982c893 100644
--- a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
+++ b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
@@ -443,35 +443,35 @@
       <h2>Localization and character escaping</h2>
       <p ui:field="funnyCharsParagraph">Templates can be marked up for <b>localization</b>,
       which presents alls kinds of exciting opportunities for bugs related to
-      character escaping. Consider these funny characters " &quot; ' &#39; &amp; &lt; &gt; > { },
+      character escaping. Consider these funny characters \ " &quot; ' &#39; &amp; &lt; &gt; > { },
       and the various places they might make your life miserable, like this
       untranslated paragraph.</p>
       <p ui:field="funnyCharsMessageParagraph"><ui:msg>They might show up
-      in body text that has been <b>marked for translation</b>: funny characters " &quot; ' &#39; &amp; &lt; &gt; > { }</ui:msg></p>
-      <p><ui:msg>Or perhaps in a subelement with a ui:field: <span ui:field='funnyCharsMessageChildSpan'>funny characters " &quot; ' &#39; &amp; &lt; &gt; > { }</span></ui:msg></p>
-      <p ui:field="funnyCharsProtectedMessageParagraph"><ui:msg>Don't forget about protected untranslatable blocks: <ui:ph name='francine'>funny characters " &quot; ' &#39; &amp; &lt; &gt; > { }</ui:ph></ui:msg></p>
-      <p ui:field="funnyCharsMessageDomAttributeParagraph" title="funny characters &quot; ' &#39; &amp; &lt; &gt; > { }">
+      in body text that has been <b>marked for translation</b>: funny characters \ " &quot; ' &#39; &amp; &lt; &gt; > { }</ui:msg></p>
+      <p><ui:msg>Or perhaps in a subelement with a ui:field: <span ui:field='funnyCharsMessageChildSpan'>funny characters \ " &quot; ' &#39; &amp; &lt; &gt; > { }</span></ui:msg></p>
+      <p ui:field="funnyCharsProtectedMessageParagraph"><ui:msg>Don't forget about protected untranslatable blocks: <ui:ph name='francine'>funny characters \ " &quot; ' &#39; &amp; &lt; &gt; > { }</ui:ph></ui:msg></p>
+      <p ui:field="funnyCharsMessageDomAttributeParagraph" title="funny characters \ &quot; ' &#39; &amp; &lt; &gt; > { }">
         <ui:attribute name="title"/>
         Attributes of dom elements can be translated too, like the
         tooltip of this paragraph, which features the challenging characters.
       </p>
       <p ui:field="funnyCharsDomAttributeParagraph"
-        title="funny characters &quot; ' &#39; &amp; &lt; &gt; > { }">
+        title="funny characters \ &quot; ' &#39; &amp; &lt; &gt; > { }">
         They might also appear in an unstranslated attribute of a dom element, like
         the tooltip for this paragraph.
       </p>
       <p>And all the cases above apply to widgets as well:</p>
-      <gwt:Label>I am an untranslatable HasText with funny characters " &quot; ' &#39; &amp; &lt; &gt; > { }</gwt:Label>
-      <gwt:HTML>I am an untranslatable HasHTML with funny characters " &quot; ' &#39; &amp; &lt; &gt; > { }</gwt:HTML>
-      <gwt:Label><ui:msg>I am a translatable <ui:ph name="widgetType" example="myWidget">HasText</ui:ph> with funny characters " &quot; ' &#39; &amp; &lt; &gt; > { }</ui:msg></gwt:Label>
-      <gwt:HTML><ui:msg>I am a translatable <ui:ph name="widgetType" example="myWidget">HasHTML</ui:ph> with funny characters " &quot; ' &#39; &amp; &lt; &gt; > { }</ui:msg></gwt:HTML>
+      <gwt:Label>I am an untranslatable HasText with funny characters \ " &quot; ' &#39; &amp; &lt; &gt; > { }</gwt:Label>
+      <gwt:HTML>I am an untranslatable HasHTML with funny characters \ " &quot; ' &#39; &amp; &lt; &gt; > { }</gwt:HTML>
+      <gwt:Label><ui:msg>I am a translatable <ui:ph name="widgetType" example="myWidget">HasText</ui:ph> with funny characters \ " &quot; ' &#39; &amp; &lt; &gt; > { }</ui:msg></gwt:Label>
+      <gwt:HTML><ui:msg>I am a translatable <ui:ph name="widgetType" example="myWidget">HasHTML</ui:ph> with funny characters \ " &quot; ' &#39; &amp; &lt; &gt; > { }</ui:msg></gwt:HTML>
       <demo:ClickyLink ui:field="funnyCharsAttributeWidget"
-        popupText="funny characters &quot; ' &#39; &amp; &lt; &gt; > { }">
+        popupText="funny characters \ &quot; ' &#39; &amp; &lt; &gt; > { }">
         Click to see my untranslatable text passed by attribute
       </demo:ClickyLink>
       <br/>
       <demo:ClickyLink ui:field="funnyCharsMessageAttributeWidget"
-        popupText="funny characters &quot; ' &#39; &amp; &lt; &gt; > { }">
+        popupText="funny characters \ &quot; ' &#39; &amp; &lt; &gt; > { }">
         <ui:attribute name="popupText"/>
         Click to see my translatable text passed by attribute
       </demo:ClickyLink>