Fixes missing body scroll-position addition in IE8's implementation of
getAbsoluteLeft/Top().

Review: http://gwt-code-reviews.appspot.com/34827


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5485 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/dom/client/DOMImplIE6.java b/user/src/com/google/gwt/dom/client/DOMImplIE6.java
index fbaacae..98dee7f 100644
--- a/user/src/com/google/gwt/dom/client/DOMImplIE6.java
+++ b/user/src/com/google/gwt/dom/client/DOMImplIE6.java
@@ -24,14 +24,14 @@
   @Override
   public int getAbsoluteLeft(Element elem) {
     Document doc = elem.getOwnerDocument();
-    return (int) Math.floor(super.getAbsoluteLeft(elem)
+    return (int) Math.floor(getBoundingClientRectLeft(elem)
         / getZoomMultiple(doc) + doc.getScrollLeft());
   }
 
   @Override
   public int getAbsoluteTop(Element elem) {
     Document doc = elem.getOwnerDocument();
-    return (int) Math.floor(super.getAbsoluteTop(elem)
+    return (int) Math.floor(getBoundingClientRectTop(elem)
         / getZoomMultiple(doc) + doc.getScrollTop());
   }
 
diff --git a/user/src/com/google/gwt/dom/client/DOMImplIE8.java b/user/src/com/google/gwt/dom/client/DOMImplIE8.java
index b5f0787..2b65cd8 100644
--- a/user/src/com/google/gwt/dom/client/DOMImplIE8.java
+++ b/user/src/com/google/gwt/dom/client/DOMImplIE8.java
@@ -18,6 +18,18 @@
 class DOMImplIE8 extends DOMImplTrident {
 
   @Override
+  public int getAbsoluteLeft(Element elem) {
+    Document doc = elem.getOwnerDocument();
+    return getBoundingClientRectLeft(elem) + doc.getScrollLeft();
+  }
+
+  @Override
+  public int getAbsoluteTop(Element elem) {
+    Document doc = elem.getOwnerDocument();
+    return getBoundingClientRectTop(elem) + doc.getScrollTop();
+  }
+
+  @Override
   public int getScrollLeft(Element elem) {
     if (isRTL(elem)) {
       // IE8 returns increasingly *positive* values as you scroll left in RTL.
diff --git a/user/src/com/google/gwt/dom/client/DOMImplTrident.java b/user/src/com/google/gwt/dom/client/DOMImplTrident.java
index d1b5e59..74b4e19 100644
--- a/user/src/com/google/gwt/dom/client/DOMImplTrident.java
+++ b/user/src/com/google/gwt/dom/client/DOMImplTrident.java
@@ -166,16 +166,6 @@
     return "[event" + evt.type + "]";
   }-*/;
 
-  @Override
-  public int getAbsoluteLeft(Element elem) {
-    return getBoundingClientRectLeft(elem);
-  }
-
-  @Override
-  public int getAbsoluteTop(Element elem) {
-    return getBoundingClientRectTop(elem);
-  }
-
   /**
    * IE returns a numeric type for some attributes that are really properties,
    * such as offsetWidth.  We need to coerce these to strings to prevent a
@@ -253,6 +243,26 @@
     elem.innerText = text || '';
   }-*/;
 
+  protected native int getBoundingClientRectLeft(Element elem) /*-{
+    // getBoundingClientRect() throws a JS exception if the elem is not attached
+    // to the document, so we wrap it in a try/catch block
+    try {
+      return elem.getBoundingClientRect().left;
+    } catch (e) {
+      return 0;
+    }
+  }-*/;
+
+  protected native int getBoundingClientRectTop(Element elem) /*-{
+    // getBoundingClientRect() throws a JS exception if the elem is not attached
+    // to the document, so we wrap it in a try/catch block
+    try {
+      return elem.getBoundingClientRect().top;
+    } catch (e) {
+      return 0;
+    }
+  }-*/;
+
   protected native boolean isRTL(Element elem) /*-{
     return elem.currentStyle.direction == 'rtl';
   }-*/;
@@ -269,26 +279,6 @@
     return doc.__gwt_container;
   }-*/;
 
-  private native int getBoundingClientRectLeft(Element elem) /*-{
-    // getBoundingClientRect() throws a JS exception if the elem is not attached
-    // to the document, so we wrap it in a try/catch block
-    try {
-      return elem.getBoundingClientRect().left;
-    } catch (e) {
-      return 0;
-    }
-  }-*/;
-
-  private native int getBoundingClientRectTop(Element elem) /*-{
-    // getBoundingClientRect() throws a JS exception if the elem is not attached
-    // to the document, so we wrap it in a try/catch block
-    try {
-      return elem.getBoundingClientRect().top;
-    } catch (e) {
-      return 0;
-    }
-  }-*/;
-
   /**
    * clientLeft is non-standard and not implemented on all browsers.
    */
diff --git a/user/test/com/google/gwt/dom/client/ElementTest.java b/user/test/com/google/gwt/dom/client/ElementTest.java
index 4d927ba..5203499 100644
--- a/user/test/com/google/gwt/dom/client/ElementTest.java
+++ b/user/test/com/google/gwt/dom/client/ElementTest.java
@@ -16,6 +16,8 @@
 package com.google.gwt.dom.client;
 
 import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DeferredCommand;
@@ -212,37 +214,28 @@
   }
 
   /**
-   * scroll[Left|Top], scrollIntoView.
+   * scroll[Left|Top], getAbsolute[Left|Top].
    */
-  public void testGetAbsolutePositionWhenScrolled() {
-    final DivElement outer = Document.get().createDivElement();
-    final DivElement inner = Document.get().createDivElement();
+  public void testGetAbsolutePositionWhenBodyScrolled() {
+    Document doc = Document.get();
+    BodyElement body = doc.getBody();
 
-    outer.getStyle().setProperty("position", "absolute");
-    outer.getStyle().setProperty("top", "0px");
-    outer.getStyle().setProperty("left", "0px");
-    outer.getStyle().setProperty("overflow", "auto");
-    outer.getStyle().setProperty("width", "200px");
-    outer.getStyle().setProperty("height", "200px");
+    DivElement div = doc.createDivElement();
+    body.appendChild(div);
 
-    inner.getStyle().setProperty("marginTop", "800px");
-    inner.getStyle().setProperty("marginLeft", "800px");
+    div.setInnerText("foo");
+    div.getStyle().setPosition(Position.ABSOLUTE);
+    div.getStyle().setLeft(1000, Unit.PX);
+    div.getStyle().setTop(1000, Unit.PX);
 
-    outer.appendChild(inner);
-    Document.get().getBody().appendChild(outer);
-    inner.setInnerText(":-)");
-    inner.scrollIntoView();
+    int absLeft = div.getAbsoluteLeft();
+    int absTop = div.getAbsoluteTop();
 
-    // Ensure that we are scrolled.
-    assertTrue(outer.getScrollTop() > 0);
-    assertTrue(outer.getScrollLeft() > 0);
+    body.setScrollLeft(10000);
+    body.setScrollTop(10000);
 
-    outer.setScrollLeft(0);
-    outer.setScrollTop(0);
-
-    // Ensure that we are no longer scrolled.
-    assertEquals(outer.getScrollTop(), 0);
-    assertEquals(outer.getScrollLeft(), 0);
+    assertEquals(absLeft, div.getAbsoluteLeft());
+    assertEquals(absTop, div.getAbsoluteTop());
   }
 
   /**
@@ -308,6 +301,20 @@
   }
 
   /**
+   * Tests Element.is() and Element.as().
+   */
+  public void testIsAndAs() {
+    assertFalse(Element.is(Document.get()));
+
+    Node div = Document.get().createDivElement();
+    assertTrue(Element.is(div));
+    assertEquals("div", Element.as(div).getTagName().toLowerCase());
+
+    // Element.is(null) is allowed and should return false.
+    assertFalse(Element.is(null));
+  }
+
+  /**
    * Document.createElement('ns:tag'), getTagName().
    */
   public void testNamespaces() {
@@ -392,6 +399,40 @@
   }
 
   /**
+   * scroll[Left|Top], scrollIntoView.
+   */
+  public void testScrollIntoView() {
+    final DivElement outer = Document.get().createDivElement();
+    final DivElement inner = Document.get().createDivElement();
+
+    outer.getStyle().setProperty("position", "absolute");
+    outer.getStyle().setProperty("top", "0px");
+    outer.getStyle().setProperty("left", "0px");
+    outer.getStyle().setProperty("overflow", "auto");
+    outer.getStyle().setProperty("width", "200px");
+    outer.getStyle().setProperty("height", "200px");
+
+    inner.getStyle().setProperty("marginTop", "800px");
+    inner.getStyle().setProperty("marginLeft", "800px");
+
+    outer.appendChild(inner);
+    Document.get().getBody().appendChild(outer);
+    inner.setInnerText(":-)");
+    inner.scrollIntoView();
+
+    // Ensure that we are scrolled.
+    assertTrue(outer.getScrollTop() > 0);
+    assertTrue(outer.getScrollLeft() > 0);
+
+    outer.setScrollLeft(0);
+    outer.setScrollTop(0);
+
+    // Ensure that we are no longer scrolled.
+    assertEquals(outer.getScrollTop(), 0);
+    assertEquals(outer.getScrollLeft(), 0);
+  }
+
+  /**
    * Tests that scrollLeft behaves as expected in RTL mode.
    */
   public void testScrollLeftInRtl() {
@@ -535,18 +576,4 @@
     var ua = navigator.userAgent.toLowerCase();
     return ua.indexOf("msie") != -1;
   }-*/;
-
-  /**
-   * Tests Element.is() and Element.as().
-   */
-  public void testIsAndAs() {
-    assertFalse(Element.is(Document.get()));
-
-    Node div = Document.get().createDivElement();
-    assertTrue(Element.is(div));
-    assertEquals("div", Element.as(div).getTagName().toLowerCase());
-
-    // Element.is(null) is allowed and should return false.
-    assertFalse(Element.is(null));
-  }
 }