Adds a new class called DocumentRootImpl that sets the document root based on the render mode of the browser, strict or quirks.  The replaces all of the JSNI methods that used a conditional to pick doc.body or doc.documentRoot.  This patch also adds WindowImpl classes, separating the Window specific JSNI methods out of the DOMImpl classes.

Issue: 1400
Patch by: mmastrac, fredsa, ecc, jlabanca
Review by: ecc



git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1800 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/DocumentRoot.gwt.xml b/user/src/com/google/gwt/user/DocumentRoot.gwt.xml
new file mode 100644
index 0000000..211eb95
--- /dev/null
+++ b/user/src/com/google/gwt/user/DocumentRoot.gwt.xml
@@ -0,0 +1,27 @@
+<!--                                                                        -->
+<!-- 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   -->
+<!-- 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. License for the specific language governing permissions and   -->
+<!-- limitations under the License.                                         -->
+
+<!-- Deferred binding rules for DocumentRootImpl implementation.            -->
+<!--                                                                        -->
+<!-- This module is typically inherited via com.google.gwt.user.User        -->
+<!--                                                                        -->
+<module>
+	<inherits name="com.google.gwt.core.Core"/>
+	<inherits name="com.google.gwt.user.UserAgent"/>
+
+	<replace-with class="com.google.gwt.user.client.impl.DocumentRootImplSafari">
+		<when-type-is class="com.google.gwt.user.client.impl.DocumentRootImpl"/>
+		<when-property-is name="user.agent" value="safari"/>
+	</replace-with>
+</module>
diff --git a/user/src/com/google/gwt/user/User.gwt.xml b/user/src/com/google/gwt/user/User.gwt.xml
index 252649e..4110e74 100644
--- a/user/src/com/google/gwt/user/User.gwt.xml
+++ b/user/src/com/google/gwt/user/User.gwt.xml
@@ -20,7 +20,9 @@
 <module>
    <inherits name="com.google.gwt.core.Core"/>
    <inherits name="com.google.gwt.user.RemoteService"/>
+   <inherits name="com.google.gwt.user.DocumentRoot" />
    <inherits name="com.google.gwt.user.DOM"/>
+   <inherits name="com.google.gwt.user.Window" />
    <inherits name="com.google.gwt.user.HTTPRequest"/>
    <inherits name="com.google.gwt.user.History"/>
    <inherits name="com.google.gwt.user.Popup"/>
diff --git a/user/src/com/google/gwt/user/Window.gwt.xml b/user/src/com/google/gwt/user/Window.gwt.xml
new file mode 100644
index 0000000..ad8d23d
--- /dev/null
+++ b/user/src/com/google/gwt/user/Window.gwt.xml
@@ -0,0 +1,32 @@
+<!--                                                                        -->
+<!-- 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   -->
+<!-- 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. License for the specific language governing permissions and   -->
+<!-- limitations under the License.                                         -->
+
+<!-- Deferred binding rules for Window's implementation.                    -->
+<!--                                                                        -->
+<!-- This module is typically inherited via com.google.gwt.user.User        -->
+<!--                                                                        -->
+<module>
+	<inherits name="com.google.gwt.core.Core"/>
+	<inherits name="com.google.gwt.user.UserAgent"/>
+
+	<replace-with class="com.google.gwt.user.client.impl.WindowImplOpera">
+		<when-type-is class="com.google.gwt.user.client.impl.WindowImpl"/>
+		<when-property-is name="user.agent" value="opera"/>
+	</replace-with>
+
+	<replace-with class="com.google.gwt.user.client.impl.WindowImplSafari">
+		<when-type-is class="com.google.gwt.user.client.impl.WindowImpl"/>
+		<when-property-is name="user.agent" value="safari"/>
+	</replace-with>
+</module>
diff --git a/user/src/com/google/gwt/user/client/DOM.java b/user/src/com/google/gwt/user/client/DOM.java
index d8509d3..76cde13 100644
--- a/user/src/com/google/gwt/user/client/DOM.java
+++ b/user/src/com/google/gwt/user/client/DOM.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
@@ -1179,23 +1179,19 @@
   }
 
   /**
-   * Gets the height of the browser window's client area excluding the scroll
-   * bar.
-   * 
-   * @return the window's client height
+   * @deprecated  As of GWT 1.5, replaced by {@link Window#getClientHeight()}
    */
