Merged changes from 1.5 into trunk.

svn merge -r3188:3205 https://google-web-toolkit.googlecode.com/svn/releases/1.5 .


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@3206 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/dom/client/DOMImplMozilla.java b/user/src/com/google/gwt/dom/client/DOMImplMozilla.java
index 3b9d0ec..5a637c5 100644
--- a/user/src/com/google/gwt/dom/client/DOMImplMozilla.java
+++ b/user/src/com/google/gwt/dom/client/DOMImplMozilla.java
@@ -22,47 +22,45 @@
 
   @Override
   public native int getAbsoluteLeft(Element elem) /*-{
-    // We cannot use DOMImpl here because offsetLeft/Top return erroneous
-    // values when overflow is not visible.  We have to difference screenX
-    // here due to a change in getBoxObjectFor which causes inconsistencies
-    // on whether the calculations are inside or outside of the element's
-    // border.
-    try {
+    // Firefox 3 is actively throwing errors when getBoxObjectFor() is called,
+    // so we use getBoundingClientRect() whenever possible (but it's not
+    // supported on older versions). If changing this code, make sure to check
+    // the museum entry for issue 1932.
+    if (Element.prototype.getBoundingClientRect) {
+      // getBoundingClientRect().left is off by the document element's
+      // border-left-width.
+      var style = $wnd.getComputedStyle($doc.documentElement, '')
+      return elem.getBoundingClientRect().left + parseInt(style.borderLeftWidth);
+    } else {
+      // We cannot use DOMImpl here because offsetLeft/Top return erroneous
+      // values when overflow is not visible.  We have to difference screenX
+      // here due to a change in getBoxObjectFor which causes inconsistencies
+      // on whether the calculations are inside or outside of the element's
+      // border.
       return $doc.getBoxObjectFor(elem).screenX
           - $doc.getBoxObjectFor($doc.documentElement).screenX;
-    } catch (e) {
-      // This works around a bug in the FF3 betas. The bug
-      // should be fixed before they release, so this can
-      // be removed at a later date.
-      // https://bugzilla.mozilla.org/show_bug.cgi?id=409111
-      // DOMException.WRONG_DOCUMENT_ERR == 4
-      if (e.code == 4) {
-        return 0;
-      }
-      throw e;
     }
   }-*/;
 
   @Override
   public native int getAbsoluteTop(Element elem) /*-{
-    // We cannot use DOMImpl here because offsetLeft/Top return erroneous
-    // values when overflow is not visible.  We have to difference screenY
-    // here due to a change in getBoxObjectFor which causes inconsistencies
-    // on whether the calculations are inside or outside of the element's
-    // border.
-    try {
+    // Firefox 3 is actively throwing errors when getBoxObjectFor() is called,
+    // so we use getBoundingClientRect() whenever possible (but it's not
+    // supported on older versions). If changing this code, make sure to check
+    // the museum entry for issue 1932.
+    if (Element.prototype.getBoundingClientRect) {
+      // getBoundingClientRect().top is off by the document element's
+      // border-top-width.
+      var style = $wnd.getComputedStyle($doc.documentElement, '')
+      return elem.getBoundingClientRect().top + parseInt(style.borderTopWidth);
+    } else {
+      // We cannot use DOMImpl here because offsetLeft/Top return erroneous
+      // values when overflow is not visible.  We have to difference screenX
+      // here due to a change in getBoxObjectFor which causes inconsistencies
+      // on whether the calculations are inside or outside of the element's
+      // border.
       return $doc.getBoxObjectFor(elem).screenY
           - $doc.getBoxObjectFor($doc.documentElement).screenY;
-    } catch (e) {
-      // This works around a bug in the FF3 betas. The bug
-      // should be fixed before they release, so this can
-      // be removed at a later date.
-      // https://bugzilla.mozilla.org/show_bug.cgi?id=409111
-      // DOMException.WRONG_DOCUMENT_ERR == 4
-      if (e.code == 4) {
-        return 0;
-      }
-      throw e;
     }
   }-*/;
 
