Fixes Issue #1093.
Fixes an off-by-scroll issue in DOMImplMozillaOld.getAbsoluteTop/Left and
DOMImplSafari.getAbsoluteTop/Left. The implementation for Safari and older
Mozilla both took into account an element's scrollTop/Left in computing its
absolute position, which is incorrect as the scroll values are only relevant
to the element's children.
Review by: jgw
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1195 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplMozillaOld.java b/user/src/com/google/gwt/user/client/impl/DOMImplMozillaOld.java
index 9547e07..c710084 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplMozillaOld.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplMozillaOld.java
@@ -31,8 +31,8 @@
var left = $doc.getBoxObjectFor(elem).x - Math.round(
style.getPropertyCSSValue('border-left-width').getFloatValue(
CSSPrimitiveValue.CSS_PX));
- var parent = elem;
-
+
+ var parent = elem.parentNode;
while (parent) {
// Sometimes get NAN.
if (parent.scrollLeft > 0) {
@@ -51,7 +51,7 @@
style.getPropertyCSSValue('border-top-width').getFloatValue(
CSSPrimitiveValue.CSS_PX));
- var parent = elem;
+ var parent = elem.parentNode;
while (parent) {
// Sometimes get NAN.
if (parent.scrollTop > 0) {
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplSafari.java b/user/src/com/google/gwt/user/client/impl/DOMImplSafari.java
index 9639353..b196f20 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplSafari.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplSafari.java
@@ -44,12 +44,15 @@
}
var left = 0;
- var curr = elem;
- // This intentionally excludes body which has a null offsetParent.
- while (curr.offsetParent) {
- left -= curr.scrollLeft;
- curr = curr.parentNode;
+ var curr = elem.parentNode;
+ if (curr) {
+ // This intentionally excludes body which has a null offsetParent.
+ while (curr.offsetParent) {
+ left -= curr.scrollLeft;
+ curr = curr.parentNode;
+ }
}
+
while (elem) {
left += elem.offsetLeft;
@@ -74,12 +77,15 @@
}
var top = 0;
- var curr = elem;
- // This intentionally excludes body which has a null offsetParent.
- while (curr.offsetParent) {
- top -= curr.scrollTop;
- curr = curr.parentNode;
+ var curr = elem.parentNode;
+ if (curr) {
+ // This intentionally excludes body which has a null offsetParent.
+ while (curr.offsetParent) {
+ top -= curr.scrollTop;
+ curr = curr.parentNode;
+ }
}
+
while (elem) {
top += elem.offsetTop;
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 ca724f8..887d788 100644
--- a/user/test/com/google/gwt/user/client/ui/DOMTest.java
+++ b/user/test/com/google/gwt/user/client/ui/DOMTest.java
@@ -90,6 +90,39 @@
}
/**
+ * Tests {@link DOM#getAbsoluteTop(Element)} and
+ * {@link DOM#getAbsoluteLeft(Element)} for consistency when the element
+ * contains children and has scrollbars. See issue #1093 for more details.
+ *
+ */
+ public void testGetAbsolutePositionWhenScrolled() {
+ final Element outer = DOM.createDiv();
+ final Element inner = DOM.createDiv();
+
+ DOM.setStyleAttribute(outer, "position", "absolute");
+ DOM.setStyleAttribute(outer, "top", "0px");
+ DOM.setStyleAttribute(outer, "left", "0px");
+ DOM.setStyleAttribute(outer, "overflow", "auto");
+ DOM.setStyleAttribute(outer, "width", "200px");
+ DOM.setStyleAttribute(outer, "height", "200px");
+
+ DOM.setStyleAttribute(inner, "marginTop", "800px");
+ DOM.setStyleAttribute(inner, "marginLeft", "800px");
+
+ DOM.appendChild(outer, inner);
+ DOM.appendChild(RootPanel.getBodyElement(), outer);
+ DOM.setInnerText(inner, ":-)");
+ DOM.scrollIntoView(inner);
+
+ // Ensure that we are scrolled.
+ assertTrue(DOM.getElementPropertyInt(outer, "scrollTop") > 0);
+ assertTrue(DOM.getElementPropertyInt(outer, "scrollLeft") > 0);
+
+ assertEquals(0, DOM.getAbsoluteTop(outer));
+ assertEquals(0, DOM.getAbsoluteLeft(outer));
+ }
+
+ /**
* Tests the ability to do a parent-ward walk in the DOM.
*/
public void testGetParent() {
@@ -106,7 +139,7 @@
// If we get here, we pass, because we encountered no errors going to the
// top of the parent hierarchy.
}
-
+
/**
* Tests {@link DOM#insertChild(Element, Element, int)}.
*
@@ -115,7 +148,8 @@
Element parent = RootPanel.get().getElement();
Element div = DOM.createDiv();
DOM.insertChild(parent, div, Integer.MAX_VALUE);
- Element child = DOM.getChild(RootPanel.get().getElement(), DOM.getChildCount(parent) - 1);
+ Element child = DOM.getChild(RootPanel.get().getElement(),
+ DOM.getChildCount(parent) - 1);
assertEquals(div, child);
}