Revision: 6821
Author: [email protected]
Date: Tue Nov 10 14:44:37 2009
Log: Merges tr...@6810,6813 into releases/2.0
   keep Ie7 users from paying the AlphaImageLoader penalty
   proper behavior of g:header and g:customHeader in StackLayoutPanelparser
   layout panel units default to PX (instead of NPE, ahem)
   svn merge --ignore-ancestry -c 6810  
https://google-web-toolkit.googlecode.com/svn/trunk .
   svn merge --ignore-ancestry -c 6813  
https://google-web-toolkit.googlecode.com/svn/trunk .


http://code.google.com/p/google-web-toolkit/source/detail?r=6821

Added:
   
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/IsEmptyParser.java
   
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/IsEmptyParserTest.java
   
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParserTest.java
   
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/TabLayoutPanelParserTest.java
   
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/UIObjectParserTest.java
Modified:
  /releases/2.0/branch-info.txt
   
/releases/2.0/samples/mail/src/com/google/gwt/sample/mail/client/Shortcuts.ui.xml
   
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParser.java
   
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java
   
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/TabLayoutPanelParser.java
   
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/UIObjectParser.java
  /releases/2.0/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
  /releases/2.0/user/src/com/google/gwt/uibinder/rebind/XMLElement.java
   
/releases/2.0/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImplIE6.java
  /releases/2.0/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java
   
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParserTest.java
   
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
   
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/UiJavaResources.java
  /releases/2.0/user/test/com/google/gwt/uibinder/rebind/XMLElementTest.java

=======================================
--- /dev/null
+++  
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/IsEmptyParser.java
         
Tue Nov 10 14:44:37 2009
@@ -0,0 +1,34 @@
+/*
+ * 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.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.uibinder.rebind.UiBinderWriter;
+import com.google.gwt.uibinder.rebind.XMLElement;
+
+/**
+ * The last parser, asserts that everything has been consumed
+ * and so the template has nothing unexpected.
+ */
+public class IsEmptyParser implements ElementParser {
+
+  public void parse(XMLElement elem, String fieldName, JClassType type,
+      UiBinderWriter writer) throws UnableToCompleteException {
+    elem.assertNoAttributes();
+    elem.assertNoBody();
+  }
+}
=======================================
--- /dev/null
+++  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/IsEmptyParserTest.java
    
Tue Nov 10 14:44:37 2009
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2009 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.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+
+/**
+ * A unit test. Guess what of.
+ */
+public class IsEmptyParserTest extends TestCase {
+  private static final String PARSED_TYPE  
= "com.google.gwt.user.client.ui.UIObject";
+
+  private ElementParserTester tester;
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    tester = new ElementParserTester(PARSED_TYPE, new IsEmptyParser());
+  }
+
+  public void testExtraText() throws SAXException, IOException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:UIObject>");
+    b.append("  I have some extra");
+    b.append("</g:UIObject>");
+
+    try {
+      tester.parse(b.toString());
+      fail();
+    } catch (UnableToCompleteException e) {
+      assertTrue("Expect extra text echo",
+          tester.logger.died.contains("I have some extra"));
+    }
+  }
+
+  public void testExtraChildren() throws SAXException, IOException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:UIObject>");
+    b.append("  <blorp />");
+    b.append("</g:UIObject>");
+
+    try {
+      tester.parse(b.toString());
+      fail();
+    } catch (UnableToCompleteException e) {
+      assertTrue("Expect extra text child",
+          tester.logger.died.contains("<blorp>"));
+    }
+  }
+
+  public void testExtraAttributes() throws SAXException, IOException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:UIObject blip='blap' blorp='bloop'>");
+    b.append("</g:UIObject>");
+
+    try {
+      tester.parse(b.toString());
+      fail();
+    } catch (UnableToCompleteException e) {
+      assertTrue("Expect extra attributes list",
+          tester.logger.died.contains("\"blip\", \"blorp\""));
+    }
+  }
+}
=======================================
--- /dev/null
+++  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParserTest.java
   
Tue Nov 10 14:44:37 2009
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009 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.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.uibinder.rebind.FieldWriter;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * A unit test. Guess what of.
+ */
+public class StackLayoutPanelParserTest extends TestCase {
+
+  private static final String PARSED_TYPE  
= "com.google.gwt.user.client.ui.StackLayoutPanel";
+
+  private ElementParserTester tester;
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    tester = new ElementParserTester(PARSED_TYPE, new  
StackLayoutPanelParser());
+  }
+
+  public void testBadChild() throws SAXException, IOException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:StackLayoutPanel unit='EM'>");
+    b.append("  <g:west><foo/></g:west>");
+    b.append("</g:StackLayoutPanel>");
+
+    try {
+      tester.parse(b.toString());
+      fail();
+    } catch (UnableToCompleteException e) {
+      assertTrue("expect \"only g:stack\" error",
+          tester.logger.died.contains("only <g:stack> children"));
+    }
+  }
+
+  public void testHappy() throws UnableToCompleteException, SAXException,
+      IOException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:StackLayoutPanel unit='PX'>");
+    b.append("  <g:stack>");
+    b.append("    <g:header size='3'>Re<b>mark</b>able</g:header>");
+    b.append("    <g:Label id='able'>able</g:Label>");
+    b.append("  </g:stack>");
+    b.append("  <g:stack>");
+    b.append("    <g:customHeader size='3'>");
+    b.append("      <g:Label id='custom'>Custom</g:Label>");
+    b.append("    </g:customHeader>");
+    b.append("    <g:Label id='baker'>baker</g:Label>");
+    b.append("  </g:stack>");
+    b.append("</g:StackLayoutPanel>");
+
+    String[] expected = {
+        "fieldName.add(<g:Label id='able'>, "
+            + "new  
com.google.gwt.user.client.ui.HTML(\"Re<b>mark</b>able\"), 3);",
+        "fieldName.add(<g:Label id='baker'>, " + "<g:Label id='custom'>,  
3);",};
+
+    FieldWriter w = tester.parse(b.toString());
+    assertEquals("new " + PARSED_TYPE
+        + "(com.google.gwt.dom.client.Style.Unit.PX)", w.getInitializer());
+
+    Iterator<String> i = tester.writer.statements.iterator();
+    for (String e : expected) {
+      assertEquals(e, i.next());
+    }
+    assertFalse(i.hasNext());
+    assertNull(tester.logger.died);
+  }
+
+  public void testNoUnits() throws SAXException, IOException,
+      UnableToCompleteException {
+    StringBuffer b = new StringBuffer();
+    b.append("  <g:StackLayoutPanel>");
+    b.append("  </g:StackLayoutPanel>");
+
+    FieldWriter w = tester.parse(b.toString());
+    assertEquals("new " + PARSED_TYPE
+        + "(com.google.gwt.dom.client.Style.Unit.PX)", w.getInitializer());
+
+    Iterator<String> i = tester.writer.statements.iterator();
+    assertFalse(i.hasNext());
+  }
+}
=======================================
--- /dev/null
+++  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/TabLayoutPanelParserTest.java
     
