]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix tooltip delay (#13695)
authorJuuso Valli <juuso@vaadin.com>
Fri, 23 May 2014 09:20:08 +0000 (12:20 +0300)
committerVaadin Code Review <review@vaadin.com>
Tue, 27 May 2014 20:10:14 +0000 (20:10 +0000)
Change-Id: I1c3ed59d8a19d3355a3c729fb3635731b326a00e

client/src/com/vaadin/client/VTooltip.java
uitest/src/com/vaadin/tests/components/TooltipDelay.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicator.java
uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicatorTest.java
uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltip.java
uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java
uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java
uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java

index 4384b51393e10502a99096111fae0532d72c7db5..e0daa4d34ece714fb067fd6f0778930224d67737 100644 (file)
@@ -19,7 +19,6 @@ import com.google.gwt.aria.client.LiveValue;
 import com.google.gwt.aria.client.RelevantValue;
 import com.google.gwt.aria.client.Roles;
 import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.Style.Display;
 import com.google.gwt.event.dom.client.BlurEvent;
 import com.google.gwt.event.dom.client.BlurHandler;
 import com.google.gwt.event.dom.client.ClickEvent;
@@ -52,6 +51,8 @@ public class VTooltip extends VWindowOverlay {
     VErrorMessage em = new VErrorMessage();
     Element description = DOM.createDiv();
 
+    private TooltipInfo currentTooltipInfo = new TooltipInfo(" ");
+
     private boolean closing = false;
     private boolean opening = false;
 
@@ -102,30 +103,35 @@ public class VTooltip extends VWindowOverlay {
      */
     public void showAssistive(TooltipInfo info) {
         updatePosition(null, true);
-        show(info);
+        setTooltipText(info);
+        showTooltip();
     }
 
-    /**
-     * Show a popup containing the information in the "info" tooltip
-     * 
-     * @param info
-     */
-    private void show(TooltipInfo info) {
-        boolean hasContent = false;
+    private void setTooltipText(TooltipInfo info) {
         if (info.getErrorMessage() != null) {
             em.setVisible(true);
             em.updateMessage(info.getErrorMessage());
-            hasContent = true;
         } else {
             em.setVisible(false);
         }
         if (info.getTitle() != null && !"".equals(info.getTitle())) {
-            DOM.setInnerHTML(description, info.getTitle());
-            description.getStyle().clearDisplay();
-            hasContent = true;
+            description.setInnerHTML(info.getTitle());
         } else {
-            DOM.setInnerHTML(description, "");
-            description.getStyle().setDisplay(Display.NONE);
+            description.setInnerHTML("");
+        }
+        currentTooltipInfo = info;
+    }
+
+    /**
+     * Show a popup containing the currentTooltipInfo
+     * 
+     */
+    private void showTooltip() {
+        boolean hasContent = false;
+        if (currentTooltipInfo.getErrorMessage() != null
+                || (currentTooltipInfo.getTitle() != null && !""
+                        .equals(currentTooltipInfo.getTitle()))) {
+            hasContent = true;
         }
         if (hasContent) {
             // Issue #8454: With IE7 the tooltips size is calculated based on
@@ -164,7 +170,6 @@ public class VTooltip extends VWindowOverlay {
                             y = Window.getScrollTop();
                         }
                     }
-
                     setPopupPosition(x, y);
                     sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT);
                 }
@@ -174,18 +179,14 @@ public class VTooltip extends VWindowOverlay {
         }
     }
 
-    private void showTooltip() {
-
-        // Close current tooltip
-        if (isShowing()) {
-            closeNow();
-        }
-
-        // Schedule timer for showing the tooltip according to if it was
-        // recently closed or not.
-        int timeout = justClosed ? getQuickOpenDelay() : getOpenDelay();
-        showTimer.schedule(timeout);
-        opening = true;
+    /**
+     * For assistive tooltips to work correctly we must have the tooltip visible
+     * and attached to the DOM well in advance.
+     * 
+     * @return
+     */
+    public boolean isActuallyVisible() {
+        return super.isShowing() && getPopupLeft() > 0 && getPopupTop() > 0;
     }
 
     private void closeNow() {
@@ -197,11 +198,8 @@ public class VTooltip extends VWindowOverlay {
     private Timer showTimer = new Timer() {
         @Override
         public void run() {
-            TooltipInfo info = tooltipEventHandler.getTooltipInfo();
-            if (null != info) {
-                show(info);
-            }
             opening = false;
+            showTooltip();
         }
     };
 
@@ -209,7 +207,7 @@ public class VTooltip extends VWindowOverlay {
         @Override
         public void run() {
             closeNow();
-            justClosedTimer.schedule(2000);
+            justClosedTimer.schedule(getQuickOpenTimeout());
             justClosed = true;
         }
     };
@@ -235,8 +233,6 @@ public class VTooltip extends VWindowOverlay {
         }
         closeTimer.schedule(getCloseTimeout());
         closing = true;
-        justClosed = true;
-        justClosedTimer.schedule(getQuickOpenTimeout());
     }
 
     @Override
@@ -252,13 +248,16 @@ public class VTooltip extends VWindowOverlay {
     private int tooltipEventMouseY;
 
     public void updatePosition(Event event, boolean isFocused) {
-        if (isFocused) {
-            tooltipEventMouseX = -1000;
-            tooltipEventMouseY = -1000;
-        } else {
-            tooltipEventMouseX = DOM.eventGetClientX(event);
-            tooltipEventMouseY = DOM.eventGetClientY(event);
-        }
+        tooltipEventMouseX = getEventX(event, isFocused);
+        tooltipEventMouseY = getEventY(event, isFocused);
+    }
+
+    private int getEventX(Event event, boolean isFocused) {
+        return isFocused ? -5000 : DOM.eventGetClientX(event);
+    }
+
+    private int getEventY(Event event, boolean isFocused) {
+        return isFocused ? -5000 : DOM.eventGetClientY(event);
     }
 
     @Override
@@ -284,10 +283,7 @@ public class VTooltip extends VWindowOverlay {
             closeNow();
         }
 
-        TooltipInfo info = tooltipEventHandler.getTooltipInfo();
-        if (null != info) {
-            show(info);
-        }
+        showTooltip();
         opening = false;
     }
 
@@ -305,27 +301,13 @@ public class VTooltip extends VWindowOverlay {
         private boolean handledByFocus;
 
         /**
-         * Current tooltip active
-         */
-        private TooltipInfo currentTooltipInfo = null;
-
-        /**
-         * Get current active tooltip information
-         * 
-         * @return Current active tooltip information or null
-         */
-        public TooltipInfo getTooltipInfo() {
-            return currentTooltipInfo;
-        }
-
-        /**
-         * Locate connector and it's tooltip for given element
+         * Locate the tooltip for given element
          * 
          * @param element
          *            Element used in search
-         * @return true if connector and tooltip found
+         * @return TooltipInfo if connector and tooltip found, null if not
          */
-        private boolean resolveConnector(Element element) {
+        private TooltipInfo getTooltipFor(Element element) {
 
             ApplicationConnection ac = getApplicationConnection();
             ComponentConnector connector = Util.getConnectorForElement(ac,
@@ -353,11 +335,11 @@ public class VTooltip extends VWindowOverlay {
                 assert connector.hasTooltip() : "getTooltipInfo for "
                         + Util.getConnectorString(connector)
                         + " returned a tooltip even though hasTooltip claims there are no tooltips for the connector.";
-                currentTooltipInfo = info;
-                return true;
+                return info;
+
             }
 
-            return false;
+            return null;
         }
 
         /**
@@ -368,7 +350,6 @@ public class VTooltip extends VWindowOverlay {
          */
         private void handleHideEvent() {
             hideTooltip();
-            currentTooltipInfo = null;
         }
 
         @Override
@@ -418,26 +399,38 @@ public class VTooltip extends VWindowOverlay {
                 return;
             }
 
-            boolean connectorAndTooltipFound = resolveConnector(element);
-            if (!connectorAndTooltipFound) {
-                if (isShowing()) {
+            TooltipInfo info = getTooltipFor(element);
+            if (info == null) {
+                if (isActuallyVisible()) {
                     handleHideEvent();
-                } else {
-                    currentTooltipInfo = null;
                 }
             } else {
+                setTooltipText(info);
                 updatePosition(event, isFocused);
-
-                if (isShowing() && !isFocused) {
-                    replaceCurrentTooltip();
-                } else {
+                if (isActuallyVisible() && !isFocused) {
                     showTooltip();
+                } else {
+                    if (isActuallyVisible()) {
+                        closeNow();
+                    }
+                    // Schedule timer for showing the tooltip according to if it
+                    // was
+                    // recently closed or not.
+                    int timeout = justClosed ? getQuickOpenDelay()
+                            : getOpenDelay();
+                    if (timeout == 0) {
+                        showTooltip();
+                    } else {
+                        showTimer.schedule(timeout);
+                        opening = true;
+                    }
                 }
             }
 
             handledByFocus = isFocused;
             currentElement = element;
         }
+
     }
 
     private final TooltipEventHandler tooltipEventHandler = new TooltipEventHandler();
diff --git a/uitest/src/com/vaadin/tests/components/TooltipDelay.java b/uitest/src/com/vaadin/tests/components/TooltipDelay.java
new file mode 100644 (file)
index 0000000..06fec3b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.Button;
+
+/**
+ * Test to see if tooltip delay is working properly.
+ * 
+ * @author Vaadin Ltd
+ */
+public class TooltipDelay extends AbstractTestUI {
+
+    @Override
+    protected void setup(VaadinRequest vaadinRequest) {
+
+        Button button = new Button("Expand");
+        button.setDescription("Expand");
+        addComponent(button);
+
+        getTooltipConfiguration().setOpenDelay(5000);
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription()
+     */
+    @Override
+    protected String getTestDescription() {
+        return "Tooltips should appear with a five second delay.";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber()
+     */
+    @Override
+    protected Integer getTicketNumber() {
+        return 13695;
+    }
+
+}
\ No newline at end of file
index def67c256a1b66784a6313593fe3e7745e4c3185..89490bd167ff917b653a2db18b372b50cbbc07f1 100644 (file)
@@ -54,6 +54,9 @@ public class ErrorIndicator extends AbstractTestUI {
 
         horizontalLayout.addComponent(inHorizontal);
         layout.addComponent(horizontalLayout);
+        getTooltipConfiguration().setOpenDelay(0);
+        getTooltipConfiguration().setQuickOpenDelay(0);
+        getTooltipConfiguration().setCloseTimeout(1000);
     }
 
     /*
index 0367a77c7e4b425276b70a4471c4648c674dfe9e..e784eb3b64533dfee28360bf74c805ed3b466d50 100644 (file)
@@ -19,6 +19,11 @@ import static org.junit.Assert.assertEquals;
 
 import org.junit.Test;
 import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.HasInputDevices;
+import org.openqa.selenium.interactions.Mouse;
+import org.openqa.selenium.interactions.internal.Coordinates;
+import org.openqa.selenium.internal.Locatable;
 
 import com.vaadin.testbench.elements.TextFieldElement;
 import com.vaadin.tests.tb3.MultiBrowserTest;
@@ -30,12 +35,18 @@ public class ErrorIndicatorTest extends MultiBrowserTest {
         String tooltipText;
         openTestURL();
 
-        $(TextFieldElement.class).first().showTooltip();
+        showTooltip($(TextFieldElement.class).first());
         tooltipText = driver.findElement(By.className("v-tooltip")).getText();
         assertEquals(tooltipText, "Vertical layout tooltip");
 
-        $(TextFieldElement.class).get(1).showTooltip();
+        showTooltip($(TextFieldElement.class).get(1));
         tooltipText = driver.findElement(By.className("v-tooltip")).getText();
         assertEquals(tooltipText, "Horizontal layout tooltip");
     }
+
+    private void showTooltip(WebElement element) {
+        Coordinates elementCoordinates = ((Locatable) element).getCoordinates();
+        Mouse mouse = ((HasInputDevices) getDriver()).getMouse();
+        mouse.mouseMove(elementCoordinates);
+    }
 }
index d9cc077f67d317f403aa3a1d8dde7f739a7401c9..c4af98eb3fd839fc0d0111e5cd41a1b607ac17af 100644 (file)
@@ -39,6 +39,9 @@ public class TabSheetErrorTooltip extends AbstractTestUI {
         t.setDescription("This tab has both an error and a description");
 
         setContent(tabSheet);
+        getTooltipConfiguration().setOpenDelay(0);
+        getTooltipConfiguration().setQuickOpenDelay(0);
+        getTooltipConfiguration().setCloseTimeout(1000);
     }
 
     private Tab addTab() {
index d639cd2ddc7852f6e00f3a8dcfccb80f89e8e187..5462ed253257ea80e3b6903decbbb78748e7d38b 100644 (file)
@@ -24,8 +24,11 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.openqa.selenium.By;
 import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.HasInputDevices;
+import org.openqa.selenium.interactions.Mouse;
+import org.openqa.selenium.interactions.internal.Coordinates;
+import org.openqa.selenium.internal.Locatable;
 
-import com.vaadin.testbench.commands.TestBenchElementCommands;
 import com.vaadin.tests.tb3.MultiBrowserTest;
 
 public class TabSheetErrorTooltipTest extends MultiBrowserTest {
@@ -63,8 +66,10 @@ public class TabSheetErrorTooltipTest extends MultiBrowserTest {
     }
 
     private void showTooltip(int index) {
-        TestBenchElementCommands element = testBenchElement(getTab(index));
-        element.showTooltip();
+        Coordinates elementCoordinates = ((Locatable) getTab(index))
+                .getCoordinates();
+        Mouse mouse = ((HasInputDevices) getDriver()).getMouse();
+        mouse.mouseMove(elementCoordinates);
     }
 
     private WebElement getTab(int index) {
index 9730d1d8a170805d66b2459dbe6d4c14dc9c7b3e..cd2cc7d06033a0e4de374a4ba7d26257f0ac06f6 100644 (file)
@@ -41,6 +41,9 @@ public class TooltipInWindow extends AbstractTestUI {
         TextField tf = new TextField("TextField with a tooltip");
         tf.setDescription("My tooltip");
         tf.setId(id);
+        getTooltipConfiguration().setOpenDelay(0);
+        getTooltipConfiguration().setQuickOpenDelay(0);
+        getTooltipConfiguration().setCloseTimeout(1000);
         return tf;
     }
 
index 6f144ef7a4a773070247ff1c774af77405601965..06fb659d4ab27268b1e3d5277429ef365019353c 100644 (file)
@@ -35,7 +35,7 @@ import com.vaadin.tests.tb3.MultiBrowserTest;
 public class TooltipInWindowTest extends MultiBrowserTest {
 
     @Test
-    public void testTooltipsInSubWindow() throws Exception {
+    public void testTooltipsInSubWindow() throws InterruptedException {
         openTestURL();
 
         WebElement textfield = vaadinElementById("tf1");
@@ -46,31 +46,32 @@ public class TooltipInWindowTest extends MultiBrowserTest {
 
         // Show tooltip
         mouse.mouseMove(textfieldCoordinates, 10, 10);
-        sleep(1000);
 
+        sleep(100);
         ensureVisibleTooltipPositionedCorrectly();
         assertEquals("My tooltip", getTooltipElement().getText());
 
         // Hide tooltip
         mouse.mouseMove(textfieldCoordinates, -100, -100);
-        sleep(1000);
+        sleep(2000);
 
         ensureHiddenTooltipPositionedCorrectly();
         assertEquals("", getTooltipElement().getText());
 
         // Show tooltip again
         mouse.mouseMove(textfieldCoordinates, 10, 10);
-        sleep(1000);
 
+        sleep(100);
         ensureVisibleTooltipPositionedCorrectly();
         assertEquals("My tooltip", getTooltipElement().getText());
 
         // Hide tooltip
         mouse.mouseMove(textfieldCoordinates, -100, -100);
-        sleep(1000);
+        sleep(2000);
 
         ensureHiddenTooltipPositionedCorrectly();
         assertEquals("", getTooltipElement().getText());
+
     }
 
     private WebElement getTooltipElement() {