private NativePreviewHandler topEventBlocker;
private NativePreviewHandler bottomEventBlocker;
+ private NativePreviewHandler modalEventBlocker;
private HandlerRegistration topBlockerRegistration;
private HandlerRegistration bottomBlockerRegistration;
+ private HandlerRegistration modalBlockerRegistration;
// Prevents leaving the window with the Tab key when true
private boolean doTabStop;
.addNativePreviewHandler(topEventBlocker);
bottomBlockerRegistration = Event
.addNativePreviewHandler(bottomEventBlocker);
+ modalBlockerRegistration = Event
+ .addNativePreviewHandler(modalEventBlocker);
}
}
bottomBlockerRegistration.removeHandler();
bottomBlockerRegistration = null;
+
+ modalBlockerRegistration.removeHandler();
+ modalBlockerRegistration = null;
}
}
nativeEvent.preventDefault();
}
};
+
+ // Handle modal window + tabbing when the focus is not inside the
+ // window (custom tab order or tabbing in from browser url bar)
+ modalEventBlocker = event -> {
+ if (!vaadinModality
+ || getElement().isOrHasChild(WidgetUtil.getFocusedElement())
+ || (getTopmostWindow() != VWindow.this)) {
+ return;
+ }
+
+ NativeEvent nativeEvent = event.getNativeEvent();
+ if (nativeEvent.getType().equals("keyup")
+ && nativeEvent.getKeyCode() == KeyCodes.KEY_TAB) {
+ nativeEvent.preventDefault();
+ focus();
+
+ }
+ };
+
}
/**
protected void setup(VaadinRequest req) {
Button button = new Button("Open windows");
+ button.setTabIndex(2);
button.setId("firstButton");
addComponent(button);
button.addClickListener(event -> {
});
Button button2 = new Button(
"Open unclosable and unresizable modal window");
+ button2.setTabIndex(1);
addComponent(button2);
button2.setId("modalWindowButton");
button2.addClickListener(event -> {
"this has been focused".equals(tfe.getValue()));
}
- private void pressKeyAndWait(Keys key) {
+ protected void pressKeyAndWait(Keys key) {
new Actions(driver).sendKeys(key).build().perform();
sleep(100);
}
assertEquals("true", ariaModal);
String role = windowElement.getAttribute("role");
assertEquals("dialog", role);
-
}
}
--- /dev/null
+package com.vaadin.tests.components.window;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.testbench.parallel.Browser;
+
+/**
+ * Tests that a modal window is focused on creation and that on closing a window
+ * focus is given to underlying modal window
+ *
+ * @author Vaadin Ltd
+ */
+public class ModalWindowRefocusTest extends ModalWindowFocusTest {
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ // Chrome doesn't support clicking on the modality curtain
+ return getBrowserCapabilities(Browser.IE11, Browser.EDGE,
+ Browser.FIREFOX);
+ }
+
+ @Override
+ protected Class<?> getUIClass() {
+ return ModalWindowFocus.class;
+ }
+
+ /**
+ * Open modal window -> click modality curtain to remove focus from Window
+ * -> press tab thrice so that focus goes into Window again and focuses the
+ * text field so that the focus event is fired.
+ */
+ @Test
+ public void testFocusOutsideModal() {
+ waitForElementPresent(By.id("modalWindowButton"));
+ WebElement button = findElement(By.id("modalWindowButton"));
+ button.click();
+ waitForElementPresent(By.id("focusfield"));
+ WebElement curtain = findElement(
+ org.openqa.selenium.By.className("v-window-modalitycurtain"));
+ curtain.click();
+
+ pressKeyAndWait(Keys.TAB);
+ pressKeyAndWait(Keys.TAB);
+ pressKeyAndWait(Keys.TAB);
+
+ TextFieldElement tfe = $(TextFieldElement.class).id("focusfield");
+ assertTrue("First TextField should have received focus",
+ "this has been focused".equals(tfe.getValue()));
+
+ }
+
+}