]> source.dussan.org Git - vaadin-framework.git/commitdiff
(#9949) Flush focused connector on historyChange 14/514/8
authorMikael Grankvist <mgrankvi@vaadin.com>
Mon, 17 Dec 2012 06:35:53 +0000 (08:35 +0200)
committerVaadin Code Review <review@vaadin.com>
Wed, 19 Dec 2012 12:56:53 +0000 (12:56 +0000)
Change-Id: Ia0f41220a038a83fcbcbbe9feebe066cbc626e27

client/src/com/vaadin/client/ApplicationConnection.java
client/src/com/vaadin/client/ComponentConnector.java
client/src/com/vaadin/client/Util.java
client/src/com/vaadin/client/ui/AbstractComponentConnector.java
client/src/com/vaadin/client/ui/VUI.java
client/src/com/vaadin/client/ui/richtextarea/RichTextAreaConnector.java
client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java
uitest/src/com/vaadin/tests/components/uitest/BackButtonTest.java [new file with mode: 0644]

index 2e8387c5da4431d3a457839eb53a5c573b0b0e33..4a625383a5188c589b3cd73adbfd1771e4a1965f 100644 (file)
@@ -3271,4 +3271,30 @@ public class ApplicationConnection {
             GwtEvent.Type<H> type, H handler) {
         return eventBus.addHandler(type, handler);
     }
+
+    /**
+     * Calls {@link ComponentConnector#flush()} on the active connector. Does
+     * nothing if there is no active (focused) connector.
+     */
+    public void flushActiveConnector() {
+        ComponentConnector activeConnector = getActiveConnector();
+        if (activeConnector == null) {
+            return;
+        }
+        activeConnector.flush();
+    }
+
+    /**
+     * Gets the active connector for focused element in browser.
+     * 
+     * @return Connector for focused element or null.
+     */
+    private ComponentConnector getActiveConnector() {
+        Element focusedElement = Util.getFocusedElement();
+        if (focusedElement == null) {
+            return null;
+        }
+        return Util.getConnectorForElement(this, getUIConnector().getWidget(),
+                focusedElement);
+    }
 }
index 63e55153b6c4b6ed93c5f2823820fc62c061df0f..db3cc25c560c94491dfd1df549d7dc1f815dba0b 100644 (file)
@@ -127,4 +127,16 @@ public interface ComponentConnector extends ServerConnector {
      */
     public TooltipInfo getTooltipInfo(Element element);
 
+    /**
+     * Called for the active (focused) connector when a situation occurs that
+     * the focused connector might have buffered changes which need to be
+     * processed before other activity takes place.
+     * <p>
+     * This is currently called when the user changes the fragment using the
+     * back/forward button in the browser and allows the focused field to submit
+     * its value to the server before the fragment change event takes place.
+     * </p>
+     */
+    public void flush();
+
 }
index 0df8bfb90f42884f6d745a699e5cae0a80044b00..3d6f64d4d5222b4987bf68f8ed473071c40479c8 100644 (file)
@@ -1059,11 +1059,11 @@ public class Util {
     }
 
     /**
-     * Gets the currently focused element for Internet Explorer.
+     * Gets the currently focused element.
      * 
-     * @return The currently focused element
+     * @return The active element or null if no active element could be found.
      */
-    public native static Element getIEFocusedElement()
+    public native static Element getFocusedElement()
     /*-{
        if ($wnd.document.activeElement) {
            return $wnd.document.activeElement;
@@ -1072,6 +1072,17 @@ public class Util {
        return null;
      }-*/
     ;
+    
+    /**
+     * Gets the currently focused element for Internet Explorer.
+     * 
+     * @return The currently focused element
+     * @deprecated Use #getFocusedElement instead
+     */
+    @Deprecated
+    public static Element getIEFocusedElement() {
+        return getFocusedElement();
+    }
 
     /**
      * Kind of stronger version of isAttached(). In addition to std isAttached,
index f8088d63a2f88c6d23b0f04e8c3ef9b7b08b8cb4..2c599743e4d19cf02f2bd3276cffab328b772e73 100644 (file)
@@ -426,4 +426,13 @@ public abstract class AbstractComponentConnector extends AbstractConnector
     protected String getIcon() {
         return getResourceUrl(ComponentConstants.ICON_RESOURCE);
     }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.vaadin.client.ComponentConnector#flush()
+     */
+    public void flush() {
+        // No generic implementation. Override if needed
+    }
 }
