diff options
author | Juuso Valli <juuso@vaadin.com> | 2014-06-06 12:55:56 +0300 |
---|---|---|
committer | Juuso Valli <juuso@vaadin.com> | 2014-06-11 16:06:21 +0300 |
commit | 534485ded6e7ec8e5534b11ade5fdd5b8abbc2bf (patch) | |
tree | bfbf47e13fe2ee7e91690f7a22d4477ef54c48ce | |
parent | 3e5c5bc10752ae011ee74c82530452ba26521833 (diff) | |
download | vaadin-framework-534485ded6e7ec8e5534b11ade5fdd5b8abbc2bf.tar.gz vaadin-framework-534485ded6e7ec8e5534b11ade5fdd5b8abbc2bf.zip |
Make tooltips stationary when hovering (#13981)
Change-Id: I44acce87ea5c37d7b210e6c6c3dd9cd511192524
13 files changed, 175 insertions, 35 deletions
diff --git a/client/src/com/vaadin/client/TooltipInfo.java b/client/src/com/vaadin/client/TooltipInfo.java index 67d2ad37c2..06940536c8 100644 --- a/client/src/com/vaadin/client/TooltipInfo.java +++ b/client/src/com/vaadin/client/TooltipInfo.java @@ -21,6 +21,11 @@ public class TooltipInfo { private String errorMessageHtml; + // Contains the tooltip's identifier. If a tooltip's contents and this + // identifier haven't changed, the tooltip won't be updated in subsequent + // events. + private Object identifier; + public TooltipInfo() { } @@ -29,10 +34,23 @@ public class TooltipInfo { } public TooltipInfo(String tooltip, String errorMessage) { + this(tooltip, errorMessage, null); + } + + public TooltipInfo(String tooltip, String errorMessage, Object identifier) { + setIdentifier(identifier); setTitle(tooltip); setErrorMessage(errorMessage); } + public void setIdentifier(Object identifier) { + this.identifier = identifier; + } + + public Object getIdentifier() { + return identifier; + } + public String getTitle() { return title; } @@ -61,6 +79,7 @@ public class TooltipInfo { } public boolean equals(TooltipInfo other) { - return (other != null && other.title == title && other.errorMessageHtml == errorMessageHtml); + return (other != null && other.title == title + && other.errorMessageHtml == errorMessageHtml && other.identifier == identifier); } } diff --git a/client/src/com/vaadin/client/VTooltip.java b/client/src/com/vaadin/client/VTooltip.java index 77720089b1..8e653a0476 100644 --- a/client/src/com/vaadin/client/VTooltip.java +++ b/client/src/com/vaadin/client/VTooltip.java @@ -358,11 +358,9 @@ public class VTooltip extends VWindowOverlay { * @return TooltipInfo if connector and tooltip found, null if not */ private TooltipInfo getTooltipFor(Element element) { - ApplicationConnection ac = getApplicationConnection(); ComponentConnector connector = Util.getConnectorForElement(ac, RootPanel.get(), element); - // Try to find first connector with proper tooltip info TooltipInfo info = null; while (connector != null) { @@ -447,10 +445,26 @@ public class VTooltip extends VWindowOverlay { return; } + // If the parent (sub)component already has a tooltip open and it + // hasn't changed, we ignore the event. + // TooltipInfo contains a reference to the parent component that is + // checked in it's equals-method. + if (currentElement != null && isActuallyVisible()) { + TooltipInfo currentTooltip = getTooltipFor(currentElement); + TooltipInfo newTooltip = getTooltipFor(element); + if (currentTooltip != null && currentTooltip.equals(newTooltip)) { + return; + } + } + TooltipInfo info = getTooltipFor(element); if (info == null) { handleHideEvent(); } else { + if (closing) { + closeTimer.cancel(); + closing = false; + } setTooltipText(info); updatePosition(event, isFocused); if (isActuallyVisible() && !isFocused) { @@ -460,8 +474,7 @@ public class VTooltip extends VWindowOverlay { closeNow(); } // Schedule timer for showing the tooltip according to if it - // was - // recently closed or not. + // was recently closed or not. int timeout = justClosed ? getQuickOpenDelay() : getOpenDelay(); if (timeout == 0) { diff --git a/client/src/com/vaadin/client/ui/VMenuBar.java b/client/src/com/vaadin/client/ui/VMenuBar.java index f17ffbefed..11fda6222c 100644 --- a/client/src/com/vaadin/client/ui/VMenuBar.java +++ b/client/src/com/vaadin/client/ui/VMenuBar.java @@ -1034,7 +1034,7 @@ public class VMenuBar extends SimpleFocusablePanel implements return null; } - return new TooltipInfo(description); + return new TooltipInfo(description, null, this); } /** diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index d6eec66561..d3317abd4d 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -5157,7 +5157,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, String rowDescription = uidl.getStringAttribute("rowdescr"); if (rowDescription != null && !rowDescription.equals("")) { - tooltipInfo = new TooltipInfo(rowDescription); + tooltipInfo = new TooltipInfo(rowDescription, null, this); } else { tooltipInfo = null; } @@ -5430,7 +5430,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private void setTooltip(TableCellElement td, String description) { if (description != null && !description.equals("")) { - TooltipInfo info = new TooltipInfo(description); + TooltipInfo info = new TooltipInfo(description, null, this); cellToolTips.put(td, info); } else { cellToolTips.remove(td); diff --git a/client/src/com/vaadin/client/ui/VTabsheet.java b/client/src/com/vaadin/client/ui/VTabsheet.java index 3f2d90b721..15d9c83c49 100644 --- a/client/src/com/vaadin/client/ui/VTabsheet.java +++ b/client/src/com/vaadin/client/ui/VTabsheet.java @@ -329,7 +329,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, private boolean update(TabState tabState) { if (tabState.description != null || tabState.componentError != null) { setTooltipInfo(new TooltipInfo(tabState.description, - tabState.componentError)); + tabState.componentError, this)); } else { setTooltipInfo(null); } diff --git a/client/src/com/vaadin/client/ui/tree/TreeConnector.java b/client/src/com/vaadin/client/ui/tree/TreeConnector.java index c57430b3b4..55224b455f 100644 --- a/client/src/com/vaadin/client/ui/tree/TreeConnector.java +++ b/client/src/com/vaadin/client/ui/tree/TreeConnector.java @@ -269,7 +269,8 @@ public class TreeConnector extends AbstractComponentConnector implements String description = uidl.getStringAttribute("descr"); if (description != null) { - tooltipMap.put(treeNode, new TooltipInfo(description)); + tooltipMap.put(treeNode, new TooltipInfo(description, null, + treeNode)); } if (uidl.getBooleanAttribute("expanded") && !treeNode.getState()) { diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java index 197963a612..3cfe30a991 100644 --- a/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java +++ b/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java @@ -29,7 +29,6 @@ import org.openqa.selenium.interactions.internal.Coordinates; import org.openqa.selenium.internal.Locatable; import org.openqa.selenium.remote.DesiredCapabilities; -import com.vaadin.testbench.By; import com.vaadin.testbench.elements.MenuBarElement; import com.vaadin.tests.tb3.MultiBrowserTest; @@ -62,8 +61,4 @@ public class MenuBarTooltipsNearEdgeTest extends MultiBrowserTest { - tooltip.getSize().getWidth()))); } - - private WebElement getTooltipElement() { - return getDriver().findElement(By.className("v-tooltip-text")); - } } diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java index b4bae160b9..bb8f87daaa 100644 --- a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java +++ b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java @@ -23,12 +23,9 @@ import static org.junit.Assert.assertThat; import java.util.List; 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 org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.testbench.elements.MenuBarElement; @@ -43,20 +40,14 @@ public class MenuTooltipTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - browsers.remove(Browser.IE8.getDesiredCapabilities()); - browsers.remove(Browser.IE9.getDesiredCapabilities()); - browsers.remove(Browser.IE10.getDesiredCapabilities()); - browsers.remove(Browser.IE11.getDesiredCapabilities()); - return browsers; - }; + return getBrowsersExcludingIE(); + } @Test public void testToolTipDelay() throws InterruptedException { openTestURL(); - Coordinates elementCoordinates = ((Locatable) $(MenuBarElement.class) - .first().getWrappedElement()).getCoordinates(); + Coordinates elementCoordinates = getCoordinates($(MenuBarElement.class).first()); Mouse mouse = ((HasInputDevices) getDriver()).getMouse(); @@ -74,8 +65,4 @@ public class MenuTooltipTest extends MultiBrowserTest { is(greaterThan(elementCoordinates.onPage().getX()))); assertThat(getTooltipElement().getText(), is("TOOLTIP 1")); } - - private WebElement getTooltipElement() { - return getDriver().findElement(By.className("v-tooltip-text")); - } } diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java b/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java index 06fb659d4a..412fd3049d 100644 --- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java +++ b/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java @@ -74,10 +74,6 @@ public class TooltipInWindowTest extends MultiBrowserTest { } - private WebElement getTooltipElement() { - return getDriver().findElement(By.className("v-tooltip-text")); - } - private WebElement getTooltipContainerElement() { return getDriver().findElement(By.className("v-tooltip")); } diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index c8e4e3c9a9..8783a4dc42 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -24,6 +24,7 @@ import java.net.URL; import java.util.Collections; import java.util.List; +import com.vaadin.testbench.TestBenchElement; import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; @@ -35,6 +36,8 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.HasInputDevices; import org.openqa.selenium.interactions.Keyboard; import org.openqa.selenium.interactions.Mouse; +import org.openqa.selenium.interactions.internal.Coordinates; +import org.openqa.selenium.internal.Locatable; import org.openqa.selenium.remote.BrowserType; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; @@ -153,6 +156,14 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } + protected WebElement getTooltipElement() { + return getDriver().findElement(com.vaadin.testbench.By.className("v-tooltip-text")); + } + + protected Coordinates getCoordinates(TestBenchElement element) { + return ((Locatable) element.getWrappedElement()).getCoordinates(); + } + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface RunLocally { diff --git a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java index 74073af217..ccbb6ca872 100644 --- a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java +++ b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java @@ -40,6 +40,16 @@ import org.openqa.selenium.remote.DesiredCapabilities; */ public abstract class MultiBrowserTest extends PrivateTB3Configuration { + protected List<DesiredCapabilities> getBrowsersExcludingIE() { + List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>(getAllBrowsers()); + browsers.remove(Browser.IE8.getDesiredCapabilities()); + browsers.remove(Browser.IE9.getDesiredCapabilities()); + browsers.remove(Browser.IE10.getDesiredCapabilities()); + browsers.remove(Browser.IE11.getDesiredCapabilities()); + + return browsers; + } + public enum Browser { FIREFOX(BrowserUtil.firefox(24)), CHROME(BrowserUtil.chrome(33)), SAFARI( BrowserUtil.safari(7)), IE8(BrowserUtil.ie(8)), IE9(BrowserUtil diff --git a/uitest/src/com/vaadin/tests/tooltip/StationaryTooltip.java b/uitest/src/com/vaadin/tests/tooltip/StationaryTooltip.java new file mode 100644 index 0000000000..5c7b52d96f --- /dev/null +++ b/uitest/src/com/vaadin/tests/tooltip/StationaryTooltip.java @@ -0,0 +1,31 @@ +package com.vaadin.tests.tooltip; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.VerticalLayout; + +public class StationaryTooltip extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout vl = new VerticalLayout(); + Button button = new Button("Button"); + button.setDescription("description"); + + button.setWidth("200px"); + vl.addComponent(button); + + addComponent(vl); + } + + @Override + protected String getTestDescription() { + return null; + } + + @Override + protected Integer getTicketNumber() { + return null; + } +} diff --git a/uitest/src/com/vaadin/tests/tooltip/StationaryTooltipTest.java b/uitest/src/com/vaadin/tests/tooltip/StationaryTooltipTest.java new file mode 100644 index 0000000000..6b751e7a6b --- /dev/null +++ b/uitest/src/com/vaadin/tests/tooltip/StationaryTooltipTest.java @@ -0,0 +1,77 @@ +package com.vaadin.tests.tooltip; + +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.interactions.Mouse; +import org.openqa.selenium.interactions.internal.Coordinates; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class StationaryTooltipTest extends MultiBrowserTest { + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + // With IEDriver, the cursor seems to jump to default position after the + // mouse move, + // so we are not able to test the tooltip behaviour properly. + return getBrowsersExcludingIE(); + } + + @Test + public void tooltipShouldBeStationary() throws InterruptedException { + openTestURL(); + + Mouse mouse = getMouse(); + + moveMouseToButtonUpperLeftCorner(mouse); + sleep(3000); // wait for the tooltip to become visible + int originalTooltipLocationX = getTooltipLocationX(); + + moveMouseToButtonBottomRightCorner(mouse); + int actualTooltipLocationX = getTooltipLocationX(); + + assertThat(actualTooltipLocationX, is(greaterThan(0))); + assertThat(actualTooltipLocationX, is(originalTooltipLocationX)); + } + + private Coordinates getButtonCoordinates() { + return getCoordinates(getButtonElement()); + } + + private ButtonElement getButtonElement() { + return $(ButtonElement.class).first(); + } + + private void moveMouseToButtonBottomRightCorner(Mouse mouse) { + Coordinates buttonCoordinates = getButtonCoordinates(); + Dimension buttonDimensions = getButtonDimensions(); + + mouse.mouseMove(buttonCoordinates, buttonDimensions.getWidth() - 1, + buttonDimensions.getHeight() - 1); + } + + private void moveMouseToButtonUpperLeftCorner(Mouse mouse) { + Coordinates buttonCoordinates = getButtonCoordinates(); + + mouse.mouseMove(buttonCoordinates, 0, 0); + } + + private org.openqa.selenium.Dimension getButtonDimensions() { + ButtonElement buttonElement = getButtonElement(); + + return buttonElement.getWrappedElement().getSize(); + } + + private int getTooltipLocationX() { + return getTooltipElement().getLocation().getX(); + } + +}
\ No newline at end of file |