+  @Deprecated
   public static int windowGetClientHeight() {
-    return impl.windowGetClientHeight();
+    return Window.getClientHeight();
   }
 
   /**
-   * Gets the width of the browser window's client area excluding the vertical
-   * scroll bar.
-   * 
-   * @return the window's client width
+   * @deprecated  As of GWT 1.5, replaced by {@link Window#getClientWidth()}
    */
+  @Deprecated
   public static int windowGetClientWidth() {
-    return impl.windowGetClientWidth();
+    return Window.getClientWidth();
   }
 
   /**
diff --git a/user/src/com/google/gwt/user/client/Window.java b/user/src/com/google/gwt/user/client/Window.java
index d350c43..5768634 100644
--- a/user/src/com/google/gwt/user/client/Window.java
+++ b/user/src/com/google/gwt/user/client/Window.java
@@ -18,6 +18,7 @@
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
 import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.impl.WindowImpl;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -172,6 +173,7 @@
   }
 
   private static boolean handlersAreInitialized;
+  private static final WindowImpl impl = GWT.create(WindowImpl.class);
 
   private static ArrayList<WindowCloseListener> closingListeners;
   private static ArrayList<WindowResizeListener> resizeListeners;
@@ -230,9 +232,9 @@
    * 
    * @param enable <code>false</code> to disable window scrolling
    */
-  public static native void enableScrolling(boolean enable) /*-{
-    $doc.body.style.overflow = $doc.documentElement.style.overflow = enable ? '' : 'hidden';
-  }-*/;
+  public static void enableScrolling(boolean enable) {
+    impl.enableScrolling(enable);
+  }
 
   /**
    * Gets the height of the browser window's client area excluding the scroll
@@ -241,7 +243,7 @@
    * @return the window's client height
    */
   public static int getClientHeight() {
-    return DOM.windowGetClientHeight();
+    return impl.getClientHeight();
   }
 
   /**
@@ -251,7 +253,7 @@
    * @return the window's client width
    */
   public static int getClientWidth() {
-    return DOM.windowGetClientWidth();
+    return impl.getClientWidth();
   }
 
   /**
@@ -259,20 +261,18 @@
    * 
    * @return window's scroll left
    */
-  public static native int getScrollLeft() /*-{
-    // Standard mode || Quirks mode.  
-    return $doc.documentElement.scrollLeft || $doc.body.scrollLeft
-  }-*/;
+  public static int getScrollLeft() {
+    return impl.getScrollLeft();
+  }
 
   /**
    * Get the window's scroll top.
    * 
    * @return the window's scroll top
    */
-  public static native int getScrollTop() /*-{
-    // Standard mode || Quirks mode. 
-    return $doc.documentElement.scrollTop || $doc.body.scrollTop;
-  }-*/;
+  public static int getScrollTop() {
+    return impl.getScrollTop();
+  }
 
   /**
    * Gets the browser window's current title.
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImpl.java b/user/src/com/google/gwt/user/client/impl/DOMImpl.java
index e2f3c96..a0b49bf 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImpl.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImpl.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
@@ -394,22 +394,6 @@
   }-*/;
 
   /**
-   * Gets the height of the browser window's client area excluding the scroll
-   * bar.
-   * 
-   * @return the window's client height
-   */
-  public abstract int windowGetClientHeight();
-
-  /**
-   * Gets the width of the browser window's client area excluding the vertical
-   * scroll bar.
-   * 
-   * @return the window's client width
-   */
-  public abstract int windowGetClientWidth();
-
-  /**
    * Initializes the event dispatch system.
    */
   protected abstract void initEventSystem();
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
index efe794f..7902753 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.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
@@ -26,18 +26,6 @@
 
   private static Element currentEventTarget;
 
