瀏覽代碼

Revert "Moved accessibility shortcut handling to server-side. [#14843]"

This reverts commit e88f71dd6d.

Change-Id: I1d4ed60ec4a194f6ed18fa5506134ef3a185a6cf
tags/7.5.0.beta1
Leif Åstrand 9 年之前
父節點
當前提交
0a7d5bcd58

+ 3
- 1
client/src/com/vaadin/client/ui/VWindow.java 查看文件

@@ -1354,7 +1354,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,

@Override
public void onKeyUp(KeyUpEvent event) {
// do nothing
if (isClosable() && event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
onCloseClick();
}
}

@Override

+ 0
- 38
server/src/com/vaadin/event/ShortcutAction.java 查看文件

@@ -17,8 +17,6 @@
package com.vaadin.event;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@@ -238,42 +236,6 @@ public class ShortcutAction extends Action {
return modifiers;
}

/**
* Checks whether the shortcut can be triggered with the given combination
* of keys.
*
* @param keyCode
* potential match for the {@link KeyCode} that this shortcut
* reacts to
* @param modifierKeys
* (optional) potential matches for the {@link ModifierKey}s
* required for this shortcut to react
* @return <code>true</code> if keyCode and modifierKeys are a match,
* <code>false</code> otherwise
*/
public boolean isTriggeredBy(int keyCode, int... modifierKeys) {
boolean result = false;
if (keyCode == this.keyCode) {
if (modifierKeys == null) {
result = (modifiers == null);
} else if (modifiers != null) {
List<Integer> modifierList = new ArrayList<Integer>();
for (int modifier : modifiers) {
modifierList.add(modifier);
}
for (int modifierKey : modifierKeys) {
if (modifierList.contains(modifierKey)) {
modifierList.remove(modifierKey);
} else {
return false;
}
}
result = modifierList.isEmpty();
}
}
return result;
}

/**
* Key codes that can be used for shortcuts
*

+ 12
- 90
server/src/com/vaadin/ui/Window.java 查看文件

@@ -21,9 +21,6 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;

@@ -133,7 +130,6 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
super(caption, content);
registerRpc(rpc);
setSizeUndefined();
setCloseShortcut(ShortcutAction.KeyCode.ESCAPE);
}

/* ********************************************************************* */
@@ -820,48 +816,14 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
/*
* Actions
*/
private LinkedHashSet<CloseShortcut> closeShortcuts = new LinkedHashSet<CloseShortcut>();

protected Collection<CloseShortcut> getCloseShortcuts() {
return Collections.unmodifiableCollection(closeShortcuts);
}

/**
* Adds a keyboard shortcut for closing the window when user presses the
* given {@link KeyCode} and (optional) {@link ModifierKey}s.<br/>
* Note that this shortcut only reacts while the window has focus, closing
* itself - if you want to close a window from a UI, use
* {@link UI#addAction(com.vaadin.event.Action)} of the UI instead.
* <p>
* If there is a prior CloseShortcut with the same keycode and modifiers,
* that gets removed before the new one is added. Prior CloseShortcuts with
* differing keycodes or modifiers are not affected.
*
* @param keyCode
* the keycode for invoking the shortcut
* @param modifiers
* the (optional) modifiers for invoking the shortcut, null for
* none
*/
public void addCloseShortcut(int keyCode, int... modifiers) {
// make sure there are no duplicates
removeCloseShortcut(keyCode, modifiers);
CloseShortcut closeShortcut = new CloseShortcut(this, keyCode,
modifiers);
closeShortcuts.add(closeShortcut);
addAction(closeShortcut);
}
protected CloseShortcut closeShortcut;

/**
* Sets the keyboard shortcut for closing the window when user presses the
* given {@link KeyCode} and (optional) {@link ModifierKey}s.<br/>
* Makes is possible to close the window by pressing the given
* {@link KeyCode} and (optional) {@link ModifierKey}s.<br/>
* Note that this shortcut only reacts while the window has focus, closing
* itself - if you want to close a window from a UI, use
* {@link UI#addAction(com.vaadin.event.Action)} of the UI instead.
* <p>
* If there are any prior CloseShortcuts when this method is called those
* get removed before the new one is added. <b>NOTE: this also removes the
* default shortcut that is added for accessibility purposes.</b>
*
* @param keyCode
* the keycode for invoking the shortcut
@@ -870,61 +832,22 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
* none
*/
public void setCloseShortcut(int keyCode, int... modifiers) {
removeCloseShortcuts();
addCloseShortcut(keyCode, modifiers);
}

