diff options
author | Henri Sara <henri.sara@gmail.com> | 2017-03-10 13:08:36 +0200 |
---|---|---|
committer | Ilia Motornyi <elmot@vaadin.com> | 2017-03-10 13:08:36 +0200 |
commit | dc657b3208f1eaf1b41b3640bd854cc0e2ef47f9 (patch) | |
tree | c210fa5d0efb05bd5779209da6dbf3f24a05801b | |
parent | a7eb9f7f704e8dfc098efe1e5115ccddb8367c45 (diff) | |
download | vaadin-framework-dc657b3208f1eaf1b41b3640bd854cc0e2ef47f9.tar.gz vaadin-framework-dc657b3208f1eaf1b41b3640bd854cc0e2ef47f9.zip |
Fix ComboBox popup location on scrolled pages in IE/Firefox
Fixes #8778
4 files changed, 169 insertions, 5 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/VComboBox.java b/client/src/main/java/com/vaadin/client/ui/VComboBox.java index d0de766a55..668e88b126 100644 --- a/client/src/main/java/com/vaadin/client/ui/VComboBox.java +++ b/client/src/main/java/com/vaadin/client/ui/VComboBox.java @@ -243,12 +243,12 @@ public class VComboBox extends Composite implements Field, KeyDownHandler, return $entry(function(e) { var deltaX = e.deltaX ? e.deltaX : -0.5*e.wheelDeltaX; var deltaY = e.deltaY ? e.deltaY : -0.5*e.wheelDeltaY; - + // IE8 has only delta y if (isNaN(deltaY)) { deltaY = -0.5*e.wheelDelta; } - + @com.vaadin.client.ui.VComboBox.JsniUtil::moveScrollFromEvent(*)(widget, deltaX, deltaY, e, e.deltaMode); }); }-*/; @@ -410,10 +410,13 @@ public class VComboBox extends Composite implements Field, KeyDownHandler, // Add TT anchor point getElement().setId("VAADIN_COMBOBOX_OPTIONLIST"); - final int x = VComboBox.this.getAbsoluteLeft(); + final int x = toInt32(WidgetUtil + .getBoundingClientRect(VComboBox.this.getElement()) + .getLeft()); - topPosition = tb.getAbsoluteTop(); - topPosition += tb.getOffsetHeight(); + topPosition = toInt32(WidgetUtil + .getBoundingClientRect(tb.getElement()).getBottom()) + + Window.getScrollTop(); setPopupPosition(x, topPosition); @@ -449,6 +452,11 @@ public class VComboBox extends Composite implements Field, KeyDownHandler, setPopupPositionAndShow(popup); } + private native int toInt32(double val) + /*-{ + return val | 0; + }-*/; + /** * Should the next page button be visible to the user? * diff --git a/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxEmbeddedInDiv.java b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxEmbeddedInDiv.java new file mode 100644 index 0000000000..f8775f36e5 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/combobox/ComboBoxEmbeddedInDiv.java @@ -0,0 +1,25 @@ +package com.vaadin.tests.components.combobox; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; + +public class ComboBoxEmbeddedInDiv extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout vl = new VerticalLayout(); + for (int i = 0; i < 20; i++) { + vl.addComponent(new Label("" + i)); + } + ComboBox<String> cb = new ComboBox<>(); + vl.addComponent(cb); + for (int i = 0; i < 20; i++) { + vl.addComponent(new Label("" + i)); + } + addComponent(vl); + } + +} diff --git a/uitest/src/main/webapp/statictestfiles/ComboBoxEmbeddingHtmlPage.html b/uitest/src/main/webapp/statictestfiles/ComboBoxEmbeddingHtmlPage.html new file mode 100644 index 0000000000..c5bf6db511 --- /dev/null +++ b/uitest/src/main/webapp/statictestfiles/ComboBoxEmbeddingHtmlPage.html @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE html> +<html> +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=UTF-8" /> + <meta http-equiv="X-UA-Compatible" + content="IE=9;chrome=1" /> + + <title>Embedding a Vaadin Application in HTML Page</title> + + <!-- Set up the favicon from the Vaadin theme --> + <link rel="shortcut icon" type="image/vnd.microsoft.icon" + href="/VAADIN/themes/valo/favicon.ico" /> + <link rel="icon" type="image/vnd.microsoft.icon" + href="/VAADIN/themes/valo/favicon.ico" /> +</head> + +<body> + <!-- Loads the Vaadin widget set, etc. --> + <script type="text/javascript" + src="/VAADIN/vaadinBootstrap.js"></script> + + <h1>Embedding a Vaadin UI</h1> + + <p>This is a static web page that contains an embedded Vaadin + application. It's here:</p> + + <div style="width: 200px; overflow: auto; border: 2px solid green;"> + <!-- So here comes the div element in which the Vaadin --> + <!-- application is embedded. --> + <div style="width: 300px;" id="embeddedcombobox" class="v-app"> + + <!-- Optional placeholder for the loading indicator --> + <div class=" v-app-loading"></div> + + <!-- Alternative fallback text --> + <noscript>You have to enable javascript in your browser to + use an application built with Vaadin.</noscript> + </div> + </div> + + <script type="text/javascript">//<![CDATA[ + if (!window.vaadin) + alert("Failed to load the bootstrap JavaScript: "+ + "/VAADIN/vaadinBootstrap.js"); + + /* The UI Configuration */ + vaadin.initApplication("embeddedcombobox", { + "browserDetailsUrl": "/run/com.vaadin.tests.components.combobox.ComboBoxEmbeddedInDiv", + "serviceUrl": "/run/", + "widgetset": "com.vaadin.DefaultWidgetSet", + "theme": "valo", + "versionInfo": {"vaadinVersion": "8.0.1"}, + "vaadinDir": "/VAADIN/", + "heartbeatInterval": 300, + "debug": true, + "standalone": false, + "authErrMsg": { + "message": "Take note of any unsaved data, "+ + "and <u>click here<\/u> to continue.", + "caption": "Authentication problem" + }, + "comErrMsg": { + "message": "Take note of any unsaved data, "+ + "and <u>click here<\/u> to continue.", + "caption": "Communication problem" + }, + "sessExpMsg": { + "message": "Take note of any unsaved data, "+ + "and <u>click here<\/u> to continue.", + "caption": "Session Expired" + } + });//]] > + </script> + + <p>Please view the page source to see how embedding works.</p> +</body> +</html>
\ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxPopupPositionEmbeddedInDivTest.java b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxPopupPositionEmbeddedInDivTest.java new file mode 100644 index 0000000000..2845283c7a --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/combobox/ComboBoxPopupPositionEmbeddedInDivTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2016 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.combobox; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ComboBoxElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ComboBoxPopupPositionEmbeddedInDivTest extends MultiBrowserTest { + + @Test + public void popupBelow() { + driver.get(StringUtils.strip(getBaseURL(), "/") + + "/statictestfiles/ComboBoxEmbeddingHtmlPage.html"); + + // Chrome requires document.scrollTop (<body>) + // Firefox + IE wants document.documentElement.scrollTop (<html>) + executeScript( + "document.body.scrollTop=200;document.documentElement.scrollTop=200;document.body.scrollLeft=50;document.documentElement.scrollLeft=50;"); + + ComboBoxElement combobox = $(ComboBoxElement.class).first(); + combobox.openPopup(); + WebElement popup = $(ComboBoxElement.class).first() + .getSuggestionPopup(); + + Point comboboxLocation = combobox.getLocation(); + Point popupLocation = popup.getLocation(); + Assert.assertTrue("Popup should be below combobox", + popupLocation.getY() > comboboxLocation.getY()); + + Assert.assertTrue("Popup should be left aligned with the combobox", + popupLocation.getX() == comboboxLocation.getX()); + } +} |