]> source.dussan.org Git - vaadin-framework.git/commitdiff
DateField popup doesn't close when popup button is clicked (#14857)
authorAnna Miroshnik <anna.miroshnik@arcadia.spb.ru>
Mon, 17 Nov 2014 14:33:54 +0000 (17:33 +0300)
committerJouni Koivuviita <jouni@vaadin.com>
Wed, 10 Dec 2014 08:54:46 +0000 (08:54 +0000)
Change-Id: Ieb6ff2f072726fe8707d3cce61569dd623b13ebd

client/src/com/vaadin/client/ui/VPopupCalendar.java
uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java [new file with mode: 0644]

index 15302f078448ee5c7a715f69ef72a3666ff6ef9f..cf88ceb8d6d1174f649aad97351b75bbfba9a6f4 100644 (file)
@@ -27,6 +27,10 @@ import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.event.dom.client.DomEvent;
 import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.MouseOutEvent;
+import com.google.gwt.event.dom.client.MouseOutHandler;
+import com.google.gwt.event.dom.client.MouseOverEvent;
+import com.google.gwt.event.dom.client.MouseOverHandler;
 import com.google.gwt.event.logical.shared.CloseEvent;
 import com.google.gwt.event.logical.shared.CloseHandler;
 import com.google.gwt.i18n.client.DateTimeFormat;
@@ -77,6 +81,15 @@ public class VPopupCalendar extends VTextualDate implements Field,
 
     private boolean open = false;
 
+    /*
+     * #14857: If calendarToggle button is clicked when calendar popup is
+     * already open we should prevent calling openCalendarPanel() in onClick,
+     * since we don't want to reopen it again right after it closes.
+     */
+    private boolean preventOpenPopupCalendar = false;
+    private boolean cursorOverCalendarToggleButton = false;
+    private boolean toggleButtonClosesWithGuarantee = false;
+
     private boolean textFieldEnabled = true;
 
     private String captionId;
@@ -90,6 +103,21 @@ public class VPopupCalendar extends VTextualDate implements Field,
 
         calendarToggle.setText("");
         calendarToggle.addClickHandler(this);
+
+        calendarToggle.addDomHandler(new MouseOverHandler() {
+            @Override
+            public void onMouseOver(MouseOverEvent event) {
+                cursorOverCalendarToggleButton = true;
+            }
+        }, MouseOverEvent.getType());
+
+        calendarToggle.addDomHandler(new MouseOutHandler() {
+            @Override
+            public void onMouseOut(MouseOutEvent event) {
+                cursorOverCalendarToggleButton = false;
+            }
+        }, MouseOutEvent.getType());
+
         // -2 instead of -1 to avoid FocusWidget.onAttach to reset it
         calendarToggle.getElement().setTabIndex(-2);
 
@@ -389,7 +417,10 @@ public class VPopupCalendar extends VTextualDate implements Field,
     @Override
     public void onClick(ClickEvent event) {
         if (event.getSource() == calendarToggle && isEnabled()) {
-            openCalendarPanel();
+            if (!preventOpenPopupCalendar) {
+                openCalendarPanel();
+            }
+            preventOpenPopupCalendar = false;
         }
     }
 
@@ -412,15 +443,14 @@ public class VPopupCalendar extends VTextualDate implements Field,
                 focus();
             }
 
-            // TODO resolve what the "Sigh." is all about and document it here
-            // Sigh.
-            Timer t = new Timer() {
-                @Override
-                public void run() {
-                    open = false;
-                }
-            };
-            t.schedule(100);
+            open = false;
+
+            if (cursorOverCalendarToggleButton
+                    && !toggleButtonClosesWithGuarantee) {
+                preventOpenPopupCalendar = true;
+            }
+
+            toggleButtonClosesWithGuarantee = false;
         }
     }
 
@@ -520,6 +550,7 @@ public class VPopupCalendar extends VTextualDate implements Field,
      */
     public void closeCalendarPanel() {
         if (open) {
+            toggleButtonClosesWithGuarantee = true;
             popup.hide(true);
         }
     }
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java
new file mode 100644 (file)
index 0000000..60508a3
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ * 
+ * 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.vaadin.tests.components.datefield;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.DateField;
+
+public class DateFieldPopupClosing extends AbstractTestUI {
+
+    static final String DATEFIELD_ID = "datefield";
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        final DateField df = new DateField();
+        df.setId(DATEFIELD_ID);
+        addComponent(df);
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "DateField popup should be closed when click on popup button";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 14857;
+    }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java
new file mode 100644 (file)
index 0000000..9fd6fe8
--- /dev/null
@@ -0,0 +1,81 @@
+package com.vaadin.tests.components.datefield;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+import com.vaadin.testbench.elements.DateFieldElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class DateFieldPopupClosingTest extends MultiBrowserTest {
+
+    @Test
+    public void testDateFieldPopupClosingLongClick()
+            throws InterruptedException, IOException {
+        openTestURL();
+
+        fastClickDateDatePickerButton();
+
+        assertThatPopupIsVisible();
+
+        longClickDateDatePickerButton();
+
+        assertThatPopupIsInvisible();
+    }
+
+    private void assertThatPopupIsVisible() {
+        waitUntil(ExpectedConditions.visibilityOfElementLocated(By
+                .className("v-datefield-popup")));
+    }
+
+    private void assertThatPopupIsInvisible() {
+        // ExpectedConditions.invisibilityOfElementLocated doesn't work
+        // with PhantomJS when running with a hub:
+        // https://code.google.com/p/selenium/issues/detail?id=5000
+        // so we need to make our own.
+
+        waitUntil(new ExpectedCondition<Boolean>() {
+            @Override
+            public Boolean apply(WebDriver input) {
+                try {
+                    return !(findElement(By.className("v-datefield-popup"))
+                            .isDisplayed());
+                } catch (Exception e) {
+                    return true;
+                }
+            }
+
+            @Override
+            public String toString() {
+                // Timed out after 10 seconds waiting for ...
+                return "popup to not be visible";
+            }
+        });
+    }
+
+    private void longClickDateDatePickerButton() {
+        WebElement button = getToggleButton();
+
+        new Actions(getDriver()).clickAndHold(button).perform();
+        assertThatPopupIsInvisible();
+
+        new Actions(getDriver()).release(button).perform();
+    }
+
+    private WebElement getToggleButton() {
+        DateFieldElement dateField = $(DateFieldElement.class).first();
+
+        return dateField.findElement(By.tagName("button"));
+    }
+
+    private void fastClickDateDatePickerButton() {
+        getToggleButton().click();
+    }
+
+}
\ No newline at end of file