@@ -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, |
@@ -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); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |