Author: jlaba...@google.com
Date: Mon Apr 13 12:21:06 2009
New Revision: 5216

Modified:
    trunk/user/src/com/google/gwt/dom/client/DOMImpl.java
    trunk/user/src/com/google/gwt/dom/client/DOMImplIE6.java
    trunk/user/src/com/google/gwt/dom/client/DOMImplSafari.java
    trunk/user/src/com/google/gwt/dom/client/Document.java
    trunk/user/src/com/google/gwt/dom/client/Element.java
    trunk/user/test/com/google/gwt/dom/client/ElementTest.java

Log:
IE and WebKit report incorrect values for scroll-left in RTL mode, and I've  
normalized on what Firefox does, which is to report negative offsets from  
the right edge. This makes the absolute-positioning math work out properly,  
and is what other toolkits seem to have standardized on as well.

Patch by: jgw
Review by: jlabanca



Modified: trunk/user/src/com/google/gwt/dom/client/DOMImpl.java
==============================================================================
--- trunk/user/src/com/google/gwt/dom/client/DOMImpl.java       (original)
+++ trunk/user/src/com/google/gwt/dom/client/DOMImpl.java       Mon Apr 13  
12:21:06 2009
@@ -224,6 +224,10 @@
      return doc.getViewportElement().getScrollLeft();
    }

+  public native int getScrollLeft(Element elem) /*-{
+    return elem.scrollLeft || 0;
+  }-*/;
+
    public int getScrollTop(Document doc) {
      return doc.getViewportElement().getScrollTop();
    }
@@ -309,6 +313,10 @@
    public void setScrollLeft(Document doc, int left) {
      doc.getViewportElement().setScrollLeft(left);
    }
+
+  public native void setScrollLeft(Element elem, int left) /*-{
+    elem.scrollLeft = left;
+  }-*/;

    public void setScrollTop(Document doc, int top) {
      doc.getViewportElement().setScrollTop(top);

Modified: trunk/user/src/com/google/gwt/dom/client/DOMImplIE6.java
==============================================================================
--- trunk/user/src/com/google/gwt/dom/client/DOMImplIE6.java    (original)
+++ trunk/user/src/com/google/gwt/dom/client/DOMImplIE6.java    Mon Apr 13  
12:21:06 2009
@@ -193,6 +193,14 @@
      return elem.parentElement;
    }-*/;

+  @Override
+  public int getScrollLeft(Element elem) {
+    if (isRTL(elem)) {
+      return super.getScrollLeft(elem) - (elem.getScrollWidth() -  
elem.getClientWidth());
+    }
+    return super.getScrollLeft(elem);
+  }
+
    /*
     * The src may not be set yet because of funky logic in setImgSrc(). See
     * setImgSrc().
@@ -237,6 +245,14 @@
      elem.innerText = text || '';
    }-*/;

+  @Override
+  public void setScrollLeft(Element elem, int left) {
+    if (isRTL(elem)) {
+      left += elem.getScrollWidth() - elem.getClientWidth();
+    }
+    super.setScrollLeft(elem, left);
+  }
+
    private native int getBoundingClientRectLeft(Element elem) /*-{
      // getBoundingClientRect() throws a JS exception if the elem is not  
attached
      // to the document, so we wrap it in a try/catch block
@@ -286,4 +302,8 @@
          doc.getBody().getOffsetWidth();
      }
    }
+
+  private native boolean isRTL(Element elem) /*-{
+    return elem.currentStyle.direction == 'rtl';
+  }-*/;
  }

Modified: trunk/user/src/com/google/gwt/dom/client/DOMImplSafari.java
==============================================================================
--- trunk/user/src/com/google/gwt/dom/client/DOMImplSafari.java (original)
+++ trunk/user/src/com/google/gwt/dom/client/DOMImplSafari.java Mon Apr 13  
12:21:06 2009
@@ -155,6 +155,14 @@
    }

    @Override
+  public int getScrollLeft(Element elem) {
+    if (isRTL(elem)) {
+      return super.getScrollLeft(elem) - (elem.getScrollWidth() -  
elem.getClientWidth());
+    }
+    return super.getScrollLeft(elem);
+  }
+
+  @Override
    public int getScrollTop(Document doc) {
      // Safari always applies document scrolling to the body element, even  
in
      // strict mode.
@@ -213,9 +221,21 @@
    }

    @Override