-  private static native int getBodyClientLeft() /*-{
-    // Standard mode uses $doc.documentElement.clientLeft
-    // Quirks mode uses $doc.body.clientLeft
-    return $doc.documentElement.clientLeft || $doc.body.clientLeft;
-  }-*/;
-
-  private static native int getBodyClientTop() /*-{
-    // Standards mode uses $doc.documentElement.clientTop
-    // Quirks mode uses $doc.body.clientTop
-    return $doc.documentElement.clientTop || $doc.body.clientTop;
-  }-*/;
-
   @Override
   public native boolean compare(Element elem1, Element elem2) /*-{
     if (!elem1 && !elem2)
@@ -68,13 +56,13 @@
   @Override
   public native int eventGetClientX(Event evt) /*-{
     return evt.clientX -
-        @com.google.gwt.user.client.impl.DOMImplIE6::getBodyClientLeft()();
+        @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.clientLeft;
   }-*/;
 
   @Override
   public native int eventGetClientY(Event evt) /*-{
     return evt.clientY -
-        @com.google.gwt.user.client.impl.DOMImplIE6::getBodyClientTop()();
+        @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.clientTop;
   }-*/;
 
   @Override
@@ -115,19 +103,17 @@
 
   @Override
   public native int getAbsoluteLeft(Element elem) /*-{
-    // Standard mode || Quirks mode.
-    var scrollLeft = $doc.documentElement.scrollLeft || $doc.body.scrollLeft;
-    return (elem.getBoundingClientRect().left + scrollLeft)
-        - @com.google.gwt.user.client.impl.DOMImplIE6::getBodyClientLeft()();
+    return elem.getBoundingClientRect().left
+        + @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.scrollLeft
+        - @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.clientLeft;
   }-*/;
 
   @Override
   public native int getAbsoluteTop(Element elem) /*-{
-    // Standard mode || Quirks mode.
-    var scrollTop = $doc.documentElement.scrollTop || $doc.body.scrollTop;
-    return (elem.getBoundingClientRect().top + scrollTop)
-        - @com.google.gwt.user.client.impl.DOMImplIE6::getBodyClientTop()();
-   }-*/;
+    return elem.getBoundingClientRect().top
+        + @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.scrollTop
+        - @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.clientTop;
+  }-*/;
 
   @Override
   public native Element getChild(Element elem, int index) /*-{
@@ -301,18 +287,6 @@
     sinkEventsImpl(elem, bits);
   }
 
-  @Override
-  public native int windowGetClientHeight() /*-{
-    // IE standard mode || IE quirks mode.
-    return $doc.documentElement.clientHeight || $doc.body.clientHeight; 
-  }-*/;
-
-  @Override
-  public native int windowGetClientWidth() /*-{
-    // IE standard mode || IE quirks mode.
-    return $doc.documentElement.clientWidth || $doc.body.clientWidth;
-  }-*/;
-
   private native void releaseCaptureImpl(Element elem) /*-{
     elem.releaseCapture();
   }-*/;
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 4051d3f..055b0f7 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.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
@@ -132,28 +132,6 @@
   }-*/;
 
   @Override
