From: Artur Signell Date: Wed, 17 Aug 2016 11:13:23 +0000 (+0300) Subject: Flush the active connector before executing a shortcut action X-Git-Tag: 8.0.0.alpha1~157 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=99e90f8c563f2e577777f7e9c9c481427270f6e3;p=vaadin-framework.git Flush the active connector before executing a shortcut action This change removes the old BeforeShortcutActionListener which was introduced before ComponentConnector.flush() to resolve the same problem. Change-Id: I79dc25bc0d2b98ce708f64b4fad950b13f6f132b --- diff --git a/client/src/main/java/com/vaadin/client/legacy/ui/textfield/LegacyTextFieldConnector.java b/client/src/main/java/com/vaadin/client/legacy/ui/textfield/LegacyTextFieldConnector.java index d86ccf8db9..c91ba13531 100644 --- a/client/src/main/java/com/vaadin/client/legacy/ui/textfield/LegacyTextFieldConnector.java +++ b/client/src/main/java/com/vaadin/client/legacy/ui/textfield/LegacyTextFieldConnector.java @@ -1,12 +1,12 @@ /* * 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 @@ -18,14 +18,12 @@ package com.vaadin.client.legacy.ui.textfield; import com.google.gwt.core.client.Scheduler; import com.google.gwt.user.client.Command; -import com.google.gwt.user.client.Event; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.Paintable; import com.vaadin.client.UIDL; import com.vaadin.client.Util; import com.vaadin.client.legacy.ui.VLegacyTextField; import com.vaadin.client.ui.AbstractFieldConnector; -import com.vaadin.client.ui.ShortcutActionHandler.BeforeShortcutActionListener; import com.vaadin.legacy.ui.LegacyTextField; import com.vaadin.shared.legacy.ui.textfield.LegacyAbstractTextFieldState; import com.vaadin.shared.legacy.ui.textfield.LegacyTextFieldConstants; @@ -34,8 +32,8 @@ import com.vaadin.shared.ui.Connect.LoadStyle; @Deprecated @Connect(value = LegacyTextField.class, loadStyle = LoadStyle.EAGER) -public class LegacyTextFieldConnector extends AbstractFieldConnector implements - Paintable, BeforeShortcutActionListener { +public class LegacyTextFieldConnector extends AbstractFieldConnector + implements Paintable { @Override public LegacyAbstractTextFieldState getState() { @@ -60,14 +58,14 @@ public class LegacyTextFieldConnector extends AbstractFieldConnector implements getWidget().listenTextChangeEvents = hasEventListener("ie"); if (getWidget().listenTextChangeEvents) { - getWidget().textChangeEventMode = uidl - .getStringAttribute(LegacyTextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE); + getWidget().textChangeEventMode = uidl.getStringAttribute( + LegacyTextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE); if (getWidget().textChangeEventMode .equals(LegacyTextFieldConstants.TEXTCHANGE_MODE_EAGER)) { getWidget().textChangeEventTimeout = 1; } else { - getWidget().textChangeEventTimeout = uidl - .getIntAttribute(LegacyTextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT); + getWidget().textChangeEventTimeout = uidl.getIntAttribute( + LegacyTextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT); if (getWidget().textChangeEventTimeout < 1) { // Sanitize and allow lazy/timeout with timeout set to 0 to // work as eager @@ -91,7 +89,8 @@ public class LegacyTextFieldConnector extends AbstractFieldConnector implements * force updating if not focused. Lost focus issue appeared in (#15144) */ if (!(Util.getFocusedElement() == getWidget().getElement()) - || !uidl.getBooleanAttribute(LegacyTextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS) + || !uidl.getBooleanAttribute( + LegacyTextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS) || getWidget().valueBeforeEdit == null || !text.equals(getWidget().valueBeforeEdit)) { getWidget().updateFieldContent(text); @@ -117,11 +116,6 @@ public class LegacyTextFieldConnector extends AbstractFieldConnector implements return (VLegacyTextField) super.getWidget(); } - @Override - public void onBeforeShortcutAction(Event e) { - flush(); - } - @Override public void flush() { getWidget().valueChange(false); diff --git a/client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java b/client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java index d76408e1b8..aa11d52502 100644 --- a/client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java +++ b/client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java @@ -28,7 +28,6 @@ import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.KeyboardListener; import com.google.gwt.user.client.ui.KeyboardListenerCollection; import com.vaadin.client.ApplicationConnection; -import com.vaadin.client.BrowserInfo; import com.vaadin.client.ComponentConnector; import com.vaadin.client.UIDL; import com.vaadin.client.Util; @@ -59,25 +58,6 @@ public class ShortcutActionHandler { ShortcutActionHandler getShortcutActionHandler(); } - /** - * A focusable {@link ComponentConnector} implementing this interface will - * be notified before shortcut actions are handled if it will be the target - * of the action (most commonly means it is the focused component during the - * keyboard combination is triggered by the user). - */ - public interface BeforeShortcutActionListener extends ComponentConnector { - /** - * This method is called by ShortcutActionHandler before firing the - * shortcut if the Paintable is currently focused (aka the target of the - * shortcut action). Eg. a field can update its possibly changed value - * to the server before shortcut action is fired. - * - * @param e - * the event that triggered the shortcut action - */ - public void onBeforeShortcutAction(Event e); - } - private final ArrayList actions = new ArrayList(); private ApplicationConnection client; private String paintableId; @@ -155,21 +135,10 @@ public class ShortcutActionHandler { event.preventDefault(); /* - * The target component might have unpublished changes, try to + * The focused component might have unpublished changes, try to * synchronize them before firing shortcut action. */ - if (finalTarget instanceof BeforeShortcutActionListener) { - ((BeforeShortcutActionListener) finalTarget) - .onBeforeShortcutAction(event); - } else { - shakeTarget(et); - Scheduler.get().scheduleDeferred(new Command() { - @Override - public void execute() { - shakeTarget(et); - } - }); - } + client.flushActiveConnector(); Scheduler.get().scheduleDeferred(new Command() { @Override @@ -183,37 +152,6 @@ public class ShortcutActionHandler { }); } - /** - * We try to fire value change in the component the key combination was - * typed. Eg. textfield may contain newly typed text that is expected to be - * sent to server. This is done by removing focus and then returning it - * immediately back to target element. - *

- * This is practically a hack and should be replaced with an interface - * {@link BeforeShortcutActionListener} via widgets could be notified when - * they should fire value change. Big task for TextFields, DateFields and - * various selects. - * - *

- * TODO separate opera impl with generator - */ - private static void shakeTarget(final Element e) { - blur(e); - if (BrowserInfo.get().isOpera()) { - // will mess up with focus and blur event if the focus is not - // deferred. Will cause a small flickering, so not doing it for all - // browsers. - Scheduler.get().scheduleDeferred(new Command() { - @Override - public void execute() { - focus(e); - } - }); - } else { - focus(e); - } - } - private static native void blur(Element e) /*-{ if(e.blur) { diff --git a/client/src/main/java/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java b/client/src/main/java/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java index bcf61a9338..d709f99d2f 100644 --- a/client/src/main/java/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java @@ -1,12 +1,12 @@ /* * 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 @@ -17,12 +17,10 @@ package com.vaadin.client.ui.richtextarea; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; -import com.google.gwt.user.client.Event; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.Paintable; import com.vaadin.client.UIDL; import com.vaadin.client.ui.AbstractFieldConnector; -import com.vaadin.client.ui.ShortcutActionHandler.BeforeShortcutActionListener; import com.vaadin.client.ui.SimpleManagedLayout; import com.vaadin.client.ui.VRichTextArea; import com.vaadin.shared.ui.Connect; @@ -32,8 +30,8 @@ import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.RichTextArea; @Connect(value = RichTextArea.class, loadStyle = LoadStyle.LAZY) -public class RichTextAreaConnector extends AbstractFieldConnector implements - Paintable, BeforeShortcutActionListener, SimpleManagedLayout { +public class RichTextAreaConnector extends AbstractFieldConnector + implements Paintable, SimpleManagedLayout { /* * Last value received from the server @@ -80,8 +78,8 @@ public class RichTextAreaConnector extends AbstractFieldConnector implements getWidget().setEnabled(isEnabled()); getWidget().setReadOnly(isReadOnly()); getWidget().immediate = getState().immediate; - int newMaxLength = uidl.hasAttribute("maxLength") ? uidl - .getIntAttribute("maxLength") : -1; + int newMaxLength = uidl.hasAttribute("maxLength") + ? uidl.getIntAttribute("maxLength") : -1; if (newMaxLength >= 0) { if (getWidget().maxLength == -1) { getWidget().keyPressHandler = getWidget().rta @@ -100,11 +98,6 @@ public class RichTextAreaConnector extends AbstractFieldConnector implements } - @Override - public void onBeforeShortcutAction(Event e) { - flush(); - } - @Override public VRichTextArea getWidget() { return (VRichTextArea) super.getWidget(); @@ -125,10 +118,10 @@ public class RichTextAreaConnector extends AbstractFieldConnector implements @Override public void layout() { if (!isUndefinedHeight()) { - int rootElementInnerHeight = getLayoutManager().getInnerHeight( - getWidget().getElement()); - int formatterHeight = getLayoutManager().getOuterHeight( - getWidget().formatter.getElement()); + int rootElementInnerHeight = getLayoutManager() + .getInnerHeight(getWidget().getElement()); + int formatterHeight = getLayoutManager() + .getOuterHeight(getWidget().formatter.getElement()); int editorHeight = rootElementInnerHeight - formatterHeight; if (editorHeight < 0) { editorHeight = 0; diff --git a/client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java b/client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java index 8ddf099e28..f13bf3a3ba 100644 --- a/client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java @@ -1,12 +1,12 @@ /* * 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 @@ -31,7 +31,6 @@ import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.DoubleClickEvent; import com.google.gwt.event.dom.client.DoubleClickHandler; import com.google.gwt.user.client.DOM; -import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Window; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; @@ -47,7 +46,6 @@ import com.vaadin.client.ui.AbstractSingleComponentContainerConnector; import com.vaadin.client.ui.ClickEventHandler; import com.vaadin.client.ui.PostLayoutListener; import com.vaadin.client.ui.ShortcutActionHandler; -import com.vaadin.client.ui.ShortcutActionHandler.BeforeShortcutActionListener; import com.vaadin.client.ui.SimpleManagedLayout; import com.vaadin.client.ui.VWindow; import com.vaadin.client.ui.layout.MayScrollChildren; @@ -59,9 +57,8 @@ import com.vaadin.shared.ui.window.WindowState; @Connect(value = com.vaadin.ui.Window.class) public class WindowConnector extends AbstractSingleComponentContainerConnector - implements Paintable, BeforeShortcutActionListener, - SimpleManagedLayout, PostLayoutListener, MayScrollChildren, - WindowMoveHandler { + implements Paintable, SimpleManagedLayout, PostLayoutListener, + MayScrollChildren, WindowMoveHandler { private Node windowClone; @@ -73,8 +70,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector } }; - abstract class WindowEventHandler implements ClickHandler, - DoubleClickHandler { + abstract class WindowEventHandler + implements ClickHandler, DoubleClickHandler { } private WindowEventHandler maximizeRestoreClickHandler = new WindowEventHandler() { @@ -184,19 +181,14 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector // NOP, window has own caption, layout caption not rendered } - @Override - public void onBeforeShortcutAction(Event e) { - // NOP, nothing to update just avoid workaround ( causes excess - // blur/focus ) - } - @Override public VWindow getWidget() { return (VWindow) super.getWidget(); } @Override - public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) { + public void onConnectorHierarchyChange( + ConnectorHierarchyChangeEvent event) { // We always have 1 child, unless the child is hidden getWidget().contentPanel.setWidget(getContentWidget()); @@ -246,8 +238,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector int minHeight = footerHeight + headerHeight; getWidget().getElement().getStyle().setPropertyPx("minWidth", minWidth); - getWidget().getElement().getStyle() - .setPropertyPx("minHeight", minHeight); + getWidget().getElement().getStyle().setPropertyPx("minHeight", + minHeight); /* * Must set absolute position if the child has relative height and @@ -289,8 +281,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector VWindow window = getWidget(); if (!window.isAttached()) { - Logger.getLogger(WindowConnector.class.getName()).warning( - "Called postLayout to detached Window."); + Logger.getLogger(WindowConnector.class.getName()) + .warning("Called postLayout to detached Window."); return; } if (window.centered && getState().windowMode != WindowMode.MAXIMIZED) { @@ -311,8 +303,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector // have to replace them with stubs in the clone. And we can't just // erase them, because there are corresponding player widgets to // animate - windowClone = cloneNodeFilteringMedia(getWidget().getElement() - .getFirstChild()); + windowClone = cloneNodeFilteringMedia( + getWidget().getElement().getFirstChild()); } } @@ -328,7 +320,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector } Element newEl = DOM.createElement(old.getTagName()); if (old.hasAttribute("controls")) { - newEl.setAttribute("controls", old.getAttribute("controls")); + newEl.setAttribute("controls", + old.getAttribute("controls")); } if (old.hasAttribute("style")) { newEl.setAttribute("style", old.getAttribute("style")); @@ -373,10 +366,11 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector window.resizeLazy = state.resizeLazy; - window.setDraggable(state.draggable - && state.windowMode == WindowMode.NORMAL); + window.setDraggable( + state.draggable && state.windowMode == WindowMode.NORMAL); - window.updateMaximizeRestoreClassName(state.resizable, state.windowMode); + window.updateMaximizeRestoreClassName(state.resizable, + state.windowMode); // Caption must be set before required header size is measured. If // the caption attribute is missing the caption should be cleared. @@ -394,7 +388,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector window.setTabStopEnabled(getState().assistiveTabStop); window.setTabStopTopAssistiveText(getState().assistiveTabStopTopText); - window.setTabStopBottomAssistiveText(getState().assistiveTabStopBottomText); + window.setTabStopBottomAssistiveText( + getState().assistiveTabStopBottomText); clickEventHandler.handleEventHandlerRegistration(); @@ -459,14 +454,15 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector WindowState state = getState(); // update draggable on widget - window.setDraggable(state.draggable - && state.windowMode == WindowMode.NORMAL); + window.setDraggable( + state.draggable && state.windowMode == WindowMode.NORMAL); // update resizable on widget - window.setResizable(state.resizable - && state.windowMode == WindowMode.NORMAL); + window.setResizable( + state.resizable && state.windowMode == WindowMode.NORMAL); updateComponentSize(); updateWindowPosition(); - window.updateMaximizeRestoreClassName(state.resizable, state.windowMode); + window.updateMaximizeRestoreClassName(state.resizable, + state.windowMode); window.updateContentsSize(); } @@ -483,8 +479,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector VWindow window = getWidget(); window.bringToFront(); - getRpcProxy(WindowServerRpc.class).windowModeChanged( - state.windowMode); + getRpcProxy(WindowServerRpc.class) + .windowModeChanged(state.windowMode); } } @@ -508,8 +504,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector @Override public void onWindowMove(WindowMoveEvent event) { - RpcProxy.create(WindowServerRpc.class, this).windowMoved( - event.getNewX(), event.getNewY()); + RpcProxy.create(WindowServerRpc.class, this) + .windowMoved(event.getNewX(), event.getNewY()); } }