Tue Nov 10 14:44:37 2009
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2009 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.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.uibinder.rebind.FieldWriter;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * A unit test. Guess what of.
+ */
+public class TabLayoutPanelParserTest extends TestCase {
+
+  private static final String PARSED_TYPE  
= "com.google.gwt.user.client.ui.TabLayoutPanel";
+
+  private ElementParserTester tester;
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    tester = new ElementParserTester(PARSED_TYPE, new  
TabLayoutPanelParser());
+  }
+
+  public void testBadChild() throws SAXException, IOException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:TabLayoutPanel unit='EM'>");
+    b.append("  <g:west><foo/></g:west>");
+    b.append("</g:TabLayoutPanel>");
+
+    try {
+      tester.parse(b.toString());
+      fail();
+    } catch (UnableToCompleteException e) {
+      assertNotNull(tester.logger.died);
+    }
+  }
+
+  public void testHappy() throws UnableToCompleteException, SAXException,
+      IOException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:TabLayoutPanel barUnit='PX' barHeight='30'>");
+    b.append("  <g:tab>");
+    b.append("    <g:header size='3'>Re<b>mark</b>able</g:header>");
+    b.append("    <g:Label id='able'>able</g:Label>");
+    b.append("  </g:tab>");
+    b.append("  <g:tab>");
+    b.append("    <g:customHeader size='3'>");
+    b.append("      <g:Label id='custom'>Custom</g:Label>");
+    b.append("    </g:customHeader>");
+    b.append("    <g:Label id='baker'>baker</g:Label>");
+    b.append("  </g:tab>");
+    b.append("</g:TabLayoutPanel>");
+
+    String[] expected = {
+        "fieldName.add(<g:Label id='able'>, \"Re<b>mark</b>able\", true);",
+        "fieldName.add(<g:Label id='baker'>, " + "<g:Label  
id='custom'>);",};
+
+    FieldWriter w = tester.parse(b.toString());
+    assertEquals("new " + PARSED_TYPE
+        + "(30, com.google.gwt.dom.client.Style.Unit.PX)",  
w.getInitializer());
+
+    Iterator<String> i = tester.writer.statements.iterator();
+    for (String e : expected) {
+      assertEquals(e, i.next());
+    }
+    assertFalse(i.hasNext());
+    assertNull(tester.logger.died);
+  }
+
+  public void testNoUnits() throws SAXException, IOException,
+      UnableToCompleteException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:TabLayoutPanel barHeight='3'>");
+    b.append("  </g:TabLayoutPanel>");
+
+    FieldWriter w = tester.parse(b.toString());
+    assertEquals("new " + PARSED_TYPE
+        + "(3, com.google.gwt.dom.client.Style.Unit.PX)",  
w.getInitializer());
+
+    Iterator<String> i = tester.writer.statements.iterator();
+    assertFalse(i.hasNext());
+  }
+}
=======================================
--- /dev/null
+++  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/UIObjectParserTest.java
   
Tue Nov 10 14:44:37 2009
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2009 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.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * A unit test. Guess what of.
+ */
+public class UIObjectParserTest extends TestCase {
+  private static final String PARSED_TYPE  
= "com.google.gwt.user.client.ui.UIObject";
+
+  private ElementParserTester tester;
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    tester = new ElementParserTester(PARSED_TYPE, new UIObjectParser());
+  }
+
+  public void testHappy() throws UnableToCompleteException, SAXException,
+      IOException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:UIObject debugId='blat' addStyleNames='foo, bar baz'");
+    b.append("    addStyleDependentNames='able, baker charlie' >");
+    b.append("</g:UIObject>");
+
+    String[] expected = {
+        "fieldName.ensureDebugId(\"blat\");",
+        "fieldName.addStyleName(\"foo\");", "fieldName.addStyleName(\"bar\");",
+        "fieldName.addStyleName(\"baz\");",
+        "fieldName.addStyleDependentName(\"able\");",
+        "fieldName.addStyleDependentName(\"baker\");",
+        "fieldName.addStyleDependentName(\"charlie\");",};
+
+    tester.parse(b.toString());
+
+    Iterator<String> i = tester.writer.statements.iterator();
+    for (String e : expected) {
+      assertEquals(e, i.next());
+    }
+    assertFalse(i.hasNext());
+    assertNull(tester.logger.died);
+  }
+}
=======================================
--- /releases/2.0/branch-info.txt       Tue Nov 10 13:15:16 2009
+++ /releases/2.0/branch-info.txt       Tue Nov 10 14:44:37 2009
@@ -523,3 +523,9 @@
    Fix null.nullMethod() in DynaTable sample app due to null-tightened field
    svn merge --ignore-ancestry -c6814,6815   