diff --git a/user/src/com/google/gwt/dom/client/DOMImplOpera.java b/user/src/com/google/gwt/dom/client/DOMImplOpera.java
index e1011fa..e8c27e4 100644
--- a/user/src/com/google/gwt/dom/client/DOMImplOpera.java
+++ b/user/src/com/google/gwt/dom/client/DOMImplOpera.java
@@ -23,10 +23,10 @@
   @Override
   public native int getAbsoluteLeft(Element elem) /*-{
     var left = 0;
-    var curr = elem.parentNode;
-    // This intentionally excludes body
-    while (curr != $doc.body) {
 
+    // This intentionally excludes body and its ancestors
+    var curr = elem.parentNode;
+    while (curr && curr.offsetParent) {
       // see https://bugs.opera.com/show_bug.cgi?id=249965
       // The net effect is that TR and TBODY elemnts report the scroll offsets
       // of the BODY and HTML elements instead of 0.
@@ -47,9 +47,9 @@
   public native int getAbsoluteTop(Element elem) /*-{
     var top = 0;
 
-    // This intentionally excludes body
+    // This intentionally excludes body and its ancestors
     var curr = elem.parentNode;
-    while (curr != $doc.body) {
+    while (curr && curr.offsetParent) {
       // see getAbsoluteLeft()
       if (curr.tagName != 'TR' && curr.tagName != 'TBODY') {
         top -= curr.scrollTop;
diff --git a/user/src/com/google/gwt/user/client/DOM.java b/user/src/com/google/gwt/user/client/DOM.java
index b36d04b..ab29f1a 100644
--- a/user/src/com/google/gwt/user/client/DOM.java
+++ b/user/src/com/google/gwt/user/client/DOM.java
@@ -884,7 +884,7 @@
    * @param attr the name of the attribute to be retrieved
    * @return the style attribute's value as an integer
    */
-  public native int getIntStyleAttribute(Element elem, String attr) /*-{
+  public static native int getIntStyleAttribute(Element elem, String attr) /*-{
     return parseInt(elem.style[attr]) || 0;
   }-*/;
 
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java b/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java
index 6c5c0df..7440b5f 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java
@@ -1,12 +1,12 @@
 /*
  * 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
  * the License at
- *
+ * 
  * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -25,12 +25,40 @@
 
   @Override
   public native int eventGetClientX(Event evt) /*-{
-    return evt.clientX - $doc.getBoxObjectFor($doc.getElementsByTagName('html')[0]).x || 0;
+    var htmlOffset;
+    // Firefox 3 is actively throwing errors when getBoxObjectFor() is called,
+    // so we use getBoundingClientRect() whenever possible (but it's not
+    // supported on older versions). If changing this code, make sure to check
+    // the museum entry for issue 1932.
+    if (Element.prototype.getBoundingClientRect) {
+      // getBoundingClientRect().left is off by the document element's
+      // border-left-width.
+      var style = $wnd.getComputedStyle($doc.documentElement, '')
+      htmlOffset = $doc.documentElement.getBoundingClientRect().left +
+        parseInt(style.borderLeftWidth);
+    } else {
+      htmlOffset = $doc.getBoxObjectFor($doc.documentElement).x || 0;
+    }
+    return evt.clientX - htmlOffset;
   }-*/;
 
   @Override
   public native int eventGetClientY(Event evt) /*-{
-    return evt.clientY - $doc.getBoxObjectFor($doc.getElementsByTagName('html')[0]).y || 0;
+    var htmlOffset;
+    // Firefox 3 is actively throwing errors when getBoxObjectFor() is called,
+    // so we use getBoundingClientRect() whenever possible (but it's not
+    // supported on older versions). If changing this code, make sure to check
+    // the museum entry for issue 1932.
+    if (Element.prototype.getBoundingClientRect) {
+      // getBoundingClientRect().top is off by the document element's
+      // border-top-width.
+      var style = $wnd.getComputedStyle($doc.documentElement, '')
+      htmlOffset = $doc.documentElement.getBoundingClientRect().top +
+        parseInt(style.borderTopWidth);
+    } else {
+      htmlOffset = $doc.getBoxObjectFor($doc.documentElement).y || 0;
+    }
+    return evt.clientY - htmlOffset;
   }-*/;
 
   @Override
