Revision: 9582
Author: rj...@google.com
Date: Thu Jan 20 14:28:08 2011
Log: Public (larse...@gmail.com):
Adds the ability to set a DialogBox caption widget.
Review by jlba...@google.com, rj...@google.com
http://gwt-code-reviews.appspot.com/1149803
Review by: jlaba...@google.com
http://code.google.com/p/google-web-toolkit/source/detail?r=9582
Modified:
/trunk/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java
/trunk/user/src/com/google/gwt/user/client/ui/DialogBox.java
/trunk/user/test/com/google/gwt/uibinder/elementparsers/DialogBoxParserTest.java
/trunk/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
/trunk/user/test/com/google/gwt/user/client/ui/DialogBoxTest.java
=======================================
---
/trunk/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java
Mon Jun 7 12:20:31 2010
+++
/trunk/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java
Thu Jan 20 14:28:08 2011
@@ -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
@@ -20,26 +20,43 @@
import com.google.gwt.uibinder.rebind.UiBinderWriter;
import com.google.gwt.uibinder.rebind.XMLElement;
import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.DialogBox.Caption;
+
+import java.util.Set;
/**
* Parses {@link DialogBox} widgets.
*/
public class DialogBoxParser implements ElementParser {
+
+ private static final String CAPTION = "caption";
+ private static final String CUSTOM_CAPTION = "customCaption";
public void parse(XMLElement elem, String fieldName, JClassType type,
UiBinderWriter writer) throws UnableToCompleteException {
-
+
String caption = null;
String body = null;
+ XMLElement customCaption = null;
+
+ String prefix = elem.getPrefix();
for (XMLElement child : elem.consumeChildElements()) {
- if ("caption".equals(child.getLocalName())) {
+ if (CAPTION.equals(child.getLocalName())) {
if (caption != null) {
- writer.die(elem, "May have only one <%s:caption>",
elem.getPrefix());
+ writer.die(elem, "May have only one <%s:%s>", prefix,
+ CAPTION);
}
HtmlInterpreter interpreter =
HtmlInterpreter.newInterpreterForUiObject(
writer, fieldName);
caption = child.consumeInnerHtml(interpreter);
+ } else if (CUSTOM_CAPTION.equals(child.getLocalName())) {
+ if (customCaption != null) {
+ writer.die(elem, "May only have one <%s:%s>", prefix,
+ CUSTOM_CAPTION);
+ }
+ customCaption = child.consumeSingleChildElement();
+
} else {
if (body != null) {
writer.die(elem, "May have only one widget, but found %s and %s",
@@ -52,8 +69,13 @@
}
}
- handleConstructorArgs(elem, fieldName, type, writer);
-
+ if (caption != null && customCaption != null) {
+ writer.die("Must choose between <%s:%s> or <%s:%s>", prefix, CAPTION,
+ prefix, CUSTOM_CAPTION);
+ }
+
+ handleConstructorArgs(elem, fieldName, type, writer, customCaption);
+
if (caption != null) {
writer.addStatement("%s.setHTML(\"%s\");", fieldName, caption);
}
@@ -63,20 +85,60 @@
}
/**
- * If this is DialogBox (not a subclass), parse constructor args
- * and generate the constructor call. For subtypes do nothing.
+ * Determines if the element implements Caption.
+ *
+ * @throws UnableToCompleteException
*/
- private void handleConstructorArgs(XMLElement elem, String fieldName,
- JClassType type, UiBinderWriter writer) throws
UnableToCompleteException {
- boolean custom = !type.equals(writer.getOracle().findType(
+ protected boolean isCaption(UiBinderWriter writer, XMLElement element)
+ throws UnableToCompleteException {
+ JClassType type = writer.findFieldType(element);
+
+ Set<? extends JClassType> classes =
type.getFlattenedSupertypeHierarchy();
+ JClassType captionType = writer.getOracle().findType(
+ Caption.class.getCanonicalName());
+ return classes.contains(captionType);
+ }
+
+ /**
+ * Checks to see if the widget extends DialogBox or is DialogBox proper.
+ */
+ protected boolean isCustomWidget(UiBinderWriter writer, JClassType type)
{
+ return !type.equals(writer.getOracle().findType(
DialogBox.class.getCanonicalName()));
+ }
+
+ /**
+ * If this is DialogBox (not a subclass), parse constructor args and
generate
+ * the constructor call. For subtypes do nothing.
+ */
+ void handleConstructorArgs(XMLElement elem, String fieldName,
+ JClassType type, UiBinderWriter writer, XMLElement customCaption)
+ throws UnableToCompleteException {
+ boolean custom = isCustomWidget(writer, type);
if (!custom) {
String autoHide = elem.consumeBooleanAttribute("autoHide", false);
String modal = elem.consumeBooleanAttribute("modal", true);
- writer.setFieldInitializerAsConstructor(fieldName,
+ if (customCaption != null) {
+ if (!writer.isWidgetElement(customCaption)) {
+ writer.die(customCaption, "<%s:%s> must be a widget",
+ customCaption.getPrefix(), CUSTOM_CAPTION);
+ }
+ if (!isCaption(writer, customCaption)) {
+ writer.die(customCaption, "<%s:%s> must implement %s",
+ customCaption.getPrefix(), CUSTOM_CAPTION,
+ Caption.class.getCanonicalName());
+ }
+ String fieldElement = writer.parseElementToField(customCaption);
+
+ writer.setFieldInitializerAsConstructor(fieldName,
+
writer.getOracle().findType(DialogBox.class.getCanonicalName()),
+ autoHide, modal, fieldElement);
+ } else {
+ writer.setFieldInitializerAsConstructor(fieldName,
writer.getOracle().findType(DialogBox.class.getCanonicalName()),
autoHide, modal);
+ }
}
}
}
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/DialogBox.java Tue Sep 21
07:53:19 2010
+++ /trunk/user/src/com/google/gwt/user/client/ui/DialogBox.java Thu Jan 20
14:28:08 2011
@@ -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
@@ -34,11 +34,12 @@
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.safehtml.client.HasSafeHtml;
import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.Window;
/**
* A form of popup that has a caption area at the top and can be dragged
by the
@@ -84,14 +85,17 @@
*
* <h3>Use in UiBinder Templates</h3>
* <p>
- * DialogBox elements in
- * {@link com.google.gwt.uibinder.client.UiBinder UiBinder} templates can
- * have one widget child and one <g:caption> child. (Note the lower case
- * "c", meant to signal that the caption is not a runtime object, and so
cannot
- * have a <code>ui:field</code> attribute.) The body of the
- * caption can be html.
+ * DialogBox elements in {@link com.google.gwt.uibinder.client.UiBinder
+ * UiBinder} templates can have one widget child and one <g:caption>
child.
+ * (Note the lower case "c", meant to signal that the caption is not a
runtime
+ * object, and so cannot have a <code>ui:field</code> attribute.) The body
of
+ * the caption can be html.
+ *
* <p>
- * For example: <pre>
+ *
+ * For example:
+ *
+ * <pre>
* <g:DialogBox autoHide="true" modal="true">
* <g:caption><b>Caption text</b></g:caption>
* <g:HTMLPanel>
@@ -101,20 +105,51 @@
* </g:HTMLPanel>
* </g:DialogBox>
* </pre>
+ *
+ * You may also create your own header caption. The caption must implement
+ * {@link Caption}.
+ *
+ * <p>
+ *
+ * For example:
+ *
+ * <p>
+ *
+ * <pre>
+ * <g:DialogBox autoHide="true" modal="true">
+ * <-- foo is your prefix and Bar is a class that implements {@link
Caption}-->
+ * <g:customCaption><foo:Bar/></g:customCaption>
+ * <g:HTMLPanel>
+ * Body text
+ * <g:Button ui:field='cancelButton'>Cancel</g:Button>
+ * <g:Button ui:field='okButton'>Okay</g:Button>
+ * </g:HTMLPanel>
+ * </g:DialogBox>
+ * </pre>
+ *
*/
@SuppressWarnings("deprecation")
public class DialogBox extends DecoratedPopupPanel implements HasHTML,
HasSafeHtml, MouseListener {
/**
- * Set of characteristic interfaces supported by the {@link DialogBox}
caption
- *
- * Note that this set might expand over time, so implement this
interface at
- * your own risk.
+ * Set of characteristic interfaces supported by the {@link DialogBox}
+ * caption.
+ *
*/
- public interface Caption extends HasAllMouseHandlers {
+ public interface Caption extends HasAllMouseHandlers, HasHTML,
HasSafeHtml,
+ IsWidget {
}
- private static class CaptionImpl extends HTML implements Caption {
+ /**
+ * Default implementation of Caption. This will be created as the header
if
+ * there isn't a header specified.
+ */
+ public static class CaptionImpl extends HTML implements Caption {
+
+ public CaptionImpl() {
+ super();
+ setStyleName("Caption");
+ }
}
private class MouseHandler implements MouseDownHandler, MouseUpHandler,
@@ -129,11 +164,11 @@
}
public void onMouseOut(MouseOutEvent event) {
- DialogBox.this.onMouseLeave(caption);
+ DialogBox.this.onMouseLeave(caption.asWidget());
}
public void onMouseOver(MouseOverEvent event) {
- DialogBox.this.onMouseEnter(caption);
+ DialogBox.this.onMouseEnter(caption.asWidget());
}
public void onMouseUp(MouseUpEvent event) {
@@ -146,7 +181,7 @@
*/
private static final String DEFAULT_STYLENAME = "gwt-DialogBox";
- private CaptionImpl caption = new CaptionImpl();
+ private Caption caption;
private boolean dragging;
private int dragStartX, dragStartY;
private int windowWidth;
@@ -167,7 +202,7 @@
* Creates an empty dialog box specifying its "auto-hide" property. It
should
* not be shown until its child widget has been added using
* {@link #add(Widget)}.
- *
+ *
* @param autoHide <code>true</code> if the dialog should be
automatically
* hidden when the user clicks outside of it
*/
@@ -176,24 +211,53 @@
}
/**
- * Creates an empty dialog box specifying its "auto-hide" property. It
should
- * not be shown until its child widget has been added using
- * {@link #add(Widget)}.
- *
+ * Creates an empty dialog box specifying its {@link Caption}. It should
not
+ * be shown until its child widget has been added using {@link
#add(Widget)}.
+ *
+ * @param captionWidget the widget that is the DialogBox's header.
+ */
+ public DialogBox(Caption captionWidget) {
+ this(false, true, captionWidget);
+ }
+
+ /**
+ * Creates an empty dialog box specifying its "auto-hide" and "modal"
+ * properties. It should not be shown until its child widget has been
added
+ * using {@link #add(Widget)}.
+ *
* @param autoHide <code>true</code> if the dialog should be
automatically
* hidden when the user clicks outside of it
* @param modal <code>true</code> if keyboard and mouse events for
widgets not
* contained by the dialog should be ignored
*/
public DialogBox(boolean autoHide, boolean modal) {
+ this(autoHide, modal, new CaptionImpl());
+ }
+
+ /**
+ *
+ * Creates an empty dialog box specifying its "auto-hide", "modal"
properties
+ * and an implementation a custom {@link Caption}. It should not be shown
+ * until its child widget has been added using {@link #add(Widget)}.
+ *
+ * @param autoHide <code>true</code> if the dialog should be
automatically
+ * hidden when the user clicks outside of it
+ * @param modal <code>true</code> if keyboard and mouse events for
widgets not
+ * contained by the dialog should be ignored
+ * @param captionWidget the widget that is the DialogBox's header.
+ */
+ public DialogBox(boolean autoHide, boolean modal, Caption captionWidget)
{
super(autoHide, modal, "dialog");
+ assert captionWidget != null : "The caption must not be null";
+ captionWidget.asWidget().removeFromParent();
+ caption = captionWidget;
+
// Add the caption to the top row of the decorator panel. We need to
// logically adopt the caption so we can catch mouse events.
Element td = getCellElement(0, 1);
- DOM.appendChild(td, caption.getElement());
- adopt(caption);
- caption.setStyleName("Caption");
+ DOM.appendChild(td, caption.asWidget().getElement());
+ adopt(caption.asWidget());
// Set the style name
setStyleName(DEFAULT_STYLENAME);
@@ -212,14 +276,10 @@
/**
* Provides access to the dialog's caption.
- *
- * This method is final because the Caption interface will expand.
Therefore
- * it is highly likely that subclasses which implemented this method
would end
- * up breaking.
- *
+ *
* @return the logical caption for this dialog box
*/
- public final Caption getCaption() {
+ public Caption getCaption() {
return caption;
}
@@ -259,15 +319,22 @@
}
/**
- * @deprecated Use {@link #beginDragging} and {@link #getCaption}
- * instead
+ * @deprecated Use {@link #beginDragging} and {@link #getCaption} instead
*/
@Deprecated
public void onMouseDown(Widget sender, int x, int y) {
- dragging = true;
- DOM.setCapture(getElement());
- dragStartX = x;
- dragStartY = y;
+ if (DOM.getCaptureElement() == null) {
+ /*
+ * Need to check to make sure that we aren't already capturing an
element
+ * otherwise events will not fire as expected. If this check isn't
here,
+ * any class which extends custom button will not fire its click
event for
+ * example.
+ */
+ dragging = true;
+ DOM.setCapture(getElement());
+ dragStartX = x;
+ dragStartY = y;
+ }
}
/**
@@ -314,31 +381,35 @@
}
/**
- * Sets the html string inside the caption.
- *
+ * Sets the html string inside the caption by calling its
+ * {@link #setHTML(SafeHTML)} method.
+ *
* Use {@link #setWidget(Widget)} to set the contents inside the
* {@link DialogBox}.
- *
+ *
* @param html the object's new HTML
*/
- public void setHTML(String html) {
+ public void setHTML(SafeHtml html) {
caption.setHTML(html);
}
/**
- * Sets the html string inside the caption.
+ * Sets the html string inside the caption by calling its
+ * {@link #setHTML(SafeHtml)} method. Only known safe HTML should be
inserted
+ * in here.
*
* Use {@link #setWidget(Widget)} to set the contents inside the
* {@link DialogBox}.
*
* @param html the object's new HTML
*/
- public void setHTML(SafeHtml html) {
- setHTML(html.asString());
+ public void setHTML(String html) {
+ caption.setHTML(SafeHtmlUtils.fromTrustedString(html));
}
/**
- * Sets the text inside the caption.
+ * Sets the text inside the caption by calling its {@link
#setText(String)}
+ * method.
*
* Use {@link #setWidget(Widget)} to set the contents inside the
* {@link DialogBox}.
@@ -364,25 +435,25 @@
/**
* Called on mouse down in the caption area, begins the dragging loop by
* turning on event capture.
- *
+ *
* @see DOM#setCapture
* @see #continueDragging
* @param event the mouse down event that triggered dragging
*/
protected void beginDragging(MouseDownEvent event) {
- onMouseDown(caption, event.getX(), event.getY());
+ onMouseDown(caption.asWidget(), event.getX(), event.getY());
}
/**
* Called on mouse move in the caption area, continues dragging if it was
* started by {@link #beginDragging}.
- *
+ *
* @see #beginDragging
* @see #endDragging
* @param event the mouse move event that continues dragging
*/
protected void continueDragging(MouseMoveEvent event) {
- onMouseMove(caption, event.getX(), event.getY());
+ onMouseMove(caption.asWidget(), event.getX(), event.getY());
}
@Override
@@ -391,7 +462,7 @@
super.doAttachChildren();
} finally {
// See comment in doDetachChildren for an explanation of this call
- caption.onAttach();
+ caption.asWidget().onAttach();
}
}
@@ -400,26 +471,28 @@
try {
super.doDetachChildren();
} finally {
- // We need to detach the caption specifically because it is not part
of the
- // iterator of Widgets that the {@link SimplePanel} super class
returns.
- // This is similar to a {@link ComplexPanel}, but we do not want to
expose
- // the caption widget, as its just an internal implementation.
- caption.onDetach();
+ /*
+ * We need to detach the caption specifically because it is not part
of
+ * the iterator of Widgets that the {@link SimplePanel} super class
+ * returns. This is similar to a {@link ComplexPanel}, but we do not
want
+ * to expose the caption widget, as its just an internal
implementation.
+ */
+ caption.asWidget().onDetach();
}
}
/**
* Called on mouse up in the caption area, ends dragging by ending event
* capture.
- *
+ *
* @param event the mouse up event that ended dragging
- *
+ *
* @see DOM#releaseCapture
* @see #beginDragging
* @see #endDragging
*/
protected void endDragging(MouseUpEvent event) {
- onMouseUp(caption, event.getX(), event.getY());
+ onMouseUp(caption.asWidget(), event.getX(), event.getY());
}
/**
@@ -428,13 +501,13 @@
* <li>-caption = text at the top of the {@link DialogBox}.</li>
* <li>-content = the container around the content.</li>
* </ul>
- *
+ *
* @see UIObject#onEnsureDebugId(String)
*/
@Override
protected void onEnsureDebugId(String baseID) {
super.onEnsureDebugId(baseID);
- caption.ensureDebugId(baseID + "-caption");
+ caption.asWidget().ensureDebugId(baseID + "-caption");
ensureDebugId(getCellElement(1, 1), baseID, "content");
}
@@ -445,8 +518,7 @@
// is dragged.
NativeEvent nativeEvent = event.getNativeEvent();
- if (!event.isCanceled()
- && (event.getTypeInt() == Event.ONMOUSEDOWN)
+ if (!event.isCanceled() && (event.getTypeInt() == Event.ONMOUSEDOWN)
&& isCaptionEvent(nativeEvent)) {
nativeEvent.preventDefault();
}
=======================================
---
/trunk/user/test/com/google/gwt/uibinder/elementparsers/DialogBoxParserTest.java
Wed Dec 2 10:02:31 2009
+++
/trunk/user/test/com/google/gwt/uibinder/elementparsers/DialogBoxParserTest.java
Thu Jan 20 14:28:08 2011
@@ -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
@@ -18,6 +18,7 @@
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.impl.MockJavaResource;
import com.google.gwt.uibinder.rebind.FieldWriter;
+import com.google.gwt.user.client.ui.DialogBox;
import junit.framework.TestCase;
@@ -32,7 +33,20 @@
public class DialogBoxParserTest extends TestCase {
private static final String PARSED_TYPE
= "com.google.gwt.user.client.ui.DialogBox";
-
+ private static final MockJavaResource CAPTION_SUBCLASS = new
MockJavaResource(
+ "my.MyCaption") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package my;\n");
+ code.append("import com.google.gwt.user.client.ui.DialogBox;\n");
+ code.append("import com.google.gwt.user.client.ui.Widget;\n");
+ code.append("public class MyCaption extends Widget implements
DialogBox.Caption {\n");
+ code.append(" public MyCaption() { super(); } \n");;
+ code.append("}\n");
+ return code;
+ }
+ };
private static final MockJavaResource DIALOG_SUBCLASS = new
MockJavaResource(
"my.MyDialogBox") {
@Override
@@ -109,6 +123,33 @@
assertFalse(i.hasNext());
assertNull(tester.logger.died);
}
+
+ public void testCustomCaptionAndCaption() throws SAXException,
IOException,
+ UnableToCompleteException {
+ StringBuffer b = new StringBuffer();
+
+ DialogBoxParser parser = new DialogBoxParser();
+ String typeName = DialogBox.class.getCanonicalName();
+ tester = new ElementParserTester(typeName, parser, CAPTION_SUBCLASS);
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI
+ "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <g:DialogBox autoHide='true' modal='true'>");
+ b.append(" <g:caption>Hello, I <b>caption</b>you.</g:caption>");
+ b.append(" <g:customCaption><my:MyCaption/></g:customCaption>");
+ b.append(" <g:Label>And your little dog, too!</g:Label>");
+ b.append(" </g:DialogBox> ");
+ b.append("</ui:UiBinder>");
+
+ try {
+
parser.parse(tester.getElem(b.toString(), "g:DialogBox"), "fieldName",
+ tester.parsedType, tester.writer);
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertNotNull(tester.logger.died);
+ }
+ }
public void testWidgetInCaption() throws SAXException, IOException {
StringBuffer b = new StringBuffer();
@@ -119,6 +160,86 @@
b.append(" </g:caption> ");
b.append("</g:DialogBox> ");
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertNotNull(tester.logger.died);
+ }
+ }
+
+ public void testTooManyCaptionWidgets() throws SAXException, IOException,
+ UnableToCompleteException {
+
+ StringBuffer b = new StringBuffer();
+ DialogBoxParser parser = new DialogBoxParser();
+ String typeName = DialogBox.class.getCanonicalName();
+ tester = new ElementParserTester(typeName, parser, CAPTION_SUBCLASS);
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI
+ "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <g:DialogBox autoHide='true' modal='true'>");
+ b.append(" <g:customCaption><my:MyCaption/></g:customCaption>");
+ b.append(" <g:customCaption><my:MyCaption/></g:customCaption>");
+ b.append(" </g:DialogBox> ");
+ b.append("</ui:UiBinder>");
+
+ try {
+
parser.parse(tester.getElem(b.toString(), "g:DialogBox"), "fieldName",
+ tester.parsedType, tester.writer);
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertNotNull(tester.logger.died);
+ }
+ }
+
+ public void testCustomCaption() throws SAXException, IOException,
+ UnableToCompleteException {
+ StringBuffer b = new StringBuffer();
+
+ DialogBoxParser parser = new DialogBoxParser();
+ String typeName = DialogBox.class.getCanonicalName();
+ tester = new ElementParserTester(typeName, parser, CAPTION_SUBCLASS);
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI
+ "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <g:DialogBox autoHide='true' modal='true'>");
+ b.append(" <g:customCaption><my:MyCaption/></g:customCaption>");
+ b.append(" <g:Label>And your little dog, too!</g:Label>");
+ b.append(" </g:DialogBox> ");
+ b.append("</ui:UiBinder>");
+
+ parser.parse(tester.getElem(b.toString(), "g:DialogBox"), "fieldName",
+ tester.parsedType, tester.writer);
+
+ String[] expected = {"fieldName.setWidget(<g:Label>);",};
+
+ FieldWriter w = tester.fieldManager.lookup("fieldName");
+
+ assertEquals("new " + PARSED_TYPE + "(true, true, <my:MyCaption>)",
+ 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 testCaptionWidgetDoesntImplementCaption() throws
SAXException,
+ IOException {
+
+ StringBuffer b = new StringBuffer();
+
+ b.append("<g:DialogBox autoHide='true' modal='true'>");
+ b.append(" <g:customCaption> ");
+ b.append(" <g:Label>And your little dog, too!</g:Label>");
+ b.append(" </g:customCaption> ");
+ b.append("</g:DialogBox> ");
+
try {
tester.parse(b.toString());
fail();
@@ -151,6 +272,24 @@
b.append(" <g:caption>Hello, I <b>caption</b>you.</g:caption>");
b.append("</g:DialogBox> ");
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertNotNull(tester.logger.died);
+ }
+ }
+
+ public void testBadCaptionWidgetContent() throws SAXException,
IOException {
+
+ StringBuffer b = new StringBuffer();
+
+ b.append("<g:DialogBox autoHide='true' modal='true'>");
+ b.append(" <g:customCaption>");
+ b.append(" <div>Oops</div>");
+ b.append(" </g:customCaption>");
+ b.append("</g:DialogBox> ");
+
try {
tester.parse(b.toString());
fail();
@@ -195,8 +334,7 @@
SAXException, IOException {
DialogBoxParser parser = new DialogBoxParser();
String typeName = "my.MyDialogBox";
- tester = new ElementParserTester(typeName, parser,
- DIALOG_SUBCLASS);
+ tester = new ElementParserTester(typeName, parser, DIALOG_SUBCLASS);
StringBuffer b = new StringBuffer();
@@ -208,15 +346,15 @@
b.append(" <g:Label>And your little dog, too!</g:Label>");
b.append(" </my:MyDialogBox> ");
b.append("</ui:UiBinder>");
-
+
String[] expected = {
"fieldName.setHTML(\"Hello, I <b>caption</b>you.\");",
"fieldName.setWidget(<g:Label>);",};
-
parser.parse(tester.getElem(b.toString(), "my:MyDialogBox"), "fieldName",
+
parser.parse(tester.getElem(b.toString(), "my:MyDialogBox"), "fieldName",
tester.parsedType, tester.writer);
FieldWriter w = tester.fieldManager.lookup("fieldName");
-
+
assertNull(w.getInitializer());
Iterator<String> i = tester.writer.statements.iterator();
=======================================
--- /trunk/user/test/com/google/gwt/uibinder/test/UiJavaResources.java Fri
Jan 7 08:26:38 2011
+++ /trunk/user/test/com/google/gwt/uibinder/test/UiJavaResources.java Thu
Jan 20 14:28:08 2011
@@ -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
@@ -150,7 +150,9 @@
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.user.client.ui;\n");
code.append("public class DialogBox extends Widget {\n");
- code.append(" public DialogBox(boolean autoHide, boolean modal)
{} ");
+ code.append(" public interface Caption {} \n");
+ code.append(" public DialogBox(boolean autoHide, boolean modal) {}
\n");
+ code.append(" public DialogBox(boolean autoHide, boolean modal,
Caption caption) {} ");
code.append("}\n");
return code;
}
=======================================
--- /trunk/user/test/com/google/gwt/user/client/ui/DialogBoxTest.java Thu
Dec 16 05:45:53 2010
+++ /trunk/user/test/com/google/gwt/user/client/ui/DialogBoxTest.java Thu
Jan 20 14:28:08 2011
@@ -19,15 +19,83 @@
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.MouseDownHandler;
+import com.google.gwt.event.dom.client.MouseMoveHandler;
+import com.google.gwt.event.dom.client.MouseOutHandler;
+import com.google.gwt.event.dom.client.MouseOverHandler;
+import com.google.gwt.event.dom.client.MouseUpHandler;
+import com.google.gwt.event.dom.client.MouseWheelHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.junit.DoNotRunWith;
import com.google.gwt.junit.Platform;
+import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
/**
* Unit test for {@link DialogBox}.
*/
public class DialogBoxTest extends PopupTest {
+
+ /**
+ * An implementation of Caption which is used for testing.
+ */
+ private static class CaptionForTesting extends Composite implements
+ DialogBox.Caption, HasHTML {
+
+ private FocusPanel panel = new FocusPanel();
+ private HTML htmlWidget = new HTML();
+
+ public CaptionForTesting() {
+ panel.add(htmlWidget);
+ initWidget(panel);
+ }
+
+ public HandlerRegistration addMouseDownHandler(MouseDownHandler
handler) {
+ return panel.addMouseDownHandler(handler);
+ }
+
+ public HandlerRegistration addMouseMoveHandler(MouseMoveHandler
handler) {
+ return panel.addMouseMoveHandler(handler);
+ }
+
+ public HandlerRegistration addMouseOutHandler(MouseOutHandler handler)
{
+ return panel.addMouseOutHandler(handler);
+ }
+
+ public HandlerRegistration addMouseOverHandler(MouseOverHandler
handler) {
+ return panel.addMouseOverHandler(handler);
+ }
+
+ public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
+ return panel.addMouseUpHandler(handler);
+ }
+
+ public HandlerRegistration addMouseWheelHandler(MouseWheelHandler
handler) {
+ return panel.addMouseWheelHandler(handler);
+ }
+
+ public String getHTML() {
+ return htmlWidget.getHTML();
+ }
+
+ public String getText() {
+ return htmlWidget.getText();
+ }
+
+ public void setHTML(SafeHtml html) {
+ htmlWidget.setHTML(html);
+ }
+
+ public void setHTML(String html) {
+ this.htmlWidget.setHTML(html);
+ }
+
+ public void setText(String text) {
+ htmlWidget.setText(text);
+ }
+ }
private static final String html = "<b>hello</b><i>world</i>";
@@ -75,20 +143,6 @@
assertEquals("text", dialogBox.getText());
assertTrue(dialogBox.getHTML().equalsIgnoreCase("<b>text</b>"));
}
-
- public void testSimpleCloseButtonOnModalDialog() {
- final DialogBox dialogBox = new DialogBox(false, true);
- Button button = new Button();
- button.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent event) {
- dialogBox.hide();
- }
- });
- dialogBox.add(button);
- dialogBox.show();
- button.click();
- assertFalse(dialogBox.isShowing());
- }
public void testDebugId() {
DialogBox dBox = new DialogBox();
@@ -109,7 +163,7 @@
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
public void execute() {
UIObjectTest.assertDebugIdContents("myDialogBox-caption",
- "test caption");
+ "test caption");
finishTest();
}
});
@@ -150,6 +204,37 @@
assertEquals(html, box.getHTML().toLowerCase());
}
+
+ /**
+ * Test setting the caption.
+ */
+ public void testSetCaption() {
+ CaptionForTesting caption = new CaptionForTesting();
+ DialogBox dialogBox = new DialogBox(caption);
+ caption.setText("text");
+ Element td = dialogBox.getCellElement(0, 1);
+ assertEquals(dialogBox.getText(), "text");
+ caption.setHTML("<b>text</b>");
+ assertEquals("<b>text</b>", dialogBox.getHTML().toLowerCase());
+ dialogBox.show();
+ assertTrue(dialogBox.getCaption() == caption);
+ assertTrue(caption.asWidget().getElement() == DOM.getChild(td, 0));
+ dialogBox.hide();
+ }
+
+ public void testSimpleCloseButtonOnModalDialog() {
+ final DialogBox dialogBox = new DialogBox(false, true);
+ Button button = new Button();
+ button.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ dialogBox.hide();
+ }
+ });
+ dialogBox.add(button);
+ dialogBox.show();
+ button.click();
+ assertFalse(dialogBox.isShowing());
+ }
@Override
protected PopupPanel createPopupPanel() {
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors