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