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 -~----------~----~----~----~------~----~------~--~---