diff --git a/user/src/com/google/gwt/user/client/ui/impl/PopupImplIE6.java b/user/src/com/google/gwt/user/client/ui/impl/PopupImplIE6.java
index 1dffb8d..74d28b3 100644
--- a/user/src/com/google/gwt/user/client/ui/impl/PopupImplIE6.java
+++ b/user/src/com/google/gwt/user/client/ui/impl/PopupImplIE6.java
@@ -25,10 +25,15 @@
 
   @Override
   public native void onHide(Element popup) /*-{
+    // It is at least rarely possible to get an onHide() without a matching
+    // onShow(), usually because of timing issues created by animations. So
+    // we're careful not to assume the existence of '__frame' here.
     var frame = popup.__frame;
-    frame.parentElement.removeChild(frame);
-    popup.__frame = null;
-    frame.__popup = null;
+    if (frame) {
+      frame.parentElement.removeChild(frame);
+      frame.__popup = null;
+      popup.__frame = null;
+    }
   }-*/;
 
   @Override
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 9177c28..7d61e56 100644
--- a/user/test/com/google/gwt/user/client/ui/DOMTest.java
+++ b/user/test/com/google/gwt/user/client/ui/DOMTest.java
@@ -15,6 +15,8 @@
  */
 package com.google.gwt.user.client.ui;
 
+import com.google.gwt.dom.client.BodyElement;
+import com.google.gwt.dom.client.Document;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
@@ -163,6 +165,22 @@
   }
 
   /**
+   * Tests getAbsoluteLeft/Top() for the document.body element. This used to
+   * cause exceptions to be thrown on Opera (see issue 1556).
+   */
+  public void testGetBodyAbsolutePosition() {
+    try {
+      // The body's absolute left/top depends upon the browser, but we just
+      // need to make sure nothing goes wrong reading them.
+      BodyElement body = Document.get().getBody();
+      body.getAbsoluteLeft();
+      body.getAbsoluteTop();
+    } catch (Throwable e) {
+      fail("Exception occurred getting the absolute position of the body");
+    }
+  }
+
+  /**
    * Tests the ability to do a parent-ward walk in the DOM.
    */
   public void testGetParent() {
diff --git a/user/test/com/google/gwt/user/client/ui/WidgetSubclassingTest.java b/user/test/com/google/gwt/user/client/ui/WidgetSubclassingTest.java
index 9432fdb..6e5e83d 100644
--- a/user/test/com/google/gwt/user/client/ui/WidgetSubclassingTest.java
+++ b/user/test/com/google/gwt/user/client/ui/WidgetSubclassingTest.java
@@ -33,194 +33,194 @@
   }
 
   // Correct subclasses.