https://google-web-toolkit.googlecode.com/svn/trunk/ .

+tr...@6810,6813 were merged into this branch
+  keep Ie7 users from paying the AlphaImageLoader penalty
+  proper behavior of g:header and g:customHeader in StackLayoutPanelparser
+  layout panel units default to PX (instead of NPE, ahem)
+  svn merge --ignore-ancestry -c 6810  
https://google-web-toolkit.googlecode.com/svn/trunk .
+  svn merge --ignore-ancestry -c 6813  
https://google-web-toolkit.googlecode.com/svn/trunk .
=======================================
---  
/releases/2.0/samples/mail/src/com/google/gwt/sample/mail/client/Shortcuts.ui.xml
        
Mon Nov  9 11:00:52 2009
+++  
/releases/2.0/samples/mail/src/com/google/gwt/sample/mail/client/Shortcuts.ui.xml
        
Tue Nov 10 14:44:37 2009
@@ -45,29 +45,17 @@

    <g:StackLayoutPanel styleName='{style.shortcuts}' unit='EM'>
      <g:stack>
-      <g:header size='3'>
-        <g:HTMLPanel styleName='{style.stackHeader}'>
-          <div class='{style.mailboxesIcon}'/> Mailboxes
-        </g:HTMLPanel>
-      </g:header>
+      <g:header size='3'><div class='{style.mailboxesIcon}'/>  
Mailboxes</g:header>
        <mail:Mailboxes ui:field='mailboxes'/>
      </g:stack>

      <g:stack>
-      <g:header size='3'>
-        <g:HTMLPanel styleName='{style.stackHeader}'>
-          <div class='{style.tasksIcon}'/> Tasks
-        </g:HTMLPanel>
-      </g:header>
+      <g:header size='3'><div class='{style.tasksIcon}'/> Tasks</g:header>
        <mail:Tasks ui:field='tasks'/>
      </g:stack>

      <g:stack>
-      <g:header size='3'>
-        <g:HTMLPanel styleName='{style.stackHeader}'>
-          <div class='{style.contactsIcon}'/> Contacts
-        </g:HTMLPanel>
-      </g:header>
+      <g:header size='3'><div class='{style.contactsIcon}'/>  
Contacts</g:header>
        <mail:Contacts ui:field='contacts'/>
      </g:stack>
    </g:StackLayoutPanel>
=======================================
---  
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParser.java
         
Fri Nov  6 17:41:50 2009
+++  
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParser.java
         
Tue Nov 10 14:44:37 2009
@@ -62,11 +62,13 @@
    public void parse(XMLElement elem, String fieldName, JClassType type,
        UiBinderWriter writer) throws UnableToCompleteException {
      // Generate instantiation (requires a 'unit' ctor param).
-    // (Don't generate a ctor for the SplitLayoutPanel; it's implicitly  
PX).
+    // (Don't generate a ctor for the SplitLayoutPanel, it has its own  
parser).
      if (type != getSplitLayoutPanelType(writer)) {
        JEnumType unitEnumType = writer.getOracle().findType(
            Unit.class.getCanonicalName()).isEnum();
-      String unit = elem.consumeAttribute("unit", unitEnumType);
+      String unit = elem.consumeAttributeWithDefault("unit",
+          String.format("%s.%s",  
unitEnumType.getQualifiedSourceName(), "PX"),
+          unitEnumType);
        writer.setFieldInitializerAsConstructor(fieldName,
            writer.getOracle().findType(DockLayoutPanel.class.getName()),  
unit);
      }
