]> source.dussan.org Git - vaadin-framework.git/commitdiff
Manage fix for overflow: auto in LayoutManager (#8615)
authorLeif Åstrand <leif@vaadin.com>
Wed, 4 Apr 2012 09:10:10 +0000 (12:10 +0300)
committerLeif Åstrand <leif@vaadin.com>
Wed, 4 Apr 2012 09:10:10 +0000 (12:10 +0300)
14 files changed:
src/com/vaadin/terminal/gwt/client/BrowserInfo.java
src/com/vaadin/terminal/gwt/client/LayoutManager.java
src/com/vaadin/terminal/gwt/client/Util.java
src/com/vaadin/terminal/gwt/client/ui/AccordionConnector.java
src/com/vaadin/terminal/gwt/client/ui/PanelConnector.java
src/com/vaadin/terminal/gwt/client/ui/RootConnector.java
src/com/vaadin/terminal/gwt/client/ui/TabsheetConnector.java
src/com/vaadin/terminal/gwt/client/ui/VAccordion.java
src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java
src/com/vaadin/terminal/gwt/client/ui/VTabsheetPanel.java
src/com/vaadin/terminal/gwt/client/ui/VView.java
src/com/vaadin/terminal/gwt/client/ui/VWindow.java
src/com/vaadin/terminal/gwt/client/ui/WindowConnector.java
src/com/vaadin/terminal/gwt/client/ui/layout/RequiresOverflowAutoFix.java [new file with mode: 0644]

index 50a59e49753e5f8022b7340de3dbb067630f1970..ef1dc481b1a39205cf17c0a1a934b27db5e45eaa 100644 (file)
@@ -300,4 +300,16 @@ public class BrowserInfo {
         return touchDevice;
     }
 
+    /**
+     * Indicates whether the browser might require juggling to properly update
+     * sizes inside elements with overflow: auto.
+     * 
+     * @return <code>true</code> if the browser requires the workaround,
+     *         otherwise <code>false</code>
+     */
+    public boolean requiresOverflowAutoFix() {
+        return (getWebkitVersion() > 0 || getOperaVersion() >= 11)
+                && Util.getNativeScrollbarSize() > 0;
+    }
+
 }
index f7c5570072e735e9e0a4b934abb4473e7da27700..d772f7cb3735681a3755c6efcabca3a64baadde9 100644 (file)
@@ -12,12 +12,14 @@ import java.util.Set;
 import com.google.gwt.core.client.Duration;
 import com.google.gwt.core.client.JsArrayString;
 import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style.Unit;
 import com.vaadin.terminal.gwt.client.MeasuredSize.MeasureResult;
 import com.vaadin.terminal.gwt.client.ui.ManagedLayout;
 import com.vaadin.terminal.gwt.client.ui.PostLayoutListener;
 import com.vaadin.terminal.gwt.client.ui.SimpleManagedLayout;
 import com.vaadin.terminal.gwt.client.ui.VNotification;
 import com.vaadin.terminal.gwt.client.ui.layout.LayoutDependencyTree;
