Adds to HTMLPanel: - addAndReplaceElement() - getElementById() Patch by: jgw Review by: scottb, knorton Issues: 1616, 2357 git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2701 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/HTMLPanel.java b/user/src/com/google/gwt/user/client/ui/HTMLPanel.java index 3e6a458..b2e9d03 100644 --- a/user/src/com/google/gwt/user/client/ui/HTMLPanel.java +++ b/user/src/com/google/gwt/user/client/ui/HTMLPanel.java
@@ -26,6 +26,8 @@ */ public class HTMLPanel extends ComplexPanel { + private static Element hiddenDiv; + /** * A helper method for creating unique IDs for elements within dynamically- * generated HTML. This is important because no two elements in a document @@ -37,8 +39,6 @@ return DOM.createUniqueId(); } - private Element hiddenDiv; - /** * Creates an HTML panel with the specified HTML contents. Any element within * this HTML that has a specified id can contain a child widget. @@ -58,8 +58,7 @@ * @param id the id of the element within which it will be contained */ public void add(Widget widget, String id) { - final Element elem = (isAttached()) ? DOM.getElementById(id) - : attachToDomAndGetElement(id); + final Element elem = getElementById(id); if (elem == null) { throw new NoSuchElementException(id); @@ -68,15 +67,35 @@ super.add(widget, elem); } - @Override - protected void onLoad() { - if (hiddenDiv != null) { - // This widget's element has already been moved, just need to remove the - // hidden DIV. - DOM.removeChild(RootPanel.getBodyElement(), hiddenDiv); - hiddenDiv = null; + /** + * Adds a child widget to the panel, replacing the HTML element specified by a + * given id. + * + * @param widget the widget to be added + * @param id the id of the element to be replaced by the widget + */ + public void addAndReplaceElement(Widget widget, String id) { + final Element toReplace = getElementById(id); + + if (toReplace == null) { + throw new NoSuchElementException(id); } - super.onLoad(); + + // Logic pulled from super.add(), replacing the element rather than adding. + widget.removeFromParent(); + getChildren().add(widget); + toReplace.getParentNode().replaceChild(widget.getElement(), toReplace); + adopt(widget); + } + + /** + * Finds an {@link Element element} within this panel by its id. + * + * @param id the id of the element to be found + * @return the element with the given id, or <code>null</code> if none is found + */ + public Element getElementById(String id) { + return isAttached() ? DOM.getElementById(id) : attachToDomAndGetElement(id); } /**
diff --git a/user/test/com/google/gwt/user/client/ui/HTMLPanelTest.java b/user/test/com/google/gwt/user/client/ui/HTMLPanelTest.java index 72494ec..8d6986d 100644 --- a/user/test/com/google/gwt/user/client/ui/HTMLPanelTest.java +++ b/user/test/com/google/gwt/user/client/ui/HTMLPanelTest.java
@@ -15,8 +15,10 @@ */ package com.google.gwt.user.client.ui; +import com.google.gwt.dom.client.Node; import com.google.gwt.junit.client.GWTTestCase; import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; /** * Tests the HTMLPanel widget. @@ -98,4 +100,34 @@ assertTrue(DOM.getNextSibling(ba.getElement()) == hp.getElement()); assertTrue(DOM.getNextSibling(hp.getElement()) == bb.getElement()); } + + /** + * Ensures that addAndReplaceChild() 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"); + + assertEquals("parent", button.getElement().getParentElement().getId()); + + Node prev = button.getElement().getPreviousSibling(); + assertEquals("foo", prev.getNodeValue()); + + Node next = button.getElement().getNextSibling(); + assertEquals("bar", next.getNodeValue()); + } + + 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); + } }