Allow flexibilty on root tag of HTMLPanel
Merge branch 'fix-htmlpanel'
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5760 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 1bbdeb6..a00b1c5 100644
--- a/user/src/com/google/gwt/user/client/ui/HTMLPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/HTMLPanel.java
@@ -15,6 +15,8 @@
*/
package com.google.gwt.user.client.ui;
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Document;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
@@ -40,17 +42,55 @@
}
/**
- * Creates an HTML panel with the specified HTML contents. Any element within
- * this HTML that has a specified id can contain a child widget.
+ * Creates an HTML panel with the specified HTML contents inside a DIV
+ * element. Any element within this HTML that has a specified id can contain a
+ * child widget.
*
* @param html the panel's HTML
*/
public HTMLPanel(String html) {
- setElement(DOM.createDiv());
- DOM.setInnerHTML(getElement(), html);
+ /*
+ * Normally would call this("div", html), but that method
+ * has some slightly expensive IE defensiveness that we just
+ * don't need for a div
+ */
+ setElement(Document.get().createDivElement());
+ getElement().setInnerHTML(html);
}
/**
+ * Creates an HTML panel whose root element has the given tag, and with the
+ * specified HTML contents. Any element within this HTML that has a specified
+ * id can contain a child widget.
+ *
+ * @param tag the tag of the root element
+ * @param html the panel's HTML
+ */
+ public HTMLPanel(String tag, String html) {
+ /*
+ * IE has very arbitrary rules about what will and will not accept
+ * innerHTML. <table> and <tbody> simply won't, the property is read only.
+ * <p> will explode if you incorrectly try to put another <p> inside of it.
+ * And who knows what else.
+ *
+ * However, if you cram a complete, possibly incorrect structure inside a
+ * div, IE will swallow it gladly. So that's what we do here in the name of
+ * IE robustification.
+ */
+ StringBuilder b = new StringBuilder();
+ b.append('<').append(tag).append('>').append(html);
+ b.append("</").append(tag).append('>');
+
+ // We could use the static hiddenDiv, but that thing is attached
+ // to the document. The caller might not want that.
+
+ DivElement scratchDiv = Document.get().createDivElement();
+ scratchDiv.setInnerHTML(b.toString());
+ setElement(scratchDiv.getFirstChildElement());
+ getElement().removeFromParent();
+ }
+
+ /**
* Adds a child widget to the panel, contained within the HTML element
* specified by a given 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 9e7f8ac..9409b7d 100644
--- a/user/test/com/google/gwt/user/client/ui/HTMLPanelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/HTMLPanelTest.java
@@ -1,12 +1,12 @@
/*
* Copyright 2008 Google Inc.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -120,6 +120,29 @@
}
/**
+ * Tests table root tag.
+ */
+ public void testCustomRootTagAsTable() {
+ HTMLPanel hp = new HTMLPanel("table",
+ "<tr><td>Hello <span id='labelHere'></span></td></tr></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());
+
+ 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.
*/