blob: a5e9561a3ab942219d10422ebee6bd39393499bc [file] [log] [blame]
/*
* 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());
}
}
}