Intruducing AutoDirHandler, a handler for automatically adjusting the direction
of an object (typically a TextBox variant) while text is being entered. This
handler is then used to add BiDi support to TextBox and TextArea.
Review at http://gwt-code-reviews.appspot.com/386803
Review by: jat@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8286 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/samples/showcase/src/com/google/gwt/sample/showcase/client/content/text/CwBasicText.java b/samples/showcase/src/com/google/gwt/sample/showcase/client/content/text/CwBasicText.java
index d6979c8..7533b09 100644
--- a/samples/showcase/src/com/google/gwt/sample/showcase/client/content/text/CwBasicText.java
+++ b/samples/showcase/src/com/google/gwt/sample/showcase/client/content/text/CwBasicText.java
@@ -22,6 +22,7 @@
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.i18n.client.Constants;
+import com.google.gwt.i18n.shared.AnyRtlDirectionEstimator;
import com.google.gwt.sample.showcase.client.ContentWidget;
import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseData;
import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseSource;
@@ -103,6 +104,10 @@
// Add a normal and disabled text box
TextBox normalText = new TextBox();
normalText.ensureDebugId("cwBasicText-textbox");
+ // Set the normal text box to automatically adjust its direction according
+ // to the input text. Use the Any-RTL heuristic, which sets an RTL direction
+ // iff the text contains at least one RTL character.
+ normalText.setDirectionEstimator(AnyRtlDirectionEstimator.get());
TextBox disabledText = new TextBox();
disabledText.ensureDebugId("cwBasicText-textbox-disabled");
disabledText.setText(constants.cwBasicTextReadOnly());
diff --git a/user/src/com/google/gwt/i18n/I18N.gwt.xml b/user/src/com/google/gwt/i18n/I18N.gwt.xml
index 23d1c29..9d0c77a 100644
--- a/user/src/com/google/gwt/i18n/I18N.gwt.xml
+++ b/user/src/com/google/gwt/i18n/I18N.gwt.xml
@@ -17,7 +17,7 @@
<module>
<inherits name="com.google.gwt.regexp.RegExp"/>
<source path="" includes="client/,shared/" />
-
+
<!-- Browser-sensitive code should use the 'locale' client property. -->
<!-- 'default' is always defined. -->
<define-property name="locale" values="default" />
@@ -54,7 +54,7 @@
} else {
$wnd['__gwt_Locale'] = locale || defaultLocale;
}
-
+
if (locale == null) {
return defaultLocale;
}
@@ -95,7 +95,7 @@
the locale of the current permutation will actually be included. Note
that currently only number/date format constants, locale names, and
currency data will support runtime locales - everything else will just
- reference the compile-time locale set in the "locale" property.
+ reference the compile-time locale set in the "locale" property.
-->
<define-configuration-property name="runtime.locales" is-multi-valued="true"/>
<set-configuration-property name="runtime.locales" value=""/>
@@ -111,4 +111,17 @@
be generated as the locale specified here.
-->
<set-property-fallback name="locale" value="default"/>
+
+ <!-- Force BiDi policy to be enabled -->
+ <define-property name="gwt.forceBidi" values="true, false"/>
+
+ <!-- Default to not forced -->
+ <set-property name="gwt.forceBidi" value="false"/>
+
+ <!-- Replace the BidiPolicyImpl -->
+ <replace-with class="com.google.gwt.i18n.client.BidiPolicy.BidiPolicyImplOn">
+ <when-type-is class="com.google.gwt.i18n.client.BidiPolicy.BidiPolicyImpl"/>
+ <when-property-is name="gwt.forceBidi" value="true"/>
+ </replace-with>
</module>
+
diff --git a/user/src/com/google/gwt/i18n/client/AutoDirectionHandler.java b/user/src/com/google/gwt/i18n/client/AutoDirectionHandler.java
new file mode 100644
index 0000000..09ad8b7
--- /dev/null
+++ b/user/src/com/google/gwt/i18n/client/AutoDirectionHandler.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2010 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.i18n.client;
+
+import com.google.gwt.event.dom.client.HasKeyUpHandlers;
+import com.google.gwt.event.dom.client.KeyUpEvent;
+import com.google.gwt.event.dom.client.KeyUpHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.i18n.client.HasDirection.Direction;
+import com.google.gwt.i18n.shared.DirectionEstimator;
+import com.google.gwt.i18n.shared.HasDirectionEstimator;
+import com.google.gwt.i18n.shared.WordCountDirectionEstimator;
+import com.google.gwt.user.client.ui.HasText;
+
+/**
+ * Utility class for handling auto-direction adjustment.
+ *
+ * This class is useful for automatically adjusting the direction of an object
+ * that takes text input, while the text is being entered.
+ */
+public class AutoDirectionHandler implements KeyUpHandler,
+ HasDirectionEstimator {
+
+ /**
+ * The interface an object must implement in order to add an
+ * AutoDirectionHandler to it.
+ *
+ * TODO(tomerigo): add Paste and Input events once they're available in GWT.
+ */
+ public interface Target extends HasText, HasDirection, HasKeyUpHandlers {
+ }
+
+ /**
+ * Operates like {@link #addTo(Target, DirectionEstimator)}, but always uses
+ * a default DirectionEstimator, {@link
+ * com.google.gwt.i18n.shared.WordCountDirectionEstimator}.
+ *
+ * @param target Object whose direction should be automatically adjusted on
+ * relevant events.
+ * @return AutoDirectionHandler An instance of AutoDirectionHandler for the
+ * given object.
+ */
+ public static AutoDirectionHandler addTo(Target target) {
+ return addTo(target, true);
+ }
+
+ /**
+ * Operates like {@link #addTo(Target, DirectionEstimator)}, but uses a
+ * default DirectionEstimator, {@link
+ * com.google.gwt.i18n.shared.WordCountDirectionEstimator} if {@code enabled},
+ * or else a null DirectionEstimator, which means disabling direction
+ * estimation.
+ *
+ * @param target Object whose direction should be automatically adjusted on
+ * relevant events.
+ * @param enabled Whether the handler is enabled upon creation.
+ * @return AutoDirectionHandler An instance of AutoDirectionHandler for the
+ * given object.
+ */
+ public static AutoDirectionHandler addTo(Target target, boolean enabled) {
+ return addTo(target, enabled ? WordCountDirectionEstimator.get() : null);
+ }
+
+ /**
+ * Adds auto-direction adjustment to a given object:
+ * - Creates an AutoDirectionHandler.
+ * - Initializes it with the given DirectionEstimator.
+ * - Adds it as an event handler for the relevant events on the given object.
+ * - Returns the AutoDirectionHandler, so its setAutoDir() method can be
+ * called when the object's text changes by means other than the handled
+ * events.
+ *
+ * @param target Object whose direction should be automatically adjusted on
+ * relevant events.
+ * @param directionEstimator A DirectionEstimator object used for direction
+ * estimation (use null to disable direction estimation).
+ * @return AutoDirectionHandler An instance of AutoDirectionHandler for the
+ * given object.
+ */
+ public static AutoDirectionHandler addTo(Target target, DirectionEstimator
+ directionEstimator) {
+ AutoDirectionHandler autoDirHandler = new AutoDirectionHandler(target,
+ directionEstimator);
+ return autoDirHandler;
+ }
+
+ /**
+ * A DirectionEstimator object used for direction estimation.
+ */
+ private DirectionEstimator directionEstimator;
+
+ /**
+ * A HandlerRegistration object used to remove this handler.
+ */
+ private HandlerRegistration handlerRegistration;
+
+ /**
+ * The object being handled.
+ */
+ private Target target;
+
+ /**
+ * Private constructor. Instantiate using one of the addTo() methods.
+ *
+ * @param target Object whose direction should be automatically adjusted on
+ * relevant events.
+ * @param directionEstimator A DirectionEstimator object used for direction
+ * estimation.
+ */
+ private AutoDirectionHandler(Target target, DirectionEstimator
+ directionEstimator) {
+ this.target = target;
+ this.handlerRegistration = null;
+ setDirectionEstimator(directionEstimator);
+ }
+
+ /**
+ * Returns the DirectionEstimator object.
+ */
+ public DirectionEstimator getDirectionEstimator() {
+ return directionEstimator;
+ }
+
+ /**
+ * Automatically adjusts hasDirection's direction on KeyUpEvent events.
+ * Implementation of KeyUpHandler interface method.
+ */
+ public void onKeyUp(KeyUpEvent event) {
+ refreshDirection();
+ }
+
+ /**
+ * Adjusts target's direction according to the estimated direction of the text
+ * it supplies.
+ */
+ public void refreshDirection() {
+ if (directionEstimator != null) {
+ Direction dir = directionEstimator.estimateDirection(target.getText());
+ if (dir != target.getDirection()) {
+ target.setDirection(dir);
+ }
+ }
+ }
+
+ /**
+ * Toggles direction estimation on (using a default estimator) and off.
+ */
+ public void setDirectionEstimator(boolean enabled) {
+ setDirectionEstimator(enabled ? WordCountDirectionEstimator.get() : null);
+ }
+
+ /**
+ * Sets the DirectionEstimator object.
+ */
+ public void setDirectionEstimator(DirectionEstimator directionEstimator) {
+ this.directionEstimator = directionEstimator;
+ if ((directionEstimator == null) != (handlerRegistration == null)) {
+ if (directionEstimator == null) {
+ handlerRegistration.removeHandler();
+ handlerRegistration = null;
+ } else {
+ handlerRegistration = target.addKeyUpHandler(this);
+ }
+ }
+ refreshDirection();
+ }
+}
diff --git a/user/src/com/google/gwt/i18n/client/BidiPolicy.java b/user/src/com/google/gwt/i18n/client/BidiPolicy.java
new file mode 100644
index 0000000..5a0427e
--- /dev/null
+++ b/user/src/com/google/gwt/i18n/client/BidiPolicy.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010 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.i18n.client;
+
+import com.google.gwt.core.client.GWT;
+
+/**
+ * Provides low-level functionality to determine whether to support bidi.
+ */
+public class BidiPolicy {
+ /**
+ * Implementation class for {@link BidiPolicy}.
+ */
+ public static class BidiPolicyImpl {
+ public boolean isBidiEnabled() {
+ return LocaleInfo.hasAnyRTL();
+ }
+ }
+
+ /**
+ * Implementation class for {@link BidiPolicy} used when bidi is always on.
+ */
+ @SuppressWarnings("unused")
+ public static class BidiPolicyImplOn extends BidiPolicyImpl {
+ @Override
+ public boolean isBidiEnabled() {
+ return true;
+ }
+ }
+
+ private static BidiPolicyImpl impl = GWT.create(BidiPolicyImpl.class);
+
+ /**
+ * @return true if bidi is enabled, false if disabled.
+ */
+ public static boolean isBidiEnabled() {
+ return impl.isBidiEnabled();
+ }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/TextArea.java b/user/src/com/google/gwt/user/client/ui/TextArea.java
index 09c7fff..0cd79a4 100644
--- a/user/src/com/google/gwt/user/client/ui/TextArea.java
+++ b/user/src/com/google/gwt/user/client/ui/TextArea.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
@@ -18,36 +18,34 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.TextAreaElement;
-import com.google.gwt.i18n.client.HasDirection;
-import com.google.gwt.i18n.client.BidiUtils;
/**
* A text box that allows multiple lines of text to be entered.
- *
+ *
* <p>
* <img class='gallery' src='doc-files/TextArea.png'/>
* </p>
- *
+ *
* <h3>CSS Style Rules</h3>
* <ul class='css'>
* <li>.gwt-TextArea { primary style }</li>
* <li>.gwt-TextArea-readonly { dependent style set when the text area is read-only }</li>
* </ul>
- *
+ *
* <p>
* <h3>Example</h3> {@example com.google.gwt.examples.TextBoxExample}
* </p>
*/
-public class TextArea extends TextBoxBase implements HasDirection {
+public class TextArea extends TextBoxBase {
/**
* Creates a TextArea widget that wraps an existing <textarea>
* element.
- *
+ *
* This element must already be attached to the document. If the element is
* removed from the document, you must call
* {@link RootPanel#detachNow(Widget)}.
- *
+ *
* @param element the element to be wrapped
*/
public static TextArea wrap(Element element) {
@@ -74,7 +72,7 @@
/**
* This constructor may be used by subclasses to explicitly use an existing
* element. This element must be a <textarea> element.
- *
+ *
* @param element the element to be used
*/
protected TextArea(Element element) {
@@ -85,7 +83,7 @@
/**
* Gets the requested width of the text box (this is not an exact value, as
* not all characters are created equal).
- *
+ *
* @return the requested width, in characters
*/
public int getCharacterWidth() {
@@ -97,10 +95,6 @@
return getImpl().getTextAreaCursorPos(getElement());
}
- public Direction getDirection() {
- return BidiUtils.getDirectionOnElement(getElement());
- }
-
@Override
public int getSelectionLength() {
return getImpl().getTextAreaSelectionLength(getElement());
@@ -108,7 +102,7 @@
/**
* Gets the number of text lines that are visible.
- *
+ *
* @return the number of visible lines
*/
public int getVisibleLines() {
@@ -118,20 +112,16 @@
/**
* Sets the requested width of the text box (this is not an exact value, as
* not all characters are created equal).
- *
+ *
* @param width the requested width, in characters
*/
public void setCharacterWidth(int width) {
getTextAreaElement().setCols(width);
}
- public void setDirection(Direction direction) {
- BidiUtils.setDirectionOnElement(getElement(), direction);
- }
-
/**
* Sets the number of text lines that are visible.
- *
+ *
* @param lines the number of visible lines
*/
public void setVisibleLines(int lines) {
diff --git a/user/src/com/google/gwt/user/client/ui/TextBox.java b/user/src/com/google/gwt/user/client/ui/TextBox.java
index bfcff46..baec618 100644
--- a/user/src/com/google/gwt/user/client/ui/TextBox.java
+++ b/user/src/com/google/gwt/user/client/ui/TextBox.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
@@ -18,38 +18,36 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.InputElement;
-import com.google.gwt.i18n.client.BidiUtils;
-import com.google.gwt.i18n.client.HasDirection;
/**
* A standard single-line text box.
- *
+ *
* <p>
* <img class='gallery' src='doc-files/TextBox.png'/>
* </p>
- *
+ *
* <h3>CSS Style Rules</h3>
* <ul class='css'>
* <li>.gwt-TextBox { primary style }</li>
* <li>.gwt-TextBox-readonly { dependent style set when the text box is
* read-only }</li>
* </ul>
- *
+ *
* <p>
* <h3>Example</h3>
* {@example com.google.gwt.examples.TextBoxExample}
* </p>
*/
-public class TextBox extends TextBoxBase implements HasDirection {
+public class TextBox extends TextBoxBase {
/**
* Creates a TextBox widget that wraps an existing <input type='text'>
* element.
- *
+ *
* This element must already be attached to the document. If the element is
* removed from the document, you must call
* {@link RootPanel#detachNow(Widget)}.
- *
+ *
* @param element the element to be wrapped
*/
public static TextBox wrap(Element element) {
@@ -76,7 +74,7 @@
* This constructor may be used by subclasses to explicitly use an existing
* element. This element must be an <input> element whose type is
* 'text'.
- *
+ *
* @param element the element to be used
*/
protected TextBox(Element element) {
@@ -91,13 +89,9 @@
}
}
- public Direction getDirection() {
- return BidiUtils.getDirectionOnElement(getElement());
- }
-
/**
* Gets the maximum allowable length of the text box.
- *
+ *
* @return the maximum length, in characters
*/
public int getMaxLength() {
@@ -106,20 +100,16 @@
/**
* Gets the number of visible characters in the text box.
- *
+ *
* @return the number of visible characters
*/
public int getVisibleLength() {
return getInputElement().getSize();
}
- public void setDirection(Direction direction) {
- BidiUtils.setDirectionOnElement(getElement(), direction);
- }
-
/**
* Sets the maximum allowable length of the text box.
- *
+ *
* @param length the maximum length, in characters
*/
public void setMaxLength(int length) {
@@ -128,7 +118,7 @@
/**
* Sets the number of visible characters in the text box.
- *
+ *
* @param length the number of visible characters
*/
public void setVisibleLength(int length) {
diff --git a/user/src/com/google/gwt/user/client/ui/ValueBoxBase.java b/user/src/com/google/gwt/user/client/ui/ValueBoxBase.java
index 10e7199..dbee95f 100644
--- a/user/src/com/google/gwt/user/client/ui/ValueBoxBase.java
+++ b/user/src/com/google/gwt/user/client/ui/ValueBoxBase.java
@@ -23,6 +23,12 @@
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.i18n.client.AutoDirectionHandler;
+import com.google.gwt.i18n.client.BidiPolicy;
+import com.google.gwt.i18n.client.BidiUtils;
+import com.google.gwt.i18n.client.HasDirection;
+import com.google.gwt.i18n.shared.DirectionEstimator;
+import com.google.gwt.i18n.shared.HasDirectionEstimator;
import com.google.gwt.text.shared.Parser;
import com.google.gwt.text.shared.Renderer;
import com.google.gwt.user.client.DOM;
@@ -43,10 +49,13 @@
*/
@SuppressWarnings("deprecation")
public class ValueBoxBase<T> extends FocusWidget implements
- SourcesChangeEvents, HasChangeHandlers, HasText, HasName, HasValue<T> {
+ SourcesChangeEvents, HasChangeHandlers, HasText, HasName, HasDirection,
+ HasDirectionEstimator, HasValue<T>, AutoDirectionHandler.Target {
private static TextBoxImpl impl = GWT.create(TextBoxImpl.class);
+ private AutoDirectionHandler autoDirHandler;
+
private final Parser<T> parser;
private final Renderer<T> renderer;
@@ -61,6 +70,8 @@
*/
protected ValueBoxBase(Element elem, Renderer<T> renderer, Parser<T> parser) {
super(elem);
+ autoDirHandler = AutoDirectionHandler.addTo(this,
+ BidiPolicy.isBidiEnabled());
this.renderer = renderer;
this.parser = parser;
}
@@ -111,6 +122,17 @@
return impl.getCursorPos(getElement());
}
+ public Direction getDirection() {
+ return BidiUtils.getDirectionOnElement(getElement());
+ }
+
+ /**
+ * Gets the direction estimation model of the auto-dir handler.
+ */
+ public DirectionEstimator getDirectionEstimator() {
+ return autoDirHandler.getDirectionEstimator();
+ }
+
public String getName() {
return DOM.getElementProperty(getElement(), "name");
}
@@ -229,6 +251,24 @@
setSelectionRange(pos, 0);
}
+ public void setDirection(Direction direction) {
+ BidiUtils.setDirectionOnElement(getElement(), direction);
+ }
+
+ /**
+ * Toggles on / off direction estimation.
+ */
+ public void setDirectionEstimator(boolean enabled) {
+ autoDirHandler.setDirectionEstimator(enabled);
+ }
+
+ /**
+ * Sets the direction estimation model of the auto-dir handler.
+ */
+ public void setDirectionEstimator(DirectionEstimator directionEstimator) {
+ autoDirHandler.setDirectionEstimator(directionEstimator);
+ }
+
/**
* If a keyboard event is currently being handled by the text box, this method
* replaces the unicode character or key code associated with it. This allows
@@ -302,6 +342,7 @@
*/
public void setText(String text) {
DOM.setElementProperty(getElement(), "value", text != null ? text : "");
+ autoDirHandler.refreshDirection();
}
/**
@@ -330,4 +371,10 @@
protected TextBoxImpl getImpl() {
return impl;
}
+
+ @Override
+ protected void onLoad() {
+ super.onLoad();
+ autoDirHandler.refreshDirection();
+ }
}
diff --git a/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java b/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java
index ee46262..4ab8784 100644
--- a/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java
+++ b/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java
@@ -1,12 +1,12 @@
/*
* Copyright 2007 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
@@ -17,6 +17,7 @@
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
+import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.junit.DoNotRunWith;
import com.google.gwt.junit.Platform;
import com.google.gwt.junit.client.GWTTestCase;
@@ -27,34 +28,11 @@
*/
public abstract class TextBoxBaseTestBase extends GWTTestCase {
- public String getModuleName() {
- return "com.google.gwt.user.User";
- }
+ private static class Handler implements ValueChangeHandler<String> {
+ String received = null;
- protected abstract TextBoxBase createTextBoxBase();
-
- /**
- * Tests that {@link TextArea#setText(String)} appropriately converts nulls to
- * empty strings.
- */
- public void testNullMeansEmptyString() {
- TextBoxBase area = createTextBoxBase();
- area.setText(null);
- assertEquals("setText(null) should result in empty string", "",
- area.getText());
- }
-
- /**
- * Tests that {@link TextArea#setCursorPos(int)} updates the cursor position
- * correctly.
- */
- public void testMovingCursor() {
- TextBoxBase area = createTextBoxBase();
- RootPanel.get().add(area);
- area.setText("abcd");
- for (int i = 0; i < 4; i++) {
- area.setCursorPos(i);
- assertEquals(i, area.getCursorPos());
+ public void onValueChange(ValueChangeEvent<String> event) {
+ received = event.getValue();
}
}
@@ -97,23 +75,79 @@
area.selectAll();
}
}
-
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.user.User";
+ }
+
/**
- * Failed in all modes due to HtmlUnit bug.
+ * Tests that auto-dir works correctly.
+ */
+ public void testAutoDir() {
+ TextBoxBase tb = createTextBoxBase();
+ String rtlText = "\u05e0\u05e1";
+ String ltrText = "left to right";
+
+ // Direction should not be affected when auto-dir is disabled.
+ tb.setDirectionEstimator(false);
+ tb.setText(rtlText);
+ assertEquals("Direction should not be affected when auto-dir is disabled",
+ tb.getDirection(), Direction.DEFAULT);
+
+ // Direction should be instantly updated as auto-dir is enabled.
+ tb.setDirectionEstimator(true);
+ assertEquals("Direction should be instantly updated as auto-dir is enabled",
+ tb.getDirection(), Direction.RTL);
+
+ // Direction should be updated on setText when auto-dir is enabled.
+ tb.setText(ltrText);
+ assertEquals(
+ "Direction should be updated on setText when auto-dir is enabled",
+ tb.getDirection(), Direction.LTR);
+ }
+
+ /**
+ * Tests that {@link TextArea#setCursorPos(int)} updates the cursor position
+ * correctly.
+ */
+ public void testMovingCursor() {
+ TextBoxBase area = createTextBoxBase();
+ RootPanel.get().add(area);
+ area.setText("abcd");
+ for (int i = 0; i < 4; i++) {
+ area.setCursorPos(i);
+ assertEquals(i, area.getCursorPos());
+ }
+ }
+
+ /**
+ * Tests that {@link TextArea#setText(String)} appropriately converts nulls to
+ * empty strings.
+ */
+ public void testNullMeansEmptyString() {
+ TextBoxBase area = createTextBoxBase();
+ area.setText(null);
+ assertEquals("setText(null) should result in empty string", "",
+ area.getText());
+ }
+
+ /**
+ * Failed in all modes due to HtmlUnit bug:
*/
@DoNotRunWith({Platform.HtmlUnitBug})
public void testValueChangeEvent() {
TextBoxBase tb = createTextBoxBase();
// To work cross-platform, the tb must be added to the root panel.
RootPanel.get().add(tb);
-
+
Handler h = new Handler();
tb.addValueChangeHandler(h);
-
+
tb.setValue(null);
assertEquals("", tb.getValue());
assertNull(h.received);
-
+
tb.setText("able");
assertEquals("able", tb.getValue());
assertNull(h.received);
@@ -135,12 +169,6 @@
tb.setValue("baker", true);
assertEquals("baker", h.received);
}
-
- private static class Handler implements ValueChangeHandler<String> {
- String received = null;
-
- public void onValueChange(ValueChangeEvent<String> event) {
- received = event.getValue();
- }
- }
+
+ protected abstract TextBoxBase createTextBoxBase();
}