@@ -123,11 +125,7 @@
    }

    private boolean isValidChildElement(XMLElement parent, XMLElement child)  
{
-    String childNsUri = child.getNamespaceUri();
-    if (childNsUri == null) {
-      return false;
-    }
-    if (!childNsUri.equals(parent.getNamespaceUri())) {
+    if (!parent.getNamespaceUri().equals(child.getNamespaceUri())) {
        return false;
      }
      if (!DOCK_NAMES.containsKey(child.getLocalName())) {
=======================================
---  
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java
        
Fri Nov  6 17:41:50 2009
+++  
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java
        
Tue Nov 10 14:44:37 2009
@@ -27,56 +27,135 @@
   * Parses {...@link StackLayoutPanel} widgets.
   */
  public class StackLayoutPanelParser implements ElementParser {
-
-  private static final String HEADER_ELEM = "header";
-  private static final String STACK_ELEM = "stack";
-
-  public void parse(XMLElement elem, String fieldName, JClassType type,
+  private static class Children {
+    XMLElement body;
+    XMLElement header;
+    XMLElement customHeader;
+  }
+
+  private static final String CUSTOM = "customHeader";
+  private static final String HEADER = "header";
+  private static final String STACK = "stack";
+
+  public void parse(XMLElement panelElem, String fieldName, JClassType  
type,
        UiBinderWriter writer) throws UnableToCompleteException {
+
      JEnumType unitEnumType = writer.getOracle().findType(
          Unit.class.getCanonicalName()).isEnum();
-    String unit = elem.consumeAttribute("unit", unitEnumType);
+    String unit = panelElem.consumeAttributeWithDefault("unit",
+        String.format("%s.%s",  
unitEnumType.getQualifiedSourceName(), "PX"),
+        unitEnumType);
+
      writer.setFieldInitializerAsConstructor(fieldName,
          writer.getOracle().findType(StackLayoutPanel.class.getName()),
          unit);

      // Parse children.
-    for (XMLElement child : elem.consumeChildElements()) {
+    for (XMLElement stackElem : panelElem.consumeChildElements()) {
        // Get the stack element.
-      if (!isElementType(elem, child, STACK_ELEM)) {
-        writer.die("In %s, Only <stack> children are allowed.", elem);
-      }
-
-      XMLElement headerElem = null, widgetElem = null;
-      for (XMLElement stackChild : child.consumeChildElements()) {
-        // Get the header.
-        if (isElementType(elem, stackChild, HEADER_ELEM)) {
-          if (headerElem != null) {
-            writer.die("In %s, Only one <header> allowed per <stack>",  
elem);
-          }
-          headerElem = stackChild;
-          continue;
-        }
-
-        // Get the widget.
-        if (widgetElem != null) {
-          writer.die("In %s, Only one child widget allowed per <stack>",  
elem);
-        }
-        widgetElem = stackChild;
-      }
-
-      String size = headerElem.consumeDoubleAttribute("size");
-      XMLElement headerWidgetElem = headerElem.consumeSingleChildElement();
-      String headerFieldName =  
writer.parseElementToField(headerWidgetElem);
-      String childFieldName = writer.parseElementToField(widgetElem);
-
-      writer.addStatement("%s.add(%s, %s, %s);", fieldName, childFieldName,
-          headerFieldName, size);
-    }
-  }
+      if (!isElementType(panelElem, stackElem, STACK)) {
+        writer.die("In %s, only <%s:%s> children are allowed.", panelElem,
+            panelElem.getPrefix(), STACK);
+      }
+
+      // Find all the children of the <stack>.
+      Children children = findChildren(stackElem, writer);
+
+      // Parse the child widget.
+      if (children.body == null) {
+        writer.die("In %s, %s must have a child widget", panelElem,  
stackElem);
+      }
+      if (!writer.isWidgetElement(children.body)) {
+        writer.die("In %s, %s must be a widget", stackElem, children.body);
+      }
+      String childFieldName = writer.parseElementToField(children.body);
+
+      // Parse the header.
+      if (children.header != null) {
+        HtmlInterpreter htmlInt =  
HtmlInterpreter.newInterpreterForUiObject(
+            writer, fieldName);
+        String size = children.header.consumeDoubleAttribute("size");
+        if ("".equals(size)) {
+          writer.die("In %s, %s must have a size", panelElem, stackElem);
+        }
+        String html = children.header.consumeInnerHtml(htmlInt);
+        writer.addStatement("%s.add(%s, "
+            + "new com.google.gwt.user.client.ui.HTML(\"%s\"), "
+            + "%s);", fieldName,
+            childFieldName, html, size);
+      } else if (children.customHeader != null) {
+        XMLElement headerElement =
+          children.customHeader.consumeSingleChildElement();
+        String size = children.customHeader.consumeDoubleAttribute("size");
+        if ("".equals(size)) {
+          writer.die("In %s, %s must have a size", panelElem, stackElem);
+        }
+        if (!writer.isWidgetElement(headerElement)) {
+          writer.die("In %s of %s, %s is not a widget",  
children.customHeader,
+              stackElem, headerElement);
+        }
+
+        String headerField = writer.parseElementToField(headerElement);
+        writer.addStatement("%s.add(%s, %s, %s);", fieldName,  
childFieldName,
+            headerField, size);
+      } else {
+        // Neither a header or customHeader.
+        writer.die("In %1$s, %2$s requires either a <%3$s:%4$s> or  
<%3$s:%5$s>",
+            panelElem, stackElem, stackElem.getPrefix(), HEADER, CUSTOM);
+      }
+    }
+  }
+
+private Children findChildren(final XMLElement elem,
+    final UiBinderWriter writer) throws UnableToCompleteException {
+  final Children children = new Children();
+
+  elem.consumeChildElements(new XMLElement.Interpreter<Boolean>() {
+    public Boolean interpretElement(XMLElement child)
+        throws UnableToCompleteException {
+
+      if (hasTag(child, HEADER)) {
+        assertFirstHeader();
+        children.header = child;
+        return true;
+      }
+
+      if (hasTag(child, CUSTOM)) {
+        assertFirstHeader();
+        children.customHeader = child;
+        return true;
+      }
+
+      // Must be the body, then
+      if (null != children.body) {
+        writer.die("In %s, may have only one body element", elem);
+      }
+
+      children.body = child;
+      return true;
+    }
+
+    void assertFirstHeader() throws UnableToCompleteException {
+      if ((null != children.header) && (null != children.customHeader)) {
+        writer.die("In %1$s, may have only one %2$s:header "
+            + "or %2$s:customHeader", elem, elem.getPrefix());
+      }
+    }
+
+    private boolean hasTag(XMLElement child, final String attribute) {
+      return rightNamespace(child) &&  
child.getLocalName().equals(attribute);
+    }
+
+    private boolean rightNamespace(XMLElement child) {
+      return child.getNamespaceUri().equals(elem.getNamespaceUri());
+    }
+  });
+
+  return children;
+}

    private boolean isElementType(XMLElement parent, XMLElement child,  
String type) {
-    return child.getNamespaceUri().equals(parent.getNamespaceUri())
+    return parent.getNamespaceUri().equals(child.getNamespaceUri())
          && type.equals(child.getLocalName());
    }
  }
=======================================
---  
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/TabLayoutPanelParser.java
  
Fri Nov  6 17:41:50 2009
+++  
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/TabLayoutPanelParser.java
  
Tue Nov 10 14:44:37 2009
@@ -40,17 +40,21 @@

    public void parse(XMLElement panelElem, String fieldName, JClassType  
type,
        UiBinderWriter writer) throws UnableToCompleteException {
-    JEnumType unitEnumType = writer.getOracle().findType(
-        Unit.class.getCanonicalName()).isEnum();
-
      // TabLayoutPanel requires tabBar size and unit ctor args.
+
      String size = panelElem.consumeDoubleAttribute("barHeight");
-    String unit = panelElem.consumeAttribute("barUnit", unitEnumType);
-
-    JClassType tlpType = writer.getOracle().findType(
-        TabLayoutPanel.class.getName());
-    writer.setFieldInitializerAsConstructor(fieldName, tlpType,
-        size, unit);
+    if ("".equals(size)) {
+      writer.die("In %s, barHeight attribute is required", panelElem);
+    }
+
+    JEnumType unitEnumType = writer.getOracle().findType(
+        Unit.class.getCanonicalName()).isEnum();
+    String unit = panelElem.consumeAttributeWithDefault("barUnit",
+        String.format("%s.%s",  
unitEnumType.getQualifiedSourceName(), "PX"),
+        unitEnumType);
+
+    writer.setFieldInitializerAsConstructor(fieldName,
+        writer.getOracle().findType(TabLayoutPanel.class.getName()), size,  
unit);

      // Parse children.
      for (XMLElement tabElem : panelElem.consumeChildElements()) {
@@ -65,7 +69,7 @@

        // Parse the child widget.
        if (children.body == null) {
-        writer.die("%s must have a child widget", tabElem);
+        writer.die("In %s, %s must have a child widget", panelElem,  
tabElem);
        }
        if (!writer.isWidgetElement(children.body)) {
          writer.die("In %s, %s must be a widget", tabElem, children.body);
@@ -93,8 +97,8 @@
              headerField);
        } else {
          // Neither a header or customHeader.
-        writer.die("%1$s requires either a <%2$s:%3$s> or <%2$s:%4$s>",
-            tabElem, tabElem.getPrefix(), HEADER, CUSTOM);
+        writer.die("In %1$s, %2$s requires either a <%3$s:%4$s> or  
<%3$s:%5$s>",
+            panelElem, tabElem, tabElem.getPrefix(), HEADER, CUSTOM);
        }
      }
    }
@@ -148,7 +152,7 @@
    }

    private boolean isElementType(XMLElement parent, XMLElement child,  
String type) {
-    return child.getNamespaceUri().equals(parent.getNamespaceUri())
+    return parent.getNamespaceUri().equals(child.getNamespaceUri())
          && type.equals(child.getLocalName());
    }
  }
