]> source.dussan.org Git - vaadin-framework.git/commitdiff
Send browser window resizes if there is a listener (#10055)
authorHenri Sara <hesara@vaadin.com>
Fri, 17 May 2013 06:10:31 +0000 (09:10 +0300)
committerHenri Sara <hesara@vaadin.com>
Fri, 17 May 2013 06:10:31 +0000 (09:10 +0300)
This also introduces PageState, which is at the moment a part of
UIState.

Change-Id: I4f927e6b8217fa789d83ce5e0d8254b141f485c7

client/src/com/vaadin/client/ui/ui/UIConnector.java
server/src/com/vaadin/server/Page.java
server/src/com/vaadin/ui/UI.java
server/tests/src/com/vaadin/server/VaadinSessionTest.java
shared/src/com/vaadin/shared/ui/ui/PageState.java [new file with mode: 0644]
shared/src/com/vaadin/shared/ui/ui/UIState.java

index 079e133438132588c3709820e6785b2becc4b15f..67cba1d3ea79898c7183fe2d0d2d5bccc02c97be 100644 (file)
@@ -68,6 +68,7 @@ import com.vaadin.shared.ui.ComponentStateUtil;
 import com.vaadin.shared.ui.Connect;
 import com.vaadin.shared.ui.Connect.LoadStyle;
 import com.vaadin.shared.ui.ui.PageClientRpc;
+import com.vaadin.shared.ui.ui.PageState;
 import com.vaadin.shared.ui.ui.ScrollClientRpc;
 import com.vaadin.shared.ui.ui.UIClientRpc;
 import com.vaadin.shared.ui.ui.UIConstants;
@@ -138,7 +139,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
                 getRpcProxy(UIServerRpc.class).resize(event.getHeight(),
                         event.getWidth(), Window.getClientWidth(),
                         Window.getClientHeight());
-                if (getState().immediate) {
+                if (getState().immediate || getPageState().hasResizeListeners) {
                     getConnection().sendPendingVariableChanges();
                 }
             }
@@ -504,6 +505,23 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
         return (UIState) super.getState();
     }
 
+    /**
+     * Returns the state of the Page associated with the UI.
+     * <p>
+     * Note that state is considered an internal part of the connector. You
+     * should not rely on the state object outside of the connector who owns it.
+     * If you depend on the state of other connectors you should use their
+     * public API instead of their state object directly. The page state might
+     * not be an independent state object but can be embedded in UI state.
+     * </p>
+     * 
+     * @since 7.1
+     * @return state object of the page
+     */
+    public PageState getPageState() {
+        return getState().pageState;
+    }
+
     @Override
     public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) {
         ComponentConnector oldChild = null;
index a7e0f7dcb3d7d77deae365496bd845f3ad5cae77..d4c16fe7f7f7a9136bc0912c056acdfc2890001d 100644 (file)
@@ -30,7 +30,9 @@ import java.util.Map;
 import com.vaadin.event.EventRouter;
 import com.vaadin.shared.ui.BorderStyle;
 import com.vaadin.shared.ui.ui.PageClientRpc;
+import com.vaadin.shared.ui.ui.PageState;
 import com.vaadin.shared.ui.ui.UIConstants;
+import com.vaadin.shared.ui.ui.UIState;
 import com.vaadin.ui.JavaScript;
 import com.vaadin.ui.LegacyWindow;
 import com.vaadin.ui.Link;
@@ -220,7 +222,7 @@ public class Page implements Serializable {
         }
     }
 
-    private static final Method BROWSWER_RESIZE_METHOD = ReflectTools
+    private static final Method BROWSER_RESIZE_METHOD = ReflectTools
             .findMethod(BrowserWindowResizeListener.class,
                     "browserWindowResized", BrowserWindowResizeEvent.class);
 