-  public static class TestAnchor extends Anchor {
+  private static class TestAnchor extends Anchor {
     public TestAnchor() {
       super(Document.get().createAnchorElement());
     }
   }
 
-  public static class TestButton extends Button {
+  private static class TestButton extends Button {
     public TestButton() {
       super(Document.get().createButtonElement());
     }
   }
 
-  public static class TestFileUpload extends FileUpload {
+  private static class TestFileUpload extends FileUpload {
     public TestFileUpload() {
       super(Document.get().createFileInputElement());
     }
   }
 
-  public static class TestFormPanel extends FormPanel {
+  private static class TestFormPanel extends FormPanel {
     public TestFormPanel() {
       super(Document.get().createFormElement());
     }
   }
 
-  public static class TestFrame extends Frame {
+  private static class TestFrame extends Frame {
     public TestFrame() {
       super(Document.get().createIFrameElement());
     }
   }
 
-  public static class TestHidden extends Hidden {
+  private static class TestHidden extends Hidden {
     public TestHidden() {
       super(Document.get().createHiddenInputElement());
     }
   }
 
-  public static class TestHTML extends HTML {
+  private static class TestHTML extends HTML {
     public TestHTML() {
       super(Document.get().createDivElement());
     }
   }
 
-  public static class TestImage extends Image {
+  private static class TestImage extends Image {
     public TestImage() {
       super(Document.get().createImageElement());
     }
   }
 
-  public static class TestInlineHTML extends InlineHTML {
+  private static class TestInlineHTML extends InlineHTML {
     public TestInlineHTML() {
       super(Document.get().createSpanElement());
     }
   }
 
-  public static class TestInlineLabel extends InlineLabel {
+  private static class TestInlineLabel extends InlineLabel {
     public TestInlineLabel() {
       super(Document.get().createSpanElement());
     }
   }
 
-  public static class TestLabel extends Label {
+  private static class TestLabel extends Label {
     public TestLabel() {
       super(Document.get().createSpanElement());
     }
   }
 
-  public static class TestListBox extends ListBox {
+  private static class TestListBox extends ListBox {
     public TestListBox() {
       super(Document.get().createSelectElement());
     }
   }
 
-  public static class TestPasswordTextBox extends PasswordTextBox {
+  private static class TestPasswordTextBox extends PasswordTextBox {
     public TestPasswordTextBox() {
       super(Document.get().createPasswordInputElement());
     }
   }
 
-  public static class TestSimpleCheckBox extends SimpleCheckBox {
+  private static class TestSimpleCheckBox extends SimpleCheckBox {
     public TestSimpleCheckBox() {
       super(Document.get().createCheckInputElement());
     }
   }
 
-  public static class TestSimpleRadioButton extends SimpleRadioButton {
+  private static class TestSimpleRadioButton extends SimpleRadioButton {
     public TestSimpleRadioButton() {
       super(Document.get().createRadioInputElement("group"));
     }
   }
 
-  public static class TestTextBox extends TextBox {
+  private static class TestTextBox extends TextBox {
     public TestTextBox() {
       super(Document.get().createTextInputElement());
     }
   }
 
   // Broken subclasses.
-  public static class BrokenAnchor extends Anchor {
+  private static class BrokenAnchor extends Anchor {
     public BrokenAnchor() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenButton extends Button {
+  private static class BrokenButton extends Button {
     public BrokenButton() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenFileUpload extends FileUpload {
+  private static class BrokenFileUpload extends FileUpload {
     public BrokenFileUpload() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenFormPanel extends FormPanel {
+  private static class BrokenFormPanel extends FormPanel {
     public BrokenFormPanel() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenFrame extends Frame {
+  private static class BrokenFrame extends Frame {
     public BrokenFrame() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenHidden extends Hidden {
+  private static class BrokenHidden extends Hidden {
     public BrokenHidden() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenHTML extends HTML {
+  private static class BrokenHTML extends HTML {
     public BrokenHTML() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenImage extends Image {
+  private static class BrokenImage extends Image {
     public BrokenImage() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenInlineHTML extends InlineHTML {
+  private static class BrokenInlineHTML extends InlineHTML {
     public BrokenInlineHTML() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenInlineLabel extends InlineLabel {
+  private static class BrokenInlineLabel extends InlineLabel {
     public BrokenInlineLabel() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenLabel extends Label {
+  private static class BrokenLabel extends Label {
     public BrokenLabel() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenListBox extends ListBox {
+  private static class BrokenListBox extends ListBox {
     public BrokenListBox() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenPasswordTextBox extends PasswordTextBox {
+  private static class BrokenPasswordTextBox extends PasswordTextBox {
     public BrokenPasswordTextBox() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenSimpleCheckBox extends SimpleCheckBox {
+  private static class BrokenSimpleCheckBox extends SimpleCheckBox {
     public BrokenSimpleCheckBox() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenSimpleRadioButton extends SimpleRadioButton {
+  private static class BrokenSimpleRadioButton extends SimpleRadioButton {
     public BrokenSimpleRadioButton() {
       super(Document.get().createBRElement());
     }
   }
 
-  public static class BrokenTextBox extends TextBox {
+  private static class BrokenTextBox extends TextBox {
     public BrokenTextBox() {
       super(Document.get().createBRElement());
     }