=======================================
---  
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/UIObjectParser.java
        
Fri Nov  6 17:41:50 2009
+++  
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/UIObjectParser.java
        
Tue Nov 10 14:44:37 2009
@@ -43,14 +43,5 @@
      for (String s : styleNames) {
        writer.addStatement("%s.addStyleDependentName(%s);", fieldName, s);
      }
-
-    HtmlInterpreter interpreter =  
HtmlInterpreter.newInterpreterForUiObject(
-        writer, fieldName);
-
-    String html = elem.consumeInnerHtml(interpreter);
-    if (html.trim().length() > 0) {
-      writer.setFieldInitializer(fieldName, String.format(
-          "new DomHolder(UiBinderUtil.fromHtml(\"%s\"))", html));
-    }
    }
  }
=======================================
---  
/releases/2.0/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java       
 
Mon Nov  9 13:21:34 2009
+++  
/releases/2.0/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java       
 
Tue Nov 10 14:44:37 2009
@@ -28,6 +28,7 @@
  import com.google.gwt.uibinder.elementparsers.AttributeMessageParser;
  import com.google.gwt.uibinder.elementparsers.BeanParser;
  import com.google.gwt.uibinder.elementparsers.ElementParser;
+import com.google.gwt.uibinder.elementparsers.IsEmptyParser;
  import com.google.gwt.uibinder.rebind.messages.MessagesWriter;
  import com.google.gwt.uibinder.rebind.model.ImplicitClientBundle;
  import com.google.gwt.uibinder.rebind.model.ImplicitCssResource;
@@ -833,7 +834,8 @@
      }

      parsers.add(new BeanParser());
-
+    parsers.add(new IsEmptyParser());
+
      return parsers;
    }

=======================================
--- /releases/2.0/user/src/com/google/gwt/uibinder/rebind/XMLElement.java       
 
Mon Nov  9 13:21:34 2009
+++ /releases/2.0/user/src/com/google/gwt/uibinder/rebind/XMLElement.java       
 
