Fixes RichTextArea.isEnabled/setEnabled functionality so that it actually enables/disables the text area.

Patch by: manolo.carrasco
Review by: jlabanca
Issue: 1488


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7528 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/RichTextArea.java b/user/src/com/google/gwt/user/client/ui/RichTextArea.java
index 90cc855..68938ca 100644
--- a/user/src/com/google/gwt/user/client/ui/RichTextArea.java
+++ b/user/src/com/google/gwt/user/client/ui/RichTextArea.java
@@ -635,6 +635,16 @@
   }
 
   @Override
+  public boolean isEnabled() {
+    return impl.isEnabled();
+  }
+
+  @Override
+  public void setEnabled(boolean enabled) {
+    impl.setEnabled(enabled);
+  }
+
+  @Override
   public void setFocus(boolean focused) {
     // There are different problems on each browser when you try to focus an
     // unattached rich text iframe, so just cut it off early.
diff --git a/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImpl.java b/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImpl.java
index e2e70f4..2a31169 100644
--- a/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImpl.java
+++ b/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImpl.java
@@ -54,6 +54,14 @@
     onElementInitialized();
   }
 
+  public boolean isEnabled() {
+    return !elem.getPropertyBoolean("disabled");
+  }
+
+  public void setEnabled(boolean enabled) {
+    elem.setPropertyBoolean("disabled", !enabled);
+  }
+
   public native void setFocus(boolean focused) /*-{
     if (focused) {
       this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem.focus();
diff --git a/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplIE6.java b/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplIE6.java
index ad56246..c1fa928 100644
--- a/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplIE6.java
+++ b/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplIE6.java
@@ -115,6 +115,18 @@
   }-*/;
 
   @Override
+  protected native boolean isEnabledImpl() /*-{
+    var elem = this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
+    return elem.contentWindow.document.body.contentEditable.toLowerCase() == 'true'; 
+  }-*/;
+
+  @Override
+  protected native void setEnabledImpl(boolean enabled) /*-{
+    var elem = this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
+    elem.contentWindow.document.body.contentEditable = enabled;
+  }-*/;
+
+  @Override
   protected native void setTextImpl(String text) /*-{
     var elem = this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
     elem.contentWindow.document.body.innerText = text;
diff --git a/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplStandard.java b/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplStandard.java
index 5735cef..a60d5a2 100644
--- a/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplStandard.java
+++ b/user/src/com/google/gwt/user/client/ui/impl/RichTextAreaImplStandard.java
@@ -38,8 +38,9 @@
       "cannot be used until the RichTextArea is attached and focused.";
 
   /**
-   * Holds a cached copy of any user setHTML/setText actions until the real
-   * text area is fully initialized.  Becomes <code>null</code> after init.
+   * Holds a cached copy of any user setHTML/setText/setEnabled actions until
+   * the real text area is fully initialized.  Becomes <code>null</code> after
+   * init.
    */
   private Element beforeInitPlaceholder = DOM.createDiv();
 
@@ -123,6 +124,12 @@
     return queryCommandState("Bold");
   }
 
+  @Override
+  public boolean isEnabled() {
+    return beforeInitPlaceholder == null ? isEnabledImpl()
+        : !beforeInitPlaceholder.getPropertyBoolean("disabled");
+  }
+
   public boolean isItalic() {
     return queryCommandState("Italic");
   }
@@ -172,6 +179,15 @@
   }
 
   @Override
