Fixed a bug where Safari 3 does not correctly calculate the value of DOM.getAbsoluteLeft(elem) because elem.offsetLeft does not include borders, whereas it did in Safari 2.

Patch by: jlabanca
Review by: jgw (desk review, DOMTest TBR)
Issue: 1711



git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.5@3082 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/dom/client/DOMImplSafari.java b/user/src/com/google/gwt/dom/client/DOMImplSafari.java
index 6d34d26..5190953 100644
--- a/user/src/com/google/gwt/dom/client/DOMImplSafari.java
+++ b/user/src/com/google/gwt/dom/client/DOMImplSafari.java
@@ -41,9 +41,15 @@
     while (elem) {
       left += elem.offsetLeft;
 
+      // Safari 3 does not include borders with offsetLeft, so we need to add
+      // the borders of the parent manually.
+      var parent = elem.offsetParent;
+      if (parent && $wnd.devicePixelRatio) {
+        left += parseInt(getComputedStyle(parent, '').getPropertyValue('border-left-width'));
+      }
+
       // Safari bug: a top-level absolutely positioned element includes the
       // body's offset position already.
-      var parent = elem.offsetParent;
       if (parent && (parent.tagName == 'BODY') &&
           (elem.style.position == 'absolute')) {
         break;
@@ -75,9 +81,15 @@
     while (elem) {
       top += elem.offsetTop;
 
+      // Safari 3 does not include borders with offsetTop, so we need to add the
+      // borders of the parent manually.
+      var parent = elem.offsetParent;
+      if (parent && $wnd.devicePixelRatio) {
+        top += parseInt(getComputedStyle(parent, '').getPropertyValue('border-top-width'));
+      }
+
       // Safari bug: a top-level absolutely positioned element includes the
       // body's offset position already.
-      var parent = elem.offsetParent;
       if (parent && (parent.tagName == 'BODY') &&
           (elem.style.position == 'absolute')) {
         break;
diff --git a/user/test/com/google/gwt/user/client/ui/DOMTest.java b/user/test/com/google/gwt/user/client/ui/DOMTest.java
index c58977f..f3bbcd2 100644
--- a/user/test/com/google/gwt/user/client/ui/DOMTest.java
+++ b/user/test/com/google/gwt/user/client/ui/DOMTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 Google Inc.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
@@ -21,6 +21,7 @@
 import com.google.gwt.user.client.DeferredCommand;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
 
 /**
  * Tests standard DOM operations in the {@link DOM} class.
@@ -46,6 +47,7 @@
     return (elem.childNodes.length);
   }-*/;
 
+  @Override
   public String getModuleName() {
     return "com.google.gwt.user.UserTest";
   }
@@ -130,6 +132,36 @@
   }
 
   /**
+   * Tests {@link DOM#getAbsoluteTop(Element)} and
+   * {@link DOM#getAbsoluteLeft(Element)} for consistency when the parent
+   * element has a border.
+   * 
+   */
+  public void testGetAbsolutePositionWithPixelBorders() {
+    final Element outer = DOM.createDiv();
+    final Element inner = DOM.createDiv();
+
+    outer.getStyle().setProperty("position", "relative");
+    outer.getStyle().setProperty("width", "200px");
+    outer.getStyle().setProperty("height", "200px");
+    outer.getStyle().setProperty("border", "2px solid blue");
+
+    inner.getStyle().setProperty("position", "absolute");
+    inner.getStyle().setProperty("top", "30px");
+    inner.getStyle().setProperty("left", "40px");
+    inner.setInnerText("inner");
+
+    outer.appendChild(inner);
+    RootPanel.getBodyElement().appendChild(outer);
+
+    // Clear the margin so that absolute position is predictable.
+    Window.setMargin("0px");
+
+    assertEquals(32, inner.getAbsoluteTop());
+    assertEquals(42, inner.getAbsoluteLeft());
+  }
+
+  /**
    * Tests the ability to do a parent-ward walk in the DOM.
    */
   public void testGetParent() {
@@ -167,18 +199,18 @@
   public void testIsOrHasChild() {
     Element div = DOM.createDiv();
     Element childDiv = DOM.createDiv();
-    
+
     assertFalse(DOM.isOrHasChild(div, childDiv));
     assertTrue(DOM.isOrHasChild(div, div));
-    
+
     DOM.appendChild(div, childDiv);
     assertTrue(DOM.isOrHasChild(div, childDiv));
     assertFalse(DOM.isOrHasChild(childDiv, div));
-    
+
     DOM.appendChild(RootPanel.getBodyElement(), div);
     assertTrue(DOM.isOrHasChild(div, childDiv));
     assertTrue(DOM.isOrHasChild(div, div));
-    assertFalse(DOM.isOrHasChild(childDiv, div));    
+    assertFalse(DOM.isOrHasChild(childDiv, div));
   }
 
   /**
@@ -234,6 +266,7 @@
     assertEndsWith("b0.gif", DOM.getImgSrc(image));
     delayTestFinish(2000);
     new Timer() {
+      @Override
       public void run() {
         assertEndsWith("b0.gif", DOM.getElementProperty(image, "src"));
         finishTest();
@@ -273,6 +306,7 @@
     assertEndsWith("a1.gif", DOM.getImgSrc(images[2]));
     delayTestFinish(2000);
     new Timer() {
+      @Override
       public void run() {
         assertEndsWith("a1.gif", DOM.getElementProperty(images[0], "src"));
         assertEndsWith("b1.gif", DOM.getElementProperty(images[1], "src"));
@@ -314,6 +348,7 @@
     assertEndsWith("a2.gif", DOM.getImgSrc(images[2]));
     delayTestFinish(2000);
     new Timer() {
+      @Override
       public void run() {
         assertEndsWith("b2.gif", DOM.getElementProperty(images[0], "src"));
         assertEndsWith("a2.gif", DOM.getElementProperty(images[1], "src"));
@@ -358,6 +393,7 @@
     assertEndsWith("b3.gif", DOM.getImgSrc(images[3]));
     delayTestFinish(2000);
     new Timer() {
+      @Override
       public void run() {
         assertEndsWith("b3.gif", DOM.getElementProperty(images[0], "src"));
         assertEndsWith("a3.gif", DOM.getElementProperty(images[1], "src"));
@@ -407,6 +443,7 @@
     assertEndsWith("b4.gif", DOM.getImgSrc(images[4]));
     delayTestFinish(2000);
     new Timer() {
+      @Override
       public void run() {
         assertEndsWith("a4.gif", DOM.getElementProperty(images[0], "src"));
         assertEndsWith("a4.gif", DOM.getElementProperty(images[1], "src"));