Fixing IE6 CellTree bugs.  Child nodes disappear after the open animation completes, and images are not located correctly.

Review at http://gwt-code-reviews.appspot.com/997801

Review by: rice@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9059 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/cellview/CellView.gwt.xml b/user/src/com/google/gwt/user/cellview/CellView.gwt.xml
index 22a4326..bb7ffa1 100644
--- a/user/src/com/google/gwt/user/cellview/CellView.gwt.xml
+++ b/user/src/com/google/gwt/user/cellview/CellView.gwt.xml
@@ -55,4 +55,12 @@
       <when-property-is name="user.agent" value="ie8"/>
     </any>
   </replace-with>
+
+  <!-- IE6-specific CellTree implementation. -->
+  <replace-with class="com.google.gwt.user.cellview.client.CellTree.ImplIE6">
+    <when-type-is class="com.google.gwt.user.cellview.client.CellTree.Impl"/>
+    <any>
+      <when-property-is name="user.agent" value="ie6"/>
+    </any>
+  </replace-with>
 </module>
diff --git a/user/src/com/google/gwt/user/cellview/client/CellTree.java b/user/src/com/google/gwt/user/cellview/client/CellTree.java
index fa93a60..bbe2b4d 100644
--- a/user/src/com/google/gwt/user/cellview/client/CellTree.java
+++ b/user/src/com/google/gwt/user/cellview/client/CellTree.java
@@ -21,6 +21,7 @@
 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.Style.Display;
+import com.google.gwt.dom.client.Style.Overflow;
 import com.google.gwt.dom.client.Style.Position;
 import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.event.dom.client.KeyCodes;
@@ -226,6 +227,7 @@
     protected void onStart() {
       if (opening) {
         animFrame.getStyle().setHeight(1.0, Unit.PX);
+        animFrame.getStyle().setPosition(Position.RELATIVE);
         animFrame.getStyle().clearDisplay();
         height = contentContainer.getScrollHeight();
       } else {
@@ -242,6 +244,10 @@
         double curHeight = (1.0 - progress) * height;
         animFrame.getStyle().setHeight(curHeight, Unit.PX);
       }
+
+      // Remind IE6 that we want the overflow to be hidden.
+      animFrame.getStyle().setOverflow(Overflow.HIDDEN);
+      animFrame.getStyle().setPosition(Position.RELATIVE);
     }
 
     /**
@@ -288,6 +294,7 @@
         childContainer.setInnerHTML("");
       }
       animFrame.getStyle().clearHeight();
+      animFrame.getStyle().clearPosition();
       this.contentContainer = null;
       this.childContainer = null;
       this.animFrame = null;
@@ -437,6 +444,48 @@
         + "width:{2}px;height:{3}px;\">{4}</div>")
     SafeHtml imageWrapper(String classes, String direction, int width,
         int height, SafeHtml image);
+
+    @Template("<div class=\"{0}\" style=\"position:absolute;{1}:-{2}px;"
+        + "width:{2}px;height:{3}px;\">{4}</div>")
+    SafeHtml imageWrapperIE6(String classes, String direction, int width,
+        int height, SafeHtml image);
+  }
+
+  /**
+   * Implementation of {@link CellTree}.
+   */
+  private static class Impl {
+    /**
+     * Create an image wrapper.
+     */
+    public SafeHtml imageWrapper(String classes, String direction, int width,
+        int height, SafeHtml image) {
+      return template.imageWrapper(classes, direction, width, height, image);
+    }
+  }
+
+  /**
+   * Implementation of {@link CellTable} used by IE6.
+   */
+  @SuppressWarnings("unused")
+  private static class ImplIE6 extends Impl {
+    @Override
+    public SafeHtml imageWrapper(String classes, String direction, int width,
+        int height, SafeHtml image) {
+      /*
+       * In IE6, left/right positions are relative to the inside of the padding
+       * instead of the outside of the padding. The bug does not happen on IE7,
+       * which maps to the IE6 user agent, so we need a runtime check for IE6.
+       */
+      if (isIe6()) {
+        return template.imageWrapperIE6(classes, direction, width, height, image);
+      }
+      return super.imageWrapper(classes, direction, width, height, image);
+    }
+
+    private native boolean isIe6() /*-{
+      return @com.google.gwt.dom.client.DOMImplIE6::isIE6()();
+    }-*/;
   }
 
   /**
@@ -446,6 +495,7 @@
 
   private static Resources DEFAULT_RESOURCES;
 
+  private static Impl TREE_IMPL;
   private static Template template;
 
   private static Resources getDefaultResources() {
@@ -565,6 +615,9 @@
     if (template == null) {
       template = GWT.create(Template.class);
     }
+    if (TREE_IMPL == null) {
+      TREE_IMPL = GWT.create(Impl.class);
+    }
     this.style = resources.cellTreeStyle();
     this.style.ensureInjected();
     initWidget(new SimplePanel());
@@ -959,7 +1012,7 @@
 
     AbstractImagePrototype proto = AbstractImagePrototype.create(res);
     SafeHtml image = SafeHtmlUtils.fromTrustedString(proto.getHTML());
-    return template.imageWrapper(classesBuilder.toString(), direction,
+    return TREE_IMPL.imageWrapper(classesBuilder.toString(), direction,
         res.getWidth(), res.getHeight(), image);
   }
 
diff --git a/user/src/com/google/gwt/user/cellview/client/CellTreeNodeView.java b/user/src/com/google/gwt/user/cellview/client/CellTreeNodeView.java
index f9e524b..7104c01 100644
--- a/user/src/com/google/gwt/user/cellview/client/CellTreeNodeView.java
+++ b/user/src/com/google/gwt/user/cellview/client/CellTreeNodeView.java
@@ -24,7 +24,6 @@
 import com.google.gwt.dom.client.NativeEvent;
 import com.google.gwt.dom.client.Style.Display;
 import com.google.gwt.dom.client.Style.Overflow;
-import com.google.gwt.dom.client.Style.Position;
 import com.google.gwt.event.logical.shared.CloseEvent;
 import com.google.gwt.event.logical.shared.OpenEvent;
 import com.google.gwt.event.shared.EventHandler;
@@ -1051,7 +1050,6 @@
   Element ensureAnimationFrame() {
     if (animationFrame == null) {
       animationFrame = Document.get().createDivElement();
-      animationFrame.getStyle().setPosition(Position.RELATIVE);
       animationFrame.getStyle().setOverflow(Overflow.HIDDEN);
       animationFrame.getStyle().setDisplay(Display.NONE);
       getElement().appendChild(animationFrame);