Tue Nov 10 14:44:37 2009
@@ -86,7 +86,7 @@

    private static void clearChildren(Element elem) {
      // TODO(rjrjr) I'm nearly positive that anywhere this is called
-    // we should instead be calling assertEmpty
+    // we should instead be calling assertNoBody
      Node child;
      while ((child = elem.getFirstChild()) != null) {
        elem.removeChild(child);
@@ -145,6 +145,57 @@

      this.debugString = getOpeningTag();
    }
+
+  /**
+   * Ensure that the receiver has no attributes left
+   *
+   * @throws UnableToCompleteException if it does
+   */
+  public void assertNoAttributes() throws UnableToCompleteException {
+    int numAtts = getAttributeCount();
+    if (numAtts == 0) {
+      return;
+    }
+
+    StringBuilder b = new StringBuilder();
+    for (int i = 0; i < numAtts; i++) {
+      if (i > 0) {
+        b.append(", ");
+      }
+      b.append('"').append(getAttribute(i).getName()).append('"');
+    }
+    logger.die("Unexpected attributes in %s: %s", this, b);
+  }
+
+  /**
+   * Require that the receiver's body is empty of text and has no child  
nodes
+   *
+   * @throws UnableToCompleteException if it isn't
+   */
+  public void assertNoBody() throws UnableToCompleteException {
+    consumeChildElements(new Interpreter<Boolean>() {
+      public Boolean interpretElement(XMLElement elem)
+          throws UnableToCompleteException {
+        logger.die("In %s, found unexpected child \"%s\"", this, elem);
+        return false; // unreachable
+      }
+    });
+    assertNoText();
+  }
+
+  /**
+   * Require that the receiver's body is empty of text
+   *
+   * @throws UnableToCompleteException if it isn't
+   */
+  public void assertNoText() throws UnableToCompleteException {
+    NoBrainInterpeter<String> nullInterpreter = new  
NoBrainInterpeter<String>(
+        null);
+    String s = consumeInnerTextEscapedAsHtmlStringLiteral(nullInterpreter);
+    if (!"".equals(s)) {
+      logger.die("Unexpected text in %s: \"%s\"", this, s);
+    }
+  }

    /**
     * Consumes the given attribute as a literal or field reference. The  
optional
@@ -259,7 +310,7 @@
    public Iterable<XMLElement> consumeChildElements()
        throws UnableToCompleteException {
      Iterable<XMLElement> rtn = consumeChildElementsNoEmptyCheck();
-    assertEmpty();
+    assertNoText();
      return rtn;
    }

@@ -651,15 +702,6 @@
    public String toString() {
      return debugString;
    }
-
-  private void assertEmpty() throws UnableToCompleteException {
-    NoBrainInterpeter<String> nullInterpreter = new  
NoBrainInterpeter<String>(
-        null);
-    String s = consumeInnerTextEscapedAsHtmlStringLiteral(nullInterpreter);
-    if (!"".equals(s)) {
-      logger.die("Unexpected text in %s: \"%s\"", this, s);
-    }
-  }

    private Iterable<XMLElement> consumeChildElementsNoEmptyCheck() {
      try {
=======================================
---  
/releases/2.0/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImplIE6.java
       
Fri Feb  6 13:06:24 2009
+++  
/releases/2.0/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImplIE6.java
       
Tue Nov 10 14:44:37 2009
@@ -36,6 +36,8 @@
    private static String moduleBaseUrlProtocol =
         
GWT.getHostPageBaseURL().startsWith("https") ?  "https://"; : "http://";;

+  private static boolean isIE6 = isIE6();
+
    private static native void injectGlobalHandler() /*-{
      $wnd.__gwt_transparentImgHandler = function (elem) {
        elem.onerror = null;
@@ -43,6 +45,28 @@
      };
    }-*/;

+  // Stolen and modified from UserAgent.gwt.xml.
+  // TODO(jgw): Get rid of this method, and switch to using soft  
permutations
+  // once they land in trunk.
+  private static native boolean isIE6() /*-{
+     function makeVersion(result) {
+       return (parseInt(result[1]) * 1000) + parseInt(result[2]);
+     }
+
+     var ua = navigator.userAgent.toLowerCase();
+     if (ua.indexOf("msie") != -1) {
+       var result = /msie ([0-9]+)\.([0-9]+)/.exec(ua);
+       if (result && result.length == 3) {
+         var v = makeVersion(result);
+         if (v < 7000) {
+           return true;
+         }
+       }
+     }
+
+     return false;
+   }-*/;
+
    public ClippedImageImplIE6() {
      injectGlobalHandler();
    }
@@ -50,7 +74,11 @@
    @Override
    public void adjust(Element clipper, String url, int left, int top, int  
width,
        int height) {
-
+    if (!isIE6) {
+      super.adjust(clipper, url, left, top, width, height);
+      return;
+    }
+
      clipper.getStyle().setPropertyPx("width", width);
      clipper.getStyle().setPropertyPx("height", height);

@@ -73,6 +101,10 @@
    @Override
    public Element createStructure(String url, int left, int top, int width,
        int height) {
+    if (!isIE6) {
+      return super.createStructure(url, left, top, width, height);
+    }
+
      // We need to explicitly sink ONLOAD on the child image element,  
because it
      // can't be fired on the clipper.
      Element clipper = super.createStructure(url, left, top, width, height);
@@ -82,6 +114,11 @@
    }

    public void fireSyntheticLoadEvent(final Image image) {
+    if (!isIE6) {
+      super.fireSyntheticLoadEvent(image);
+      return;
+    }
+
      // This is the same as the superclass' implementation, except that it
      // explicitly checks for the 'clipper' element, and dispatches the  
event
      // on the img (you can't dispatch events on the clipper).
@@ -97,6 +134,10 @@

    @Override
    public String getHTML(String url, int left, int top, int width, int  
height) {
+    if (!isIE6) {
+      return super.getHTML(url, left, top, width, height);
+    }
+
      String clipperStyle = "overflow: hidden; width: " + width + "px;  
height: "
          + height + "px; padding: 0px; zoom: 1";

=======================================
--- /releases/2.0/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java       
 
Mon Nov  9 13:21:34 2009
+++ /releases/2.0/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java       
 
Tue Nov 10 14:44:37 2009
@@ -1,12 +1,12 @@
  /*
   * Copyright 2009 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
@@ -21,6 +21,10 @@
  import com.google.gwt.uibinder.attributeparsers.StringAttributeParserTest;
  import com.google.gwt.uibinder.elementparsers.DialogBoxParserTest;
  import com.google.gwt.uibinder.elementparsers.DockLayoutPanelParserTest;
+import com.google.gwt.uibinder.elementparsers.IsEmptyParserTest;
+import com.google.gwt.uibinder.elementparsers.StackLayoutPanelParserTest;
+import com.google.gwt.uibinder.elementparsers.TabLayoutPanelParserTest;
+import com.google.gwt.uibinder.elementparsers.UIObjectParserTest;
  import com.google.gwt.uibinder.rebind.GwtResourceEntityResolverTest;
  import com.google.gwt.uibinder.rebind.HandlerEvaluatorTest;
  import com.google.gwt.uibinder.rebind.TokenatorTest;
@@ -50,14 +54,20 @@
      suite.addTestSuite(OwnerFieldClassTest.class);
      suite.addTestSuite(OwnerFieldTest.class);

-    // parsers
-    suite.addTestSuite(DialogBoxParserTest.class);
-    suite.addTestSuite(DockLayoutPanelParserTest.class);
-    suite.addTestSuite(FieldReferenceConverterTest.class);
+    // attributeparsers
      suite.addTestSuite(IntAttributeParserTest.class);
+    suite.addTestSuite(FieldReferenceConverterTest.class);
      suite.addTestSuite(StrictAttributeParserTest.class);
      suite.addTestSuite(StringAttributeParserTest.class);

+    // elementparsers
+    suite.addTestSuite(DialogBoxParserTest.class);
+    suite.addTestSuite(DockLayoutPanelParserTest.class);
+    suite.addTestSuite(IsEmptyParserTest.class);
+    suite.addTestSuite(StackLayoutPanelParserTest.class);
+    suite.addTestSuite(TabLayoutPanelParserTest.class);
+    suite.addTestSuite(UIObjectParserTest.class);
+
      return suite;
    }

=======================================
---  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParserTest.java
    
Mon Nov  9 13:21:34 2009
+++  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParserTest.java
    
Tue Nov 10 14:44:37 2009
@@ -50,7 +50,8 @@
        tester.parse(b.toString());
        fail();
      } catch (UnableToCompleteException e) {
-      assertNotNull(tester.logger.died);
+      assertTrue("expect \"must contain a widget\" error",
+          tester.logger.died.contains("must contain a widget"));
      }
    }

@@ -127,4 +128,17 @@
        assertNotNull(tester.logger.died);
      }
    }
-}
+
+  public void testNoUnits() throws SAXException, IOException,  
UnableToCompleteException {
+    StringBuffer b = new StringBuffer();
+    b.append("<g:DockLayoutPanel>");
+    b.append("</g:DockLayoutPanel>");
+
+    FieldWriter w = tester.parse(b.toString());
+    assertEquals("new " + PARSED_TYPE
+        + "(com.google.gwt.dom.client.Style.Unit.PX)", w.getInitializer());
+
+    Iterator<String> i = tester.writer.statements.iterator();
+    assertFalse(i.hasNext());
+  }
+}
=======================================
---  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
  
Tue Nov 10 11:37:16 2009
+++  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
  
Tue Nov 10 14:44:37 2009
@@ -23,6 +23,7 @@
  import com.google.gwt.dev.javac.CompilationStateBuilder;
  import com.google.gwt.dev.javac.impl.MockJavaResource;
  import com.google.gwt.dev.resource.Resource;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
  import com.google.gwt.uibinder.attributeparsers.AttributeParsers;
  import com.google.gwt.uibinder.rebind.FieldManager;
  import com.google.gwt.uibinder.rebind.FieldWriter;
@@ -33,13 +34,21 @@
  import com.google.gwt.uibinder.rebind.XMLElementProviderImpl;
  import com.google.gwt.uibinder.rebind.messages.MessagesWriter;

+import junit.framework.Assert;
+
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.xml.sax.SAXException;

  import java.io.IOException;
+import java.io.PrintWriter;
  import java.util.Set;

+/**
+ * Utility for testing {...@link ElementParser} implementations in
+ * isolation. For a new test you'll probably need to extend the
+ * mock class hierarchy in {...@link UiJavaResources}.
+ */
  class ElementParserTester {
     static final MockJavaResource BINDER_OWNER_JAVA = new MockJavaResource(
        "my.Ui") {
@@ -59,14 +68,21 @@
    static final String FIELD_NAME = "fieldName";
    static final String BINDER_URI = "binderUri";

+  private static TreeLogger createLogger() {
+    PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new  
PrintWriter(
+        System.err, true));
+    logger.setMaxDetail(TreeLogger.ERROR);
+    return logger;
+  }
    final JClassType parsedType;
    final MockMortalLogger logger = new MockMortalLogger();
-  final W3cDomHelper docHelper = new W3cDomHelper(TreeLogger.NULL);
-
+
+  final W3cDomHelper docHelper = new W3cDomHelper(createLogger());
    final TypeOracle types;
    final XMLElementProvider elemProvider;
    final MockUiBinderWriter writer;
    final FieldManager fieldManager;
+
    final ElementParser parser;

    ElementParserTester(String parsedTypeName, ElementParser parser)
@@ -74,7 +90,7 @@
      this.parser = parser;
      String templatePath = "TemplatePath.ui.xml";
      String implName = "ImplClass";
-    CompilationState state =  
CompilationStateBuilder.buildFrom(TreeLogger.NULL,
+    CompilationState state =  
CompilationStateBuilder.buildFrom(createLogger(),
          getUiResources());
      types = state.getTypeOracle();

@@ -107,8 +123,11 @@

    private XMLElement getElem(String string) throws SAXException,  
IOException {
      Document doc = docHelper.documentFor(string);
+    String tag = "g:" + parsedType.getName();
      Element w3cElem = (Element)  
doc.getDocumentElement().getElementsByTagName(
-        "g:" + parsedType.getName()).item(0);
+        tag).item(0);
+    Assert.assertNotNull(String.format("Expected to find <%s> element in  
test DOM", tag),
+        w3cElem);
      XMLElement elem = elemProvider.get(w3cElem);
      return elem;
    }
=======================================
---  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/UiJavaResources.java
      
Tue Nov 10 11:37:16 2009
+++  
/releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/UiJavaResources.java
      
Tue Nov 10 14:44:37 2009
@@ -72,6 +72,17 @@
        code.append("}\n");
        return code;
      }
+  };
+  public static final MockJavaResource STACK_LAYOUT_PANEL = new  
MockJavaResource(
+      "com.google.gwt.user.client.ui.StackLayoutPanel") {
+    @Override
+    protected CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package com.google.gwt.user.client.ui;\n");
+      code.append("public class StackLayoutPanel extends Widget {\n");
+      code.append("}\n");
+      return code;
+    }
    };
    public static final MockJavaResource STYLE = new MockJavaResource(
        "com.google.gwt.dom.client.Style") {
@@ -84,6 +95,17 @@
        code.append("}\n");
        return code;
      }
+  };
+  public static final MockJavaResource TAB_LAYOUT_PANEL = new  
MockJavaResource(
+      "com.google.gwt.user.client.ui.TabLayoutPanel") {
+    @Override
+    protected CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package com.google.gwt.user.client.ui;\n");
+      code.append("public class TabLayoutPanel extends Widget {\n");
+      code.append("}\n");
+      return code;
+    }
    };
    public static final MockJavaResource UI_BINDER = new MockJavaResource(
        "com.google.gwt.uibinder.client.UiBinder") {
@@ -95,6 +117,17 @@
        code.append("}\n");
        return code;
      }
+  };
+  public static final MockJavaResource UI_OBJECT = new MockJavaResource(
+  "com.google.gwt.user.client.ui.UIObject") {
+    @Override
+    protected CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package com.google.gwt.user.client.ui;\n");
+      code.append("public class UIObject {\n");
+      code.append("}\n");
+      return code;
+    }
    };
    public static final MockJavaResource WIDGET = new MockJavaResource(
        "com.google.gwt.user.client.ui.Widget") {
@@ -102,7 +135,7 @@
      protected CharSequence getContent() {
        StringBuffer code = new StringBuffer();
        code.append("package com.google.gwt.user.client.ui;\n");
-      code.append("public class Widget {\n");
+      code.append("public class Widget extends UIObject {\n");
        code.append("}\n");
        return code;
      }
@@ -119,7 +152,10 @@
      rtn.add(DOCK_LAYOUT_PANEL);
      rtn.add(LABEL);
      rtn.add(SPLIT_LAYOUT_PANEL);
+    rtn.add(STACK_LAYOUT_PANEL);
      rtn.add(STYLE);
+    rtn.add(TAB_LAYOUT_PANEL);
+    rtn.add(UI_OBJECT);
      rtn.add(UI_BINDER);
      rtn.add(WIDGET);
      return rtn;
=======================================
---  
/releases/2.0/user/test/com/google/gwt/uibinder/rebind/XMLElementTest.java      
 
Tue Nov 10 11:37:16 2009
+++  
/releases/2.0/user/test/com/google/gwt/uibinder/rebind/XMLElementTest.java      
 
Tue Nov 10 14:44:37 2009
@@ -64,6 +64,40 @@

      init("<doc><elm attr1=\"attr1Value\" attr2=\"attr2Value\"/></doc>");
    }
