From 0d3c35b4f17814a3c146134621374a8a915f10a0 Mon Sep 17 00:00:00 2001 From: Jarno Rantala Date: Mon, 4 Nov 2013 15:21:22 +0200 Subject: Forces redraw in IE 8 when table does post layout. (#12687) Without forcing the redraw, IE8 measures component sizes incorrectly in some cases. Change-Id: I38e8a70e18753714b00f5ca4492749d6c84f10dc --- client/src/com/vaadin/client/ui/table/TableConnector.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'client') diff --git a/client/src/com/vaadin/client/ui/table/TableConnector.java b/client/src/com/vaadin/client/ui/table/TableConnector.java index 47229dc9c7..07689a640f 100644 --- a/client/src/com/vaadin/client/ui/table/TableConnector.java +++ b/client/src/com/vaadin/client/ui/table/TableConnector.java @@ -343,6 +343,9 @@ public class TableConnector extends AbstractHasComponentsConnector implements Scheduler.get().scheduleFinally(new ScheduledCommand() { @Override public void execute() { + // IE8 needs some hacks to measure sizes correctly + Util.forceIE8Redraw(getWidget().getElement()); + getLayoutManager().setNeedsMeasure(TableConnector.this); ServerConnector parent = getParent(); if (parent instanceof ComponentConnector) { -- cgit v1.2.3 From 533ddcda271b7226b38c035adf3073062c562653 Mon Sep 17 00:00:00 2001 From: Tapio Aali Date: Tue, 5 Nov 2013 12:17:06 +0200 Subject: Fixed lost scrollLeft when row count changed in Table (#12652). Change-Id: I868f56c1e7003c6619859ba46619f4c53ef9744e --- client/src/com/vaadin/client/Util.java | 37 +++++++ client/src/com/vaadin/client/ui/VScrollTable.java | 47 ++++++++- ...bleHorizontalScrollPositionOnItemSetChange.html | 110 +++++++++++++++++++++ ...bleHorizontalScrollPositionOnItemSetChange.java | 101 +++++++++++++++++++ 4 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 uitest/src/com/vaadin/tests/components/table/TableHorizontalScrollPositionOnItemSetChange.html create mode 100644 uitest/src/com/vaadin/tests/components/table/TableHorizontalScrollPositionOnItemSetChange.java (limited to 'client') diff --git a/client/src/com/vaadin/client/Util.java b/client/src/com/vaadin/client/Util.java index 9cdfa954c6..fd7a354569 100644 --- a/client/src/com/vaadin/client/Util.java +++ b/client/src/com/vaadin/client/Util.java @@ -448,6 +448,35 @@ public class Util { return detectedScrollbarSize; } + /** + * Calculates maximum horizontal scrolling value for the given element. + * + * @since 7.1.9 + * @param element + * which scrollLeft should be calculated + * @return maximum value for scrollLeft of the given element + */ + public static int getMaxScrollLeft(final Element element) { + int scrollWidth = element.getScrollWidth(); + int clientWidth = element.getClientWidth(); + return scrollWidth - clientWidth; + } + + /** + * Checks if scrollLeft of the element is at its maximum value. Returns + * false if the element can't be scrolled horizontally. + * + * @since 7.1.9 + * @param element + * which scrollLeft should be checked + * @return true, if scrollLeft is at maximum (false if element can't be + * scrolled horizontally) + */ + public static boolean isScrollLeftAtMax(final Element element) { + int scrollLeft = element.getScrollLeft(); + return scrollLeft != 0 && scrollLeft == getMaxScrollLeft(element); + } + /** * Run workaround for webkits overflow auto issue. * @@ -469,6 +498,8 @@ public class Util { // check the scrolltop value before hiding the element final int scrolltop = elem.getScrollTop(); final int scrollleft = elem.getScrollLeft(); + final boolean scrollLeftAtMax = isScrollLeftAtMax(elem); + elem.getStyle().setProperty("overflow", "hidden"); Scheduler.get().scheduleDeferred(new Command() { @@ -492,6 +523,12 @@ public class Util { elem.setScrollTop(scrollvalue); } + // keep horizontal scroll at max if it was before vertical + // scroll bar was added/removed + if (scrollLeftAtMax) { + elem.setScrollLeft(getMaxScrollLeft(elem)); + } + // fix for #6940 : Table horizontal scroll sometimes not // updated when collapsing/expanding columns // Also appeared in Safari 5.1 with webkit 534 (#7667) diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index 0304acd590..48fd85144f 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -276,6 +276,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets, */ private int detachedScrollPosition = 0; + // fields used in fixing erroneously lost scrollLeft + int lastScrollBodyHeight = 0; + boolean lastScrollLeftWasAtMax = false; + /** * Represents a select range of rows */ @@ -1005,6 +1009,15 @@ public class VScrollTable extends FlowPanel implements HasWidgets, initialContentReceived = true; sizeNeedsInit = true; scrollBody.restoreRowVisibility(); + + // At least FireFox requires that scrollLeft is restored deferred after + // scrollBody is recreated + Scheduler.get().scheduleFinally(new ScheduledCommand() { + @Override + public void execute() { + restoreScrollLeft(); + } + }); } /** For internal use only. May be removed or replaced in the future. */ @@ -6864,13 +6877,45 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return s; } + /** + * Tries to restore horizontal scroll position if it was lost due to change + * in the height of scrollBody (#12652). + */ + private void restoreScrollLeft() { + int upcomingScrollLeft = scrollLeft; + + if (lastScrollLeftWasAtMax) { + upcomingScrollLeft = Util.getMaxScrollLeft(scrollBodyPanel + .getElement()); + } + scrollBodyPanel.getElement().setScrollLeft(upcomingScrollLeft); + } + + /** + * Checks if restore of scrollLeft is needed by checking if height of the + * scrollBody has changed. + * + * @return true, if restore is required + */ + private boolean isScrollLeftRestoreRequired() { + return (scrollBody.getElement().getClientHeight() != lastScrollBodyHeight); + } + /** * This method has logic which rows needs to be requested from server when * user scrolls */ - @Override public void onScroll(ScrollEvent event) { + // restore in initializeRows() doesn't work right with Chrome + if (isScrollLeftRestoreRequired()) { + restoreScrollLeft(); + } + + lastScrollBodyHeight = scrollBody.getElement().getClientHeight(); + lastScrollLeftWasAtMax = Util.isScrollLeftAtMax(scrollBodyPanel + .getElement()); + scrollLeft = scrollBodyPanel.getElement().getScrollLeft(); scrollTop = scrollBodyPanel.getScrollPosition(); /* diff --git a/uitest/src/com/vaadin/tests/components/table/TableHorizontalScrollPositionOnItemSetChange.html b/uitest/src/com/vaadin/tests/components/table/TableHorizontalScrollPositionOnItemSetChange.html new file mode 100644 index 0000000000..6fd54ba0ca --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableHorizontalScrollPositionOnItemSetChange.html @@ -0,0 +1,110 @@ + + + + + + +TableHorizontalScrollPositionOnItemSetChange + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TableHorizontalScrollPositionOnItemSetChange
open/run/com.vaadin.tests.components.table.TableHorizontalScrollPositionOnItemSetChange?restartApplication
scrollLeftvaadin=runcomvaadintestscomponentstableTableHorizontalScrollPositionOnItemSetChange::PID_Shorscrolltable/domChild[1]326
pause500
clickvaadin=runcomvaadintestscomponentstableTableHorizontalScrollPositionOnItemSetChange::PID_Slessitems/domChild[0]/domChild[0]
pause500
screenCaptureleft-scroll-position-stays-in-middle-with-fewer-items
clickvaadin=runcomvaadintestscomponentstableTableHorizontalScrollPositionOnItemSetChange::PID_Smoreitems/domChild[0]/domChild[0]
pause500
screenCaptureleft-scroll-position-stays-in-middle-with-more-items
scrollLeftvaadin=runcomvaadintestscomponentstableTableHorizontalScrollPositionOnItemSetChange::PID_Shorscrolltable/domChild[1]653
pause500
clickvaadin=runcomvaadintestscomponentstableTableHorizontalScrollPositionOnItemSetChange::PID_Slessitems/domChild[0]/domChild[0]
pause500
screenCaptureleft-scroll-position-stays-max-with-fewer-items
clickvaadin=runcomvaadintestscomponentstableTableHorizontalScrollPositionOnItemSetChange::PID_Smoreitems/domChild[0]/domChild[0]
pause500
screenCaptureleft-scroll-position-stays-max-with-more-items
scrollLeftvaadin=runcomvaadintestscomponentstableTableHorizontalScrollPositionOnItemSetChange::PID_Shorscrolltable/domChild[1]0
+ + diff --git a/uitest/src/com/vaadin/tests/components/table/TableHorizontalScrollPositionOnItemSetChange.java b/uitest/src/com/vaadin/tests/components/table/TableHorizontalScrollPositionOnItemSetChange.java new file mode 100644 index 0000000000..1f59a84428 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableHorizontalScrollPositionOnItemSetChange.java @@ -0,0 +1,101 @@ +/* + * 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.tests.components.table; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; + +public class TableHorizontalScrollPositionOnItemSetChange extends + AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout layout = new VerticalLayout(); + layout.setMargin(true); + layout.setSpacing(true); + setContent(layout); + + final Table table = new Table(); + table.setWidth("640px"); + table.setHeight("243px"); + table.setId("horscrolltable"); + layout.addComponent(table); + + for (int i = 0; i < 15; i++) { + table.addContainerProperty("Column " + i, String.class, null); + } + + for (int i = 0; i < 60; i++) { + table.addItem(); + } + + Button lessItems = new Button("Less items", new Button.ClickListener() { + + @Override + public void buttonClick(Button.ClickEvent event) { + table.removeAllItems(); + for (int i = 0; i < 5; i++) { + table.addItem(); + } + } + }); + lessItems.setId("lessitems"); + + Button moreItems = new Button("More items", new Button.ClickListener() { + + @Override + public void buttonClick(Button.ClickEvent event) { + table.removeAllItems(); + for (int i = 0; i < 50; i++) { + table.addItem(); + } + } + }); + moreItems.setId("moreitems"); + + Button clearItems = new Button("Clear all", new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + table.removeAllItems(); + } + }); + + HorizontalLayout buttonLayout = new HorizontalLayout(); + buttonLayout.setSpacing(true); + layout.addComponent(buttonLayout); + + buttonLayout.addComponent(lessItems); + buttonLayout.addComponent(moreItems); + buttonLayout.addComponent(clearItems); + clearItems.setId("clearitems"); + } + + @Override + protected String getTestDescription() { + return "Horizontal scrolling position should not be lost if amount of items changes in Table."; + } + + @Override + protected Integer getTicketNumber() { + return 12652; + } + +} -- cgit v1.2.3 From c351b6464a6154205a8bd6f79880df968df68777 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Wed, 6 Nov 2013 15:26:42 +0200 Subject: Revert "Make Panel scroll the correct div (#12736)" Revert "Reverted change in how hack works (#12727, #12736)" Revert "Fixes the handling of the scroll position of a Window (#12736)" Revert "Recovering scroll position after regression problems. (#12727)" Revert "Ticket #12727 - Panels get unnecessary scroll bars in WebKit when content is 100% wide." This reverts commit 6a63d12afc5a4bf3971dd016f8e2761cd27bcc74. This reverts commit c48c94dc23da22b6d885c69b0bc697257f9dbf11. This reverts commit 017bd0684c7d6c8475c8b43514e6f3998095c8d6. This reverts commit 51a46a038fe0353f4babfd8218153eb68e2602ca. This reverts commit ab5b20cf502f99944c82f619ffef387f0525e8ba. Test cases were left as-is as the issue (#12736) still needs a workaround Change-Id: I0b6c2afb4a9be8629f2a8f880a8ae8d0a6d5088f --- client/src/com/vaadin/client/Util.java | 51 ---------------------------- client/src/com/vaadin/client/ui/VPanel.java | 2 -- client/src/com/vaadin/client/ui/VWindow.java | 33 +++++++++++++++--- 3 files changed, 29 insertions(+), 57 deletions(-) (limited to 'client') diff --git a/client/src/com/vaadin/client/Util.java b/client/src/com/vaadin/client/Util.java index fd7a354569..7c7978be09 100644 --- a/client/src/com/vaadin/client/Util.java +++ b/client/src/com/vaadin/client/Util.java @@ -32,7 +32,6 @@ import com.google.gwt.dom.client.Node; import com.google.gwt.dom.client.NodeList; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Display; -import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.Touch; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; @@ -555,56 +554,6 @@ public class Util { } - /** - * Prevents some browsers from adding scroll bars to a component (such as a - * Window) whose contents fit in the component. - *

- * See: bugs #11994 and #12736. - * - * @param contentNode - * an element that is scrollable - * - * @since 7.1.8 - */ - public static void removeUnneededScrollbars(final Element scrollable) { - if (BrowserInfo.get().isWebkit()) { - - /* - * Shake up the DOM a bit to make the window shed unnecessary - * scrollbars and resize correctly afterwards. This resulting code - * took over a week to summon forth, and involved some pretty hairy - * black magic. Don't touch it unless you know what you're doing! - * Fixes ticket #11994. Later modified to fix ticket #12736. - */ - Scheduler.get().scheduleFinally(new ScheduledCommand() { - - @Override - public void execute() { - // Adjusting the width or height may change the scroll - // position, so store the current position - int horizontalScrollPosition = scrollable.getScrollLeft(); - int verticalScrollPosition = scrollable.getScrollTop(); - - final String oldWidth = scrollable.getStyle().getWidth(); - final String oldHeight = scrollable.getStyle().getHeight(); - - scrollable.getStyle().setWidth(110, Unit.PCT); - scrollable.getOffsetWidth(); - scrollable.getStyle().setProperty("width", oldWidth); - scrollable.getStyle().setHeight(110, Unit.PCT); - scrollable.getOffsetHeight(); - scrollable.getStyle().setProperty("height", oldHeight); - - // Restore the scroll position - scrollable.setScrollLeft(horizontalScrollPosition); - scrollable.setScrollTop(verticalScrollPosition); - - } - }); - - } - } - /** * Parses shared state and fetches the relative size of the component. If a * dimension is not specified as relative it will return -1. If the shared diff --git a/client/src/com/vaadin/client/ui/VPanel.java b/client/src/com/vaadin/client/ui/VPanel.java index 307a2e4a91..6b02f079d1 100644 --- a/client/src/com/vaadin/client/ui/VPanel.java +++ b/client/src/com/vaadin/client/ui/VPanel.java @@ -24,7 +24,6 @@ import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.SimplePanel; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.Focusable; -import com.vaadin.client.Util; import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler; @@ -207,6 +206,5 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this); } touchScrollHandler.addElement(contentNode); - Util.removeUnneededScrollbars(contentNode); } } diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java index 62937b6a67..396169eb8c 100644 --- a/client/src/com/vaadin/client/ui/VWindow.java +++ b/client/src/com/vaadin/client/ui/VWindow.java @@ -345,11 +345,36 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, if (!visibilityChangesDisabled) { super.setVisible(visible); } + if (visible && BrowserInfo.get().isWebkit()) { - Util.removeUnneededScrollbars((Element) contents - .getFirstChildElement()); - updateContentsSize(); - positionOrSizeUpdated(); + + /* + * Shake up the DOM a bit to make the window shed unnecessary + * scrollbars and resize correctly afterwards. This resulting code + * took over a week to summon forth, and involved some pretty hairy + * black magic. Don't touch it unless you know what you're doing! + * Fixes ticket #11994 + */ + Scheduler.get().scheduleFinally(new ScheduledCommand() { + @Override + public void execute() { + final com.google.gwt.dom.client.Element scrollable = contents + .getFirstChildElement(); + final String oldWidth = scrollable.getStyle().getWidth(); + final String oldHeight = scrollable.getStyle().getHeight(); + + scrollable.getStyle().setWidth(110, Unit.PCT); + scrollable.getOffsetWidth(); + scrollable.getStyle().setProperty("width", oldWidth); + + scrollable.getStyle().setHeight(110, Unit.PCT); + scrollable.getOffsetHeight(); + scrollable.getStyle().setProperty("height", oldHeight); + + updateContentsSize(); + positionOrSizeUpdated(); + } + }); } } -- cgit v1.2.3 From 2e3e877e1bf99bbaf89d5dc45625ab44322c20e0 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Wed, 6 Nov 2013 15:11:34 +0200 Subject: Fix scroll position handling in Window Webkit hack (#12736) Change-Id: If4d17c34b2d20ad983f21b892d3ab4c68f511780 --- client/src/com/vaadin/client/ui/VWindow.java | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'client') diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java index 396169eb8c..73b57c7e5b 100644 --- a/client/src/com/vaadin/client/ui/VWindow.java +++ b/client/src/com/vaadin/client/ui/VWindow.java @@ -360,6 +360,12 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, public void execute() { final com.google.gwt.dom.client.Element scrollable = contents .getFirstChildElement(); + + // Adjusting the width or height may change the scroll + // position, so store the current position + int horizontalScrollPosition = scrollable.getScrollLeft(); + int verticalScrollPosition = scrollable.getScrollTop(); + final String oldWidth = scrollable.getStyle().getWidth(); final String oldHeight = scrollable.getStyle().getHeight(); @@ -371,6 +377,10 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, scrollable.getOffsetHeight(); scrollable.getStyle().setProperty("height", oldHeight); + // Restore the scroll position + scrollable.setScrollLeft(horizontalScrollPosition); + scrollable.setScrollTop(verticalScrollPosition); + updateContentsSize(); positionOrSizeUpdated(); } -- cgit v1.2.3 From 13858578966dad8cf5a6f10448b42961817beafc Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 8 Nov 2013 11:26:08 +0200 Subject: Do not apply fix on mobile devices or devices without scrollbars (#12736) Change-Id: I38ef869d87418c18197a59a5ecd3fb7e12e1c02e --- client/src/com/vaadin/client/BrowserInfo.java | 16 ++++++++++++++++ client/src/com/vaadin/client/ui/VWindow.java | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'client') diff --git a/client/src/com/vaadin/client/BrowserInfo.java b/client/src/com/vaadin/client/BrowserInfo.java index 273964c889..78c5c1f59f 100644 --- a/client/src/com/vaadin/client/BrowserInfo.java +++ b/client/src/com/vaadin/client/BrowserInfo.java @@ -346,6 +346,22 @@ public class BrowserInfo { && Util.getNativeScrollbarSize() > 0; } + /** + * Indicates whether the browser might require juggling to properly update + * sizes inside elements with overflow: auto when adjusting absolutely + * positioned elements. + *

+ * See https://bugs.webkit.org/show_bug.cgi?id=123958 and + * http://code.google.com/p/chromium/issues/detail?id=316549 + * + * @since 7.1.8 + * @return true if the browser requires the workaround, + * otherwise false + */ + public boolean requiresPositionAbsoluteOverflowAutoFix() { + return (getWebkitVersion() > 0) && Util.getNativeScrollbarSize() > 0; + } + /** * Checks if the browser is run on iOS * diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java index 73b57c7e5b..03a65e8ece 100644 --- a/client/src/com/vaadin/client/ui/VWindow.java +++ b/client/src/com/vaadin/client/ui/VWindow.java @@ -346,7 +346,8 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, super.setVisible(visible); } - if (visible && BrowserInfo.get().isWebkit()) { + if (visible + && BrowserInfo.get().requiresPositionAbsoluteOverflowAutoFix()) { /* * Shake up the DOM a bit to make the window shed unnecessary -- cgit v1.2.3