+  public void setScrollLeft(Element elem, int left) {
+    if (isRTL(elem)) {
+      left += elem.getScrollWidth() - elem.getClientWidth();
+    }
+    super.setScrollLeft(elem, left);
+  }
+
+  @Override
    public void setScrollTop(Document doc, int top) {
      // Safari always applies document scrolling to the body element, even  
in
      // strict mode.
      doc.getBody().setScrollTop(top);
    }
+
+  private native boolean isRTL(Element elem) /*-{
+    return $wnd.getComputedStyle(elem).direction == 'rtl';
+  }-*/;
  }

Modified: trunk/user/src/com/google/gwt/dom/client/Document.java
==============================================================================
--- trunk/user/src/com/google/gwt/dom/client/Document.java      (original)
+++ trunk/user/src/com/google/gwt/dom/client/Document.java      Mon Apr 13  
12:21:06 2009
@@ -889,6 +889,15 @@
    }

    /**
+   * Creates an <input type='submit'> element.
+   *
+   * @return the newly created element
+   */
+  public final InputElement createSubmitInputElement() {
+    return DOMImpl.impl.createInputElement(this, "submit");
+  }
+
+  /**
     * Creates a <table> element.
     *
     * @return the newly created element
@@ -1171,6 +1180,11 @@

    /**
     * The number of pixels that the document's content is scrolled from the  
left.
+   *
+   * <p>
+   * If the document is in RTL mode, this method will return a negative  
value of
+   * the number of pixels scrolled from the right.
+   * </p>
     *
     * @return the document's left scroll position
     */

Modified: trunk/user/src/com/google/gwt/dom/client/Element.java
==============================================================================
--- trunk/user/src/com/google/gwt/dom/client/Element.java       (original)
+++ trunk/user/src/com/google/gwt/dom/client/Element.java       Mon Apr 13  
12:21:06 2009
@@ -303,10 +303,15 @@

    /**
     * The number of pixels that an element's content is scrolled from the  
left.
+   *
+   * <p>
+   * If the element is in RTL mode, this method will return a negative  
value of
+   * the number of pixels scrolled from the right.
+   * </p>
     */
-  public final native int getScrollLeft() /*-{
-     return this.scrollLeft || 0;
-   }-*/;
+  public final int getScrollLeft() {
+    return DOMImpl.impl.getScrollLeft(this);
+  }

    /**
     * The number of pixels that an element's content is scrolled from the  
top.
@@ -492,9 +497,9 @@
    /**
     * The number of pixels that an element's content is scrolled to the  
left.
     */
-  public final native void setScrollLeft(int scrollLeft) /*-{
-     this.scrollLeft = scrollLeft;
-   }-*/;
+  public final void setScrollLeft(int scrollLeft) {
+    DOMImpl.impl.setScrollLeft(this, scrollLeft);
+  }

    /**
     * The number of pixels that an element's content is scrolled to the top.

Modified: trunk/user/test/com/google/gwt/dom/client/ElementTest.java
==============================================================================
--- trunk/user/test/com/google/gwt/dom/client/ElementTest.java  (original)
+++ trunk/user/test/com/google/gwt/dom/client/ElementTest.java  Mon Apr 13  
12:21:06 2009
@@ -125,6 +125,42 @@
    }

    /**
+   * Tests that scrollLeft behaves as expected in RTL mode.
+   */
+  public void testScrollLeftInRtl() {
+    final DivElement outer = Document.get().createDivElement();
+    final DivElement inner = Document.get().createDivElement();
+
+    outer.getStyle().setProperty("position", "absolute");
+    outer.getStyle().setProperty("top", "0px");
+    outer.getStyle().setProperty("left", "0px");
+    outer.getStyle().setProperty("overflow", "auto");
+    outer.getStyle().setProperty("width", "200px");
+    outer.getStyle().setProperty("height", "200px");
+
+    // Force scrolling on the outer div, because WebKit doesn't do this
+    // correctly in RTL mode.
+    outer.getStyle().setProperty("overflow", "scroll");
+
+    inner.getStyle().setProperty("marginTop", "800px");
+    inner.getStyle().setProperty("marginRight", "800px");
+
+    outer.appendChild(inner);
+    Document.get().getBody().appendChild(outer);
+    inner.setInnerText(":-)");
+    outer.setDir("rtl");
+
+    // The important thing is that setting and retrieving scrollLeft  
values in
+    // RTL mode works only for negative numbers, and that they round-trip
+    // correctly.
+    outer.setScrollLeft(-32);
+    assertEquals(-32, outer.getScrollLeft());
+
+    outer.setScrollLeft(32);
+    assertEquals(0, outer.getScrollLeft());
+  }
+
+  /**
     * getParentElement.
     */
    public void testGetParent() {

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to