summaryrefslogtreecommitdiffstats
path: root/client/src
diff options
context:
space:
mode:
authorHenri Sara <hesara@vaadin.com>2015-08-19 11:45:17 +0300
committerHenri Sara <hesara@vaadin.com>2015-08-19 11:45:17 +0300
commit7a3e03b5acd416141e1a95eae32c3808a8e5addd (patch)
treec8fe43fcf0f40df48a634c260a07e857f1277170 /client/src
parent554bdab01e987b09a78b23d049c0f9f9b2a2ec72 (diff)
parent4a10a70fbecdd52758ebc73512974501a02d5fdd (diff)
downloadvaadin-framework-7a3e03b5acd416141e1a95eae32c3808a8e5addd.tar.gz
vaadin-framework-7a3e03b5acd416141e1a95eae32c3808a8e5addd.zip
Merge branch 'master-18493' into grid-unbuffered-editor
Conflicts: client/src/com/vaadin/client/connectors/GridConnector.java server/src/com/vaadin/data/RpcDataProviderExtension.java server/src/com/vaadin/ui/Grid.java Change-Id: Ie8931fbae322c93aeb409e8a6d393623ba9d9dc6
Diffstat (limited to 'client/src')
-rw-r--r--client/src/com/vaadin/client/connectors/GridConnector.java395
-rw-r--r--client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java13
-rw-r--r--client/src/com/vaadin/client/ui/VFilterSelect.java23
-rw-r--r--client/src/com/vaadin/client/ui/VOverlay.java14
-rw-r--r--client/src/com/vaadin/client/ui/VScrollTable.java6
-rw-r--r--client/src/com/vaadin/client/ui/VTree.java15
-rw-r--r--client/src/com/vaadin/client/ui/tree/TreeConnector.java6
7 files changed, 158 insertions, 314 deletions
diff --git a/client/src/com/vaadin/client/connectors/GridConnector.java b/client/src/com/vaadin/client/connectors/GridConnector.java
index 3c83fb2c24..62326c4b07 100644
--- a/client/src/com/vaadin/client/connectors/GridConnector.java
+++ b/client/src/com/vaadin/client/connectors/GridConnector.java
@@ -19,13 +19,13 @@ package com.vaadin.client.connectors;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;
@@ -40,6 +40,7 @@ import com.vaadin.client.ConnectorHierarchyChangeEvent;
import com.vaadin.client.DeferredWorker;
import com.vaadin.client.MouseEventDetailsBuilder;
import com.vaadin.client.TooltipInfo;
+import com.vaadin.client.ServerConnector;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.connectors.RpcDataSourceConnector.DetailsListener;
import com.vaadin.client.connectors.RpcDataSourceConnector.RpcDataSource;
@@ -85,10 +86,8 @@ import com.vaadin.client.widgets.Grid.FooterCell;
import com.vaadin.client.widgets.Grid.FooterRow;
import com.vaadin.client.widgets.Grid.HeaderCell;
import com.vaadin.client.widgets.Grid.HeaderRow;
-import com.vaadin.shared.Connector;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.ui.Connect;
-import com.vaadin.shared.ui.grid.DetailsConnectorChange;
import com.vaadin.shared.ui.grid.EditorClientRpc;
import com.vaadin.shared.ui.grid.EditorServerRpc;
import com.vaadin.shared.ui.grid.GridClientRpc;
@@ -421,255 +420,107 @@ public class GridConnector extends AbstractHasComponentsConnector implements
}
};
- private static class CustomDetailsGenerator implements DetailsGenerator {
+ private class CustomDetailsGenerator implements DetailsGenerator {
- private final Map<Integer, ComponentConnector> indexToDetailsMap = new HashMap<Integer, ComponentConnector>();
+ private final Map<String, ComponentConnector> idToDetailsMap = new HashMap<String, ComponentConnector>();
+ private final Map<String, Integer> idToRowIndex = new HashMap<String, Integer>();
@Override
- @SuppressWarnings("boxing")
public Widget getDetails(int rowIndex) {
- ComponentConnector componentConnector = indexToDetailsMap
- .get(rowIndex);
- if (componentConnector != null) {
- return componentConnector.getWidget();
- } else {
- return null;
- }
- }
-
- public void setDetailsConnectorChanges(
- Set<DetailsConnectorChange> changes) {
- /*
- * To avoid overwriting connectors while moving them about, we'll
- * take all the affected connectors, first all remove those that are
- * removed or moved, then we add back those that are moved or added.
- */
+ JsonObject row = getWidget().getDataSource().getRow(rowIndex);
- /* Remove moved/removed connectors from bookkeeping */
- for (DetailsConnectorChange change : changes) {
- Integer oldIndex = change.getOldIndex();
- Connector removedConnector = indexToDetailsMap.remove(oldIndex);
-
- Connector connector = change.getConnector();
- assert removedConnector == null || connector == null
- || removedConnector.equals(connector) : "Index "
- + oldIndex + " points to " + removedConnector
- + " while " + connector + " was expected";
- }
-
- /* Add moved/added connectors to bookkeeping */
- for (DetailsConnectorChange change : changes) {
- Integer newIndex = change.getNewIndex();
- ComponentConnector connector = (ComponentConnector) change
- .getConnector();
-
- if (connector != null) {
- assert newIndex != null : "An existing connector has a missing new index.";
-
- ComponentConnector prevConnector = indexToDetailsMap.put(
- newIndex, connector);
-
- assert prevConnector == null : "Connector collision at index "
- + newIndex
- + " between old "
- + prevConnector
- + " and new " + connector;
- }
+ if (!row.hasKey(GridState.JSONKEY_DETAILS_VISIBLE)
+ || row.getString(GridState.JSONKEY_DETAILS_VISIBLE)
+ .isEmpty()) {
+ return null;
}
- }
- }
-
- @SuppressWarnings("boxing")
- private static class DetailsConnectorFetcher implements DeferredWorker {
- private static final int FETCH_TIMEOUT_MS = 5000;
+ String id = row.getString(GridState.JSONKEY_DETAILS_VISIBLE);
+ ComponentConnector componentConnector = idToDetailsMap.get(id);
+ idToRowIndex.put(id, rowIndex);
- public interface Listener {
- void fetchHasBeenScheduled(int id);
-
- void fetchHasReturned(int id);
+ return componentConnector.getWidget();
}
- /** A flag making sure that we don't call scheduleFinally many times. */
- private boolean fetcherHasBeenCalled = false;
-
- /** A rolling counter for unique values. */
- private int detailsFetchCounter = 0;
-
- /** A collection that tracks the amount of requests currently underway. */
- private Set<Integer> pendingFetches = new HashSet<Integer>(5);
-
- private final ScheduledCommand lazyDetailsFetcher = new ScheduledCommand() {
- @Override
- public void execute() {
- int currentFetchId = detailsFetchCounter++;
- pendingFetches.add(currentFetchId);
- rpc.sendDetailsComponents(currentFetchId);
- fetcherHasBeenCalled = false;
-
- if (listener != null) {
- listener.fetchHasBeenScheduled(currentFetchId);
+ public void updateConnectorHierarchy(List<ServerConnector> children) {
+ Set<String> connectorIds = new HashSet<String>();
+ for (ServerConnector child : children) {
+ if (child instanceof ComponentConnector) {
+ connectorIds.add(child.getConnectorId());
+ idToDetailsMap.put(child.getConnectorId(),
+ (ComponentConnector) child);
}
-
- assert assertRequestDoesNotTimeout(currentFetchId);
- }
- };
-
- private DetailsConnectorFetcher.Listener listener = null;
-
- private final GridServerRpc rpc;
-
- public DetailsConnectorFetcher(GridServerRpc rpc) {
- assert rpc != null : "RPC was null";
- this.rpc = rpc;
- }
-
- public void schedule() {
- if (!fetcherHasBeenCalled) {
- Scheduler.get().scheduleFinally(lazyDetailsFetcher);
- fetcherHasBeenCalled = true;
}
- }
- public void responseReceived(int fetchId) {
-
- if (fetchId < 0) {
- /* Ignore negative fetchIds (they're pushed, not fetched) */
- return;
+ Set<String> removedDetails = new HashSet<String>();
+ for (Entry<String, ComponentConnector> entry : idToDetailsMap
+ .entrySet()) {
+ ComponentConnector connector = entry.getValue();
+ String id = connector.getConnectorId();
+ if (!connectorIds.contains(id)) {
+ removedDetails.add(entry.getKey());
+ if (idToRowIndex.containsKey(id)) {
+ getWidget().setDetailsVisible(idToRowIndex.get(id),
+ false);
+ }
+ }
}
- boolean success = pendingFetches.remove(fetchId);
- assert success : "Received a response with an unidentified fetch id";
-
- if (listener != null) {
- listener.fetchHasReturned(fetchId);
+ for (String id : removedDetails) {
+ idToDetailsMap.remove(id);
+ idToRowIndex.remove(id);
}
}
-
- @Override
- public boolean isWorkPending() {
- return fetcherHasBeenCalled || !pendingFetches.isEmpty();
- }
-
- private boolean assertRequestDoesNotTimeout(final int fetchId) {
- /*
- * This method will not be compiled without asserts enabled. This
- * only makes sure that any request does not time out.
- *
- * TODO Should this be an explicit check? Is it worth the overhead?
- */
- new Timer() {
- @Override
- public void run() {
- assert !pendingFetches.contains(fetchId) : "Fetch id "
- + fetchId + " timed out.";
- }
- }.schedule(FETCH_TIMEOUT_MS);
- return true;
- }
-
- public void setListener(DetailsConnectorFetcher.Listener listener) {
- // if more are needed, feel free to convert this into a collection.
- this.listener = listener;
- }
}
/**
- * The functionality that makes sure that the scroll position is still kept
- * up-to-date even if more details are being fetched lazily.
+ * Class for handling scrolling issues with open details.
+ *
+ * @since
+ * @author Vaadin Ltd
*/
- private class LazyDetailsScrollAdjuster implements DeferredWorker {
+ private class LazyDetailsScroller implements DeferredWorker {
- private static final int SCROLL_TO_END_ID = -2;
- private static final int NO_SCROLL_SCHEDULED = -1;
-
- private class ScrollStopChecker implements DeferredWorker {
- private final ScheduledCommand checkCommand = new ScheduledCommand() {
- @Override
- public void execute() {
- isScheduled = false;
- if (queuedFetches.isEmpty()) {
- currentRow = NO_SCROLL_SCHEDULED;
- destination = null;
- }
- }
- };
-
- private boolean isScheduled = false;
-
- public void schedule() {
- if (isScheduled) {
- return;
- }
- Scheduler.get().scheduleDeferred(checkCommand);
- isScheduled = true;
- }
-
- @Override
- public boolean isWorkPending() {
- return isScheduled;
- }
- }
-
- private DetailsConnectorFetcher.Listener fetcherListener = new DetailsConnectorFetcher.Listener() {
- @Override
- @SuppressWarnings("boxing")
- public void fetchHasBeenScheduled(int id) {
- if (currentRow != NO_SCROLL_SCHEDULED) {
- queuedFetches.add(id);
- }
- }
+ /* Timer value tested to work in our test cluster with slow IE8s. */
+ private static final int DISABLE_LAZY_SCROLL_TIMEOUT = 1500;
+ /*
+ * Cancels details opening scroll after timeout. Avoids any unexpected
+ * scrolls via details opening.
+ */
+ private Timer disableScroller = new Timer() {
@Override
- @SuppressWarnings("boxing")
- public void fetchHasReturned(int id) {
- if (currentRow == NO_SCROLL_SCHEDULED
- || queuedFetches.isEmpty()) {
- return;
- }
-
- queuedFetches.remove(id);
- if (currentRow == SCROLL_TO_END_ID) {
- getWidget().scrollToEnd();
- } else {
- getWidget().scrollToRow(currentRow, destination);
- }
-
- /*
- * Schedule a deferred call whether we should stop adjusting for
- * scrolling.
- *
- * This is done deferredly just because we can't be absolutely
- * certain whether this most recent scrolling won't cascade into
- * further lazy details loading (perhaps deferredly).
- */
- scrollStopChecker.schedule();
+ public void run() {
+ targetRow = -1;
}
};
- private int currentRow = NO_SCROLL_SCHEDULED;
- private final Set<Integer> queuedFetches = new HashSet<Integer>();
- private final ScrollStopChecker scrollStopChecker = new ScrollStopChecker();
- private ScrollDestination destination;
-
- public LazyDetailsScrollAdjuster() {
- detailsConnectorFetcher.setListener(fetcherListener);
- }
+ private Integer targetRow = -1;
+ private ScrollDestination destination = null;
- public void adjustForEnd() {
- currentRow = SCROLL_TO_END_ID;
+ public void scrollToRow(Integer row, ScrollDestination dest) {
+ targetRow = row;
+ destination = dest;
+ disableScroller.schedule(DISABLE_LAZY_SCROLL_TIMEOUT);
}
- public void adjustFor(int row, ScrollDestination destination) {
- currentRow = row;
- this.destination = destination;
+ /**
+ * Inform LazyDetailsScroller that a details row has opened on a row.
+ *
+ * @since
+ * @param rowIndex
+ * index of row with details now open
+ */
+ public void detailsOpened(int rowIndex) {
+ if (targetRow == rowIndex) {
+ getWidget().scrollToRow(targetRow, destination);
+ disableScroller.run();
+ }
}
@Override
public boolean isWorkPending() {
- return currentRow != NO_SCROLL_SCHEDULED
- || !queuedFetches.isEmpty()
- || scrollStopChecker.isWorkPending();
+ return disableScroller.isRunning();
}
}
@@ -732,39 +583,46 @@ public class GridConnector extends AbstractHasComponentsConnector implements
private final CustomDetailsGenerator customDetailsGenerator = new CustomDetailsGenerator();
private final CustomStyleGenerator styleGenerator = new CustomStyleGenerator();
- private final DetailsConnectorFetcher detailsConnectorFetcher = new DetailsConnectorFetcher(
- getRpcProxy(GridServerRpc.class));
-
private final DetailsListener detailsListener = new DetailsListener() {
@Override
public void reapplyDetailsVisibility(final int rowIndex,
final JsonObject row) {
- Scheduler.get().scheduleDeferred(new ScheduledCommand() {
- @Override
- public void execute() {
- if (hasDetailsOpen(row)) {
- getWidget().setDetailsVisible(rowIndex, true);
- detailsConnectorFetcher.schedule();
- } else {
+ if (hasDetailsOpen(row)) {
+ // Command for opening details row.
+ ScheduledCommand openDetails = new ScheduledCommand() {
+ @Override
+ public void execute() {
+ // Re-apply to force redraw.
getWidget().setDetailsVisible(rowIndex, false);
+ getWidget().setDetailsVisible(rowIndex, true);
+ lazyDetailsScroller.detailsOpened(rowIndex);
}
+ };
+
+ if (initialChange) {
+ Scheduler.get().scheduleDeferred(openDetails);
+ } else {
+ Scheduler.get().scheduleFinally(openDetails);
}
- });
+ } else {
+ getWidget().setDetailsVisible(rowIndex, false);
+ }
}
private boolean hasDetailsOpen(JsonObject row) {
return row.hasKey(GridState.JSONKEY_DETAILS_VISIBLE)
- && row.getBoolean(GridState.JSONKEY_DETAILS_VISIBLE);
- }
-
- @Override
- public void closeDetails(int rowIndex) {
- getWidget().setDetailsVisible(rowIndex, false);
+ && row.getString(GridState.JSONKEY_DETAILS_VISIBLE) != null;
}
};
- private final LazyDetailsScrollAdjuster lazyDetailsScrollAdjuster = new LazyDetailsScrollAdjuster();
+ private final LazyDetailsScroller lazyDetailsScroller = new LazyDetailsScroller();
+
+ /*
+ * Initially details need to behave a bit differently to allow some
+ * escalator magic.
+ */
+ private boolean initialChange;
@Override
@SuppressWarnings("unchecked")
@@ -799,11 +657,13 @@ public class GridConnector extends AbstractHasComponentsConnector implements
@Override
public void scrollToEnd() {
- lazyDetailsScrollAdjuster.adjustForEnd();
Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override
public void execute() {
getWidget().scrollToEnd();
+ // Scrolls further if details opens.
+ lazyDetailsScroller.scrollToRow(dataSource.size() - 1,
+ ScrollDestination.END);
}
});
}
@@ -811,11 +671,12 @@ public class GridConnector extends AbstractHasComponentsConnector implements
@Override
public void scrollToRow(final int row,
final ScrollDestination destination) {
- lazyDetailsScrollAdjuster.adjustFor(row, destination);
Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override
public void execute() {
getWidget().scrollToRow(row, destination);
+ // Scrolls a bit further if details opens.
+ lazyDetailsScroller.scrollToRow(row, destination);
}
});
}
@@ -824,51 +685,6 @@ public class GridConnector extends AbstractHasComponentsConnector implements
public void recalculateColumnWidths() {
getWidget().recalculateColumnWidths();
}
-
- @Override
- @SuppressWarnings("boxing")
- public void setDetailsConnectorChanges(
- Set<DetailsConnectorChange> connectorChanges, int fetchId) {
- customDetailsGenerator
- .setDetailsConnectorChanges(connectorChanges);
-
- List<DetailsConnectorChange> removedFirst = new ArrayList<DetailsConnectorChange>(
- connectorChanges);
- Collections.sort(removedFirst,
- DetailsConnectorChange.REMOVED_FIRST_COMPARATOR);
-
- // refresh moved/added details rows
- for (DetailsConnectorChange change : removedFirst) {
- Integer oldIndex = change.getOldIndex();
- Integer newIndex = change.getNewIndex();
-
- assert oldIndex == null || oldIndex >= 0 : "Got an "
- + "invalid old index: " + oldIndex
- + " (connector: " + change.getConnector() + ")";
- assert newIndex == null || newIndex >= 0 : "Got an "
- + "invalid new index: " + newIndex
- + " (connector: " + change.getConnector() + ")";
-
- if (oldIndex != null) {
- /* Close the old/removed index */
- getWidget().setDetailsVisible(oldIndex, false);
-
- if (change.isShouldStillBeVisible()) {
- getWidget().setDetailsVisible(oldIndex, true);
- }
- }
-
- if (newIndex != null) {
- /*
- * Since the component was lazy loaded, we need to
- * refresh the details by toggling it.
- */
- getWidget().setDetailsVisible(newIndex, false);
- getWidget().setDetailsVisible(newIndex, true);
- }
- }
- detailsConnectorFetcher.responseReceived(fetchId);
- }
});
getWidget().addSelectionHandler(internalSelectionChangeHandler);
@@ -954,16 +770,11 @@ public class GridConnector extends AbstractHasComponentsConnector implements
}
@Override
- public void onUnregister() {
- customDetailsGenerator.indexToDetailsMap.clear();
-
- super.onUnregister();
- }
-
- @Override
public void onStateChanged(final StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
+ initialChange = stateChangeEvent.isInitialStateChange();
+
// Column updates
if (stateChangeEvent.hasPropertyChanged("columns")) {
@@ -1428,6 +1239,7 @@ public class GridConnector extends AbstractHasComponentsConnector implements
@Override
public void onConnectorHierarchyChange(
ConnectorHierarchyChangeEvent connectorHierarchyChangeEvent) {
+ customDetailsGenerator.updateConnectorHierarchy(getChildren());
}
public String getColumnId(Grid.Column<?, ?> column) {
@@ -1444,8 +1256,7 @@ public class GridConnector extends AbstractHasComponentsConnector implements
@Override
public boolean isWorkPending() {
- return detailsConnectorFetcher.isWorkPending()
- || lazyDetailsScrollAdjuster.isWorkPending();
+ return lazyDetailsScroller.isWorkPending();
}
/**
diff --git a/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java b/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java
index 627ee74eca..c1b9f13ef4 100644
--- a/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java
+++ b/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java
@@ -64,14 +64,6 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector {
* @see GridState#JSONKEY_DETAILS_VISIBLE
*/
void reapplyDetailsVisibility(int rowIndex, JsonObject row);
-
- /**
- * Closes details for a row.
- *
- * @param rowIndex
- * the index of the row for which to close details
- */
- void closeDetails(int rowIndex);
}
public class RpcDataSource extends AbstractRemoteDataSource<JsonObject> {
@@ -221,11 +213,6 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector {
rowData.get(i));
}
}
-
- @Override
- protected void onDropFromCache(int rowIndex) {
- detailsListener.closeDetails(rowIndex);
- }
}
private final RpcDataSource dataSource = new RpcDataSource();
diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java
index 7951759fa2..8d9e30ac6e 100644
--- a/client/src/com/vaadin/client/ui/VFilterSelect.java
+++ b/client/src/com/vaadin/client/ui/VFilterSelect.java
@@ -65,6 +65,7 @@ import com.vaadin.client.BrowserInfo;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ComputedStyle;
import com.vaadin.client.ConnectorMap;
+import com.vaadin.client.DeferredWorker;
import com.vaadin.client.Focusable;
import com.vaadin.client.UIDL;
import com.vaadin.client.VConsole;
@@ -90,7 +91,7 @@ import com.vaadin.shared.util.SharedUtil;
public class VFilterSelect extends Composite implements Field, KeyDownHandler,
KeyUpHandler, ClickHandler, FocusHandler, BlurHandler, Focusable,
SubPartAware, HandlesAriaCaption, HandlesAriaInvalid,
- HandlesAriaRequired {
+ HandlesAriaRequired, DeferredWorker {
/**
* Represents a suggestion in the suggestion popup box
@@ -417,7 +418,9 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
selectPrevPage();
} else {
- selectItem(menu.getItems().get(menu.getItems().size() - 1));
+ if (!menu.getItems().isEmpty()) {
+ selectLastItem();
+ }
}
}
@@ -2185,11 +2188,15 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
@Override
public com.google.gwt.user.client.Element getSubPartElement(String subPart) {
- if ("textbox".equals(subPart)) {
+ String[] parts = subPart.split("/");
+ if ("textbox".equals(parts[0])) {
return tb.getElement();
- } else if ("button".equals(subPart)) {
+ } else if ("button".equals(parts[0])) {
return popupOpener.getElement();
- } else if ("popup".equals(subPart) && suggestionPopup.isAttached()) {
+ } else if ("popup".equals(parts[0]) && suggestionPopup.isAttached()) {
+ if (parts.length == 2) {
+ return suggestionPopup.menu.getSubPartElement(parts[1]);
+ }
return suggestionPopup.getElement();
}
return null;
@@ -2233,4 +2240,10 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
selectPopupItemWhenResponseIsReceived = Select.NONE;
}
+ @Override
+ public boolean isWorkPending() {
+ return waitingForFilteringResponse
+ || suggestionPopup.lazyPageScroller.isRunning();
+ }
+
}
diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java
index 3649afc74f..e823e8ee80 100644
--- a/client/src/com/vaadin/client/ui/VOverlay.java
+++ b/client/src/com/vaadin/client/ui/VOverlay.java
@@ -22,6 +22,8 @@ import java.util.logging.Logger;
import com.google.gwt.animation.client.Animation;
import com.google.gwt.aria.client.Roles;
import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.IFrameElement;
@@ -471,7 +473,17 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
if (isAnimationEnabled()) {
new ResizeAnimation().run(POPUP_PANEL_ANIMATION_DURATION);
} else {
- positionOrSizeUpdated(1.0);
+ if (BrowserInfo.get().isIE8()) {
+ Scheduler.get().scheduleFinally(new ScheduledCommand() {
+
+ @Override
+ public void execute() {
+ positionOrSizeUpdated(1.0);
+ }
+ });
+ } else {
+ positionOrSizeUpdated(1.0);
+ }
}
current = null;
}
diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java
index 6bb3199b08..e036725ceb 100644
--- a/client/src/com/vaadin/client/ui/VScrollTable.java
+++ b/client/src/com/vaadin/client/ui/VScrollTable.java
@@ -3628,6 +3628,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
} else {
c.setText(caption);
+ if (BrowserInfo.get().isIE10()) {
+ // IE10 can some times define min-height to include
+ // padding when setting the text...
+ // See https://dev.vaadin.com/ticket/15169
+ WidgetUtil.forceIERedraw(c.getElement());
+ }
}
c.setSorted(false);
diff --git a/client/src/com/vaadin/client/ui/VTree.java b/client/src/com/vaadin/client/ui/VTree.java
index 8729de4a43..846b16d0cb 100644
--- a/client/src/com/vaadin/client/ui/VTree.java
+++ b/client/src/com/vaadin/client/ui/VTree.java
@@ -179,7 +179,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
@Override
public void execute() {
- Util.notifyParentOfSizeChange(VTree.this, true);
+ doLayout();
}
});
@@ -969,7 +969,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
open = state;
if (!rendering) {
- Util.notifyParentOfSizeChange(VTree.this, false);
+ doLayout();
}
}
@@ -2239,4 +2239,15 @@ public class VTree extends FocusElementPanel implements VHasDropHandler,
com.google.gwt.user.client.Element captionElement) {
AriaHelper.bindCaption(body, captionElement);
}
+
+ /**
+ * Tell LayoutManager that a layout is needed later for this VTree
+ */
+ private void doLayout() {
+ // IE8 needs a hack to measure the tree again after update
+ WidgetUtil.forceIE8Redraw(getElement());
+
+ // This calls LayoutManager setNeedsMeasure and layoutNow
+ Util.notifyParentOfSizeChange(this, false);
+ }
}
diff --git a/client/src/com/vaadin/client/ui/tree/TreeConnector.java b/client/src/com/vaadin/client/ui/tree/TreeConnector.java
index fc3e6ca0fc..23091d0ad5 100644
--- a/client/src/com/vaadin/client/ui/tree/TreeConnector.java
+++ b/client/src/com/vaadin/client/ui/tree/TreeConnector.java
@@ -27,8 +27,8 @@ import com.vaadin.client.BrowserInfo;
import com.vaadin.client.Paintable;
import com.vaadin.client.TooltipInfo;
import com.vaadin.client.UIDL;
-import com.vaadin.client.WidgetUtil;
import com.vaadin.client.VConsole;
+import com.vaadin.client.WidgetUtil;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.client.ui.VTree;
@@ -62,6 +62,10 @@ public class TreeConnector extends AbstractComponentConnector implements
if (uidl.hasAttribute("partialUpdate")) {
handleUpdate(uidl);
+
+ // IE8 needs a hack to measure the tree again after update
+ WidgetUtil.forceIE8Redraw(getWidget().getElement());
+
getWidget().rendering = false;
return;
}