From afa1aa38bd0a61c43d68be7f8120eb01991e7412 Mon Sep 17 00:00:00 2001 From: Henrik Paul Date: Thu, 18 Dec 2014 12:49:16 +0200 Subject: Fixes an issue where IE8 refused to fire one scroll event (#13334) Change-Id: Iaf9278a3a16360369fde5ac6d759e27e5c443d1b --- .../client/widget/escalator/ScrollbarBundle.java | 74 ++++++++++++++++++++-- .../src/com/vaadin/client/widgets/Escalator.java | 4 +- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/client/src/com/vaadin/client/widget/escalator/ScrollbarBundle.java b/client/src/com/vaadin/client/widget/escalator/ScrollbarBundle.java index dfc4abe62b..be8d11761f 100644 --- a/client/src/com/vaadin/client/widget/escalator/ScrollbarBundle.java +++ b/client/src/com/vaadin/client/widget/escalator/ScrollbarBundle.java @@ -29,6 +29,7 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventListener; import com.google.gwt.user.client.Timer; +import com.vaadin.client.DeferredWorker; import com.vaadin.client.Util; import com.vaadin.client.widget.grid.events.ScrollEvent; import com.vaadin.client.widget.grid.events.ScrollHandler; @@ -42,7 +43,7 @@ import com.vaadin.client.widget.grid.events.ScrollHandler; * @see VerticalScrollbarBundle * @see HorizontalScrollbarBundle */ -public abstract class ScrollbarBundle { +public abstract class ScrollbarBundle implements DeferredWorker { private class ScrollEventFirer { private final ScheduledCommand fireEventCommand = new ScheduledCommand() { @@ -336,6 +337,9 @@ public abstract class ScrollbarBundle { private final ScrollEventFirer scrollEventFirer = new ScrollEventFirer(); + private HandlerRegistration scrollSizeTemporaryScrollHandler; + private HandlerRegistration offsetSizeTemporaryScrollHandler; + private ScrollbarBundle() { root.appendChild(scrollSizeElement); } @@ -399,10 +403,37 @@ public abstract class ScrollbarBundle { * @param px * the length of the scrollbar in pixels */ - public final void setOffsetSize(double px) { + public final void setOffsetSize(final double px) { + + /* + * This needs to be made step-by-step because IE8 flat-out refuses to + * fire a scroll event when the scroll size becomes smaller than the + * offset size. All other browser need to suffer alongside. + */ + + boolean newOffsetSizeIsGreaterThanScrollSize = px > getOffsetSize(); + boolean offsetSizeBecomesGreaterThanScrollSize = showsScrollHandle() + && newOffsetSizeIsGreaterThanScrollSize; + if (offsetSizeBecomesGreaterThanScrollSize && getScrollPos() != 0) { + // must be a field because Java insists. + offsetSizeTemporaryScrollHandler = addScrollHandler(new ScrollHandler() { + @Override + public void onScroll(ScrollEvent event) { + setOffsetSizeNow(px); + offsetSizeTemporaryScrollHandler.removeHandler(); + offsetSizeTemporaryScrollHandler = null; + } + }); + setScrollPos(0); + } else { + setOffsetSizeNow(px); + } + } + + private void setOffsetSizeNow(double px) { internalSetOffsetSize(Math.max(0, truncate(px))); - forceScrollbar(showsScrollHandle()); recalculateMaxScrollPos(); + forceScrollbar(showsScrollHandle()); fireVisibilityChangeIfNeeded(); } @@ -540,10 +571,37 @@ public abstract class ScrollbarBundle { * the number of pixels the scrollbar should be able to scroll * through */ - public final void setScrollSize(double px) { + public final void setScrollSize(final double px) { + + /* + * This needs to be made step-by-step because IE8 flat-out refuses to + * fire a scroll event when the scroll size becomes smaller than the + * offset size. All other browser need to suffer alongside. + */ + + boolean newScrollSizeIsSmallerThanOffsetSize = px <= getOffsetSize(); + boolean scrollSizeBecomesSmallerThanOffsetSize = showsScrollHandle() + && newScrollSizeIsSmallerThanOffsetSize; + if (scrollSizeBecomesSmallerThanOffsetSize && getScrollPos() != 0) { + // must be a field because Java insists. + scrollSizeTemporaryScrollHandler = addScrollHandler(new ScrollHandler() { + @Override + public void onScroll(ScrollEvent event) { + setScrollSizeNow(px); + scrollSizeTemporaryScrollHandler.removeHandler(); + scrollSizeTemporaryScrollHandler = null; + } + }); + setScrollPos(0); + } else { + setScrollSizeNow(px); + } + } + + private void setScrollSizeNow(double px) { internalSetScrollSize(Math.max(0, px)); - forceScrollbar(showsScrollHandle()); recalculateMaxScrollPos(); + forceScrollbar(showsScrollHandle()); fireVisibilityChangeIfNeeded(); } @@ -749,4 +807,10 @@ public abstract class ScrollbarBundle { public HandlerRegistration addScrollHandler(final ScrollHandler handler) { return getHandlerManager().addHandler(ScrollEvent.TYPE, handler); } + + @Override + public boolean isWorkPending() { + return scrollSizeTemporaryScrollHandler != null + || offsetSizeTemporaryScrollHandler != null; + } } diff --git a/client/src/com/vaadin/client/widgets/Escalator.java b/client/src/com/vaadin/client/widgets/Escalator.java index 57879517c9..b54c45625b 100644 --- a/client/src/com/vaadin/client/widgets/Escalator.java +++ b/client/src/com/vaadin/client/widgets/Escalator.java @@ -5042,7 +5042,9 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker @Override public boolean isWorkPending() { return body.domSorter.waiting - || columnAutoWidthAssignScheduler.isScheduled; + || columnAutoWidthAssignScheduler.isScheduled + || verticalScrollbar.isWorkPending() + || horizontalScrollbar.isWorkPending(); } @Override -- cgit v1.2.3