From 729448fb19dc318149a4c12d160d50e1f780fd09 Mon Sep 17 00:00:00 2001 From: "denis.magdenkov" Date: Wed, 10 Sep 2014 15:14:57 +0400 Subject: [PATCH] TextFields inside Drag and Drop Wrappers cannot get focus (#12838) Add detection logic to distinguish bweteen click and drag. Change-Id: I43129183e990266243bfaafe83396f52b09b16d4 --- .../vaadin/client/ui/VDragAndDropWrapper.java | 42 +++++++++++++- .../DragAndDropFocusObtain.java | 55 +++++++++++++++++++ .../DragAndDropFocusObtainTest.java | 52 ++++++++++++++++++ 3 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropFocusObtain.java create mode 100644 uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropFocusObtainTest.java diff --git a/client/src/com/vaadin/client/ui/VDragAndDropWrapper.java b/client/src/com/vaadin/client/ui/VDragAndDropWrapper.java index 7bf341a387..defa27fbac 100644 --- a/client/src/com/vaadin/client/ui/VDragAndDropWrapper.java +++ b/client/src/com/vaadin/client/ui/VDragAndDropWrapper.java @@ -26,6 +26,8 @@ import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; +import com.google.gwt.event.dom.client.MouseUpEvent; +import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.user.client.Command; @@ -66,29 +68,65 @@ import com.vaadin.shared.ui.dd.VerticalDropLocation; public class VDragAndDropWrapper extends VCustomComponent implements VHasDropHandler { + /** + * Minimum pixel delta is used to detect click from drag. #12838 + */ + private static final int MIN_PX_DELTA = 4; private static final String CLASSNAME = "v-ddwrapper"; protected static final String DRAGGABLE = "draggable"; /** For internal use only. May be removed or replaced in the future. */ public boolean hasTooltip = false; + private int startX = 0; + private int startY = 0; public VDragAndDropWrapper() { super(); - hookHtml5Events(getElement()); setStyleName(CLASSNAME); + addDomHandler(new MouseDownHandler() { @Override - public void onMouseDown(MouseDownEvent event) { + public void onMouseDown(final MouseDownEvent event) { if (getConnector().isEnabled() && event.getNativeEvent().getButton() == Event.BUTTON_LEFT && startDrag(event.getNativeEvent())) { event.preventDefault(); // prevent text selection + startX = event.getClientX(); + startY = event.getClientY(); } } }, MouseDownEvent.getType()); + addDomHandler(new MouseUpHandler() { + + @Override + public void onMouseUp(final MouseUpEvent event) { + final int deltaX = Math.abs(event.getClientX() - startX); + final int deltaY = Math.abs(event.getClientY() - startY); + if ((deltaX + deltaY) < MIN_PX_DELTA) { + setFocusOnLastElement(event); + } + } + + private void setFocusOnLastElement(final MouseUpEvent event) { + Element el = event.getRelativeElement(); + getLastChildElement(el).focus(); + } + + private Element getLastChildElement(Element el) { + do { + if (el == null) { + break; + } + el = el.getFirstChildElement(); + } while (el.getFirstChildElement() != null); + return el; + } + + }, MouseUpEvent.getType()); + addDomHandler(new TouchStartHandler() { @Override diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropFocusObtain.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropFocusObtain.java new file mode 100644 index 0000000000..c182894db4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropFocusObtain.java @@ -0,0 +1,55 @@ +/* + * 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.draganddropwrapper; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.DragStartMode; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.VerticalLayout; + +/** + * Test UI for text area inside {@link DragAndDropWrapper}: text area should + * obtain focus on click. + * + * @since + * @author Vaadin Ltd + */ +public class DragAndDropFocusObtain extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout dndLayout = new VerticalLayout(); + TextArea area = new TextArea(); + area.setValue("text"); + dndLayout.addComponent(area); + + DragAndDropWrapper wrapper = new DragAndDropWrapper(dndLayout); + wrapper.setDragStartMode(DragStartMode.COMPONENT); + addComponent(wrapper); + } + + @Override + protected String getTestDescription() { + return "Text fields/areas inside Drag and Drop Wrappers should get focus inside DnD wrapper on click."; + } + + @Override + protected Integer getTicketNumber() { + return 12838; + } +} \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropFocusObtainTest.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropFocusObtainTest.java new file mode 100644 index 0000000000..ccb28b7103 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropFocusObtainTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2013 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.draganddropwrapper; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.ui.DragAndDropWrapper; + +/** + * Test for text area inside {@link DragAndDropWrapper}: text area should obtain + * focus on click. + * + * @since + * @author Vaadin Ltd + */ +public class DragAndDropFocusObtainTest extends MultiBrowserTest { + + @Test + public void testTextAreaDndImage() { + openTestURL(); + + WebElement wrapper = driver.findElement(By.className("v-ddwrapper")); + Actions actions = new Actions(driver); + actions.click(wrapper); + actions.perform(); + + WebElement focusedElement = driver.findElement(By + .className("v-textarea-focus")); + Assert.assertNotNull("Text area did not obtain focus after click", + focusedElement); + + } + +} -- 2.39.5