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"));