-  public native int windowGetClientHeight() /*-{
-    // Standards mode: 
-    //    doc.body.clientHeight --> client height with scrollbars.
-    //    doc.documentElement.clientHeight --> client height without scrollbars.
-    // Quirks mode:
-    //    doc.body.clientHeight --> client height without scrollbars.
-    //    doc.documentElement.clientHeight --> document height.
-    // So, must switch value on compatMode.
-    return ($doc.compatMode == 'BackCompat')?
-      $doc.body.clientHeight:
-      $doc.documentElement.clientHeight;
-  }-*/;
-
-  @Override
-  public native int windowGetClientWidth() /*-{
-    // See comment for windowGetClientHeight. 
-    return ($doc.compatMode == 'BackCompat')?
-      $doc.body.clientWidth:
-      $doc.documentElement.clientWidth;
-  }-*/;
-
-  @Override
   protected void initEventSystem() {
     super.initEventSystem();
     initSyntheticMouseUpEvents();
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 837dd7a..830a92e 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplMozillaOld.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplMozillaOld.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
@@ -25,7 +25,6 @@
  * https://bugzilla.mozilla.org/show_bug.cgi?id=330619
  */
 public class DOMImplMozillaOld extends DOMImplMozilla {
-  
   @Override
   public native int getAbsoluteLeft(Element elem) /*-{
     var style = $doc.defaultView.getComputedStyle(elem, null);
@@ -42,8 +41,8 @@
       parent = parent.parentNode;
     }
 
-    // Must cover both Standard and Quirks mode.
-    return left + $doc.body.scrollLeft + $doc.documentElement.scrollLeft;  
+    return left +
+      @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.scrollLeft;
   }-*/;
 
   @Override
@@ -62,7 +61,7 @@
       parent = parent.parentNode;
     }
 
-    // Must cover both Standard and Quirks mode.
-    return top + $doc.body.scrollTop + $doc.documentElement.scrollTop;
+    return top +
+      @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.scrollTop;
   }-*/;
 }
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java b/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java
index ac38d80..6bb87ef 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplOpera.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
@@ -72,16 +72,6 @@
     return top;
   }-*/;
 
-  @Override
-  public native int windowGetClientHeight() /*-{
-    return $doc.body.clientHeight;
-  }-*/;
-
-  @Override
-  public native int windowGetClientWidth() /*-{
-    return $doc.body.clientWidth;
-  }-*/;
-
   /**
    * As Opera sinks events very quickly, adding guards to prevent the sinking of
    * events actually slows Opera down.
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 54a8e85..5bad5b4 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplSafari.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplSafari.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
@@ -120,26 +120,4 @@
       select.insertBefore(newOption, select.children[index]);
     }
   }-*/;
-
-  /**
-   * Gets the height of the browser window's client area excluding the
-   * scroll bar.
-   * 
-   * @return the window's client height
-   */
-  @Override
-  public native int windowGetClientHeight() /*-{
-    return $wnd.innerHeight;
-  }-*/;
-
-  /**
-   * Gets the width of the browser window's client area excluding the
-   * vertical scroll bar.
-   * 
-   * @return the window's client width
-   */
-  @Override
-  public native int windowGetClientWidth() /*-{
-    return $wnd.innerWidth;
-  }-*/;
 }
