Browse Source

Fix tooltip delay (#13695)

Change-Id: I1c3ed59d8a19d3355a3c729fb3635731b326a00e
tags/7.3.0.alpha3
Juuso Valli 10 years ago
parent
commit
a25aab4ca1

+ 69
- 76
client/src/com/vaadin/client/VTooltip.java View File

import com.google.gwt.aria.client.RelevantValue; import com.google.gwt.aria.client.RelevantValue;
import com.google.gwt.aria.client.Roles; import com.google.gwt.aria.client.Roles;
import com.google.gwt.dom.client.Element; 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.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickEvent;
VErrorMessage em = new VErrorMessage(); VErrorMessage em = new VErrorMessage();
Element description = DOM.createDiv(); Element description = DOM.createDiv();


private TooltipInfo currentTooltipInfo = new TooltipInfo(" ");

private boolean closing = false; private boolean closing = false;
private boolean opening = false; private boolean opening = false;


*/ */
public void showAssistive(TooltipInfo info) { public void showAssistive(TooltipInfo info) {
updatePosition(null, true); 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) { if (info.getErrorMessage() != null) {
em.setVisible(true); em.setVisible(true);
em.updateMessage(info.getErrorMessage()); em.updateMessage(info.getErrorMessage());
hasContent = true;
} else { } else {
em.setVisible(false); em.setVisible(false);
} }
if (info.getTitle() != null && !"".equals(info.getTitle())) { if (info.getTitle() != null && !"".equals(info.getTitle())) {
DOM.setInnerHTML(description, info.getTitle());
description.getStyle().clearDisplay();
hasContent = true;
description.setInnerHTML(info.getTitle());
} else { } 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) { if (hasContent) {
// Issue #8454: With IE7 the tooltips size is calculated based on // Issue #8454: With IE7 the tooltips size is calculated based on
y = Window.getScrollTop(); y = Window.getScrollTop();
} }
} }

setPopupPosition(x, y); setPopupPosition(x, y);
sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT); sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT);
} }
} }
} }


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() { private void closeNow() {
private Timer showTimer = new Timer() { private Timer showTimer = new Timer() {
@Override @Override
public void run() { public void run() {
TooltipInfo info = tooltipEventHandler.getTooltipInfo();
if (null != info) {
show(info);
}
opening = false; opening = false;
showTooltip();
} }
}; };


@Override @Override
public void run() { public void run() {
closeNow(); closeNow();
justClosedTimer.schedule(2000);
justClosedTimer.schedule(getQuickOpenTimeout());
justClosed = true; justClosed = true;
} }
}; };
} }
closeTimer.schedule(getCloseTimeout()); closeTimer.schedule(getCloseTimeout());
closing = true; closing = true;
justClosed = true;
justClosedTimer.schedule(getQuickOpenTimeout());
} }


@Override @Override
private int tooltipEventMouseY; private int tooltipEventMouseY;


public void updatePosition(Event event, boolean isFocused) { 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 @Override
closeNow(); closeNow();
} }


TooltipInfo info = tooltipEventHandler.getTooltipInfo();
if (null != info) {
show(info);
}
showTooltip();
opening = false; opening = false;
} }


private boolean handledByFocus; 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 * @param element
* Element used in search * 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(); ApplicationConnection ac = getApplicationConnection();
ComponentConnector connector = Util.getConnectorForElement(ac, ComponentConnector connector = Util.getConnectorForElement(ac,
assert connector.hasTooltip() : "getTooltipInfo for " assert connector.hasTooltip() : "getTooltipInfo for "
+ Util.getConnectorString(connector) + Util.getConnectorString(connector)
+ " returned a tooltip even though hasTooltip claims there are no tooltips for the 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;
} }


/** /**
*/ */
private void handleHideEvent() { private void handleHideEvent() {
hideTooltip(); hideTooltip();
currentTooltipInfo = null;
} }


@Override @Override
return; return;
} }


boolean connectorAndTooltipFound = resolveConnector(element);
if (!connectorAndTooltipFound) {
if (isShowing()) {
TooltipInfo info = getTooltipFor(element);
if (info == null) {
if (isActuallyVisible()) {
handleHideEvent(); handleHideEvent();
} else {
currentTooltipInfo = null;
} }
} else { } else {
setTooltipText(info);
updatePosition(event, isFocused); updatePosition(event, isFocused);

if (isShowing() && !isFocused) {
replaceCurrentTooltip();
} else {
if (isActuallyVisible() && !isFocused) {
showTooltip(); 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; handledByFocus = isFocused;
currentElement = element; currentElement = element;
} }

} }


private final TooltipEventHandler tooltipEventHandler = new TooltipEventHandler(); private final TooltipEventHandler tooltipEventHandler = new TooltipEventHandler();

+ 59
- 0
uitest/src/com/vaadin/tests/components/TooltipDelay.java View File