+
+  public void testAssertNoAttributes() throws SAXException, IOException {
+    init("<doc><elm yes='true' no='false'>Blah <blah/> blah</elm></doc>");
+    try {
+      elm.assertNoAttributes();
+      fail();
+    } catch (UnableToCompleteException e) {
+      assertTrue("Expect extra attributes list",
+          logger.died.contains("\"yes\""));
+      assertTrue("Expect extra attributes list",
+          logger.died.contains("\"no\""));
+    }
+  }
+
+  public void testAssertNoBody() throws SAXException, IOException {
+    init("<doc><elm yes='true' no='false'>Blah <blah/> blah</elm></doc>");
+    try {
+      elm.assertNoBody();
+      fail();
+    } catch (UnableToCompleteException e) {
+      assertTrue("Expect extra child", logger.died.contains("<blah>"));
+    }
+  }
+
+  public void testAssertNoText() throws SAXException, IOException {
+    init("<doc><elm yes='true' no='false'>Blah <blah/> blah</elm></doc>");
+    try {
+      elm.assertNoText();
+      fail();
+    } catch (UnableToCompleteException e) {
+      assertTrue("Expect extra text", logger.died.contains("Blah"));
+      assertTrue("Expect extra text", logger.died.contains("blah"));
+    }
+  }

    public void testConsumeBoolean() throws SAXException, IOException,
        UnableToCompleteException {

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to