+import com.vaadin.terminal.gwt.client.ui.layout.RequiresOverflowAutoFix;
 
 public class LayoutManager {
     private static final String LOOP_ABORT_MESSAGE = "Aborting layout after 100 passes. This would probably be an infinite loop.";
@@ -30,6 +32,8 @@ public class LayoutManager {
     private final Collection<ManagedLayout> needsHorizontalLayout = new HashSet<ManagedLayout>();
     private final Collection<ManagedLayout> needsVerticalLayout = new HashSet<ManagedLayout>();
 
+    private final Collection<ComponentConnector> pendingOverflowFixes = new HashSet<ComponentConnector>();
+
     public void setConnection(ApplicationConnection connection) {
         if (this.connection != null) {
             throw new RuntimeException(
@@ -272,6 +276,26 @@ public class LayoutManager {
 
     private int measureConnectors(LayoutDependencyTree layoutDependencyTree,
             boolean measureAll) {
+        if (!pendingOverflowFixes.isEmpty()) {
+            Duration duration = new Duration();
+            for (ComponentConnector componentConnector : pendingOverflowFixes) {
+                componentConnector.getWidget().getElement().getParentElement()
+                        .getStyle().setTop(1, Unit.PX);
+            }
+            for (ComponentConnector componentConnector : pendingOverflowFixes) {
+                componentConnector.getWidget().getElement().getParentElement()
+                        .getOffsetHeight();
+            }
+            for (ComponentConnector componentConnector : pendingOverflowFixes) {
+                componentConnector.getWidget().getElement().getParentElement()
+                        .getStyle().setTop(0, Unit.PX);
+                layoutDependencyTree.setNeedsMeasure(componentConnector, true);
+            }
+            VConsole.log("Did overflow fix for " + pendingOverflowFixes.size()
+                    + " elements  in " + duration.elapsedMillis() + " ms");
+            pendingOverflowFixes.clear();
+        }
+
         int measureCount = 0;
         if (measureAll) {
             ComponentConnector[] connectors = ConnectorMap.get(connection)
@@ -306,6 +330,9 @@ public class LayoutManager {
         MeasureResult measureResult = measuredAndUpdate(element, measuredSize,
                 layoutDependencyTree);
 
+        if (measureResult.isChanged()) {
+            doOverflowAutoFix(connector);
+        }
         if (measureResult.isHeightChanged()) {
             layoutDependencyTree.markHeightAsChanged(connector);
         }
@@ -314,6 +341,15 @@ public class LayoutManager {
         }
     }
 
+    private void doOverflowAutoFix(ComponentConnector connector) {
+        if (connector.getParent() instanceof RequiresOverflowAutoFix
+                && BrowserInfo.get().requiresOverflowAutoFix()
+                && !"absolute".equals(connector.getWidget().getElement()
+                        .getStyle().getPosition())) {
+            pendingOverflowFixes.add(connector);
+        }
+    }
+
     private void measureNonPaintables(LayoutDependencyTree layoutDependencyTree) {
         for (Element element : nonPaintableElements) {
             MeasuredSize measuredSize = getMeasuredSize(element, null);
@@ -455,6 +491,7 @@ public class LayoutManager {
 
         if (heightChanged) {
             currentDependencyTree.markHeightAsChanged(component);
+            doOverflowAutoFix(component);
         }
         currentDependencyTree.setNeedsVerticalMeasure(component, false);
     }
@@ -494,6 +531,7 @@ public class LayoutManager {
 
         if (widthChanged) {
             currentDependencyTree.markWidthAsChanged(component);
+            doOverflowAutoFix(component);
         }
         currentDependencyTree.setNeedsHorizontalMeasure(component, false);
     }
index faaad8c7d25c670c8b72a0d098489fd9427d1e07..374d2103794fb291fae831c847d06737af7ee231 100644 (file)
@@ -433,8 +433,7 @@ public class Util {
     public static void runWebkitOverflowAutoFix(final Element elem) {
         // Add max version if fix lands sometime to Webkit
         // Starting from Opera 11.00, also a problem in Opera
-        if ((BrowserInfo.get().getWebkitVersion() > 0 || BrowserInfo.get()
-                .getOperaVersion() >= 11) && getNativeScrollbarSize() > 0) {
+        if (BrowserInfo.get().requiresOverflowAutoFix()) {
             final String originalOverflow = elem.getStyle().getProperty(
                     "overflow");
             if ("hidden".equals(originalOverflow)) {
index 7153d46e4dff18afc4d8699b0672110bacc4be7f..488b07b4c1e1a167646ff7b34dc43c658efed3f1 100644 (file)
@@ -11,9 +11,10 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.ui.VAccordion.StackItem;
+import com.vaadin.terminal.gwt.client.ui.layout.RequiresOverflowAutoFix;
 
 public class AccordionConnector extends TabsheetBaseConnector implements
-        SimpleManagedLayout {
+        SimpleManagedLayout, RequiresOverflowAutoFix {
 
     @Override
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
index e39781952a1123ed86d293e8519896a399839dae..03e30071a3d3b43f6231a74bb497a9aabf3e76b5 100644 (file)
@@ -15,11 +15,12 @@ import com.vaadin.terminal.gwt.client.ConnectorHierarchyChangedEvent;
 import com.vaadin.terminal.gwt.client.LayoutManager;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.communication.ServerRpc;
+import com.vaadin.terminal.gwt.client.ui.layout.RequiresOverflowAutoFix;
 
 public class PanelConnector extends AbstractComponentContainerConnector
-        implements SimpleManagedLayout, PostLayoutListener {
+        implements SimpleManagedLayout, PostLayoutListener,
+        RequiresOverflowAutoFix {
 
     public interface PanelServerRPC extends ClickRPC, ServerRpc {
 
@@ -231,8 +232,6 @@ public class PanelConnector extends AbstractComponentContainerConnector
         // Read actual value back to ensure update logic is correct
         panel.scrollTop = panel.contentNode.getScrollTop();
         panel.scrollLeft = panel.contentNode.getScrollLeft();
-
-        Util.runWebkitOverflowAutoFix(panel.contentNode);
     }
 
     public void postLayout() {
index 988c1558cce79785cdd80f5684f2c211cf9b1fd0..bfab87f90f1b938632cb579b10081ad93f1654ec 100644 (file)
@@ -27,13 +27,14 @@ import com.vaadin.terminal.gwt.client.ConnectorMap;
 import com.vaadin.terminal.gwt.client.Focusable;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.VConsole;
 import com.vaadin.terminal.gwt.client.communication.ServerRpc;
 import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
 import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler;
+import com.vaadin.terminal.gwt.client.ui.layout.RequiresOverflowAutoFix;
 
-public class RootConnector extends AbstractComponentContainerConnector {
+public class RootConnector extends AbstractComponentContainerConnector
+        implements RequiresOverflowAutoFix {
 
     public interface RootServerRPC extends ClickRPC, ServerRpc {
 
@@ -271,12 +272,6 @@ public class RootConnector extends AbstractComponentContainerConnector {
             getWidget().scrollable = false;
         }
 
-        // Safari workaround must be run after scrollTop is updated as it sets
-        // scrollTop using a deferred command.
-        if (BrowserInfo.get().isSafari()) {
-            Util.runWebkitOverflowAutoFix(getWidget().getElement());
-        }
-
         getWidget().scrollIntoView(uidl);
 
         if (uidl.hasAttribute(VView.FRAGMENT_VARIABLE)) {
index 180fb8ac3499cd5b90f6afc17c612eefd5f7869a..dc6793a0be06fdc42955a7f9a22d0d10052ff7cc 100644 (file)
@@ -9,9 +9,10 @@ import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
 import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.layout.RequiresOverflowAutoFix;
 
 public class TabsheetConnector extends TabsheetBaseConnector implements
-        SimpleManagedLayout {
+        SimpleManagedLayout, RequiresOverflowAutoFix {
 
     @Override
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
index c4965220949580902af8b9f955a59970dfae851e..ae7130fe6d1605c7b8ad19874f3cbba7747c0554 100644 (file)
@@ -252,9 +252,6 @@ public class VAccordion extends VTabsheetBase {
             super.setWidth(maxWidth + "px");
             openTab.setWidth(maxWidth);
         }
-
-        Util.runWebkitOverflowAutoFix(openTab.getContainerElement());
-
     }
 
     /**
index ffef5825f4dd7359ce10c14a9b5389fc98008100..76e507a783c50b0bdd11c4bf67e86ce6457c1579 100644 (file)
@@ -939,7 +939,6 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
 
     public void iLayout() {
         updateTabScroller();
-        tp.runWebkitOverflowAutoFix();
     }
 
     /**
index 68270da85e01edf5a1057e4bb8fc431aa1689361..0bca5303675834491018e25c84be22e90912e2b6 100644 (file)
@@ -13,7 +13,6 @@ import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.ui.ComplexPanel;
 import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.Util;
 
 /**
  * A panel that displays all of its child widgets in a 'deck', where only one
@@ -194,15 +193,6 @@ public class VTabsheetPanel extends ComplexPanel {
 
         // widget wrapper height
         wrapperDiv.getStyle().setPropertyPx("height", height);
-        runWebkitOverflowAutoFix();
-    }
-
-    public void runWebkitOverflowAutoFix() {
-        if (visibleWidget != null) {
-            Util.runWebkitOverflowAutoFix(DOM.getParent(visibleWidget
-                    .getElement()));
-        }
-
     }
 
     public void replaceComponent(Widget oldComponent, Widget newComponent) {
index 014a016410d13771d36413eca1a930e6c01a1753..1c655ec6d9201e727b26aaf00a401431854a0000 100644 (file)
@@ -26,7 +26,6 @@ import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
 import com.vaadin.terminal.gwt.client.Focusable;
 import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.VConsole;
 import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
 
@@ -168,8 +167,6 @@ public class VView extends SimplePanel implements ResizeHandler,
         }
         if (changed) {
             VConsole.log("Running layout functions due to window resize");
-            Util.runWebkitOverflowAutoFix(getElement());
-
             sendClientResized();
 
             connection.doLayout(false);
index d3529987fa44765a7aaec300fdc845a21e41db4c..4bc7bdf371385d79b4cb2fba9278566b469e7330 100644 (file)
@@ -702,7 +702,6 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
             client.runDescendentsLayout((HasWidgets) layout.getWidget());
         }
 
-        Util.runWebkitOverflowAutoFix(contentPanel.getElement());
         client.doLayout(false);
     }
 
index e209c2aaa1395aabfe20573b17ee1d794be26318..c61ae93d8631e8300da4a243bde2b762f05f2de2 100644 (file)
@@ -20,14 +20,14 @@ import com.vaadin.terminal.gwt.client.ComponentConnector;
 import com.vaadin.terminal.gwt.client.LayoutManager;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.communication.ServerRpc;
 import com.vaadin.terminal.gwt.client.ui.PanelConnector.PanelState;
 import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
+import com.vaadin.terminal.gwt.client.ui.layout.RequiresOverflowAutoFix;
 
 public class WindowConnector extends AbstractComponentContainerConnector
         implements BeforeShortcutActionListener, SimpleManagedLayout,
-        PostLayoutListener {
+        PostLayoutListener, RequiresOverflowAutoFix {
 
     public interface WindowServerRPC extends ClickRPC, ServerRpc {
     }
@@ -301,8 +301,6 @@ public class WindowConnector extends AbstractComponentContainerConnector
         } else {
             childStyle.clearPosition();
         }
-
-        Util.runWebkitOverflowAutoFix(window.contentPanel.getElement());
     }
 
     public void postLayout() {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/RequiresOverflowAutoFix.java b/src/com/vaadin/terminal/gwt/client/ui/layout/RequiresOverflowAutoFix.java
new file mode 100644 (file)
index 0000000..18e82c8
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.layout;
+
+import com.vaadin.terminal.gwt.client.ComponentContainerConnector;
+
+public interface RequiresOverflowAutoFix extends ComponentContainerConnector {
+
+}