diff options
author | Péter Török <31210544+torok-peter@users.noreply.github.com> | 2017-11-07 11:39:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-07 11:39:11 +0200 |
commit | b5b57375a3b785d758e09a4f27d3023b87e6f339 (patch) | |
tree | df9652d6e979534a5018ca63f011a0519e73ac44 | |
parent | f7abbea6bef3eb46fa4f3580a7da2a2440463266 (diff) | |
download | vaadin-framework-b5b57375a3b785d758e09a4f27d3023b87e6f339.tar.gz vaadin-framework-b5b57375a3b785d758e09a4f27d3023b87e6f339.zip |
Make focus circulate in modal dialog to improve accessibility (#10260)
Make focus circulate in modal dialog to improve accessibility
5 files changed, 47 insertions, 4 deletions
diff --git a/client/src/main/java/com/vaadin/client/ui/FocusUtil.java b/client/src/main/java/com/vaadin/client/ui/FocusUtil.java index 16b3f68456..9a0a4ecea4 100644 --- a/client/src/main/java/com/vaadin/client/ui/FocusUtil.java +++ b/client/src/main/java/com/vaadin/client/ui/FocusUtil.java @@ -15,6 +15,7 @@ */ package com.vaadin.client.ui; +import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.Focusable; import com.google.gwt.user.client.ui.Widget; @@ -94,4 +95,26 @@ public class FocusUtil { return focusable.getElement().getTabIndex(); } + + public static native Element[] getFocusableChildren(Element parent) + /*-{ + var focusableChildren = parent.querySelectorAll('[type][tabindex]:not([tabindex="-1"]), [role=button][tabindex]:not([tabindex="-1"])'); + return focusableChildren; + }-*/; + + public static void focusOnFirstFocusableElement(Element parent) + { + Element[] focusableChildren = getFocusableChildren(parent); + if (focusableChildren.length > 0) { + focusableChildren[0].focus(); + } + } + + public static void focusOnLastFocusableElement(Element parent) + { + Element[] focusableChildren = getFocusableChildren(parent); + if (focusableChildren.length > 0) { + focusableChildren[focusableChildren.length - 1].focus(); + } + } } diff --git a/client/src/main/java/com/vaadin/client/ui/VWindow.java b/client/src/main/java/com/vaadin/client/ui/VWindow.java index e7618ed59b..e53997ec17 100644 --- a/client/src/main/java/com/vaadin/client/ui/VWindow.java +++ b/client/src/main/java/com/vaadin/client/ui/VWindow.java @@ -429,14 +429,18 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, Roles.getDialogRole().setAriaLabelledbyProperty(getElement(), Id.of(headerText)); - // Handlers to Prevent tab to leave the window + // Handlers to Prevent tab to leave the window (by circulating focus) // and backspace to cause browser navigation topEventBlocker = event -> { + if (!getElement().isOrHasChild(WidgetUtil.getFocusedElement())) { + return; + } NativeEvent nativeEvent = event.getNativeEvent(); if (nativeEvent.getEventTarget().cast() == topTabStop && nativeEvent.getKeyCode() == KeyCodes.KEY_TAB && nativeEvent.getShiftKey()) { nativeEvent.preventDefault(); + FocusUtil.focusOnLastFocusableElement(this.getElement()); } if (nativeEvent.getEventTarget().cast() == topTabStop && nativeEvent.getKeyCode() == KeyCodes.KEY_BACKSPACE) { @@ -445,11 +449,15 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, }; bottomEventBlocker = event -> { + if (!getElement().isOrHasChild(WidgetUtil.getFocusedElement())) { + return; + } NativeEvent nativeEvent = event.getNativeEvent(); if (nativeEvent.getEventTarget().cast() == bottomTabStop && nativeEvent.getKeyCode() == KeyCodes.KEY_TAB && !nativeEvent.getShiftKey()) { nativeEvent.preventDefault(); + FocusUtil.focusOnFirstFocusableElement(this.getElement()); } if (nativeEvent.getEventTarget().cast() == bottomTabStop && nativeEvent.getKeyCode() == KeyCodes.KEY_BACKSPACE) { diff --git a/uitest/src/main/java/com/vaadin/tests/components/window/BackspaceKeyWithModalOpened.java b/uitest/src/main/java/com/vaadin/tests/components/window/BackspaceKeyWithModalOpened.java index 2aca0b91f2..5cc3c02016 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/window/BackspaceKeyWithModalOpened.java +++ b/uitest/src/main/java/com/vaadin/tests/components/window/BackspaceKeyWithModalOpened.java @@ -15,11 +15,13 @@ */ package com.vaadin.tests.components.window; +import com.vaadin.annotations.Theme; +import com.vaadin.annotations.Widgetset; import com.vaadin.navigator.Navigator; import com.vaadin.navigator.View; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.server.VaadinRequest; -import com.vaadin.tests.components.AbstractReindeerTestUI; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.Label; import com.vaadin.ui.Layout; @@ -27,7 +29,9 @@ import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; -public class BackspaceKeyWithModalOpened extends AbstractReindeerTestUI { +@Theme("valo") +@Widgetset("com.vaadin.DefaultWidgetSet") +public class BackspaceKeyWithModalOpened extends AbstractTestUI { private static final String DEFAULT_VIEW_ID = ""; private static final String SECOND_VIEW_ID = "second"; diff --git a/uitest/src/main/java/com/vaadin/tests/components/window/ModalWindowFocus.java b/uitest/src/main/java/com/vaadin/tests/components/window/ModalWindowFocus.java index a9578840d2..9e77600213 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/window/ModalWindowFocus.java +++ b/uitest/src/main/java/com/vaadin/tests/components/window/ModalWindowFocus.java @@ -15,12 +15,14 @@ */ package com.vaadin.tests.components.window; +import com.vaadin.annotations.Widgetset; import com.vaadin.server.VaadinRequest; import com.vaadin.tests.components.AbstractReindeerTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Window; +@Widgetset("com.vaadin.DefaultWidgetSet") public class ModalWindowFocus extends AbstractReindeerTestUI { @Override diff --git a/uitest/src/test/java/com/vaadin/tests/components/window/BackspaceKeyWithModalOpenedTest.java b/uitest/src/test/java/com/vaadin/tests/components/window/BackspaceKeyWithModalOpenedTest.java index ce015bab9d..b9199e0aec 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/window/BackspaceKeyWithModalOpenedTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/window/BackspaceKeyWithModalOpenedTest.java @@ -22,6 +22,7 @@ import static org.openqa.selenium.Keys.BACK_SPACE; import static org.openqa.selenium.Keys.TAB; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; @@ -60,9 +61,14 @@ public class BackspaceKeyWithModalOpenedTest extends MultiBrowserTest { } /** - * Tests that backspace action in the bottom component is prevented + * Tests that backspace action in the bottom component is prevented. + * + * Ignored because the fix to #8855 stops the top and bottom components + * from functioning as focus traps. Meanwhile, navigation with Backspace + * is not anymore supported by reasonable browsers. */ @Test + @Ignore public void testWithFocusOnBottom() throws Exception { TextFieldElement textField = getTextField(); |