]> source.dussan.org Git - vaadin-framework.git/commitdiff
fix: Focus-activated shortcut listener in compatibility TextField (#12203)
authorTatu Lund <tatu@vaadin.com>
Tue, 16 Feb 2021 11:16:49 +0000 (13:16 +0200)
committerGitHub <noreply@github.com>
Tue, 16 Feb 2021 11:16:49 +0000 (13:16 +0200)
client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java
uitest/src/main/java/com/vaadin/tests/components/textfield/CompatibilityTextFieldShortcut.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/textfield/CompatibilityTextFieldShortcutTest.java [new file with mode: 0644]

index 1c03a2719d35996b0bd33131d8d0578f10a6afec..92c26d2b70dd63f3624dd1bc55878c237cffd2da 100644 (file)
@@ -127,30 +127,48 @@ public class ShortcutActionHandler {
         }
         final ComponentConnector finalTarget = target;
         event.preventDefault();
+
         /*
          * The focused component might have unpublished changes, try to
          * synchronize them before firing shortcut action.
          */
-        client.flushActiveConnector();
-        /*
-         * Legacy components don't have built-in logic for flushing, they need a
-         * workaround with blur and focus to trigger the value change.
-         */
+        boolean flushed = false;
         ComponentConnector activeConnector = getActiveConnector(client);
+
         if (activeConnector != null) {
             Class<?> clz = activeConnector.getClass();
             while (clz != null) {
+                if (clz.getName().equals(
+                        "com.vaadin.v7.client.ui.textfield.TextFieldConnector")) {
+                    /*
+                     * Legacy textfields support modern flushing.
+                     */
+                    client.flushActiveConnector();
+                    flushed = true;
+                    break;
+                }
                 if (clz.getName().equals(
                         "com.vaadin.v7.client.ui.AbstractLegacyComponentConnector")) {
+                    /*
+                     * Most of the legacy components don't have built-in logic
+                     * for flushing, they need a workaround with blur and focus
+                     * to trigger the value change.
+                     */
                     shakeTarget(et);
                     Scheduler.get().scheduleDeferred(() -> {
                         shakeTarget(et);
                     });
+                    flushed = true;
                     break;
                 }
                 clz = clz.getSuperclass();
             }
         }
+        if (!flushed) {
+            // Use V8 style flushing for the rest.
+            client.flushActiveConnector();
+        }
+
         Scheduler.get().scheduleDeferred(() -> {
             if (finalTarget != null) {
                 client.updateVariable(paintableId, "actiontarget", finalTarget,
diff --git a/uitest/src/main/java/com/vaadin/tests/components/textfield/CompatibilityTextFieldShortcut.java b/uitest/src/main/java/com/vaadin/tests/components/textfield/CompatibilityTextFieldShortcut.java
new file mode 100644 (file)
index 0000000..9ad6fbd
--- /dev/null
@@ -0,0 +1,49 @@
+package com.vaadin.tests.components.textfield;
+
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.event.ShortcutListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.Registration;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Notification;
+import com.vaadin.v7.ui.TextField;
+
+@SuppressWarnings("deprecation")
+public class CompatibilityTextFieldShortcut extends AbstractTestUI {
+
+    Registration listenerRegistration;
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        TextField textField = new TextField("F8 shortcut when focused");
+        ShortcutListener c = new ShortcutListener("ShortcutForMAMedRemarks",
+                ShortcutAction.KeyCode.F8, null) {
+
+            @Override
+            public void handleAction(Object sender, Object target) {
+                Notification.show("Received F8: " + textField.getValue());
+            }
+        };
+
+        textField.addFocusListener(e -> {
+            listenerRegistration = textField.addShortcutListener(c);
+            Label label = new Label("Focused");
+            label.addStyleName("focus-label");
+            addComponent(label);
+        });
+
+        textField.addBlurListener(e -> {
+            listenerRegistration.remove();
+        });
+
+        Label label = new Label(
+                "F8 will have an effect only if the following component is focused.");
+        Button button = new Button("focus");
+        button.addClickListener(event -> {
+            textField.focus();
+        });
+        addComponents(label, textField, button);
+    }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/textfield/CompatibilityTextFieldShortcutTest.java b/uitest/src/test/java/com/vaadin/tests/components/textfield/CompatibilityTextFieldShortcutTest.java
new file mode 100644 (file)
index 0000000..5c5d277
--- /dev/null
@@ -0,0 +1,35 @@
+package com.vaadin.tests.components.textfield;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.NotificationElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class CompatibilityTextFieldShortcutTest extends SingleBrowserTest {
+
+    private static final String TEXTFIELD_VALUE = "input";
+    private static final String NOTIFICATION = "Received F8: "
+            + TEXTFIELD_VALUE;
+
+    @Test
+    public void focusAndPressF8() {
+        openTestURL();
+
+        WebElement textFieldText = findElement(By.tagName("input"));
+        $(ButtonElement.class).first().click();
+
+        waitForElementVisible(By.className("focus-label"));
+        textFieldText.sendKeys(TEXTFIELD_VALUE);
+
+        textFieldText.sendKeys(Keys.F8);
+
+        assertEquals(NOTIFICATION,
+                $(NotificationElement.class).first().getCaption());
+    }
+}