index cbfbda813e10b9f5c965d64420edd1acd835da3b..a21397c060e55f6a5874750c07e00f8935bb64cc 100644 (file)
@@ -129,8 +129,10 @@ public class VUI extends SimplePanel implements ResizeHandler,
             String newFragment = event.getValue();
 
             // Send the location to the server if the fragment has changed
+            // and flush active connectors in UI.
             if (!newFragment.equals(currentFragment) && connection != null) {
                 currentFragment = newFragment;
+                connection.flushActiveConnector();
                 connection.updateVariable(id, UIConstants.LOCATION_VARIABLE,
                         Window.Location.getHref(), true);
             }
index afcf4794993868421ac3f3e80b5a08d61801334c..8875fc421baa04d06a05965891448ecc8cb98263 100644 (file)
@@ -75,12 +75,17 @@ public class RichTextAreaConnector extends AbstractFieldConnector implements
 
     @Override
     public void onBeforeShortcutAction(Event e) {
-        getWidget().synchronizeContentToServer();
+        flush();
     }
 
     @Override
     public VRichTextArea getWidget() {
         return (VRichTextArea) super.getWidget();
+    }
+
+    @Override
+    public void flush() {
+        getWidget().synchronizeContentToServer();
     };
 
 }
index c653b06cf9a6fafe82325ea9ce500dc98e8bca89..bedcd5f9366216a83b7f4d16e61454e87615e32d 100644 (file)
@@ -114,6 +114,11 @@ public class TextFieldConnector extends AbstractFieldConnector implements
 
     @Override
     public void onBeforeShortcutAction(Event e) {
+        flush();
+    }
+
+    @Override
+    public void flush() {
         getWidget().valueChange(false);
     }
 
diff --git a/uitest/src/com/vaadin/tests/components/uitest/BackButtonTest.java b/uitest/src/com/vaadin/tests/components/uitest/BackButtonTest.java
new file mode 100644 (file)
index 0000000..d5bac0d
--- /dev/null
@@ -0,0 +1,117 @@
+package com.vaadin.tests.components.uitest;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.server.Page.UriFragmentChangedEvent;
+import com.vaadin.server.Page.UriFragmentChangedListener;
+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.Label;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+public class BackButtonTest extends AbstractTestUI {
+
+    private VerticalLayout layout;
+
+    private String value = "Hello";
+    private Page1 p1;
+    private Page2 p2;
+
+    @Override
+    public void setup(VaadinRequest request) {
+        getPage().setUriFragment("page1");
+
+        layout = new VerticalLayout();
+        addComponent(layout);
+
+        p1 = new Page1();
+        addComponent(p1);
+
+        p2 = new Page2();
+        getPage().addUriFragmentChangedListener(
+                new UriFragmentChangedListener() {
+
+                    @Override
+                    public void uriFragmentChanged(UriFragmentChangedEvent event) {
+                        String f = event.getUriFragment();
+                        if ("page2".equals(f)) {
+                            showPage2();
+                        }
+
+                        if ("page1".equals(f)) {
+                            showPage1();
+                        }
+                    }
+                });
+    }
+
+    class Page1 extends VerticalLayout {
+        Label l = new Label();
+
+        public Page1() {
+            setSizeFull();
+            l.setCaption("Data from Page 1 : " + value);
+            addComponent(l);
+
+            Button b = new Button("Go to Page 2", new Button.ClickListener() {
+                public void buttonClick(ClickEvent event) {
+                    l.setCaption("Data from Page 1 : " + value);
+                    getPage().setUriFragment("page2");
+                }
+            });
+            addComponent(b);
+        }
+    }
+
+    private void showPage2() {
+        removeComponent(p1);
+        p2.f.setValue("");
+        addComponent(p2);
+    }
+
+    private void showPage1() {
+        removeComponent(p2);
+        addComponent(p1);
+    }
+
+    class Page2 extends VerticalLayout {
+        private final TextField f = new TextField();
+
+        public Page2() {
+            setSizeFull();
+
+            addComponent(f);
+            f.addValueChangeListener(new ValueChangeListener() {
+                public void valueChange(ValueChangeEvent event) {
+                    value = f.getValue();
+                    p1.l.setCaption("Data from Page 2 : " + value);
+                }
+            });
+
+            Button b = new Button("Go Back", new Button.ClickListener() {
+                public void buttonClick(ClickEvent event) {
+                    getPage().setUriFragment("page1");
+                }
+            });
+            addComponent(b);
+            addComponent(new Label(
+                    "Go back with the back button without creating a blur event on the text field. Text should transfer to page1 label."));
+        }
+
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 9949;
+    }
+
+    @Override
+    protected String getTestDescription() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}