+  public void setEnabled(boolean enabled) {
+    if (beforeInitPlaceholder == null) {
+      setEnabledImpl(enabled);
+    } else {
+      beforeInitPlaceholder.setPropertyBoolean("disabled", !enabled);
+    }
+  }
+
+  @Override
   public native void setFocus(boolean focused) /*-{
     if (focused) {
       this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem.contentWindow.focus();
@@ -265,12 +281,14 @@
     // Unhook all custom event handlers when the element is detached.
     unhookEvents();
 
-    // Recreate the placeholder element and store the iframe's contents in it.
-    // This is necessary because some browsers will wipe the iframe's contents
-    // when it is removed from the DOM.
+    // Recreate the placeholder element and store the iframe's contents and the
+    // enabled status in it. This is necessary because some browsers will wipe
+    // the iframe's contents when it is removed from the DOM.
     String html = getHTML();
+    boolean enabled = isEnabled();
     beforeInitPlaceholder = DOM.createDiv();
     DOM.setInnerHTML(beforeInitPlaceholder, html);
+    setEnabled(enabled);
   }
 
   protected native String getHTMLImpl() /*-{
@@ -324,6 +342,11 @@
     wnd.addEventListener('blur', elem.__gwt_blurHandler, true);
   }-*/;
 
+  protected native boolean isEnabledImpl() /*-{
+    var elem = this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
+    return elem.contentWindow.document.designMode.toUpperCase() == 'ON';
+  }-*/;
+
   @Override
   protected void onElementInitialized() {
     // Issue 1897: This method is called after a timeout, during which time the
@@ -337,12 +360,18 @@
     // When the iframe is ready, ensure cached content is set.
     if (beforeInitPlaceholder != null) {
       setHTMLImpl(DOM.getInnerHTML(beforeInitPlaceholder));
+      setEnabledImpl(isEnabled());
       beforeInitPlaceholder = null;
     }
     
     super.onElementInitialized();
   }
 
+  protected native void setEnabledImpl(boolean enabled) /*-{
+    var elem = this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
+    elem.contentWindow.document.designMode = enabled ? 'On' : 'Off';
+  }-*/;
+
   protected native void setHTMLImpl(String html) /*-{
     this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem.contentWindow.document.body.innerHTML = html;
   }-*/;
diff --git a/user/test/com/google/gwt/user/client/ui/RichTextAreaTest.java b/user/test/com/google/gwt/user/client/ui/RichTextAreaTest.java
index a6ee986..cd0a41b 100644
--- a/user/test/com/google/gwt/user/client/ui/RichTextAreaTest.java
+++ b/user/test/com/google/gwt/user/client/ui/RichTextAreaTest.java
@@ -161,6 +161,45 @@
   }
 
   /**
+   * Test that a delayed call to setEnable is reflected.
+   */
+  @DoNotRunWith(Platform.HtmlUnit)
+  public void testSetEnabledAfterInit() {
+    final RichTextArea richTextArea = new RichTextArea();
+    delayTestFinish(RICH_TEXT_ASYNC_DELAY);
+    richTextArea.addInitializeHandler(new InitializeHandler() {
+      public void onInitialize(InitializeEvent event) {
+        richTextArea.setEnabled(false);
+        assertEquals(false, richTextArea.isEnabled());
+        richTextArea.setEnabled(true);
+        assertEquals(true, richTextArea.isEnabled());
+        finishTest();
+      }
+    });
+    RootPanel.get().add(richTextArea);
+  }
+
+  /**
+   * Test that a call to setEnable is reflected immediately, and after the area
+   * loads.
+   */
+  @DoNotRunWith(Platform.HtmlUnit)
+  public void testSetEnabledBeforeInit() {
+    final RichTextArea richTextArea = new RichTextArea();
+    richTextArea.setEnabled(false);
+    assertEquals(false, richTextArea.isEnabled());
+    delayTestFinish(RICH_TEXT_ASYNC_DELAY);
+    richTextArea.addInitializeHandler(new InitializeHandler() {
+      public void onInitialize(InitializeEvent event) {
+        assertEquals(false, richTextArea.isEnabled());
+        finishTest();
+      }
+    });
+    RootPanel.get().add(richTextArea);
+    assertEquals(false, richTextArea.isEnabled());
+  }
+
+  /**
    * Test that a delayed set of HTML is reflected. Some platforms have timing
    * subtleties that need to be tested.
    */