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;
+ }
+
}
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.";
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(
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)
MeasureResult measureResult = measuredAndUpdate(element, measuredSize,
layoutDependencyTree);
+ if (measureResult.isChanged()) {
+ doOverflowAutoFix(connector);
+ }
if (measureResult.isHeightChanged()) {
layoutDependencyTree.markHeightAsChanged(connector);
}
}
}
+ 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);
if (heightChanged) {
currentDependencyTree.markHeightAsChanged(component);
+ doOverflowAutoFix(component);
}
currentDependencyTree.setNeedsVerticalMeasure(component, false);
}
if (widthChanged) {
currentDependencyTree.markWidthAsChanged(component);
+ doOverflowAutoFix(component);
}
currentDependencyTree.setNeedsHorizontalMeasure(component, false);
}
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)) {
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) {
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 {
// 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() {
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 {
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)) {
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) {
super.setWidth(maxWidth + "px");
openTab.setWidth(maxWidth);
}
-
- Util.runWebkitOverflowAutoFix(openTab.getContainerElement());
-
}
/**
public void iLayout() {
updateTabScroller();
- tp.runWebkitOverflowAutoFix();
}
/**
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
// 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) {
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;
}
if (changed) {
VConsole.log("Running layout functions due to window resize");
- Util.runWebkitOverflowAutoFix(getElement());
-
sendClientResized();
connection.doLayout(false);
client.runDescendentsLayout((HasWidgets) layout.getWidget());
}
- Util.runWebkitOverflowAutoFix(contentPanel.getElement());
client.doLayout(false);
}
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 {
}
} else {
childStyle.clearPosition();
}
-
- Util.runWebkitOverflowAutoFix(window.contentPanel.getElement());
}
public void postLayout() {
--- /dev/null
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.ui.layout;
+
+import com.vaadin.terminal.gwt.client.ComponentContainerConnector;
+
+public interface RequiresOverflowAutoFix extends ComponentContainerConnector {
+
+}