From: Juuso Valli Date: Fri, 23 May 2014 09:20:08 +0000 (+0300) Subject: Fix tooltip delay (#13695) X-Git-Tag: 7.3.0.alpha3~1^2~3^2~5 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a25aab4ca166ff1989f04eef41fde2e9c01131b2;p=vaadin-framework.git Fix tooltip delay (#13695) Change-Id: I1c3ed59d8a19d3355a3c729fb3635731b326a00e --- diff --git a/client/src/com/vaadin/client/VTooltip.java b/client/src/com/vaadin/client/VTooltip.java index 4384b51393..e0daa4d34e 100644 --- a/client/src/com/vaadin/client/VTooltip.java +++ b/client/src/com/vaadin/client/VTooltip.java @@ -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 index 0000000000..06fec3b233 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/TooltipDelay.java @@ -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 diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicator.java b/uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicator.java index def67c256a..89490bd167 100644 --- a/uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicator.java +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicator.java @@ -54,6 +54,9 @@ public class ErrorIndicator extends AbstractTestUI { horizontalLayout.addComponent(inHorizontal); layout.addComponent(horizontalLayout); + getTooltipConfiguration().setOpenDelay(0); + getTooltipConfiguration().setQuickOpenDelay(0); + getTooltipConfiguration().setCloseTimeout(1000); } /* diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicatorTest.java b/uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicatorTest.java index 0367a77c7e..e784eb3b64 100644 --- a/uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicatorTest.java +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicatorTest.java @@ -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); + } } diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltip.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltip.java index d9cc077f67..c4af98eb3f 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltip.java +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltip.java @@ -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() { diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java index d639cd2ddc..5462ed2532 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java @@ -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) { diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java b/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java index 9730d1d8a1..cd2cc7d060 100644 --- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java +++ b/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java @@ -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; } diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java b/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java index 6f144ef7a4..06fb659d4a 100644 --- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java +++ b/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java @@ -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() {