]> source.dussan.org Git - vaadin-framework.git/commitdiff
Flush the active connector before executing a shortcut action
authorArtur Signell <artur@vaadin.com>
Wed, 17 Aug 2016 11:13:23 +0000 (14:13 +0300)
committerVaadin Code Review <review@vaadin.com>
Wed, 17 Aug 2016 12:51:26 +0000 (12:51 +0000)
This change removes the old BeforeShortcutActionListener which was
introduced before ComponentConnector.flush() to resolve the same problem.

Change-Id: I79dc25bc0d2b98ce708f64b4fad950b13f6f132b

client/src/main/java/com/vaadin/client/legacy/ui/textfield/LegacyTextFieldConnector.java
client/src/main/java/com/vaadin/client/ui/ShortcutActionHandler.java
client/src/main/java/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java
client/src/main/java/com/vaadin/client/ui/window/WindowConnector.java

index d86ccf8db9a3bc6097edb18d7b8cbf0e7c9767e6..c91ba13531c54dfbd33d0c1be245261801c100cf 100644 (file)
@@ -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);
index d76408e1b89168a134c9920418474d73cd3555cd..aa11d525027b480052a9180eca74f6633e31846b 100644 (file)
@@ -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<ShortcutAction> actions = new ArrayList<ShortcutAction>();
     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.
-     * <p>
-     * 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.
-     *
-     * <p>
-     * 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) {
index bcf61a9338989473ff767dd0dfa47522021c57bb..d709f99d2f87ee46db5225b7d82c1b09ce407e2d 100644 (file)
@@ -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;
index 8ddf099e288e681c33caa768ad48890f324132a7..f13bf3a3ba9d86f7edf9a3719e972814f2c3ff04 100644 (file)
@@ -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());
 
     }
 }