blob: 6df56dcbc439895f5029c006a75b99f862b95651 [file] [log] [blame]
/*
* 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
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.user.client.ui;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
/**
* Tests the HTMLPanel widget.
*/
public class HTMLPanelTest extends GWTTestCase {
static class Adder implements HasWidgetsTester.WidgetAdder {
public void addChild(HasWidgets container, Widget child) {
((HTMLPanel) container).add(child, "w00t");
}
}
public String getModuleName() {
return "com.google.gwt.user.User";
}
/**
* A SafeHtmlTemplates interface for testing.
*/
public interface TestTemplates extends SafeHtmlTemplates {
@Template("<table><tr><td>{0} <span id='labelHere'></span></td></tr></table>")
SafeHtml tableTemplate(String body);
}
/**
* Tests {@link HTMLPanel#add(Widget)}.
*/
public void testAdd() {
Label labelA = new Label("A");
Label labelB = new Label("B");
HTMLPanel p = new HTMLPanel("<div></div>");
p.add(labelA);
p.add(labelB);
// Ensure that both Labels have the correct parent.
Element first = p.getElement().getFirstChildElement();
assertSame(labelA.getElement(), first.getNextSiblingElement());
assertSame(labelB.getElement(), labelA.getElement().getNextSiblingElement());
assertNull(labelB.getElement().getNextSiblingElement());
}
/**
* Tests {@link HTMLPanel#add(Widget, String)}.
*/
public void testAddToElementWithId() {
Label labelA = new Label("A"), labelB = new Label("B");
HTMLPanel p = new HTMLPanel("<div id=\"a\"></div><div id=\"b\"></div>");
p.add(labelA, "a");
p.add(labelB, "b");
// Ensure that both Label's have the correct parent.
assertEquals("a", labelA.getElement().getParentElement().getId());
assertEquals("b", labelB.getElement().getParentElement().getId());
}
/**
* Tests {@link HTMLPanel#add(Widget, Element)}.
*/
public void testAddToElement() {
Label labelA = new Label("A"), labelB = new Label("B");
HTMLPanel p = new HTMLPanel(
"<div class=\"a\"></div><div class=\"b\"></div>");
Element first = p.getElement().getFirstChildElement();
Element second = first.getNextSiblingElement();
p.add(labelA, first);
p.add(labelB, second);
// Ensure that both Label's have the correct parent.
assertEquals("a", labelA.getElement().getParentElement().getClassName());
assertEquals("b", labelB.getElement().getParentElement().getClassName());
}
/**
* This is meant to catch an issue created by a faulty optimization. To
* optimize add() when the HTMLPanel is unattached, we would originally move
* its element to a hidden div so that getElementById() would work.
* Unfortunately, we didn't move it back to its original parent, causing a
* problem in the case described in this test.
*/
public void testAddPartiallyAttached() {
SimplePanel sp = new SimplePanel();
HTMLPanel p = new HTMLPanel("<div id='foo'></div>");
// Add the HTMLPanel to another panel before adding the button.
sp.add(p);
// Add a button the HTMLPanel, causing the panel's element to be attached
// to the DOM.
p.add(new Button("foo"), "foo");
// If all goes well, the HTMLPanel's element should still be properly
// connected to the SimplePanel's element.
assertTrue(sp.getElement().isOrHasChild(p.getElement()));
}
/**
* Tests child attachment order using {@link HasWidgetsTester}.
*/
public void testAttachDetachOrder() {
HTMLPanel p = new HTMLPanel("<div id='w00t'></div>");
HasWidgetsTester.testAll(p, new Adder(), true);
}
/**
* Ensures that attachToDomAndGetElement() puts the HTMLPanel back exactly
* where it was in the DOM originally.
*/
public void testAttachDoesntMangleChildOrder() {
FlowPanel fp = new FlowPanel();
Button ba = new Button("before");
Button bb = new Button("after");
HTMLPanel hp = new HTMLPanel("<div id='foo'></div>");
fp.add(ba);
fp.add(hp);
fp.add(bb);
hp.add(new Button("foo"), "foo");
assertTrue(fp.getElement().isOrHasChild(hp.getElement()));
assertTrue(ba.getElement().getNextSibling() == hp.getElement());
assertTrue(hp.getElement().getNextSibling() == bb.getElement());
}
/**
* Ensures that {@link HTMLPanel#addAndReplaceChild(Widget,String)} puts the
* widget in exactly the right place in the DOM.
*/
public void testAddAndReplaceElement() {
HTMLPanel hp = new HTMLPanel(
"<div id='parent'>foo<span id='placeholder'></span>bar</div>");
Button button = new Button("my button");
hp.addAndReplaceElement(button, "placeholder");
assertParentId(button, "parent");
assertIsBetweenSiblings(button, "foo", "bar");
}
/**
* Ensures that
* {@link HTMLPanel#addAndReplaceElement(Widget, com.google.gwt.user.client.Element)}
* puts the widget in exactly the right place in the DOM.
*/
@SuppressWarnings("deprecation")
public void testAddAndReplaceElementForUserElement() {
HTMLPanel hp = new HTMLPanel(
"<div id='parent'>foo<span id='placeholder'></span>bar</div>");
RootPanel.get().add(hp);
com.google.gwt.user.client.Element placeholder = hp.getElementById("placeholder");
Button button = new Button("my button");
hp.addAndReplaceElement(button, placeholder);
assertParentId(button, "parent");
assertIsBetweenSiblings(button, "foo", "bar");
}
/**
* Ensures that overloaded version of
* {@link HTMLPanel#addAndReplaceElement(IsWidget, com.google.gwt.user.client.Element)}
* for IsWidget puts the widget in exactly the right place in the DOM.
*/
public void testAddAndReplaceElementForUserElementAsIsWidget() {
HTMLPanel hp = new HTMLPanel(
"<div id='parent'>foo<span id='placeholder'></span>bar</div>");
RootPanel.get().add(hp);
com.google.gwt.user.client.Element placeholder = hp.getElementById("placeholder");
Button button = new Button("my button");
// IsWidget reference to call the overloaded version
IsWidget isWidget = button;
hp.addAndReplaceElement(isWidget, placeholder);
assertParentId(button, "parent");
assertIsBetweenSiblings(button, "foo", "bar");
}
/**
* Ensures that {@link HTMLPanel#addAndReplaceElement(Widget, Element)} puts
* the widget in exactly the right place in the DOM.
*/
public void testAddAndReplaceElementForElement() {
HTMLPanel hp = new HTMLPanel(
"<div id='parent'>foo<span id='placeholder'></span>bar</div>");
RootPanel.get().add(hp);
Element placeholder = hp.getElementById("placeholder");
Button button = new Button("my button");
hp.addAndReplaceElement(button, placeholder);
assertParentId(button, "parent");
assertIsBetweenSiblings(button, "foo", "bar");
}
/**
* Tests {@link HTMLPanel#addAndReplaceElement(Widget, String)}.
*/
public void testAddAndReplaceElementById() {
HTMLPanel hp = new HTMLPanel(
"<div id='parent'>foo<span id='placeholder'></span>bar</div>");
RootPanel.get().add(hp);
Button button = new Button("my button");
hp.addAndReplaceElement(button, "placeholder");
assertParentId(button, "parent");
assertIsBetweenSiblings(button, "foo", "bar");
}
/**
* Tests {@link HTMLPanel#addAndReplaceElement(IsWidget, String)}.
*/
public void testAddAndReplaceElementByIdAsIsWidget() {
HTMLPanel hp = new HTMLPanel(
"<div id='parent'>foo<span id='placeholder'></span>bar</div>");
RootPanel.get().add(hp);
Button button = new Button("my button");
// IsWidget cast to call the overloaded version
hp.addAndReplaceElement((IsWidget) button, "placeholder");
assertParentId(button, "parent");
assertIsBetweenSiblings(button, "foo", "bar");
}
/**
* Tests table root tag.
*/
public void testCustomRootTagAsTable() {
HTMLPanel hp = new HTMLPanel("table",
"<tr><td>Hello <span id='labelHere'></span></td></tr>");
InlineLabel label = new InlineLabel("World");
hp.addAndReplaceElement(label, "labelHere");
Element parent = label.getElement().getParentElement();
assertEquals("td", parent.getTagName().toLowerCase());
parent = parent.getParentElement();
assertEquals("tr", parent.getTagName().toLowerCase());
while (parent != null && parent != hp.getElement()) {
parent = parent.getParentElement();
}
assertNotNull(parent);
assertEquals("table", parent.getTagName().toLowerCase());
}
/**
* Ensure that {@link HTMLPanel#getElementById(String)} behaves properly in
* both attached and unattached states.
*/
public void testGetElementById() {
HTMLPanel hp = new HTMLPanel("foo<div id='toFind'>bar</div>baz");
// Get the element twice, once before and once after attachment.
Element elem0 = hp.getElementById("toFind");
RootPanel.get().add(hp);
Element elem1 = hp.getElementById("toFind");
// Make sure we got the same element in both cases.
assertEquals(elem0, elem1);
}
/**
* Tests that the HTMLPanel's element is not moved from its original location
* when {@link HTMLPanel#add(Widget, String)} is called on it while it is
* unattached.
*/
public void testElementIsUnmoved() {
HTMLPanel unattached = new HTMLPanel("<div id='unattached'></div>");
HTMLPanel attached = new HTMLPanel("<div id='attached'></div>");
RootPanel.get().add(attached);
Element unattachedParentElem = unattached.getElement().getParentElement();
Element attachedParentElem = attached.getElement().getParentElement();
unattached.add(new Button("unattached"), "unattached");
attached.add(new Button("attached"), "attached");
assertEquals("Unattached's parent element should be unaffected",
unattachedParentElem, unattached.getElement().getParentElement());
assertEquals("Unattached's parent element should be unaffected",
attachedParentElem, attached.getElement().getParentElement());
}
/**
* Tests SafeHtml constructor.
*/
public void testSafeHtml() {
TestTemplates templates = GWT.create(TestTemplates.class);
SafeHtml table = templates.tableTemplate("Hello");
HTMLPanel hp = new HTMLPanel(table);
InlineLabel label = new InlineLabel("World");
hp.addAndReplaceElement(label, "labelHere");
Element parent = label.getElement().getParentElement();
assertEquals("td", parent.getTagName().toLowerCase());
parent = parent.getParentElement();
assertEquals("tr", parent.getTagName().toLowerCase());
// Look for the table in the main panel div
Element firstChild = null;
while (parent != null && parent != hp.getElement()) {
firstChild = parent;
parent = parent.getParentElement();
}
assertNotNull(parent);
assertEquals("div", parent.getTagName().toLowerCase());
assertEquals("table", firstChild.getTagName().toLowerCase());
}
/**
* Asserts that the widget w is between the given previous and next nodes.
*
* @param w the widget
* @param previous the expected previous node string representation of the
* widget
* @param next the expected next node string representation of the widget
*/
private void assertIsBetweenSiblings(Widget w, String previous, String next) {
Node prevNode = w.getElement().getPreviousSibling();
assertEquals(previous, prevNode.getNodeValue());
Node nextNode = w.getElement().getNextSibling();
assertEquals(next, nextNode.getNodeValue());
}
/**
* Asserts that the parent id of the widget is the given one.
*
* @param w the widget
* @param expected the expected parent id of w
*/
private void assertParentId(Widget w, String expected) {
assertEquals(expected, w.getElement().getParentElement().getId());
}
}