@@ -417,8 +419,11 @@ public class Page implements Serializable {
      */
     private URI location;
 
-    public Page(UI uI) {
+    private final PageState state;
+
+    public Page(UI uI, PageState state) {
         this.uI = uI;
+        this.state = state;
     }
 
     private void addListener(Class<?> eventType, Object target, Method method) {
@@ -604,20 +609,27 @@ public class Page implements Serializable {
     }
 
     /**
-     * Adds a new {@link BrowserWindowResizeListener} to this uI. The listener
-     * will be notified whenever the browser window within which this uI resides
+     * Adds a new {@link BrowserWindowResizeListener} to this UI. The listener
+     * will be notified whenever the browser window within which this UI resides
      * is resized.
+     * <p>
+     * In most cases, the UI should be in lazy resize mode when using browser
+     * window resize listeners. Otherwise, a large number of events can be
+     * received while a resize is being performed. Use
+     * {@link UI#setResizeLazy(boolean)}.
+     * </p>
      * 
      * @param resizeListener
      *            the listener to add
      * 
      * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent)
-     * @see #setResizeLazy(boolean)
+     * @see UI#setResizeLazy(boolean)
      */
     public void addBrowserWindowResizeListener(
             BrowserWindowResizeListener resizeListener) {
         addListener(BrowserWindowResizeEvent.class, resizeListener,
-                BROWSWER_RESIZE_METHOD);
+                BROWSER_RESIZE_METHOD);
+        getState(true).hasResizeListeners = true;
     }
 
     /**
@@ -639,7 +651,9 @@ public class Page implements Serializable {
     public void removeBrowserWindowResizeListener(
             BrowserWindowResizeListener resizeListener) {
         removeListener(BrowserWindowResizeEvent.class, resizeListener,
-                BROWSWER_RESIZE_METHOD);
+                BROWSER_RESIZE_METHOD);
+        getState(true).hasResizeListeners = eventRouter
+                .hasListeners(BrowserWindowResizeEvent.class);
     }
 
     /**
@@ -1038,4 +1052,29 @@ public class Page implements Serializable {
         uI.getRpcProxy(PageClientRpc.class).reload();
     }
 
+    /**
+     * Returns the page state.
+     * <p>
+     * The page state is transmitted to UIConnector together with
+     * {@link UIState} rather than as an individual entity.
+     * </p>
+     * <p>
+     * The state should be considered an internal detail of Page. Classes
+     * outside of Page should not access it directly but only through public
+     * APIs provided by Page.
+     * </p>
+     * 
+     * @since 7.1
+     * @param markAsDirty
+     *            true to mark the state as dirty
+     * @return PageState object that can be read in any case and modified if
+     *         markAsDirty is true
+     */
+    protected PageState getState(boolean markAsDirty) {
+        if (markAsDirty) {
+            uI.markAsDirty();
+        }
+        return state;
+    }
+
 }
index 6433bebbe48a616c2e63afd9095b730b148896d7..2e9570fa098c0e7c3ab6adbc4b1dab5407f43741 100644 (file)
@@ -117,7 +117,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
     /** Identifies the click event */
     private ConnectorTracker connectorTracker = new ConnectorTracker(this);
 
-    private Page page = new Page(this);
+    private Page page = new Page(this, getState(false).pageState);
 
     private LoadingIndicatorConfiguration loadingIndicatorConfiguration = new LoadingIndicatorConfigurationImpl(
             this);
@@ -686,10 +686,16 @@ public abstract class UI extends AbstractSingleComponentContainer implements
 
     /**
      * Should resize operations be lazy, i.e. should there be a delay before
-     * layout sizes are recalculated. Speeds up resize operations in slow UIs
-     * with the penalty of slightly decreased usability.
+     * layout sizes are recalculated and resize events are sent to the server.
+     * Speeds up resize operations in slow UIs with the penalty of slightly
+     * decreased usability.
      * <p>
      * Default value: <code>false</code>
+     * </p>
+     * <p>
+     * When there are active window resize listeners, lazy resize mode should be
+     * used to avoid a large number of events during resize.
+     * </p>
      * 
      * @param resizeLazy
      *            true to use a delay before recalculating sizes, false to
index 8f471afd46ece7bc479a8b0641d624daaf797c1d..61a1581a6fbf7195ff5038ec2b1fcd565bd39613 100644 (file)
@@ -74,7 +74,7 @@ public class VaadinSessionTest {
         session.storeInSession(mockService, mockWrappedSession);
 
         ui = new UI() {
-            Page page = new Page(this) {
+            Page page = new Page(this, getState(false).pageState) {
                 @Override
                 public void init(VaadinRequest request) {
                 }
diff --git a/shared/src/com/vaadin/shared/ui/ui/PageState.java b/shared/src/com/vaadin/shared/ui/ui/PageState.java
new file mode 100644 (file)
index 0000000..d7c4268
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2013 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
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.shared.ui.ui;
+
+import java.io.Serializable;
+
+import com.vaadin.server.Page;
+
+/**
+ * The shared state of a {@link Page}.
+ * 
+ * Note that at the moment this is not a stand-alone state class but embedded in
+ * {@link UIState}. This might change in the future.
+ * 
+ * @since 7.1
+ */
+public class PageState implements Serializable {
+    /**
+     * True if the page has browser window resize listeners.
+     */
+    public boolean hasResizeListeners = false;
+}
\ No newline at end of file
index e8be9d674cd18f82bda04f4522318a3b6b966993..2565de59df75d926924963c70c6fe53479ef7992 100644 (file)
@@ -42,6 +42,11 @@ public class UIState extends TabIndexState {
         public int maxWidth = 500;
     }
 
+    /**
+     * State related to the {@link Page} class.
+     */
+    public PageState pageState = new PageState();
+
     {
         primaryStyleName = "v-ui";
         // Default is 1 for legacy reasons