Introducing DirectionalTextHelper, a new helper class for text and direction manipulations in widgets, and using it to enhance Anchor and Hyperlink with bidi support.
Review at http://gwt-code-reviews.appspot.com/901801
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9187 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/Anchor.java b/user/src/com/google/gwt/user/client/ui/Anchor.java
index bda6fce..35de8ef 100644
--- a/user/src/com/google/gwt/user/client/ui/Anchor.java
+++ b/user/src/com/google/gwt/user/client/ui/Anchor.java
@@ -20,7 +20,8 @@
import com.google.gwt.dom.client.Element;
import com.google.gwt.i18n.client.BidiUtils;
import com.google.gwt.i18n.client.HasDirection;
-import com.google.gwt.safehtml.client.HasSafeHtml;
+import com.google.gwt.i18n.shared.DirectionEstimator;
+import com.google.gwt.i18n.shared.HasDirectionEstimator;
import com.google.gwt.safehtml.shared.SafeHtml;
/**
@@ -30,6 +31,14 @@
* If you want use this anchor only for changing history states, use
* {@link Hyperlink} instead.
* </p>
+ *
+ * <p>
+ * <h3>Built-in Bidi Text Support</h3>
+ * This widget is capable of automatically adjusting its direction according to
+ * its content. This feature is controlled by {@link #setDirectionEstimator} or
+ * passing a DirectionEstimator parameter to the constructor, and is off by
+ * default.
+ * </p>
*
* <h3>CSS Style Rules</h3>
* <ul class='css'>
@@ -39,7 +48,11 @@
* @see Hyperlink
*/
public class Anchor extends FocusWidget implements HasHorizontalAlignment,
- HasName, HasHTML, HasWordWrap, HasDirection, HasSafeHtml {
+ HasName, HasHTML, HasWordWrap, HasDirection,
+ HasDirectionEstimator, HasDirectionalSafeHtml {
+
+ public static final DirectionEstimator DEFAULT_DIRECTION_ESTIMATOR =
+ DirectionalTextHelper.DEFAULT_DIRECTION_ESTIMATOR;
/**
* Creates an Anchor widget that wraps an existing <a> element.
@@ -63,6 +76,8 @@
return anchor;
}
+ private final DirectionalTextHelper directionalTextHelper;
+
private HorizontalAlignmentConstant horzAlign;
/**
@@ -71,6 +86,45 @@
public Anchor() {
setElement(Document.get().createAnchorElement());
setStyleName("gwt-Anchor");
+ directionalTextHelper = new DirectionalTextHelper(getAnchorElement(),
+ /* is inline */ true);
+ }
+
+ /**
+ * Creates an anchor for scripting.
+ *
+ * @param html the anchor's html
+ */
+ public Anchor(SafeHtml html) {
+ this(html.asString(), true);
+ }
+
+ /**
+ * Creates an anchor for scripting.
+ *
+ * The anchor's href is set to <code>javascript : ;</code>, based on the
+ * expectation that listeners will be added to the anchor.
+ *
+ * @param html the anchor's html
+ * @param dir the html's direction
+ */
+ public Anchor(SafeHtml html, Direction dir) {
+ this(html.asString(), true, dir, "javascript:;");
+ }
+
+ /**
+ * Creates an anchor for scripting.
+ *
+ * The anchor's href is set to <code>javascript : ;</code>, based on the
+ * expectation that listeners will be added to the anchor.
+ *
+ * @param html the anchor's html
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ */
+ public Anchor(SafeHtml html, DirectionEstimator directionEstimator) {
+ this(html.asString(), true, directionEstimator, "javascript:;");
}
/**
@@ -88,10 +142,14 @@
/**
* Creates an anchor for scripting.
*
- * @param html the anchor's text
+ * The anchor's href is set to <code>javascript : ;</code>, based on the
+ * expectation that listeners will be added to the anchor.
+ *
+ * @param text the anchor's text
+ * @param dir the text's direction
*/
- public Anchor(SafeHtml html) {
- this(html.asString(), true);
+ public Anchor(String text, Direction dir) {
+ this(text, dir, "javascript:;");
}
/**
@@ -101,6 +159,21 @@
* expectation that listeners will be added to the anchor.
*
* @param text the anchor's text
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ */
+ public Anchor(String text, DirectionEstimator directionEstimator) {
+ this(text, directionEstimator, "javascript:;");
+ }
+
+ /**
+ * Creates an anchor for scripting.
+ *
+ * The anchor's href is set to <code>javascript:;</code>, based on the
+ * expectation that listeners will be added to the anchor.
+ *
+ * @param text the anchor's text
* @param asHtml <code>true</code> to treat the specified text as html
*/
public Anchor(String text, boolean asHtml) {
@@ -108,7 +181,7 @@
}
/**
- * Creates an anchor with its text and href (target URL) specified.
+ * Creates an anchor with its html and href (target URL) specified.
*
* @param html the anchor's html
* @param href the url to which it will link
@@ -118,6 +191,66 @@
}
/**
+ * Creates an anchor with its html and href (target URL) specified.
+ *
+ * @param html the anchor's html
+ * @param dir the html's direction
+ * @param href the url to which it will link
+ */
+ public Anchor(SafeHtml html, Direction dir, String href) {
+ this(html.asString(), true, dir, href);
+ }
+
+ /**
+ * Creates an anchor with its html and href (target URL) specified.
+ *
+ * @param html the anchor's html
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ * @param href the url to which it will link
+ */
+ public Anchor(SafeHtml html, DirectionEstimator directionEstimator,
+ String href) {
+ this(html.asString(), true, directionEstimator, href);
+ }
+
+ /**
+ * Creates an anchor with its text and href (target URL) specified.
+ *
+ * @param text the anchor's text
+ * @param href the url to which it will link
+ */
+ public Anchor(String text, String href) {
+ this(text, false, href);
+ }
+
+ /**
+ * Creates an anchor with its text and href (target URL) specified.
+ *
+ * @param text the anchor's text
+ * @param dir the text's direction
+ * @param href the url to which it will link
+ */
+ public Anchor(String text, Direction dir, String href) {
+ this(text, false, dir, href);
+ }
+
+ /**
+ * Creates an anchor with its text and href (target URL) specified.
+ *
+ * @param text the anchor's text
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ * @param href the url to which it will link
+ */
+ public Anchor(String text, DirectionEstimator directionEstimator,
+ String href) {
+ this(text, false, directionEstimator, href);
+ }
+
+ /**
* Creates an anchor with its text and href (target URL) specified.
*
* @param text the anchor's text
@@ -126,11 +259,7 @@
*/
public Anchor(String text, boolean asHTML, String href) {
this();
- if (asHTML) {
- setHTML(text);
- } else {
- setText(text);
- }
+ directionalTextHelper.setTextOrHtml(text, asHTML);
setHref(href);
}
@@ -149,6 +278,18 @@
}
/**
+ * Creates a source anchor with a frame target.
+ *
+ * @param text the anchor's text
+ * @param href the url to which it will link
+ * @param target the target frame (e.g. "_blank" to open the link in a new
+ * window)
+ */
+ public Anchor(String text, String href, String target) {
+ this(text, false, href, target);
+ }
+
+ /**
* Creates a source anchor (link to URI).
*
* That is, an anchor with an href attribute specifying the destination URI.
@@ -165,30 +306,6 @@
}
/**
- * Creates an anchor with its text and href (target URL) specified.
- *
- * @param text the anchor's text
- * @param href the url to which it will link
- */
- public Anchor(String text, String href) {
- this();
- setText(text);
- setHref(href);
- }
-
- /**
- * Creates a source anchor with a frame target.
- *
- * @param text the anchor's text
- * @param href the url to which it will link
- * @param target the target frame (e.g. "_blank" to open the link in a new
- * window)
- */
- public Anchor(String text, String href, String target) {
- this(text, false, href, target);
- }
-
- /**
* This constructor may be used by subclasses to explicitly use an existing
* element. This element must be an <a> element.
*
@@ -197,12 +314,50 @@
protected Anchor(Element element) {
AnchorElement.as(element);
setElement(element);
+ directionalTextHelper = new DirectionalTextHelper(getAnchorElement(),
+ /* is inline */ true);
+ }
+
+ /**
+ * Creates an anchor with its text, direction and href (target URL) specified.
+ *
+ * @param text the anchor's text
+ * @param asHTML <code>true</code> to treat the specified text as html
+ * @param dir the text's direction
+ * @param href the url to which it will link
+ */
+ private Anchor(String text, boolean asHTML, Direction dir, String href) {
+ this();
+ directionalTextHelper.setTextOrHtml(text, dir, asHTML);
+ setHref(href);
+ }
+
+ /**
+ * Creates an anchor with its text, direction and href (target URL) specified.
+ *
+ * @param text the anchor's text
+ * @param asHTML <code>true</code> to treat the specified text as html
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ * @param href the url to which it will link
+ */
+ private Anchor(String text, boolean asHTML,
+ DirectionEstimator directionEstimator, String href) {
+ this();
+ directionalTextHelper.setDirectionEstimator(directionEstimator);
+ directionalTextHelper.setTextOrHtml(text, asHTML);
+ setHref(href);
}
public Direction getDirection() {
return BidiUtils.getDirectionOnElement(getElement());
}
+ public DirectionEstimator getDirectionEstimator() {
+ return directionalTextHelper.getDirectionEstimator();
+ }
+
public HorizontalAlignmentConstant getHorizontalAlignment() {
return horzAlign;
}
@@ -240,7 +395,11 @@
}
public String getText() {
- return getElement().getInnerText();
+ return directionalTextHelper.getTextOrHtml(false);
+ }
+
+ public Direction getTextDirection() {
+ return directionalTextHelper.getTextDirection();
}
public boolean getWordWrap() {
@@ -252,8 +411,35 @@
getAnchorElement().setAccessKey(Character.toString(key));
}
+ /**
+ * @deprecated Use {@link #setDirectionEstimator} and / or pass explicit
+ * direction to {@link #setText}, {@link #setHTML} instead
+ */
+ @Deprecated
public void setDirection(Direction direction) {
- BidiUtils.setDirectionOnElement(getElement(), direction);
+ directionalTextHelper.setDirection(direction);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * See note at {@link #setDirectionEstimator(DirectionEstimator)}.
+ */
+ public void setDirectionEstimator(boolean enabled) {
+ directionalTextHelper.setDirectionEstimator(enabled);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Note: DirectionEstimator should be set before the widget has any content;
+ * it's highly recommended to set it using a constructor. Reason: if the
+ * widget already has non-empty content, this will update its direction
+ * according to the new estimator's result. This may cause flicker, and thus
+ * should be avoided.
+ */
+ public void setDirectionEstimator(DirectionEstimator directionEstimator) {
+ directionalTextHelper.setDirectionEstimator(directionEstimator);
}
@Override
@@ -284,7 +470,11 @@
}
public void setHTML(String html) {
- getElement().setInnerHTML(html);
+ directionalTextHelper.setTextOrHtml(html, true);
+ }
+
+ public void setHTML(SafeHtml html, Direction dir) {
+ directionalTextHelper.setTextOrHtml(html.asString(), dir, true);
}
public void setName(String name) {
@@ -307,7 +497,11 @@
}
public void setText(String text) {
- getElement().setInnerText(text);
+ directionalTextHelper.setTextOrHtml(text, false);
+ }
+
+ public void setText(String text, Direction dir) {
+ directionalTextHelper.setTextOrHtml(text, dir, false);
}
public void setWordWrap(boolean wrap) {
diff --git a/user/src/com/google/gwt/user/client/ui/DirectionalTextHelper.java b/user/src/com/google/gwt/user/client/ui/DirectionalTextHelper.java
new file mode 100644
index 0000000..68d3fbd
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/DirectionalTextHelper.java
@@ -0,0 +1,245 @@
+/*
+ * 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.user.client.ui;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.i18n.client.BidiUtils;
+import com.google.gwt.i18n.client.HasDirection.Direction;
+import com.google.gwt.i18n.shared.BidiFormatter;
+import com.google.gwt.i18n.shared.DirectionEstimator;
+import com.google.gwt.i18n.shared.HasDirectionEstimator;
+import com.google.gwt.i18n.shared.WordCountDirectionEstimator;
+
+/**
+ * A helper class for displaying bidi (i.e. potentially opposite-direction) text
+ * or HTML in an element.
+ * Note: this class assumes that callers perform all their text/html and
+ * direction manipulations through it alone.
+ */
+public class DirectionalTextHelper implements HasDirectionEstimator {
+
+ /**
+ * A default direction estimator instance.
+ */
+ public static final DirectionEstimator DEFAULT_DIRECTION_ESTIMATOR =
+ WordCountDirectionEstimator.get();
+
+ /**
+ * The DirectionEstimator object.
+ */
+ private DirectionEstimator directionEstimator;
+
+ /**
+ * The target element.
+ */
+ private final Element element;
+
+ /**
+ * The initial direction of the element.
+ */
+ private Direction initialElementDir;
+
+ /**
+ * Whether direction was explicitly set on the last {@code setTextOrHtml}
+ * call. If so, {@link #setDirectionEstimator} will refrain from modifying the
+ * direction until {@link #setTextOrHtml} is called without specifying an
+ * explicit direction.
+ */
+ private boolean isDirectionExplicitlySet;
+
+ /**
+ * Whether the element is inline (e.g. a <span> element, but not a block
+ * element like <div>).
+ * This is needed because direction is handled differently for inline elements
+ * and for non-inline elements.
+ */
+ private final boolean isElementInline;
+
+ /**
+ * Whether the element contains a nested <span> element used to
+ * indicate the content's direction.
+ * <p>
+ * The element itself is used for this purpose when it is a block element
+ * (i.e. !isElementInline), but doing so on an inline element often results in
+ * garbling what follows it. Thus, when the element is inline, a nested
+ * <span> must be used to carry the content's direction, with an LRM or
+ * RLM character afterwards to prevent the garbling.
+ */
+ private boolean isSpanWrapped;
+
+ /**
+ * The direction of the element's content.
+ * Note: this may not match the direction attribute of the element itself.
+ * See
+ * {@link #setTextOrHtml(String, com.google.gwt.i18n.client.HasDirection.Direction, boolean) setTextOrHtml(String, Direction, boolean)}
+ * for details.
+ */
+ private Direction textDir;
+
+ /**
+ * @param element The widget's element holding text.
+ * @param isElementInline Whether the element is an inline element.
+ */
+ public DirectionalTextHelper(Element element, boolean isElementInline) {
+ this.element = element;
+ this.isElementInline = isElementInline;
+ isSpanWrapped = false;
+ this.initialElementDir = BidiUtils.getDirectionOnElement(element);
+ textDir = initialElementDir;
+ // setDirectionEstimator shouldn't refresh appearance of initial empty text.
+ isDirectionExplicitlySet = true;
+ }
+
+ public DirectionEstimator getDirectionEstimator() {
+ return directionEstimator;
+ }
+
+ public Direction getTextDirection() {
+ return textDir;
+ }
+
+ /**
+ * Get the inner text or html of the element, taking the inner span wrap into
+ * consideration, if needed.
+ *
+ * @param isHtml true to get the inner html, false to get the inner text
+ * @return the text or html
+ */
+ public String getTextOrHtml(boolean isHtml) {
+ Element elem = isSpanWrapped ? element.getFirstChildElement() : element;
+ return isHtml ? elem.getInnerHTML() : elem.getInnerText();
+ }
+
+ /**
+ * Provides implementation for HasDirection's method setDirection (normally
+ * deprecated), dealing with backwards compatibility issues.
+ * @deprecated
+ */
+ @Deprecated
+ public void setDirection(Direction direction) {
+ BidiUtils.setDirectionOnElement(element, direction);
+ initialElementDir = direction;
+
+ /*
+ * For backwards compatibility, assure there's no span wrap, and update the
+ * content direction.
+ */
+ setInnerTextOrHtml(getTextOrHtml(true), true);
+ isSpanWrapped = false;
+ textDir = initialElementDir;
+ isDirectionExplicitlySet = true;
+ }
+
+ /**
+ * See note at
+ * {@link #setDirectionEstimator(com.google.gwt.i18n.shared.DirectionEstimator)}.
+ */
+ public void setDirectionEstimator(boolean enabled) {
+ setDirectionEstimator(enabled ? DEFAULT_DIRECTION_ESTIMATOR : null);
+ }
+
+ /**
+ * Note: if the element already has non-empty content, this will update
+ * its direction according to the new estimator's result. This may cause
+ * flicker, and thus should be avoided; DirectionEstimator should be set
+ * before the element has any content.
+ */
+ public void setDirectionEstimator(DirectionEstimator directionEstimator) {
+ this.directionEstimator = directionEstimator;
+ /*
+ * Refresh appearance unless direction was explicitly set on last
+ * setTextOrHtml call.
+ */
+ if (!isDirectionExplicitlySet) {
+ setTextOrHtml(getTextOrHtml(true), true);
+ }
+ }
+
+ /**
+ * Sets the element's content to the given value (either plain text or HTML).
+ * If direction estimation is off, the direction is verified to match the
+ * element's initial direction. Otherwise, the direction is affected as
+ * described at
+ * {@link #setTextOrHtml(String, com.google.gwt.i18n.client.HasDirection.Direction, boolean) setTextOrHtml(String, Direction, boolean)}.
+ *
+ * @param content the element's new content
+ * @param isHtml whether the content is HTML
+ */
+ public void setTextOrHtml(String content, boolean isHtml) {
+ if (directionEstimator == null) {
+ isSpanWrapped = false;
+ setInnerTextOrHtml(content, isHtml);
+
+ /*
+ * Preserves the initial direction of the element. This is different from
+ * passing the direction parameter explicitly as DEFAULT, which forces the
+ * element to inherit the direction from its parent.
+ */
+ if (textDir != initialElementDir) {
+ textDir = initialElementDir;
+ BidiUtils.setDirectionOnElement(element, initialElementDir);
+ }
+ } else {
+ setTextOrHtml(content, directionEstimator.estimateDirection(content,
+ isHtml), isHtml);
+ }
+ isDirectionExplicitlySet = false;
+ }
+
+ /**
+ * Sets the element's content to the given value (either plain text or HTML),
+ * applying the given direction.
+ * <p>
+ * Implementation details:
+ * <ul>
+ * <li> If the element is a block element, sets its dir attribute according
+ * to the given direction.
+ * <li> Otherwise (i.e. the element is inline), the direction is set using a
+ * nested <span dir=...> element which holds the content of the element.
+ * This nested span may be followed by a zero-width Unicode direction
+ * character (LRM or RLM). This manipulation is necessary to prevent garbling
+ * in case the direction of the element is opposite to the direction of its
+ * context. See {@link com.google.gwt.i18n.shared.BidiFormatter} for more
+ * details.
+ * </ul>
+ *
+ * @param content the element's new content
+ * @param dir the content's direction
+ * @param isHtml whether the content is HTML
+ */
+ public void setTextOrHtml(String content, Direction dir, boolean isHtml) {
+ textDir = dir;
+ // Set the text and the direction.
+ if (isElementInline) {
+ isSpanWrapped = true;
+ element.setInnerHTML(BidiFormatter.getInstanceForCurrentLocale(
+ true /* alwaysSpan */).spanWrapWithKnownDir(dir, content, isHtml));
+ } else {
+ isSpanWrapped = false;
+ BidiUtils.setDirectionOnElement(element, dir);
+ setInnerTextOrHtml(content, isHtml);
+ }
+ isDirectionExplicitlySet = true;
+ }
+
+ private void setInnerTextOrHtml(String content, boolean isHtml) {
+ if (isHtml) {
+ element.setInnerHTML(content);
+ } else {
+ element.setInnerText(content);
+ }
+ }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/HTML.java b/user/src/com/google/gwt/user/client/ui/HTML.java
index 98c7fd3..fe4e6ac 100644
--- a/user/src/com/google/gwt/user/client/ui/HTML.java
+++ b/user/src/com/google/gwt/user/client/ui/HTML.java
@@ -17,8 +17,6 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
-import com.google.gwt.i18n.client.BidiUtils;
-import com.google.gwt.i18n.shared.BidiFormatter;
import com.google.gwt.i18n.shared.DirectionEstimator;
import com.google.gwt.safehtml.shared.SafeHtml;
@@ -35,6 +33,14 @@
* used properly.
* </p>
*
+ * <p>
+ * <h3>Built-in Bidi Text Support</h3>
+ * This widget is capable of automatically adjusting its direction according to
+ * its content. This feature is controlled by {@link #setDirectionEstimator} or
+ * passing a DirectionEstimator parameter to the constructor, and is off by
+ * default.
+ * </p>
+ *
* <h3>CSS Style Rules</h3>
* <ul class='css'>
* <li>.gwt-HTML { }</li>
@@ -89,18 +95,8 @@
}
/**
- * Creates an HTML widget with the specified HTML contents.
- *
- * @param html the new widget's HTML contents
- */
- public HTML(String html) {
- this();
- setHTML(html);
- }
-
- /**
- * Creates an HTML widget with the specified contents and with the
- * specified direction.
+ * Creates an HTML widget with the specified contents and with the specified
+ * direction.
*
* @param html the new widget's SafeHtml contents
* @param dir the content's direction. Note: {@code Direction.DEFAULT} means
@@ -111,6 +107,31 @@
}
/**
+ * Creates an HTML widget with the specified HTML contents and specifies a
+ * direction estimator.
+ *
+ * @param html the new widget's SafeHtml contents
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link Label#DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ */
+ public HTML(SafeHtml html, DirectionEstimator directionEstimator) {
+ this();
+ setDirectionEstimator(directionEstimator);
+ setHTML(html);
+ }
+
+ /**
+ * Creates an HTML widget with the specified HTML contents.
+ *
+ * @param html the new widget's HTML contents
+ */
+ public HTML(String html) {
+ this();
+ setHTML(html);
+ }
+
+ /**
* Creates an HTML widget with the specified HTML contents and with the
* specified direction.
*
@@ -122,7 +143,7 @@
this();
setHTML(html, dir);
}
-
+
/**
* Creates an HTML widget with the specified contents, optionally treating it
* as HTML, and optionally disabling word wrapping.
@@ -148,39 +169,7 @@
}
public String getHTML() {
- return getTextOrHtml(true);
- }
-
- /**
- * Sets the widget element's direction.
- * @deprecated Use {@link #setDirectionEstimator} and / or pass explicit
- * direction to {@link #setText} instead
- */
- @Deprecated
- public void setDirection(Direction direction) {
- BidiUtils.setDirectionOnElement(getElement(), direction);
- initialElementDir = direction;
-
- // For backwards compatibility, assure there's no span wrap, and update the
- // content direction.
- setInnerTextOrHtml(getTextOrHtml(true), true);
- isSpanWrapped = false;
- textDir = initialElementDir;
- updateHorizontalAlignment();
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Note: if the widget already has non-empty content, this will update
- * its direction according to the new estimator's result. This may cause
- * flicker, and thus should be avoided; DirectionEstimator should be set
- * before the widget has any content.
- */
- public void setDirectionEstimator(DirectionEstimator directionEstimator) {
- this.directionEstimator = directionEstimator;
- // Refresh appearance
- setHTML(getTextOrHtml(true));
+ return directionalTextHelper.getTextOrHtml(true);
}
/**
@@ -191,48 +180,22 @@
* @param html the new widget's HTML content
*/
public void setHTML(String html) {
- if (directionEstimator == null) {
- isSpanWrapped = false;
- getElement().setInnerHTML(html);
-
- // Preserves the initial direction of the widget. This is different from
- // passing the direction parameter explicitly as DEFAULT, which forces the
- // widget to inherit the direction from its parent.
- if (textDir != initialElementDir) {
- textDir = initialElementDir;
- BidiUtils.setDirectionOnElement(getElement(), initialElementDir);
- updateHorizontalAlignment();
- }
- } else {
- setHTML(html, directionEstimator.estimateDirection(html, true));
- }
+ directionalTextHelper.setTextOrHtml(html, true);
+ updateHorizontalAlignment();
}
/**
* Sets the label's content to the given HTML, applying the given direction.
* See
- * {@link #setText(String, com.google.gwt.i18n.client.HasDirection.Direction)
- * setText(String, Direction)} for details on potential effects on alignment.
+ * {@link #setText(String, com.google.gwt.i18n.client.HasDirection.Direction) setText(String, Direction)}
+ * for details on potential effects on alignment.
*
* @param html the new widget's HTML content
* @param dir the content's direction. Note: {@code Direction.DEFAULT} means
* direction should be inherited from the widget's parent element.
*/
public void setHTML(String html, Direction dir) {
- textDir = dir;
-
- // Set the text and the direction.
- if (isElementInline) {
- isSpanWrapped = true;
- getElement().setInnerHTML(BidiFormatter.getInstanceForCurrentLocale(
- true /* alwaysSpan */).spanWrapWithKnownDir(dir, html, true));
- } else {
- isSpanWrapped = false;
- BidiUtils.setDirectionOnElement(getElement(), dir);
- getElement().setInnerHTML(html);
- }
-
- // Update the horizontal alignment if needed.
+ directionalTextHelper.setTextOrHtml(html, dir, true);
updateHorizontalAlignment();
}
@@ -251,16 +214,6 @@
}
protected String getTextOrHtml(boolean isHtml) {
- Element element = isSpanWrapped ? getElement().getFirstChildElement()
- : getElement();
- return isHtml ? element.getInnerHTML() : element.getInnerText();
- }
-
- private void setInnerTextOrHtml(String content, boolean isHtml) {
- if (isHtml) {
- getElement().setInnerHTML(content);
- } else {
- getElement().setInnerText(content);
- }
+ return directionalTextHelper.getTextOrHtml(isHtml);
}
}
diff --git a/user/src/com/google/gwt/user/client/ui/Hyperlink.java b/user/src/com/google/gwt/user/client/ui/Hyperlink.java
index 9d8f2e0..08e25f8 100644
--- a/user/src/com/google/gwt/user/client/ui/Hyperlink.java
+++ b/user/src/com/google/gwt/user/client/ui/Hyperlink.java
@@ -20,7 +20,9 @@
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.safehtml.client.HasSafeHtml;
+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.safehtml.shared.SafeHtml;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
@@ -46,6 +48,14 @@
* </p>
*
* <p>
+ * <h3>Built-in Bidi Text Support</h3>
+ * This widget is capable of automatically adjusting its direction according to
+ * its content. This feature is controlled by {@link #setDirectionEstimator} or
+ * passing a DirectionEstimator parameter to the constructor, and is off by
+ * default.
+ * </p>
+ *
+ * <p>
* <img class='gallery' src='doc-files/Hyperlink.png'/>
* </p>
*
@@ -62,10 +72,14 @@
*/
@SuppressWarnings("deprecation")
public class Hyperlink extends Widget implements HasHTML, SourcesClickEvents,
- HasClickHandlers, HasSafeHtml {
+ HasClickHandlers, HasDirectionEstimator, HasDirectionalSafeHtml {
+
+ public static final DirectionEstimator DEFAULT_DIRECTION_ESTIMATOR =
+ DirectionalTextHelper.DEFAULT_DIRECTION_ESTIMATOR;
private static HyperlinkImpl impl = GWT.create(HyperlinkImpl.class);
-
+
+ protected final DirectionalTextHelper directionalTextHelper;
private final Element anchorElem = DOM.createAnchor();
private String targetHistoryToken;
@@ -88,21 +102,30 @@
}
/**
- * Creates a hyperlink with its text and target history token specified.
+ * Creates a hyperlink with its html and target history token specified.
*
- * @param text the hyperlink's text
- * @param asHTML <code>true</code> to treat the specified text as html
+ * @param html the hyperlink's safe html
+ * @param dir the html's direction
* @param targetHistoryToken the history token to which it will link
* @see #setTargetHistoryToken
*/
- public Hyperlink(String text, boolean asHTML, String targetHistoryToken) {
- this();
- if (asHTML) {
- setHTML(text);
- } else {
- setText(text);
- }
- setTargetHistoryToken(targetHistoryToken);
+ public Hyperlink(SafeHtml html, Direction dir, String targetHistoryToken) {
+ this(html.asString(), true, dir, targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its html and target history token specified.
+ *
+ * @param html the hyperlink's safe html
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ * @param targetHistoryToken the history token to which it will link
+ * @see #setTargetHistoryToken
+ */
+ public Hyperlink(SafeHtml html, DirectionEstimator directionEstimator,
+ String targetHistoryToken) {
+ this(html.asString(), true, directionEstimator, targetHistoryToken);
}
/**
@@ -114,8 +137,49 @@
* history processing)
*/
public Hyperlink(String text, String targetHistoryToken) {
+ this(text, false, targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its text and target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param dir the text's direction
+ * @param targetHistoryToken the history token to which it will link, which
+ * may not be null (use {@link Anchor} instead if you don't need
+ * history processing)
+ */
+ public Hyperlink(String text, Direction dir, String targetHistoryToken) {
+ this(text, false, dir, targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its text and target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ * @param targetHistoryToken the history token to which it will link, which
+ * may not be null (use {@link Anchor} instead if you don't need
+ * history processing)
+ */
+ public Hyperlink(String text, DirectionEstimator directionEstimator,
+ String targetHistoryToken) {
+ this(text, false, directionEstimator, targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its text and target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param asHTML <code>true</code> to treat the specified text as html
+ * @param targetHistoryToken the history token to which it will link
+ * @see #setTargetHistoryToken
+ */
+ public Hyperlink(String text, boolean asHTML, String targetHistoryToken) {
this();
- setText(text);
+ directionalTextHelper.setTextOrHtml(text, asHTML);
setTargetHistoryToken(targetHistoryToken);
}
@@ -129,6 +193,43 @@
sinkEvents(Event.ONCLICK);
setStyleName("gwt-Hyperlink");
+ directionalTextHelper = new DirectionalTextHelper(anchorElem,
+ /* is inline */ true);
+ }
+
+ /**
+ * Creates a hyperlink with its text target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param asHTML <code>true</code> to treat the specified text as html
+ * @param dir the text's direction
+ * @param targetHistoryToken the history token to which it will link
+ * @see #setTargetHistoryToken
+ */
+ private Hyperlink(String text, boolean asHTML, Direction dir,
+ String targetHistoryToken) {
+ this();
+ directionalTextHelper.setTextOrHtml(text, dir, asHTML);
+ setTargetHistoryToken(targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its text and target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param asHTML <code>true</code> to treat the specified text as html
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ * @param targetHistoryToken the history token to which it will link
+ * @see #setTargetHistoryToken
+ */
+ private Hyperlink(String text, boolean asHTML,
+ DirectionEstimator directionEstimator, String targetHistoryToken) {
+ this();
+ directionalTextHelper.setDirectionEstimator(directionEstimator);
+ directionalTextHelper.setTextOrHtml(text, asHTML);
+ setTargetHistoryToken(targetHistoryToken);
}
/**
@@ -151,8 +252,12 @@
ListenerWrapper.WrappedClickListener.add(this, listener);
}
+ public DirectionEstimator getDirectionEstimator() {
+ return directionalTextHelper.getDirectionEstimator();
+ }
+
public String getHTML() {
- return DOM.getInnerHTML(anchorElem);
+ return directionalTextHelper.getTextOrHtml(true);
}
/**
@@ -166,7 +271,11 @@
}
public String getText() {
- return DOM.getInnerText(anchorElem);
+ return directionalTextHelper.getTextOrHtml(false);
+ }
+
+ public Direction getTextDirection() {
+ return directionalTextHelper.getTextDirection();
}
@Override
@@ -187,14 +296,40 @@
ListenerWrapper.WrappedClickListener.remove(this, listener);
}
- public void setHTML(String html) {
- DOM.setInnerHTML(anchorElem, html);
+ /**
+ * {@inheritDoc}
+ * <p>
+ * See note at {@link #setDirectionEstimator(DirectionEstimator)}.
+ */
+ public void setDirectionEstimator(boolean enabled) {
+ directionalTextHelper.setDirectionEstimator(enabled);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Note: DirectionEstimator should be set before the widget has any content;
+ * it's highly recommended to set it using a constructor. Reason: if the
+ * widget already has non-empty content, this will update its direction
+ * according to the new estimator's result. This may cause flicker, and thus
+ * should be avoided.
+ */
+ public void setDirectionEstimator(DirectionEstimator directionEstimator) {
+ directionalTextHelper.setDirectionEstimator(directionEstimator);
}
public void setHTML(SafeHtml html) {
setHTML(html.asString());
}
+ public void setHTML(String html) {
+ directionalTextHelper.setTextOrHtml(html, true);
+ }
+
+ public void setHTML(SafeHtml html, Direction dir) {
+ directionalTextHelper.setTextOrHtml(html.asString(), dir, true);
+ }
+
/**
* Sets the history token referenced by this hyperlink. This is the history
* token that will be passed to {@link History#newItem} when this link is
@@ -211,7 +346,11 @@
}
public void setText(String text) {
- DOM.setInnerText(anchorElem, text);
+ directionalTextHelper.setTextOrHtml(text, false);
+ }
+
+ public void setText(String text, Direction dir) {
+ directionalTextHelper.setTextOrHtml(text, dir, false);
}
/**
@@ -228,4 +367,3 @@
ensureDebugId(getElement(), baseID, "wrapper");
}
}
-
diff --git a/user/src/com/google/gwt/user/client/ui/InlineHTML.java b/user/src/com/google/gwt/user/client/ui/InlineHTML.java
index a1a0bc1..09f8f98 100644
--- a/user/src/com/google/gwt/user/client/ui/InlineHTML.java
+++ b/user/src/com/google/gwt/user/client/ui/InlineHTML.java
@@ -17,6 +17,9 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
+
+
+import com.google.gwt.i18n.shared.DirectionEstimator;
import com.google.gwt.safehtml.shared.SafeHtml;
/**
@@ -32,6 +35,14 @@
* used properly.
* </p>
*
+ * <p>
+ * <h3>Built-in Bidi Text Support</h3>
+ * This widget is capable of automatically adjusting its direction according to
+ * its content. This feature is controlled by {@link #setDirectionEstimator} or
+ * passing a DirectionEstimator parameter to the constructor, and is off by
+ * default.
+ * </p>
+ *
* <h3>CSS Style Rules</h3>
* <ul class='css'>
* <li>.gwt-InlineHTML { }</li>
@@ -80,16 +91,6 @@
}
/**
- * Creates an HTML widget with the specified HTML contents.
- *
- * @param html the new widget's HTML contents
- */
- public InlineHTML(String html) {
- this();
- setHTML(html);
- }
-
- /**
* Creates an HTML widget with the specified contents and with the
* specified direction.
*
@@ -102,6 +103,31 @@
}
/**
+ * Creates an HTML widget with the specified HTML contents and with a default
+ * direction estimator.
+ *
+ * @param html the new widget's SafeHtml contents
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link Label#DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ */
+ public InlineHTML(SafeHtml html, DirectionEstimator directionEstimator) {
+ this();
+ setDirectionEstimator(directionEstimator);
+ setHTML(html);
+ }
+
+ /**
+ * Creates an HTML widget with the specified HTML contents.
+ *
+ * @param html the new widget's HTML contents
+ */
+ public InlineHTML(String html) {
+ this();
+ setHTML(html);
+ }
+
+ /**
* Creates an HTML widget with the specified HTML contents and with the
* specified direction.
*
@@ -113,7 +139,7 @@
this();
setHTML(html, dir);
}
-
+
/**
* This constructor may be used by subclasses to explicitly use an existing
* element. This element must be either a <div> <span> element.
diff --git a/user/src/com/google/gwt/user/client/ui/InlineHyperlink.java b/user/src/com/google/gwt/user/client/ui/InlineHyperlink.java
index 663d6f9..43b20be 100644
--- a/user/src/com/google/gwt/user/client/ui/InlineHyperlink.java
+++ b/user/src/com/google/gwt/user/client/ui/InlineHyperlink.java
@@ -16,6 +16,8 @@
package com.google.gwt.user.client.ui;
+import com.google.gwt.i18n.client.HasDirection.Direction;
+import com.google.gwt.i18n.shared.DirectionEstimator;
import com.google.gwt.safehtml.shared.SafeHtml;
/**
@@ -24,6 +26,14 @@
* {@link com.google.gwt.user.client.ui.Hyperlink}, save that it lays out
* as an inline element, not block.
*
+ * <p>
+ * <h3>Built-in Bidi Text Support</h3>
+ * This widget is capable of automatically adjusting its direction according to
+ * its content. This feature is controlled by {@link #setDirectionEstimator} or
+ * passing a DirectionEstimator parameter to the constructor, and is off by
+ * default.
+ * </p>
+ *
* <h3>CSS Style Rules</h3>
* <ul class='css'>
* <li>.gwt-InlineHyperlink { }</li>
@@ -52,22 +62,31 @@
}
/**
- * Creates a hyperlink with its text and target history token specified.
- *
- * @param text the hyperlink's text
- * @param asHTML <code>true</code> to treat the specified text as html
+ * Creates a hyperlink with its html and target history token specified.
+ *
+ * @param html the hyperlink's html
+ * @param dir the html's direction
* @param targetHistoryToken the history token to which it will link
* @see #setTargetHistoryToken
*/
- public InlineHyperlink(String text, boolean asHTML, String targetHistoryToken) {
- this();
-
- if (asHTML) {
- setHTML(text);
- } else {
- setText(text);
- }
- setTargetHistoryToken(targetHistoryToken);
+ public InlineHyperlink(SafeHtml html, Direction dir,
+ String targetHistoryToken) {
+ this(html.asString(), true, dir, targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its html and target history token specified.
+ *
+ * @param html the hyperlink's html
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link Hyperlink#DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ * @param targetHistoryToken the history token to which it will link
+ * @see #setTargetHistoryToken
+ */
+ public InlineHyperlink(SafeHtml html, DirectionEstimator directionEstimator,
+ String targetHistoryToken) {
+ this(html.asString(), true, directionEstimator, targetHistoryToken);
}
/**
@@ -79,4 +98,80 @@
public InlineHyperlink(String text, String targetHistoryToken) {
this(text, false, targetHistoryToken);
}
+
+ /**
+ * Creates a hyperlink with its text and target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param dir the text's direction
+ * @param targetHistoryToken the history token to which it will link
+ */
+ public InlineHyperlink(String text, Direction dir,
+ String targetHistoryToken) {
+ this(text, false, dir, targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its text and target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link Hyperlink#DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ * @param targetHistoryToken the history token to which it will link
+ */
+ public InlineHyperlink(String text, DirectionEstimator directionEstimator,
+ String targetHistoryToken) {
+ this(text, false, directionEstimator, targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its text and target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param asHTML <code>true</code> to treat the specified text as html
+ * @param targetHistoryToken the history token to which it will link
+ * @see #setTargetHistoryToken
+ */
+ public InlineHyperlink(String text, boolean asHTML,
+ String targetHistoryToken) {
+ this();
+ directionalTextHelper.setTextOrHtml(text, asHTML);
+ setTargetHistoryToken(targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its text and target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param asHTML <code>true</code> to treat the specified text as html
+ * @param dir the text's direction
+ * @param targetHistoryToken the history token to which it will link
+ * @see #setTargetHistoryToken
+ */
+ private InlineHyperlink(String text, boolean asHTML, Direction dir,
+ String targetHistoryToken) {
+ this();
+ directionalTextHelper.setTextOrHtml(text, dir, asHTML);
+ setTargetHistoryToken(targetHistoryToken);
+ }
+
+ /**
+ * Creates a hyperlink with its text and target history token specified.
+ *
+ * @param text the hyperlink's text
+ * @param asHTML <code>true</code> to treat the specified text as html
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link Hyperlink#DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ * @param targetHistoryToken the history token to which it will link
+ * @see #setTargetHistoryToken
+ */
+ private InlineHyperlink(String text, boolean asHTML,
+ DirectionEstimator directionEstimator, String targetHistoryToken) {
+ this();
+ directionalTextHelper.setDirectionEstimator(directionEstimator);
+ directionalTextHelper.setTextOrHtml(text, asHTML);
+ setTargetHistoryToken(targetHistoryToken);
+ }
}
diff --git a/user/src/com/google/gwt/user/client/ui/InlineLabel.java b/user/src/com/google/gwt/user/client/ui/InlineLabel.java
index 75bafab..5a33856 100644
--- a/user/src/com/google/gwt/user/client/ui/InlineLabel.java
+++ b/user/src/com/google/gwt/user/client/ui/InlineLabel.java
@@ -18,12 +18,23 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
+
+import com.google.gwt.i18n.shared.DirectionEstimator;
+
/**
* A widget that contains arbitrary text, <i>not</i> interpreted as HTML.
*
* This widget uses a <span> element, causing it to be displayed with
* inline layout.
*
+ * <p>
+ * <h3>Built-in Bidi Text Support</h3>
+ * This widget is capable of automatically adjusting its direction according to
+ * its content. This feature is controlled by {@link #setDirectionEstimator} or
+ * passing a DirectionEstimator parameter to the constructor, and is off by
+ * default.
+ * </p>
+ *
* <h3>CSS Style Rules</h3>
* <ul class='css'>
* <li>.gwt-InlineLabel { }</li>
@@ -85,6 +96,20 @@
}
/**
+ * Creates a label with the specified text and a default direction estimator.
+ *
+ * @param text the new label's text
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link Label#DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ */
+ public InlineLabel(String text, DirectionEstimator directionEstimator) {
+ this();
+ setDirectionEstimator(directionEstimator);
+ setText(text);
+ }
+
+ /**
* This constructor may be used by subclasses to explicitly use an existing
* element. This element must be either a <div> <span> element.
*
diff --git a/user/src/com/google/gwt/user/client/ui/Label.java b/user/src/com/google/gwt/user/client/ui/Label.java
index b689c3b..ab4792e 100644
--- a/user/src/com/google/gwt/user/client/ui/Label.java
+++ b/user/src/com/google/gwt/user/client/ui/Label.java
@@ -42,10 +42,8 @@
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.BidiUtils;
import com.google.gwt.i18n.client.HasDirection;
-import com.google.gwt.i18n.shared.BidiFormatter;
import com.google.gwt.i18n.shared.DirectionEstimator;
import com.google.gwt.i18n.shared.HasDirectionEstimator;
-import com.google.gwt.i18n.shared.WordCountDirectionEstimator;
/**
* A widget that contains arbitrary text, <i>not</i> interpreted as HTML.
@@ -53,6 +51,14 @@
* This widget uses a <div> element, causing it to be displayed with block
* layout.
*
+ * <p>
+ * <h3>Built-in Bidi Text Support</h3>
+ * This widget is capable of automatically adjusting its direction according to
+ * its content. This feature is controlled by {@link #setDirectionEstimator} or
+ * passing a DirectionEstimator parameter to the constructor, and is off by
+ * default.
+ * </p>
+ *
* <h3>CSS Style Rules</h3>
* <ul class='css'>
* <li>.gwt-Label { }</li>
@@ -69,6 +75,9 @@
SourcesMouseEvents, HasAllMouseHandlers, HasDirectionEstimator,
HasAutoHorizontalAlignment, IsEditor<LeafValueEditor<String>> {
+ public static final DirectionEstimator DEFAULT_DIRECTION_ESTIMATOR =
+ DirectionalTextHelper.DEFAULT_DIRECTION_ESTIMATOR;
+
/**
* Creates a Label widget that wraps an existing <div> or <span>
* element.
@@ -93,53 +102,16 @@
}
/**
+ * The widget's DirectionalTextHelper object.
+ */
+ final DirectionalTextHelper directionalTextHelper;
+
+ /**
* The widget's auto horizontal alignment policy.
* @see HasAutoHorizontalAlignment
*/
private AutoHorizontalAlignmentConstant autoHorizontalAlignment;
-
- /**
- * The direction of the widget's content.
- * Note: this may not match the direction of the widget's top DOM element
- * ({@code getElement()}).
- * See {@link #setText(String, Direction)} for details.
- */
- Direction textDir;
-
- /**
- * The widget's DirectionEstimator object.
- */
- DirectionEstimator directionEstimator;
-
- /**
- * The initial direction of the widget's element.
- */
- Direction initialElementDir;
-
- /**
- * Whether the widget is inline (a <span> element).
- * This is needed because direction is handled differently for inline elements
- * and for non-inline elements.
- * <p>
- * In case Label supports types of elements other than span and div, this
- * should get true for any element that is inline by default. Another approach
- * could be calculating the element's display property, but this may have some
- * overhead, and is problematic when the element is yet unattached.
- */
- boolean isElementInline;
-
- /**
- * Whether the widget contains a nested <span> element used to
- * indicate the content's direction.
- * <p>
- * The widget's top element is used for this purpose when it is a <div>,
- * but doing so on an inline element often results in garbling what follows
- * it. Thus, when the widget's top element is a <span>, a nested
- * <span> must be used to carry the content's direction, with an LRM or
- * RLM character afterwards to prevent the garbling.
- */
- boolean isSpanWrapped;
-
+
/**
* The widget's horizontal alignment.
*/
@@ -151,10 +123,7 @@
public Label() {
setElement(Document.get().createDivElement());
setStyleName("gwt-Label");
- isElementInline = false;
- isSpanWrapped = false;
- textDir = Direction.DEFAULT;
- initialElementDir = Direction.DEFAULT;
+ directionalTextHelper = new DirectionalTextHelper(getElement(), false);
}
/**
@@ -168,6 +137,32 @@
}
/**
+ * Creates a label with the specified text and direction.
+ *
+ * @param text the new label's text
+ * @param dir the text's direction. Note that {@code DEFAULT} means direction
+ * should be inherited from the widget's parent element.
+ */
+ public Label(String text, Direction dir) {
+ this();
+ setText(text, dir);
+ }
+
+ /**
+ * Creates a label with the specified text and a default direction estimator.
+ *
+ * @param text the new label's text
+ * @param directionEstimator A DirectionEstimator object used for automatic
+ * direction adjustment. For convenience,
+ * {@link #DEFAULT_DIRECTION_ESTIMATOR} can be used.
+ */
+ public Label(String text, DirectionEstimator directionEstimator) {
+ this();
+ setDirectionEstimator(directionEstimator);
+ setText(text);
+ }
+
+ /**
* Creates a label with the specified text.
*
* @param text the new label's text
@@ -179,18 +174,6 @@
}
/**
- * Creates a label with the specified text and direction.
- *
- * @param text the new label's text
- * @param dir the text's direction. Note that {@code DEFAULT} means direction
- * should be inherited from the widget's parent element.
- */
- public Label(String text, Direction dir) {
- this();
- setText(text, dir);
- }
-
- /**
* This constructor may be used by subclasses to explicitly use an existing
* element. This element must be either a <div> or <span> element.
*
@@ -199,11 +182,10 @@
protected Label(Element element) {
setElement(element);
String tagName = element.getTagName();
- isElementInline = tagName.equalsIgnoreCase("span");
+ boolean isElementInline = tagName.equalsIgnoreCase("span");
assert isElementInline || tagName.equalsIgnoreCase("div");
- isSpanWrapped = false;
- initialElementDir = BidiUtils.getDirectionOnElement(element);
- textDir = initialElementDir;
+ directionalTextHelper = new DirectionalTextHelper(getElement(),
+ isElementInline);
}
public HandlerRegistration addClickHandler(ClickHandler handler) {
@@ -285,7 +267,7 @@
}
public DirectionEstimator getDirectionEstimator() {
- return directionEstimator;
+ return directionalTextHelper.getDirectionEstimator();
}
/**
@@ -296,13 +278,11 @@
}
public String getText() {
- Element element = isSpanWrapped ? getElement().getFirstChildElement()
- : getElement();
- return element.getInnerText();
+ return directionalTextHelper.getTextOrHtml(false);
}
public Direction getTextDirection() {
- return textDir;
+ return directionalTextHelper.getTextDirection();
}
public boolean getWordWrap() {
@@ -352,14 +332,7 @@
*/
@Deprecated
public void setDirection(Direction direction) {
- BidiUtils.setDirectionOnElement(getElement(), direction);
- initialElementDir = direction;
-
- // For backwards compatibility, assure there's no span wrap, and update the
- // content direction.
- getElement().setInnerText(getText());
- isSpanWrapped = false;
- textDir = initialElementDir;
+ directionalTextHelper.setDirection(direction);
updateHorizontalAlignment();
}
@@ -369,21 +342,22 @@
* See note at {@link #setDirectionEstimator(DirectionEstimator)}.
*/
public void setDirectionEstimator(boolean enabled) {
- setDirectionEstimator(enabled ? WordCountDirectionEstimator.get() : null);
+ directionalTextHelper.setDirectionEstimator(enabled);
+ updateHorizontalAlignment();
}
/**
* {@inheritDoc}
* <p>
- * Note: if the widget already has non-empty content, this will update
- * its direction according to the new estimator's result. This may cause
- * flicker, and thus should be avoided; DirectionEstimator should be set
- * before the widget has any content.
+ * Note: DirectionEstimator should be set before the widget has any content;
+ * it's highly recommended to set it using a constructor. Reason: if the
+ * widget already has non-empty content, this will update its direction
+ * according to the new estimator's result. This may cause flicker, and thus
+ * should be avoided.
*/
public void setDirectionEstimator(DirectionEstimator directionEstimator) {
- this.directionEstimator = directionEstimator;
- // Refresh appearance
- setText(getText());
+ directionalTextHelper.setDirectionEstimator(directionEstimator);
+ updateHorizontalAlignment();
}
/**
@@ -406,27 +380,13 @@
* Doesn't change the widget's direction or horizontal alignment if {@code
* directionEstimator} is null. Otherwise, the widget's direction is set using
* the estimator, and its alignment may therefore change as described in
- * {@link #setText(String, com.google.gwt.i18n.client.HasDirection.Direction)
- * setText(String, Direction)}.
+ * {@link #setText(String, com.google.gwt.i18n.client.HasDirection.Direction) setText(String, Direction)}.
*
* @param text the widget's new text
*/
public void setText(String text) {
- if (directionEstimator == null) {
- isSpanWrapped = false;
- getElement().setInnerText(text);
-
- // Preserves the initial direction of the widget. This is different from
- // passing the direction parameter explicitly as DEFAULT, which forces the
- // widget to inherit the direction from its parent.
- if (textDir != initialElementDir) {
- textDir = initialElementDir;
- BidiUtils.setDirectionOnElement(getElement(), initialElementDir);
- updateHorizontalAlignment();
- }
- } else {
- setText(text, directionEstimator.estimateDirection(text, false));
- }
+ directionalTextHelper.setTextOrHtml(text, false);
+ updateHorizontalAlignment();
}
/**
@@ -450,20 +410,7 @@
* direction should be inherited from the widget's parent element.
*/
public void setText(String text, Direction dir) {
- textDir = dir;
-
- // Set the text and the direction.
- if (isElementInline) {
- isSpanWrapped = true;
- getElement().setInnerHTML(BidiFormatter.getInstanceForCurrentLocale(
- true /* alwaysSpan */).spanWrapWithKnownDir(dir, text, false));
- } else {
- isSpanWrapped = false;
- BidiUtils.setDirectionOnElement(getElement(), dir);
- getElement().setInnerText(text);
- }
-
- // Update the horizontal alignment if needed.
+ directionalTextHelper.setTextOrHtml(text, dir, false);
updateHorizontalAlignment();
}
@@ -474,7 +421,9 @@
/**
* Sets the horizontal alignment of the widget according to the current
- * AutoHorizontalAlignment setting.
+ * AutoHorizontalAlignment setting. Should be invoked whenever the horizontal
+ * alignment may be affected, i.e. on every modification of the content or its
+ * direction.
*/
protected void updateHorizontalAlignment() {
HorizontalAlignmentConstant align;
@@ -486,8 +435,8 @@
/* autoHorizontalAlignment is a truly automatic policy, i.e. either
ALIGN_CONTENT_START or ALIGN_CONTENT_END */
align = autoHorizontalAlignment == ALIGN_CONTENT_START ?
- HorizontalAlignmentConstant.startOf(textDir) :
- HorizontalAlignmentConstant.endOf(textDir);
+ HorizontalAlignmentConstant.startOf(getTextDirection()) :
+ HorizontalAlignmentConstant.endOf(getTextDirection());
}
if (align != horzAlign) {
diff --git a/user/test/com/google/gwt/user/UISuite.java b/user/test/com/google/gwt/user/UISuite.java
index 200e004..02b6946 100644
--- a/user/test/com/google/gwt/user/UISuite.java
+++ b/user/test/com/google/gwt/user/UISuite.java
@@ -45,6 +45,7 @@
import com.google.gwt.user.client.ui.DefaultSuggestionDisplayTest;
import com.google.gwt.user.client.ui.DelegatingKeyboardListenerCollectionTest;
import com.google.gwt.user.client.ui.DialogBoxTest;
+import com.google.gwt.user.client.ui.DirectionalTextHelperTest;
import com.google.gwt.user.client.ui.DisclosurePanelTest;
import com.google.gwt.user.client.ui.DockLayoutPanelRtlTest;
import com.google.gwt.user.client.ui.DockLayoutPanelTest;
@@ -147,6 +148,7 @@
suite.addTestSuite(DefaultSuggestionDisplayTest.class);
suite.addTestSuite(DelegatingKeyboardListenerCollectionTest.class);
suite.addTestSuite(DialogBoxTest.class);
+ suite.addTestSuite(DirectionalTextHelperTest.class);
suite.addTestSuite(DisclosurePanelTest.class);
suite.addTestSuite(DockLayoutPanelRtlTest.class);
suite.addTestSuite(DockLayoutPanelTest.class);
@@ -220,4 +222,3 @@
return suite;
}
}
-
diff --git a/user/test/com/google/gwt/user/client/ui/DirectionalTextHelperTest.java b/user/test/com/google/gwt/user/client/ui/DirectionalTextHelperTest.java
new file mode 100644
index 0000000..a5e9561
--- /dev/null
+++ b/user/test/com/google/gwt/user/client/ui/DirectionalTextHelperTest.java
@@ -0,0 +1,193 @@
+/*
+ * 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.user.client.ui;
+
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.i18n.client.BidiUtils;
+import com.google.gwt.i18n.client.HasDirection.Direction;
+import com.google.gwt.i18n.client.LocaleInfo;
+import com.google.gwt.i18n.shared.AnyRtlDirectionEstimator;
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Tests {@link DirectionalTextHelper}.
+ */
+public class DirectionalTextHelperTest extends GWTTestCase {
+
+ private final String EN_TEXT = "abc";
+ private final String IW_TEXT = "\u05e0\u05e1\u05e2";
+ private final String EN_HTML = "<b style=\"color: red\">" + EN_TEXT + "</b>";
+ private final String IW_HTML = "<b style=\"color: red\">" + IW_TEXT + "</b>";
+ private Element element;
+ private DirectionalTextHelper directionalTextHelper;
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.user.User";
+ }
+
+ // setDirection is deprecated; this only assures backwards compatibility.
+ public void testSetDirection() {
+ element = Document.get().createSpanElement();
+ directionalTextHelper = new DirectionalTextHelper(element,
+ /* is inline? */ true);
+
+ directionalTextHelper.setDirection(Direction.RTL);
+ assertDirection("element's direction is incorrect after setDirection",
+ Direction.RTL);
+
+ directionalTextHelper.setTextOrHtml(EN_TEXT, Direction.LTR, false);
+ assertDirection("target's direction is incorrect after setText with a" +
+ "specific direction", Direction.LTR);
+
+ directionalTextHelper.setTextOrHtml(EN_TEXT, false);
+ assertDirection("target's direction wasn't reverted to the direction set" +
+ "by last setDirection when calling setText with no direction argument" +
+ "and without a directionEstimator", Direction.RTL);
+
+ // We also specifically assert that the direction of the topmost element
+ // matches the last setDirection. (this is needed only for inline elements).
+ assertEquals("element's direction does not match the direction set by " +
+ "last setDirection when calling setText with no direction argument " +
+ "and without a directionEstimator", Direction.RTL,
+ BidiUtils.getDirectionOnElement(element));
+ }
+
+ public void testSetDirectionEstimator() {
+ element = Document.get().createSpanElement();
+ BidiUtils.setDirectionOnElement(element, Direction.LTR);
+ directionalTextHelper = new DirectionalTextHelper(element,
+ /* is inline? */ true);
+ directionalTextHelper.setDirectionEstimator(true);
+
+ // If the element is span-wrapped, a redundant refresh occurred.
+ assertFalse("setDirectionEstimator(true) refreshed appearance before text" +
+ "had been received", isSpanWrapped());
+
+ directionalTextHelper.setDirectionEstimator(false);
+ directionalTextHelper.setTextOrHtml(IW_TEXT, false);
+ assertDirection("Original element's direction (LTR) was modified with no" +
+ "apparent reason", Direction.LTR);
+
+ directionalTextHelper.setDirectionEstimator(true);
+ assertDirection("Direction was not refreshed on " +
+ "setDirectionEstimator(true) after receiving text with no explicit " +
+ "direction", Direction.RTL);
+
+ directionalTextHelper.setTextOrHtml(IW_TEXT, Direction.LTR, false);
+ directionalTextHelper.setDirectionEstimator(
+ AnyRtlDirectionEstimator.get());
+ assertDirection("Direction was refreshed on setDirectionEstimator after " +
+ "receiving text with explicit direction", Direction.LTR);
+
+ directionalTextHelper.setTextOrHtml(IW_TEXT, false);
+ directionalTextHelper.setDirectionEstimator(false);
+ assertDirection("Direction was not reset to the initial element direction" +
+ " on turning off direction estimation when last call to setTextOrHtml" +
+ " did not declare explicit direction.", Direction.LTR);
+ }
+
+ public void testSetDirectionEstimatorAndSetHtml() {
+ testSetTextOrHtml(true);
+ }
+
+ public void testSetDirectionEstimatorAndSetText() {
+ testSetTextOrHtml(false);
+ }
+
+ /**
+ * Asserts that both the {@link HasDirectionalText#getTextDirection} and the
+ * physical dir attribute match the expected direction.
+ *
+ * @param message Assertion message
+ * @param expected Expected direction
+ */
+ private void assertDirection(String message, Direction expected) {
+ assertTrue("dir attribute mismatch: " + message,
+ expected == getElementDirection() ||
+ /* For inline elements, empty dir attribute is acceptable if LTR is
+ * expected and the locale is not RTL. */
+ isSpanWrapped() && getElementDirection() == Direction.DEFAULT &&
+ (expected == Direction.RTL) == LocaleInfo.getCurrentLocale().isRTL());
+
+ assertEquals("textDir mismatch: " + message, expected,
+ directionalTextHelper.getTextDirection());
+ }
+
+ private Direction getElementDirection() {
+ Element elem = isSpanWrapped() ? element.getFirstChildElement() : element;
+ return BidiUtils.getDirectionOnElement(elem);
+ }
+
+ // This will not work generally. It assumes that the widget's content isn't
+ // consist of a span tag.
+ private boolean isSpanWrapped() {
+ Element inner = element.getFirstChildElement();
+ return inner != null && inner.getTagName().equalsIgnoreCase("span");
+ }
+
+ private void testSetTextOrHtml(boolean isHtml) {
+ String enContent = isHtml ? EN_HTML : EN_TEXT;
+ String iwContent = isHtml ? IW_HTML : IW_TEXT;
+ for (int i = 0; i < 2; i++) {
+ boolean isDiv = i == 0;
+ String id = isDiv ? "div widget: " : "span widget: ";
+ element = isDiv ? Document.get().createDivElement() :
+ Document.get().createSpanElement();
+ directionalTextHelper = new DirectionalTextHelper(element,
+ /* is inline? */ !isDiv);
+
+ directionalTextHelper.setTextOrHtml(enContent, isHtml);
+ assertDirection(id + "widget's direction is not DEFAULT upon " +
+ "standard initialization", Direction.DEFAULT);
+
+ directionalTextHelper.setTextOrHtml(iwContent, Direction.RTL, isHtml);
+ assertDirection(id + "widget's direction is not RTL after it was" +
+ " explicitly set to RTL", Direction.RTL);
+
+ directionalTextHelper.setTextOrHtml(enContent, isHtml);
+ assertDirection(id + "widget's direction was not specified, and no" +
+ " estimator specified, thus should return to initial value (DEFAULT)",
+ Direction.DEFAULT);
+
+ // Toggling on direction estimation from now on.
+ directionalTextHelper.setDirectionEstimator(true);
+
+ assertDirection(id + "widget's direction wasn't instantly updated" +
+ " to LTR on switching direction estimation on", Direction.LTR);
+
+ directionalTextHelper.setTextOrHtml(iwContent, isHtml);
+ assertDirection(id + "widget's direction wasn't estimated as RTL",
+ Direction.RTL);
+
+ directionalTextHelper.setTextOrHtml(iwContent, Direction.LTR, isHtml);
+ assertDirection(id + "widget's direction is not LTR after it was" +
+ " explicitly set to LTR (direction estimation is on)", Direction.LTR);
+
+ directionalTextHelper.setTextOrHtml(iwContent, Direction.DEFAULT, isHtml);
+ assertDirection(id + "widget's direction is not DEFAULT after it" +
+ " was explicitly set to DEFAULT (direction estimation is on)",
+ Direction.DEFAULT);
+
+ // TODO(jlabanca): Need a cross-browser way to test innerHTML.
+ // assertEquals(id + "retreived html is incorrect", iwContent,
+ // directionalTextHelper.getTextOrHtml(true).toLowerCase());
+ assertEquals(id + "retreived text is incorrect", IW_TEXT,
+ directionalTextHelper.getTextOrHtml(false).toLowerCase());
+ }
+ }
+}
diff --git a/user/test/com/google/gwt/user/client/ui/HTMLTest.java b/user/test/com/google/gwt/user/client/ui/HTMLTest.java
index bdb50b9..128f9bb 100644
--- a/user/test/com/google/gwt/user/client/ui/HTMLTest.java
+++ b/user/test/com/google/gwt/user/client/ui/HTMLTest.java
@@ -15,10 +15,7 @@
*/
package com.google.gwt.user.client.ui;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.i18n.client.BidiUtils;
import com.google.gwt.i18n.client.HasDirection.Direction;
-import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
/**
@@ -28,9 +25,6 @@
public class HTMLTest extends LabelTest {
private static final String html = "<b>hello</b><i>world</i>";
- private final String EN_HTML = "<b style=\"color: red\">" + EN_TEXT + "</b>";
- private final String IW_HTML = "<b style=\"color: red\">" + IW_TEXT + "</b>";
- private HTML label;
@Override
public String getModuleName() {
@@ -65,43 +59,6 @@
assertEquals(Direction.RTL, htmlElementRTL.getTextDirection());
}
- // setDirection is deprecated; this only assures backwards compatibility.
- public void testSetDirection() {
- for (int i = 0; i < 2; i++) {
- String id = i == 0 ? "div label: " : "span label: ";
- label = HTML.wrap(i == 0 ? createAttachedDivElement() :
- createAttachedSpanElement());
- label.setDirection(Direction.RTL);
- assertLabelDirection(id + "label's direction is incorrect after " +
- "setDirection", Direction.RTL);
-
- label.setText(EN_TEXT, Direction.LTR);
- assertLabelDirection(id + "label's direction is incorrect after " +
- "setText with a specific direction", Direction.LTR);
-
- label.setText(EN_TEXT);
- assertLabelDirection(id + "label's direction wasn't reverted to the " +
- "direction set by last setDirection when calling setText with no " +
- "direction argument and without a directionEstimator", Direction.RTL);
- if (i == 1) {
- // For span element, we also specifically assert that the direction of
- // the topmost element matches the last setDirection.
- assertEquals(id + "element's direction does not match the direction " +
- "set by last setDirection when calling setText with no direction " +
- "argument and without a directionEstimator", Direction.RTL,
- BidiUtils.getDirectionOnElement(label.getElement()));
- }
- }
- }
-
- public void testSetDirectionEstimatorAndSetHtml() {
- testSetDirectionEstimatorAndSetTextOrHtml(true);
- }
-
- public void testSetDirectionEstimatorAndSetText() {
- testSetDirectionEstimatorAndSetTextOrHtml(false);
- }
-
public void testSetSafeHtml() {
HTML htmlElement = new HTML("<b>foo</b>");
htmlElement.setHTML(SafeHtmlUtils.fromSafeConstant(html));
@@ -129,99 +86,4 @@
html2.setText("<b>foo</b>", Direction.RTL);
assertEquals("<b>foo</b>", html2.getText());
}
-
- /**
- * Asserts that both the {@link Label#getTextDirection} and the physical dir
- * attribute match the expected direction.
- *
- * @param message Assertion message
- * @param expected Expected direction
- */
- private void assertLabelDirection(String message, Direction expected) {
- assertTrue("attribute mismatch: " + message,
- expected == getLabelDirection() ||
- /* For inline elements, empty dir attribute is acceptable if LTR is
- * expected and the locale is not RTL. */
- isSpanWrapped() && getLabelDirection() == Direction.DEFAULT &&
- expected == Direction.LTR && !LocaleInfo.getCurrentLocale().isRTL());
-
- assertEquals("textDir mismatch: " + message, expected,
- label.getTextDirection());
- }
-
- private Direction getLabelDirection() {
- Element element = isSpanWrapped() ?
- label.getElement().getFirstChildElement() : label.getElement();
-
- return BidiUtils.getDirectionOnElement(element);
- }
-
- // This will not work generally. It assumes that the label's content isn't
- // consist of a span tag.
- private boolean isSpanWrapped() {
- Element inner = label.getElement().getFirstChildElement();
- return inner != null && inner.getTagName().equalsIgnoreCase("span");
- }
-
- private void setLabelTextOrHtml(String content, boolean isHtml) {
- if (isHtml) {
- label.setHTML(content);
- } else {
- label.setText(content);
- }
- }
-
- private void setLabelTextOrHtml(String content, Direction dir, boolean isHtml) {
- if (isHtml) {
- label.setHTML(content, dir);
- } else {
- label.setText(content, dir);
- }
- }
-
- private void testSetDirectionEstimatorAndSetTextOrHtml(boolean isHtml) {
- String enContent = isHtml ? EN_HTML : EN_TEXT;
- String iwContent = isHtml ? IW_HTML : IW_TEXT;
- for (int i = 0; i < 2; i++) {
- String id = i == 0 ? "div label: " : "span label: ";
- label = HTML.wrap(i == 0 ? createAttachedDivElement() :
- createAttachedSpanElement());
-
- setLabelTextOrHtml(enContent, isHtml);
- assertLabelDirection(id + "label's direction is not DEFAULT upon " +
- "standard initialization", Direction.DEFAULT);
-
- setLabelTextOrHtml(iwContent, Direction.RTL, isHtml);
- assertLabelDirection(id + "label's direction is not RTL after it was" +
- " explicitly set to RTL", Direction.RTL);
-
- setLabelTextOrHtml(enContent, isHtml);
- assertLabelDirection(id + "label's direction was not specified, and no" +
- " estimator specified, thus should return to initial value (DEFAULT)",
- Direction.DEFAULT);
-
- label.setDirectionEstimator(true);
- assertLabelDirection(id + "label's direction wasn't instantly updated" +
- " to LTR on switching direction estimation on", Direction.LTR);
-
- setLabelTextOrHtml(iwContent, isHtml);
- assertLabelDirection(id + "label's direction wasn't estimated as RTL",
- Direction.RTL);
-
- setLabelTextOrHtml(iwContent, Direction.LTR, isHtml);
- assertLabelDirection(id + "label's direction is not LTR after it was" +
- " explicitly set to LTR (direction estimation is on)", Direction.LTR);
-
- setLabelTextOrHtml(iwContent, Direction.DEFAULT, isHtml);
- assertLabelDirection(id + "label's direction is not DEFAULT after it" +
- " was explicitly set to DEFAULT (direction estimation is on)",
- Direction.DEFAULT);
-
- // TODO(jlabanca): Need a cross-browser way to test innerHTML.
- // assertEquals(id + "retreived html is incorrect", iwContent,
- // label.getHTML().toLowerCase());
- assertEquals(id + "retreived text is incorrect", IW_TEXT,
- label.getText().toLowerCase());
- }
- }
}
diff --git a/user/test/com/google/gwt/user/client/ui/LabelTest.java b/user/test/com/google/gwt/user/client/ui/LabelTest.java
index 98276d0..43e2879 100644
--- a/user/test/com/google/gwt/user/client/ui/LabelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/LabelTest.java
@@ -22,6 +22,7 @@
import com.google.gwt.i18n.client.BidiUtils;
import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.junit.client.GWTTestCase;
+
import com.google.gwt.user.client.ui.HasHorizontalAlignment.AutoHorizontalAlignmentConstant;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
@@ -91,7 +92,7 @@
// Initialize the div with a specific direction, to verify it remembers its
// original direction on turning direction estimator off.
BidiUtils.setDirectionOnElement(elem, Direction.LTR);
- label = Label.wrap(createAttachedDivElement());
+ label = Label.wrap(elem);
label.setAutoHorizontalAlignment(
HasAutoHorizontalAlignment.ALIGN_CONTENT_END);
@@ -117,32 +118,13 @@
HasAutoHorizontalAlignment.ALIGN_CONTENT_START);
label.setDirectionEstimator(false);
- assertAlign("direction was supposed to be reset to the original " +
- "ALIGN_LEFT after turning off direction estimator, and automatic " +
- "horizontal alignment was to ALIGN_CONTENT_START",
+ assertAlign("horizontal alignment was supposed to be reset to the " +
+ "original ALIGN_LEFT after turning off direction estimator, and " +
+ "automatic horizontal alignment was to ALIGN_CONTENT_START",
HasHorizontalAlignment.ALIGN_LEFT,
HasAutoHorizontalAlignment.ALIGN_CONTENT_START);
}
- public void testSetDirection() {
- Label label = new Label(createAttachedSpanElement());
- label.setDirectionEstimator(true);
- label.setText(IW_TEXT);
-
- // Should be span wrapped.
- assertTrue(label.getElement().getInnerHTML().toLowerCase().contains("span"));
-
- // Should not be span wrapped.
- label.setDirection(Direction.RTL);
- assertEquals(Direction.RTL, label.getDirection());
- assertFalse(label.getElement().getInnerHTML().toLowerCase().contains("span"));
-
- // Should not be span wrapped.
- label.setDirection(Direction.LTR);
- assertEquals(Direction.LTR, label.getDirection());
- assertFalse(label.getElement().getInnerHTML().toLowerCase().contains("span"));
- }
-
/**
* Create a div and attach it to the {@link RootPanel}.
*