aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillermo Alvarez <guillermo@vaadin.com>2014-08-13 14:40:38 +0300
committerVaadin Code Review <review@vaadin.com>2014-09-04 13:16:03 +0000
commitd6853c436e5acc0374cd73ce32d8e51c5b44f553 (patch)
tree59bf7b2eb8a999aedaa694b30d478d8e4c3a942d
parentd71ae18e355468487a947c84d0f92ed9c44b002e (diff)
downloadvaadin-framework-d6853c436e5acc0374cd73ce32d8e51c5b44f553.tar.gz
vaadin-framework-d6853c436e5acc0374cd73ce32d8e51c5b44f553.zip
Backspace in modal doesn't make browser navigation (#13180)
In a modal window if focus is not in an editable component the backspace default action is prevented. Also when focus is on bottom or top components. Change-Id: I53f0922e5ddff142e2d540be52e70c7d23d1b585
-rw-r--r--client/src/com/vaadin/client/Util.java19
-rw-r--r--client/src/com/vaadin/client/ui/VWindow.java22
-rw-r--r--uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpened.java2
-rw-r--r--uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpenedTest.java78
4 files changed, 97 insertions, 24 deletions
diff --git a/client/src/com/vaadin/client/Util.java b/client/src/com/vaadin/client/Util.java
index 306f26b1af..1cdd8fb458 100644
--- a/client/src/com/vaadin/client/Util.java
+++ b/client/src/com/vaadin/client/Util.java
@@ -1262,6 +1262,25 @@ public class Util {
}
/**
+ * Gets currently focused element and checks if it's editable
+ *
+ * @return true if focused element is editable
+ */
+ public static boolean isFocusedElementEditable() {
+ Element focusedElement = Util.getFocusedElement();
+ if (focusedElement != null) {
+ String tagName = focusedElement.getTagName();
+ String contenteditable = focusedElement
+ .getAttribute("contenteditable");
+
+ return "textarea".equalsIgnoreCase(tagName)
+ || "input".equalsIgnoreCase(tagName)
+ || "true".equalsIgnoreCase(contenteditable);
+ }
+ return false;
+ }
+
+ /**
* Kind of stronger version of isAttached(). In addition to std isAttached,
* this method checks that this widget nor any of its parents is hidden. Can
* be e.g used to check whether component should react to some events or
diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java
index 7223e4ac83..58e7a83012 100644
--- a/client/src/com/vaadin/client/ui/VWindow.java
+++ b/client/src/com/vaadin/client/ui/VWindow.java
@@ -16,6 +16,8 @@
package com.vaadin.client.ui;
+import static com.vaadin.client.Util.isFocusedElementEditable;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -178,8 +180,6 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
// Prevents leaving the window with the Tab key when true
private boolean doTabStop;
- private boolean hasFocus;
-
/**
* If centered (via UIDL), the window should stay in the centered -mode
* until a position is received from the server, or the user moves or
@@ -420,6 +420,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
Id.of(headerText));
// Handlers to Prevent tab to leave the window
+ // and backspace to cause browser navigation
topEventBlocker = new NativePreviewHandler() {
@Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
@@ -429,6 +430,10 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
&& nativeEvent.getShiftKey()) {
nativeEvent.preventDefault();
}
+ if (nativeEvent.getEventTarget().cast() == topTabStop
+ && nativeEvent.getKeyCode() == KeyCodes.KEY_BACKSPACE) {
+ nativeEvent.preventDefault();
+ }
}
};
@@ -441,6 +446,10 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
&& !nativeEvent.getShiftKey()) {
nativeEvent.preventDefault();
}
+ if (nativeEvent.getEventTarget().cast() == bottomTabStop
+ && nativeEvent.getKeyCode() == KeyCodes.KEY_BACKSPACE) {
+ nativeEvent.preventDefault();
+ }
}
};
}
@@ -1302,10 +1311,11 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
@Override
public void onKeyDown(KeyDownEvent event) {
- if (hasFocus && event.getNativeKeyCode() == KeyCodes.KEY_BACKSPACE) {
+ if (vaadinModality
+ && event.getNativeKeyCode() == KeyCodes.KEY_BACKSPACE
+ && !isFocusedElementEditable()) {
event.preventDefault();
}
-
if (shortcutHandler != null) {
shortcutHandler
.handleKeyboardEvent(Event.as(event.getNativeEvent()));
@@ -1322,8 +1332,6 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
@Override
public void onBlur(BlurEvent event) {
- hasFocus = false;
-
if (client.hasEventListeners(this, EventId.BLUR)) {
client.updateVariable(id, EventId.BLUR, "", true);
}
@@ -1331,8 +1339,6 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
@Override
public void onFocus(FocusEvent event) {
- hasFocus = true;
-
if (client.hasEventListeners(this, EventId.FOCUS)) {
client.updateVariable(id, EventId.FOCUS, "", true);
}
diff --git a/uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpened.java b/uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpened.java
index 849d756ca9..7f23362efd 100644
--- a/uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpened.java
+++ b/uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpened.java
@@ -36,6 +36,7 @@ public class BackspaceKeyWithModalOpened extends AbstractTestUI {
public static final String BTN_NEXT_ID = "btn_next";
public static final String BTN_OPEN_MODAL_ID = "btn_open_modal";
public static final String TEXT_FIELD_IN_MODAL = "txt_in_modal";
+ public static final String MODAL_ID = "modal_window";
private Navigator navigator;
@@ -66,6 +67,7 @@ public class BackspaceKeyWithModalOpened extends AbstractTestUI {
@Override
public void buttonClick(ClickEvent event) {
Window window = new Window("Caption");
+ window.setId(MODAL_ID);
VerticalLayout layout = new VerticalLayout();
layout.setWidth("300px");
diff --git a/uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpenedTest.java b/uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpenedTest.java
index f59c4bd762..e18b5b043a 100644
--- a/uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpenedTest.java
+++ b/uitest/src/com/vaadin/tests/components/window/BackspaceKeyWithModalOpenedTest.java
@@ -15,40 +15,86 @@
*/
package com.vaadin.tests.components.window;
+import static com.vaadin.tests.components.window.BackspaceKeyWithModalOpened.BTN_NEXT_ID;
+import static com.vaadin.tests.components.window.BackspaceKeyWithModalOpened.BTN_OPEN_MODAL_ID;
+import static org.junit.Assert.assertEquals;
+import static org.openqa.selenium.Keys.BACK_SPACE;
+import static org.openqa.selenium.Keys.TAB;
+
+import org.junit.Before;
import org.junit.Test;
-import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.TextFieldElement;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class BackspaceKeyWithModalOpenedTest extends MultiBrowserTest {
+ /**
+ * Tests that backspace in textfield does work
+ */
@Test
- public void testWindowScrollbars() throws Exception {
- openTestURL();
+ public void testWithFocusOnInput() throws Exception {
- WebElement nextButton = driver.findElement(By
- .id(BackspaceKeyWithModalOpened.BTN_NEXT_ID));
+ TextFieldElement textField = getTextField();
- nextButton.click();
+ // Try to delete characters in a text field.
+ textField.sendKeys("textt");
+ textField.sendKeys(BACK_SPACE);
+ assertEquals("text", textField.getValue());
+ checkButtonsCount();
+ }
- WebElement openModalButton = driver.findElement(By
- .id(BackspaceKeyWithModalOpened.BTN_OPEN_MODAL_ID));
+ /**
+ * Tests that backspace action outside textfield is prevented
+ */
+ @Test
+ public void testWithFocusOnModal() throws Exception {
+ // Try to send back actions to the browser.
+ new Actions(getDriver()).sendKeys(BACK_SPACE).perform();
- openModalButton.click();
+ checkButtonsCount();
+ }
+
+ /**
+ * Tests that backspace action in the bottom component is prevented
+ */
+ @Test
+ public void testWithFocusOnBottom() throws Exception {
+ TextFieldElement textField = getTextField();
+
+ // tab in last field set focus on bottom component
+ textField.sendKeys(TAB);
// Try to send back actions to the browser.
- new Actions(getDriver()).sendKeys(Keys.BACK_SPACE).perform();
+ new Actions(getDriver()).sendKeys(BACK_SPACE).perform();
- WebElement textField = driver.findElement(By
- .id(BackspaceKeyWithModalOpened.TEXT_FIELD_IN_MODAL));
+ checkButtonsCount();
+ }
- // Try to delete characters in a text field.
- textField.sendKeys("textt");
- textField.sendKeys(Keys.BACK_SPACE);
+ private TextFieldElement getTextField() {
+ return $(TextFieldElement.class).first();
+ }
+
+ @Before
+ public void testSetup() {
+ openTestURL();
+ WebElement nextButton = driver.findElement(By.id(BTN_NEXT_ID));
+ nextButton.click();
+
+ WebElement openModalButton = driver.findElement(By
+ .id(BTN_OPEN_MODAL_ID));
+ openModalButton.click();
+ }
- compareScreen(getScreenshotBaseName());
+ /**
+ * If there was a back navigation due to the backspace the next button
+ * would've been added again
+ */
+ private void checkButtonsCount() {
+ assertEquals(2, $(ButtonElement.class).all().size());
}
}