diff --git a/user/src/com/google/gwt/user/client/impl/DocumentRootImpl.java b/user/src/com/google/gwt/user/client/impl/DocumentRootImpl.java
new file mode 100644
index 0000000..1b4cf58
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/impl/DocumentRootImpl.java
@@ -0,0 +1,33 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.impl;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Element;
+
+/**
+ * Native implementation used by {@link WindowImpl} and {@link DOMImpl} to
+ * access the appropriate documentRoot element, which varies based on the render
+ * mode of the browser.
+ */
+public class DocumentRootImpl {
+  protected static Element documentRoot =
+    ((DocumentRootImpl) GWT.create(DocumentRootImpl.class)).getDocumentRoot();
+
+  protected native Element getDocumentRoot() /*-{
+    return $doc.compatMode == 'CSS1Compat' ? $doc.documentElement : $doc.body;
+  }-*/;
+}
diff --git a/user/src/com/google/gwt/user/client/impl/DocumentRootImplSafari.java b/user/src/com/google/gwt/user/client/impl/DocumentRootImplSafari.java
new file mode 100644
index 0000000..f88c4ab
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/impl/DocumentRootImplSafari.java
@@ -0,0 +1,32 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.impl;
+
+import com.google.gwt.user.client.Element;
+
+/**
+ * Safari implementation of {@link DocumentRootImpl}.
+ */
+public class DocumentRootImplSafari extends DocumentRootImpl {
+  @Override
+  protected native Element getDocumentRoot() /*-{
+    // Safari does not implement $doc.compatMode.
+    // Use a CSS test to determine rendering mode.
+    var elem = $doc.createElement('div');
+    elem.style.cssText = "width:0px;width:1";
+    return parseInt(elem.style.width) != 1 ? $doc.documentElement : $doc.body;
+  }-*/;
+}
diff --git a/user/src/com/google/gwt/user/client/impl/WindowImpl.java b/user/src/com/google/gwt/user/client/impl/WindowImpl.java
new file mode 100644
index 0000000..3d3339d
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/impl/WindowImpl.java
@@ -0,0 +1,43 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.impl;
+
+/**
+ * Native implementation associated with
+ * {@link com.google.gwt.user.client.Window}.
+ */
+public class WindowImpl {
+  public native void enableScrolling(boolean enable) /*-{
+   @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.style.overflow =
+       enable ? "auto" : "hidden";
+  }-*/;
+
+  public native int getClientHeight() /*-{
+   return @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.clientHeight;
+  }-*/;
+
+  public native int getClientWidth() /*-{
+   return @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.clientWidth;
+  }-*/;
+
+  public native int getScrollLeft() /*-{
+   return @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.scrollLeft;
+  }-*/;
+
+  public native int getScrollTop() /*-{
+   return @com.google.gwt.user.client.impl.DocumentRootImpl::documentRoot.scrollTop;
+  }-*/;
+}
diff --git a/user/src/com/google/gwt/user/client/impl/WindowImplOpera.java b/user/src/com/google/gwt/user/client/impl/WindowImplOpera.java
new file mode 100644
index 0000000..b828e18
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/impl/WindowImplOpera.java
@@ -0,0 +1,31 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.impl;
+
+/**
+ * Opera implementation of {@link com.google.gwt.user.client.impl.WindowImpl}.
+ */
+public class WindowImplOpera extends WindowImpl {
+  @Override
+  public native int getClientHeight() /*-{
+    return $doc.body.clientHeight;
+  }-*/;
+
+  @Override
+  public native int getClientWidth() /*-{
+    return $doc.body.clientWidth;
+  }-*/;
+}
diff --git a/user/src/com/google/gwt/user/client/impl/WindowImplSafari.java b/user/src/com/google/gwt/user/client/impl/WindowImplSafari.java
new file mode 100644
index 0000000..b98d53d
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/impl/WindowImplSafari.java
@@ -0,0 +1,31 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client.impl;
+
+/**
+ * Safari implementation of {@link com.google.gwt.user.client.impl.WindowImpl}.
+ */
+public class WindowImplSafari extends WindowImpl {
+  @Override
+  public native int getScrollLeft() /*-{
+    return $doc.body.scrollLeft;
+  }-*/;
+
+  @Override
+  public native int getScrollTop() /*-{
+    return $doc.body.scrollTop;
+  }-*/;
+}
diff --git a/user/test/com/google/gwt/user/client/WindowTest.java b/user/test/com/google/gwt/user/client/WindowTest.java
index 03a2310..3f1ceef 100644
--- a/user/test/com/google/gwt/user/client/WindowTest.java
+++ b/user/test/com/google/gwt/user/client/WindowTest.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
@@ -16,14 +16,15 @@
 package com.google.gwt.user.client;
 
 import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.user.client.ui.RootPanel;
 import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.RootPanel;
 
 /**
  * Test Case for {@link Cookies}.
  */
 public class WindowTest extends GWTTestCase {
 
+  @Override
   public String getModuleName() {
     return "com.google.gwt.user.User";
   }