Reviewers: Lex,

Description:
If a PopupPanel is attached to a Panel, calling show() will put it into
an invalid state where it is physically and logical attached, but its
"isShowing" boolean is set to false. Once in this state, it cannot be
hidden.

Fix:
====
When show() is called, we now check if the PopupPanel is attached (and
not showing) and remove it from its parent if it is.

Testing:
=======
Created a unit test for this bug.

Please review this at http://gwt-code-reviews.appspot.com/298804/show

Affected files:
  user/src/com/google/gwt/user/client/ui/PopupPanel.java
  user/test/com/google/gwt/user/client/ui/PopupTest.java


Index: user/test/com/google/gwt/user/client/ui/PopupTest.java
===================================================================
--- user/test/com/google/gwt/user/client/ui/PopupTest.java      (revision 7922)
+++ user/test/com/google/gwt/user/client/ui/PopupTest.java      (working copy)
@@ -428,7 +428,23 @@
   }

   /**
- * Test the showing a popup while it is hiding will not result in an illegal
+   * Test that showing a popup while it is attached does not put it in an
+   * invalid state.
+   */
+  public void testShowWhileAttached() {
+    PopupPanel popup = createPopupPanel();
+    RootPanel.get().add(popup);
+    popup.show();
+    assertTrue(popup.isAttached());
+    assertTrue(popup.isShowing());
+
+    popup.hide();
+    assertFalse(popup.isAttached());
+    assertFalse(popup.isShowing());
+  }
+
+  /**
+ * Test that showing a popup while it is hiding will not result in an illegal
    * state.
    */
   public void testShowWhileHiding() {
Index: user/src/com/google/gwt/user/client/ui/PopupPanel.java
===================================================================
--- user/src/com/google/gwt/user/client/ui/PopupPanel.java      (revision 7922)
+++ user/src/com/google/gwt/user/client/ui/PopupPanel.java      (working copy)
@@ -1001,6 +1001,11 @@
   public void show() {
     if (showing) {
       return;
+    } else if (isAttached()) {
+ // The popup is attached directly to another panel, so we need to remove + // it from its parent before showing it. This is a weird use case, but
+      // since PopupPanel is a Widget, its legal.
+      this.removeFromParent();
     }
     resizeAnimation.setState(true, false);
   }


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

To unsubscribe, reply using "remove me" as the subject.

Reply via email to