/**
* Removes a keyboard shortcut previously set with
* {@link #setCloseShortcut(int, int...)} or
* {@link #addCloseShortcut(int, int...)}.
*
* @param keyCode
* the keycode for invoking the shortcut
* @param modifiers
* the (optional) modifiers for invoking the shortcut, null for
* none
*/
public void removeCloseShortcut(int keyCode, int... modifiers) {
for (CloseShortcut closeShortcut : closeShortcuts) {
if (closeShortcut.isTriggeredBy(keyCode, modifiers)) {
removeAction(closeShortcut);
closeShortcuts.remove(closeShortcut);
break;
}
if (closeShortcut != null) {
removeAction(closeShortcut);
}
closeShortcut = new CloseShortcut(this, keyCode, modifiers);
addAction(closeShortcut);
}

/**
* @deprecated use {@link #resetCloseShortcuts()} instead, or
* {@link #removeCloseShortcuts()} if you also want to get rid
* of the default shortcut
* Removes the keyboard shortcut previously set with
* {@link #setCloseShortcut(int, int...)}.
*/
@Deprecated
public void removeCloseShortcut() {
resetCloseShortcuts();
}

/**
* Removes all the keyboard shortcuts previously set with
* {@link #setCloseShortcut(int, int...)} or
* {@link #addCloseShortcut(int, int...)} and re-adds the default shortcut
* {@link KeyCode.ESCAPE}.
*/
public void resetCloseShortcuts() {
setCloseShortcut(ShortcutAction.KeyCode.ESCAPE);
}

/**
* Removes all the keyboard shortcuts previously set with
* {@link #setCloseShortcut(int, int...)} or
* {@link #addCloseShortcut(int, int...)}.
*/
public void removeCloseShortcuts() {
for (CloseShortcut closeShortcut : closeShortcuts) {
if (closeShortcut != null) {
removeAction(closeShortcut);
closeShortcut = null;
}
closeShortcuts.clear();
}

/**
@@ -1391,8 +1314,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
}

private CloseShortcut getCloseShortcut() {
Iterator<CloseShortcut> i = getCloseShortcuts().iterator();
return i.hasNext() ? i.next() : null;
return closeShortcut;
}

@Override

+ 0
- 121
uitest/src/com/vaadin/tests/components/window/CloseShortcut.java 查看文件

@@ -1,121 +0,0 @@
/*
* 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.window;

import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutAction.ModifierKey;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

/**
* Tests close shortcuts for Window.
*
* @author Vaadin Ltd
*/
public class CloseShortcut extends AbstractTestUI {

@Override
protected void setup(VaadinRequest request) {
final Window w = new Window();
w.setWidth("300px");
w.setHeight("300px");
w.center();
addWindow(w);
w.focus();

// add textfield to the window to give TestBench something to send the
// keys to
VerticalLayout content = new VerticalLayout();
content.setMargin(true);
TextField textField = new TextField();
textField.setSizeFull();
content.addComponent(textField);
w.setContent(content);

final CheckBox cbDefault = new CheckBox("Use default (ESC) shortcut");
cbDefault.setId("default");
addComponent(cbDefault);
final CheckBox cbOther = new CheckBox("Use R shortcut");
cbOther.setId("other");
addComponent(cbOther);
final CheckBox cbCtrl = new CheckBox("Use CTRL+A shortcut");
cbCtrl.setId("control");
addComponent(cbCtrl);
final CheckBox cbShift = new CheckBox("Use SHIFT+H shortcut");
cbShift.setId("shift");
addComponent(cbShift);

cbOther.setValue(true);
cbCtrl.setValue(true);
cbShift.setValue(true);

Property.ValueChangeListener listener = new Property.ValueChangeListener() {

@Override
public void valueChange(ValueChangeEvent event) {
if (Boolean.TRUE.equals(cbDefault.getValue())) {
w.resetCloseShortcuts();
} else {
w.removeCloseShortcuts();
}
if (Boolean.TRUE.equals(cbOther.getValue())) {
w.addCloseShortcut(KeyCode.R);
}
if (Boolean.TRUE.equals(cbCtrl.getValue())) {
w.addCloseShortcut(KeyCode.A, ModifierKey.CTRL);
}
if (Boolean.TRUE.equals(cbShift.getValue())) {
w.addCloseShortcut(KeyCode.H, ModifierKey.SHIFT);
}
}
};
cbDefault.addValueChangeListener(listener);
cbOther.addValueChangeListener(listener);
cbCtrl.addValueChangeListener(listener);
cbShift.addValueChangeListener(listener);

cbDefault.setValue(true); // trigger value change

Button button = new Button("Reopen window", new Button.ClickListener() {

@Override
public void buttonClick(ClickEvent event) {
w.close();
addWindow(w);
w.focus();
}
});
addComponent(button);
}

@Override
protected String getTestDescription() {
return "It should be possible to have multiple shortcuts at the same time, and to remove the default shortcut ESC.";
}

@Override
protected Integer getTicketNumber() {
return 14843;
}
}

+ 0
- 219
uitest/src/com/vaadin/tests/components/window/CloseShortcutTest.java 查看文件

@@ -1,219 +0,0 @@
/*
* 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.window;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedCondition;

import com.vaadin.testbench.elements.CheckBoxElement;
import com.vaadin.testbench.elements.TextFieldElement;
import com.vaadin.testbench.elements.WindowElement;
import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.tb3.MultiBrowserTest;

/**
* Tests close shortcuts for Window.
*
* @author Vaadin Ltd
*/
public class CloseShortcutTest extends MultiBrowserTest {

private WindowElement window;
private CheckBoxElement cbDefault;
private CheckBoxElement cbOther;
private CheckBoxElement cbCtrl;
private CheckBoxElement cbShift;

@Override
@Before
public void setup() throws Exception {
super.setup();
openTestURL();
waitForElementPresent(By.className("v-window"));

window = $(WindowElement.class).first();
cbDefault = $(CheckBoxElement.class).id("default");
cbOther = $(CheckBoxElement.class).id("other");
cbCtrl = $(CheckBoxElement.class).id("control");
cbShift = $(CheckBoxElement.class).id("shift");
}

@Test
public void testAllCheckBoxesSelected() {
assertTrue("Default wasn't selected initially.", isChecked(cbDefault));
assertTrue("Other wasn't selected initially.", isChecked(cbOther));
assertTrue("Ctrl+A wasn't selected initially.", isChecked(cbCtrl));
assertTrue("Shift+H wasn't selected initially.", isChecked(cbShift));
}

@Test
public void testAllCheckBoxesClickable() {
click(cbDefault);
click(cbOther);
click(cbCtrl);
click(cbShift);

assertFalse("Default was selected when it shouldn't have been.",
isChecked(cbDefault));
assertFalse("Other was selected when it shouldn't have been.",
isChecked(cbOther));
assertFalse("Ctrl+A was selected when it shouldn't have been.",
isChecked(cbCtrl));
assertFalse("Shift+H was selected when it shouldn't have been.",
isChecked(cbShift));
}

@Test
public void testDefaultWithAll() {
attemptDefaultShortcut();
ensureWindowClosed();
}

@Test
public void testDefaultWithoutSelection() {
click(cbDefault);

attemptDefaultShortcut();
ensureWindowOpen();
}

@Test
public void testOtherWithAll() {
attemptOtherShortcut();
// TODO: remove this check once #14902 has been fixed
DesiredCapabilities cap = getDesiredCapabilities();
if ((BrowserUtil.isIE(cap) && !BrowserUtil.isIE8(cap))
|| BrowserUtil.isPhantomJS(cap)) {
ensureWindowClosed();
}
}

@Test
public void testOtherWithoutSelection() {
click(cbOther);

attemptOtherShortcut();
ensureWindowOpen();
}

@Test
public void testCtrlWithAll() {
attemptCtrlShortcut();
// TODO: remove this check once #14902 has been fixed
if (BrowserUtil.isPhantomJS(getDesiredCapabilities())) {
ensureWindowClosed();
}
}

@Test
public void testCtrlWithoutSelection() {
click(cbCtrl);

attemptCtrlShortcut();
ensureWindowOpen();
}

@Test
public void testShiftWithAll() {
attemptShiftShortcut();
// TODO: remove this check once #14902 has been fixed
DesiredCapabilities capabilities = getDesiredCapabilities();
if (!BrowserUtil.isIE(capabilities) || BrowserUtil.isIE8(capabilities)) {
ensureWindowClosed();
}
}

@Test
public void testShiftWithoutSelection() {
click(cbShift);

attemptShiftShortcut();
ensureWindowOpen();
}

private boolean isChecked(CheckBoxElement cb) {
String checked = cb.findElement(By.tagName("input")).getAttribute(
"checked");
if ("true".equals(checked)) {
return true;
} else if (checked == null) {
return false;
}
throw new IllegalStateException(
"Unexpected attribute value for 'checked': " + checked);
}

@Override
protected void click(final CheckBoxElement cb) {
final boolean initial = isChecked(cb);
super.click(cb);
waitUntil(new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver input) {
return initial != isChecked(cb);
}

@Override
public String toString() {
// Timed out after 10 seconds waiting for ...
return "checked state to change";
}
});
}

private void attemptDefaultShortcut() {
window.focus();
$(TextFieldElement.class).first().sendKeys(Keys.ESCAPE);
}

private void attemptOtherShortcut() {
window.focus();
$(TextFieldElement.class).first().sendKeys("R");
}

private void attemptCtrlShortcut() {
window.focus();
new Actions(driver).keyDown(Keys.CONTROL).perform();
$(TextFieldElement.class).first().sendKeys("A");
new Actions(driver).keyUp(Keys.CONTROL).perform();
}

private void attemptShiftShortcut() {
window.focus();
new Actions(driver).keyDown(Keys.SHIFT).perform();
$(TextFieldElement.class).first().sendKeys("H");
new Actions(driver).keyUp(Keys.SHIFT).perform();
}

private void ensureWindowClosed() {
assertTrue("Window didn't close as expected.", $(WindowElement.class)
.all().isEmpty());
}

private void ensureWindowOpen() {
assertFalse("Window closed when it shouldn't have.",
$(WindowElement.class).all().isEmpty());
}
}

Loading…
取消
儲存