/*
* 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;
}

}

+ 3
- 0
uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicator.java View File



horizontalLayout.addComponent(inHorizontal); horizontalLayout.addComponent(inHorizontal);
layout.addComponent(horizontalLayout); layout.addComponent(horizontalLayout);
getTooltipConfiguration().setOpenDelay(0);
getTooltipConfiguration().setQuickOpenDelay(0);
getTooltipConfiguration().setCloseTimeout(1000);
} }


/* /*

+ 13
- 2
uitest/src/com/vaadin/tests/components/orderedlayout/ErrorIndicatorTest.java View File



import org.junit.Test; import org.junit.Test;
import org.openqa.selenium.By; 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.testbench.elements.TextFieldElement;
import com.vaadin.tests.tb3.MultiBrowserTest; import com.vaadin.tests.tb3.MultiBrowserTest;
String tooltipText; String tooltipText;
openTestURL(); openTestURL();


$(TextFieldElement.class).first().showTooltip();
showTooltip($(TextFieldElement.class).first());
tooltipText = driver.findElement(By.className("v-tooltip")).getText(); tooltipText = driver.findElement(By.className("v-tooltip")).getText();
assertEquals(tooltipText, "Vertical layout tooltip"); assertEquals(tooltipText, "Vertical layout tooltip");


$(TextFieldElement.class).get(1).showTooltip();
showTooltip($(TextFieldElement.class).get(1));
tooltipText = driver.findElement(By.className("v-tooltip")).getText(); tooltipText = driver.findElement(By.className("v-tooltip")).getText();
assertEquals(tooltipText, "Horizontal layout tooltip"); assertEquals(tooltipText, "Horizontal layout tooltip");
} }

private void showTooltip(WebElement element) {
Coordinates elementCoordinates = ((Locatable) element).getCoordinates();
Mouse mouse = ((HasInputDevices) getDriver()).getMouse();
mouse.mouseMove(elementCoordinates);
}
} }

+ 3
- 0
uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltip.java View File

t.setDescription("This tab has both an error and a description"); t.setDescription("This tab has both an error and a description");


setContent(tabSheet); setContent(tabSheet);
getTooltipConfiguration().setOpenDelay(0);
getTooltipConfiguration().setQuickOpenDelay(0);
getTooltipConfiguration().setCloseTimeout(1000);
} }


private Tab addTab() { private Tab addTab() {

+ 8
- 3
uitest/src/com/vaadin/tests/components/tabsheet/TabSheetErrorTooltipTest.java View File

import org.junit.Test; import org.junit.Test;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebElement; 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; import com.vaadin.tests.tb3.MultiBrowserTest;


public class TabSheetErrorTooltipTest extends MultiBrowserTest { public class TabSheetErrorTooltipTest extends MultiBrowserTest {
} }


private void showTooltip(int index) { 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) { private WebElement getTab(int index) {

+ 3
- 0
uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java View File

TextField tf = new TextField("TextField with a tooltip"); TextField tf = new TextField("TextField with a tooltip");
tf.setDescription("My tooltip"); tf.setDescription("My tooltip");
tf.setId(id); tf.setId(id);
getTooltipConfiguration().setOpenDelay(0);
getTooltipConfiguration().setQuickOpenDelay(0);
getTooltipConfiguration().setCloseTimeout(1000);
return tf; return tf;
} }



+ 6
- 5
uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java View File

public class TooltipInWindowTest extends MultiBrowserTest { public class TooltipInWindowTest extends MultiBrowserTest {


@Test @Test
public void testTooltipsInSubWindow() throws Exception {
public void testTooltipsInSubWindow() throws InterruptedException {
openTestURL(); openTestURL();


WebElement textfield = vaadinElementById("tf1"); WebElement textfield = vaadinElementById("tf1");


// Show tooltip // Show tooltip
mouse.mouseMove(textfieldCoordinates, 10, 10); mouse.mouseMove(textfieldCoordinates, 10, 10);
sleep(1000);


sleep(100);
ensureVisibleTooltipPositionedCorrectly(); ensureVisibleTooltipPositionedCorrectly();
assertEquals("My tooltip", getTooltipElement().getText()); assertEquals("My tooltip", getTooltipElement().getText());


// Hide tooltip // Hide tooltip
mouse.mouseMove(textfieldCoordinates, -100, -100); mouse.mouseMove(textfieldCoordinates, -100, -100);
sleep(1000);
sleep(2000);


ensureHiddenTooltipPositionedCorrectly(); ensureHiddenTooltipPositionedCorrectly();
assertEquals("", getTooltipElement().getText()); assertEquals("", getTooltipElement().getText());


// Show tooltip again // Show tooltip again
mouse.mouseMove(textfieldCoordinates, 10, 10); mouse.mouseMove(textfieldCoordinates, 10, 10);
sleep(1000);


sleep(100);
ensureVisibleTooltipPositionedCorrectly(); ensureVisibleTooltipPositionedCorrectly();
assertEquals("My tooltip", getTooltipElement().getText()); assertEquals("My tooltip", getTooltipElement().getText());


// Hide tooltip // Hide tooltip
mouse.mouseMove(textfieldCoordinates, -100, -100); mouse.mouseMove(textfieldCoordinates, -100, -100);
sleep(1000);
sleep(2000);


ensureHiddenTooltipPositionedCorrectly(); ensureHiddenTooltipPositionedCorrectly();
assertEquals("", getTooltipElement().getText()); assertEquals("", getTooltipElement().getText());

} }


private WebElement getTooltipElement() { private WebElement getTooltipElement() {

Loading…
Cancel
Save