From c521f6ed4c40eeee5f4a9fa1628aff711e37bb7d Mon Sep 17 00:00:00 2001 From: Automerge Date: Wed, 18 Apr 2012 13:21:15 +0000 Subject: [merge from 6.7] Test for #8662: Improved old #2864 test case and added a TestBench script svn changeset:23572/svn branch:6.8 --- .../components/table/TestCurrentPageFirstItem.html | 42 +++++++++++ .../components/table/TestCurrentPageFirstItem.java | 83 +++++++++++++--------- 2 files changed, 91 insertions(+), 34 deletions(-) create mode 100644 tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.html diff --git a/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.html b/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.html new file mode 100644 index 0000000000..ac06706aa5 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.html @@ -0,0 +1,42 @@ + + + + + + +TestCurrentPageFirstItem + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TestCurrentPageFirstItem
open/run/TestCurrentPageFirstItem?restartApplication
clickvaadin=runTestCurrentPageFirstItem::/VHorizontalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]
clickvaadin=runTestCurrentPageFirstItem::/VHorizontalLayout[0]/ChildComponentContainer[5]/VButton[0]/domChild[0]
clickvaadin=runTestCurrentPageFirstItem::/VHorizontalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]
screenCapture
+ + diff --git a/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.java b/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.java index 1733b15e80..6e38f2a156 100644 --- a/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.java +++ b/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.java @@ -1,60 +1,75 @@ package com.vaadin.tests.components.table; -import com.vaadin.Application; import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.util.IndexedContainer; +import com.vaadin.tests.components.TestBase; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Table; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; -public class TestCurrentPageFirstItem extends Application implements - ClickListener { +public class TestCurrentPageFirstItem extends TestBase implements ClickListener { private Button buttonIndex; private Button buttonItem; - private Table table; + private Table[] tables = new Table[4]; private int counter = 0; IndexedContainer container = new IndexedContainer(); @Override - public void init() { - try { - Window main = new Window("Table header Test"); - setMainWindow(main); - main.setSizeFull(); - // setTheme("testtheme"); - VerticalLayout baseLayout = new VerticalLayout(); - main.setContent(baseLayout); - - table = new Table(); - container.addContainerProperty("row", String.class, ""); - table.setContainerDataSource(container); - table.setWidth("100%"); - table.setPageLength(3); - buttonIndex = new Button("Add row and select last index", this); - buttonItem = new Button("Add row and select last item", this); - - baseLayout.addComponent(table); - baseLayout.addComponent(buttonIndex); - baseLayout.addComponent(buttonItem); - } catch (Exception e) { - e.printStackTrace(); + public void setup() { + container.addContainerProperty("row", String.class, ""); + + HorizontalLayout baseLayout = new HorizontalLayout(); + baseLayout.setHeight("115px"); + addComponent(baseLayout); + + for (int i = 0; i < tables.length; ++i) { + Table t = new Table(); + t.setContainerDataSource(container); + t.setWidth("100px"); + baseLayout.addComponent(t); + tables[i] = t; } + tables[0].setSizeFull(); + tables[0].setCaption("Full"); + tables[1].setHeight("100px"); + tables[1].setCaption("100px"); + tables[2].setHeight("95%"); + tables[2].setCaption("95%"); + tables[3].setPageLength(3); + tables[3].setCaption("3 rows"); + + buttonIndex = new Button("Add row and select last index", this); + buttonItem = new Button("Add row and select last item", this); + baseLayout.addComponent(buttonIndex); + baseLayout.addComponent(buttonItem); } public void buttonClick(ClickEvent event) { Item item = container.addItem(++counter); item.getItemProperty("row").setValue(counter + ""); - table.select(counter); - if (event.getButton() == buttonIndex) { - table.setCurrentPageFirstItemIndex(((Container.Indexed) table - .getContainerDataSource()).indexOfId(counter)); - } else { - table.setCurrentPageFirstItemId(counter); + for (int i = 0; i < tables.length; ++i) { + Table t = tables[i]; + t.select(counter); + if (event.getButton() == buttonIndex) { + t.setCurrentPageFirstItemIndex(((Container.Indexed) t + .getContainerDataSource()).indexOfId(counter)); + } else { + t.setCurrentPageFirstItemId(counter); + } } } + + @Override + protected String getDescription() { + return "Table height changes when using setCurrentPageFirstItemId"; + } + + @Override + protected Integer getTicketNumber() { + return 2864; + } } -- cgit v1.2.3 From 4e9afbf56db644334d1d172c0193706aa64551ee Mon Sep 17 00:00:00 2001 From: Automerge Date: Wed, 18 Apr 2012 13:21:22 +0000 Subject: [merge from 6.7] Fixed layout to match test script and screenshots svn changeset:23573/svn branch:6.8 --- .../com/vaadin/tests/components/table/TestCurrentPageFirstItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.java b/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.java index 6e38f2a156..2bc03f9814 100644 --- a/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.java +++ b/tests/testbench/com/vaadin/tests/components/table/TestCurrentPageFirstItem.java @@ -24,7 +24,7 @@ public class TestCurrentPageFirstItem extends TestBase implements ClickListener HorizontalLayout baseLayout = new HorizontalLayout(); baseLayout.setHeight("115px"); - addComponent(baseLayout); + getMainWindow().setContent(baseLayout); for (int i = 0; i < tables.length; ++i) { Table t = new Table(); -- cgit v1.2.3 From 9a695b7c8ca1b6c5bdc9d29f9088e694a895420d Mon Sep 17 00:00:00 2001 From: Automerge Date: Wed, 18 Apr 2012 13:21:27 +0000 Subject: [merge from 6.7] added tests case that contains varios setups to check scrolling and related stuff work with touch devices svn changeset:23574/svn branch:6.8 --- .../vaadin/tests/components/TouchScrollables.java | 238 +++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 tests/testbench/com/vaadin/tests/components/TouchScrollables.java diff --git a/tests/testbench/com/vaadin/tests/components/TouchScrollables.java b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java new file mode 100644 index 0000000000..39e5bb02c4 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java @@ -0,0 +1,238 @@ +package com.vaadin.tests.components; + +import java.util.Collection; + +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.event.DataBoundTransferable; +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.event.dd.acceptcriteria.SourceIs; +import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; +import com.vaadin.tests.util.Person; +import com.vaadin.tests.util.PersonContainer; +import com.vaadin.tests.util.TestUtils; +import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Component; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Panel; +import com.vaadin.ui.Table; + +public class TouchScrollables extends TestBase { + java.util.Random r = new java.util.Random(1); + + private HorizontalLayout testSelector; + + @Override + public void setup() { + testSelector = new HorizontalLayout(); + getLayout().addComponent(testSelector); + + CssLayout cssLayout = new CssLayout(); + final Table table = new Table(); + + Button button = new Button("Make pagelength 0"); + button.addListener(new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + table.setCacheRate(100); + table.setHeight("400px"); + } + }); + + cssLayout.addComponent(button); + + table.addContainerProperty("foo", String.class, "bar"); + table.setRowHeaderMode(Table.ROW_HEADER_MODE_INDEX); + for (int i = 0; i < 1000; i++) { + table.addItem(); + } + cssLayout.addComponent(table); + cssLayout.setCaption("Table"); + + addTest(cssLayout); + + cssLayout = new CssLayout(); + cssLayout.setCaption("Panel"); + + final Panel p = new Panel(); + p.setScrollable(true); + p.setHeight("400px"); + p.setCaption("Panel"); + Label l50 = null; + for (int i = 0; i < 100; i++) { + Label c = new Label("Label" + i); + p.addComponent(c); + if (i == 50) { + l50 = c; + } + } + + final Label l = l50; + button = new Button("Scroll to label 50", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + getLayout().getWindow().scrollIntoView(l); + } + }); + cssLayout.addComponent(button); + button = new Button("Scroll to 100px", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + p.setScrollTop(100); + } + }); + cssLayout.addComponent(button); + cssLayout.addComponent(p); + + addTest(cssLayout); + + TestUtils + .injectCSS( + getLayout().getWindow(), + ".v-table-row-drag-middle .v-table-cell-content {" + + " background-color: inherit ; border-bottom: 1px solid cyan;" + + "}" + + ".v-table-row-drag-middle .v-table-cell-wrapper {" + + " margin-bottom: -1px;" + "}" + "" + + ); + + addDDSortableTable(); + + } + + private void addDDSortableTable() { + final Table table; + table = new Table(); + table.setCaption("DD sortable table"); + // table.setWidth("100%"); + table.setPageLength(10); + table.setRowHeaderMode(Table.ROW_HEADER_MODE_ID); + table.setSelectable(true); + table.setMultiSelect(true); + populateTable(table); + + /* + * Make table rows draggable + */ + table.setDragMode(Table.TableDragMode.ROW); + + table.setDropHandler(new DropHandler() { + // accept only drags from this table + AcceptCriterion crit = new SourceIs(table); + + public AcceptCriterion getAcceptCriterion() { + return crit; + } + + public void drop(DragAndDropEvent dropEvent) { + AbstractSelectTargetDetails dropTargetData = (AbstractSelectTargetDetails) dropEvent + .getTargetDetails(); + DataBoundTransferable transferable = (DataBoundTransferable) dropEvent + .getTransferable(); + Object itemIdOver = dropTargetData.getItemIdOver(); + Object itemId = transferable.getItemId(); + if (itemId == null || itemIdOver == null + || itemId.equals(itemIdOver)) { + return; // no move happened + } + + // IndexedContainer goodies... (hint: don't use it in real apps) + IndexedContainer containerDataSource = (IndexedContainer) table + .getContainerDataSource(); + int newIndex = containerDataSource.indexOfId(itemIdOver) - 1; + if (dropTargetData.getDropLocation() != VerticalDropLocation.TOP) { + newIndex++; + } + if (newIndex < 0) { + newIndex = 0; + } + Object idAfter = containerDataSource.getIdByIndex(newIndex); + Collection selections = (Collection) table.getValue(); + if (selections != null && selections.contains(itemId)) { + // dragged a selected item, if multiple rows selected, drag + // them too (functionality similar to apple mail) + for (Object object : selections) { + moveAfter(containerDataSource, object, idAfter); + } + + } else { + // move just the dragged row, not considering selection at + // all + moveAfter(containerDataSource, itemId, idAfter); + } + + } + + private void moveAfter(IndexedContainer containerDataSource, + Object itemId, Object idAfter) { + try { + IndexedContainer clone = null; + clone = (IndexedContainer) containerDataSource.clone(); + containerDataSource.removeItem(itemId); + Item newItem = containerDataSource.addItemAfter(idAfter, + itemId); + Item item = clone.getItem(itemId); + for (Object propId : item.getItemPropertyIds()) { + newItem.getItemProperty(propId).setValue( + item.getItemProperty(propId).getValue()); + } + + // TODO Auto-generated method stub + } catch (CloneNotSupportedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + }); + addTest(table); + } + + private void populateTable(Table table) { + table.addContainerProperty("Name", String.class, ""); + table.addContainerProperty("Weight", Integer.class, 0); + + PersonContainer testData = PersonContainer.createWithTestData(); + + for (int i = 0; i < 40; i++) { + Item addItem = table.addItem("Item" + i); + Person p = testData.getIdByIndex(i); + addItem.getItemProperty("Name").setValue( + p.getFirstName() + " " + p.getLastName()); + addItem.getItemProperty("Weight").setValue(50 + r.nextInt(60)); + } + + } + + private Component testComponent; + + private void addTest(final AbstractComponent t) { + Button button = new Button(t.getCaption()); + testSelector.addComponent(button); + button.addListener(new Button.ClickListener() { + + public void buttonClick(ClickEvent event) { + if (testComponent != null) { + getLayout().removeComponent(testComponent); + } + testComponent = t; + getLayout().addComponent(t); + } + }); + } + + @Override + protected String getDescription() { + return "Various components and setups suitable for testing scrolling on touch devices."; + } + + @Override + protected Integer getTicketNumber() { + return null; + } +} -- cgit v1.2.3 From 1a95d50942f64bec70647587408f37d34addb767 Mon Sep 17 00:00:00 2001 From: Automerge Date: Wed, 18 Apr 2012 13:21:32 +0000 Subject: [merge from 6.7] enhanced test case svn changeset:23575/svn branch:6.8 --- .../vaadin/tests/components/TouchScrollables.java | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/testbench/com/vaadin/tests/components/TouchScrollables.java b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java index 39e5bb02c4..8d3ef715cc 100644 --- a/tests/testbench/com/vaadin/tests/components/TouchScrollables.java +++ b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java @@ -4,6 +4,8 @@ import java.util.Collection; import com.vaadin.data.Item; import com.vaadin.data.util.IndexedContainer; +import com.vaadin.event.Action; +import com.vaadin.event.Action.Handler; import com.vaadin.event.DataBoundTransferable; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; @@ -108,12 +110,28 @@ public class TouchScrollables extends TestBase { private void addDDSortableTable() { final Table table; table = new Table(); - table.setCaption("DD sortable table"); + table.setCaption("DD sortable table with context menus"); // table.setWidth("100%"); table.setPageLength(10); table.setRowHeaderMode(Table.ROW_HEADER_MODE_ID); table.setSelectable(true); table.setMultiSelect(true); + + table.addActionHandler(new Handler() { + + Action[] actions = new Action[] { new Action("FOO"), + new Action("BAR"), new Action("CAR") }; + + public Action[] getActions(Object target, Object sender) { + return actions; + } + + public void handleAction(Action action, Object sender, Object target) { + getLayout().getWindow().showNotification(action.getCaption()); + + } + }); + populateTable(table); /* -- cgit v1.2.3 From 41a97f25d5a23c984698097c7f42e56e239425b7 Mon Sep 17 00:00:00 2001 From: Automerge Date: Wed, 18 Apr 2012 17:07:29 +0000 Subject: [merge from 6.7] improved test case svn changeset:23580/svn branch:6.8 --- .../vaadin/tests/components/TouchScrollables.java | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/testbench/com/vaadin/tests/components/TouchScrollables.java b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java index 8d3ef715cc..88335a1996 100644 --- a/tests/testbench/com/vaadin/tests/components/TouchScrollables.java +++ b/tests/testbench/com/vaadin/tests/components/TouchScrollables.java @@ -39,14 +39,26 @@ public class TouchScrollables extends TestBase { CssLayout cssLayout = new CssLayout(); final Table table = new Table(); - Button button = new Button("Make pagelength 0"); + Button button = new Button("Toggle lazyloading"); button.addListener(new Button.ClickListener() { public void buttonClick(ClickEvent event) { - table.setCacheRate(100); - table.setHeight("400px"); + if (table.getCacheRate() == 100) { + table.setCacheRate(2); + table.setPageLength(15); + } else { + table.setCacheRate(100); + table.setHeight("400px"); + } } }); + cssLayout.addComponent(button); + button = new Button("Toggle selectable"); + button.addListener(new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + table.setSelectable(!table.isSelectable()); + } + }); cssLayout.addComponent(button); table.addContainerProperty("foo", String.class, "bar"); @@ -95,7 +107,7 @@ public class TouchScrollables extends TestBase { TestUtils .injectCSS( getLayout().getWindow(), - ".v-table-row-drag-middle .v-table-cell-content {" + "body * {-webkit-user-select: none;} .v-table-row-drag-middle .v-table-cell-content {" + " background-color: inherit ; border-bottom: 1px solid cyan;" + "}" + ".v-table-row-drag-middle .v-table-cell-wrapper {" -- cgit v1.2.3 From 5b9baad920779278f9e24f22e45499604ef6f7bf Mon Sep 17 00:00:00 2001 From: Automerge Date: Wed, 18 Apr 2012 17:07:34 +0000 Subject: [merge from 6.7] Quickly typed in touch scroll related changes due to ridiculous android browser bug http://code.google.com/p/android/issues/detail?id=19625 . That practically breaks scrolling in vaadin on new android devices. Some other changes and cleanup in the same excersize. Fixes at least #8550, but practically makes scrolling possible on new android devices. svn changeset:23581/svn branch:6.8 --- .../gwt/client/ui/FocusableScrollPanel.java | 27 ++- .../gwt/client/ui/TouchScrollDelegate.java | 226 +++++++++++++-------- .../terminal/gwt/client/ui/VScrollTable.java | 23 ++- 3 files changed, 187 insertions(+), 89 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java index 1025752ca9..96cb4b8a35 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java @@ -3,6 +3,8 @@ */ package com.vaadin.terminal.gwt.client.ui; +import java.util.ArrayList; + import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.DivElement; @@ -22,6 +24,7 @@ import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.impl.FocusImpl; import com.vaadin.terminal.gwt.client.BrowserInfo; +import com.vaadin.terminal.gwt.client.VConsole; /** * A scrollhandlers similar to {@link ScrollPanel}. @@ -136,7 +139,11 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements * @return the vertical scroll position, in pixels */ public int getScrollPosition() { - return getElement().getScrollTop(); + if (getElement().getPropertyJSO("_vScrollTop") != null) { + return getElement().getPropertyInt("_vScrollTop"); + } else { + return getElement().getScrollTop(); + } } /** @@ -156,7 +163,23 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements * the new vertical scroll position, in pixels */ public void setScrollPosition(int position) { - getElement().setScrollTop(position); + if (isAndroidWithBrokenScrollTop()) { + ArrayList elements = TouchScrollDelegate + .getElements(getElement()); + for (com.google.gwt.dom.client.Element el : elements) { + final Style style = el.getStyle(); + style.setProperty("webkitTransform", "translate3d(0px," + + -position + "px,0px)"); + } + getElement().setPropertyInt("_vScrollTop", position); + } else { + getElement().setScrollTop(position); + } + } + + private boolean isAndroidWithBrokenScrollTop() { + return BrowserInfo.getBrowserString().contains("Android 3") + || BrowserInfo.getBrowserString().contains("Android 4"); } public void onScroll(ScrollEvent event) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java index 3c08741de5..0341a527b7 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java +++ b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java @@ -4,19 +4,22 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.ArrayList; -import java.util.Date; +import com.google.gwt.animation.client.Animation; +import com.google.gwt.core.client.Duration; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; 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.Touch; +import com.google.gwt.event.dom.client.ScrollHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.Event.NativePreviewHandler; +import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.VConsole; /** @@ -64,27 +67,33 @@ public class TouchScrollDelegate implements NativePreviewHandler { private static final double FRICTION = 0.002; private static final double DECELERATION = 0.002; private static final int MAX_DURATION = 1500; - private int origX; private int origY; private Element[] scrollableElements; private Element scrolledElement; private int origScrollTop; private HandlerRegistration handlerRegistration; private int lastClientY; - private double pixxelsPerMs; - private boolean transitionPending = false; private int deltaScrollPos; private boolean transitionOn = false; private int finalScrollTop; private ArrayList layers; private boolean moved; + private ScrollHandler scrollHandler; private static TouchScrollDelegate activeScrollDelegate; + private static final boolean androidWithBrokenScrollTop = BrowserInfo + .getBrowserString().contains("Android 3") + || BrowserInfo.getBrowserString().contains("Android 4"); + public TouchScrollDelegate(Element... elements) { scrollableElements = elements; } + public void setScrollHandler(ScrollHandler scrollHandler) { + this.scrollHandler = scrollHandler; + } + public static TouchScrollDelegate getActiveScrollDelegate() { return activeScrollDelegate; } @@ -123,26 +132,14 @@ public class TouchScrollDelegate implements NativePreviewHandler { event.stopPropagation(); handlerRegistration = Event.addNativePreviewHandler(this); activeScrollDelegate = this; - hookTransitionEndListener(scrolledElement - .getFirstChildElement()); - origX = touch.getClientX(); origY = touch.getClientY(); yPositions[0] = origY; - eventTimeStamps[0] = new Date(); + eventTimeStamps[0] = getTimeStamp(); nextEvent = 1; - if (transitionOn) { - // TODO calculate current position of ongoing transition, - // fix to that and start scroll from there. Another option - // is to investigate if we can get even close the same - // framerate with scheduler based impl instead of using - // transitions (GWT examples has impl of this, with jsni - // though). This is very smooth on native ipad, now we - // ignore touch starts during animation. - origScrollTop = scrolledElement.getScrollTop(); - } else { - origScrollTop = scrolledElement.getScrollTop(); - } + origScrollTop = getScrollTop(); + VConsole.log("ST" + origScrollTop); + moved = false; // event.preventDefault(); // event.stopPropagation(); @@ -154,16 +151,30 @@ public class TouchScrollDelegate implements NativePreviewHandler { } } - private native void hookTransitionEndListener(Element element) - /*-{ - if(!element.hasTransitionEndListener) { - var that = this; - element.addEventListener("webkitTransitionEnd",function(event){ - that.@com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate::onTransitionEnd()(); - },false); - element.hasTransitionEndListener = true; + private int getScrollTop() { + if (androidWithBrokenScrollTop) { + if (scrolledElement.getPropertyJSO("_vScrollTop") != null) { + return scrolledElement.getPropertyInt("_vScrollTop"); + } else { + return 0; + } + } else { + if (transitionOn) { + // TODO calculate current position of ongoing + // transition, + // fix to that and start scroll from there. Another + // option + // is to investigate if we can get even close the same + // framerate with scheduler based impl instead of using + // transitions (GWT examples has impl of this, with jsni + // though). This is very smooth on native ipad, now we + // ignore touch starts during animation. + return scrolledElement.getScrollTop(); + } else { + return scrolledElement.getScrollTop(); + } } - }-*/; + } private void onTransitionEnd() { if (finalScrollTop < 0) { @@ -184,7 +195,14 @@ public class TouchScrollDelegate implements NativePreviewHandler { if (time <= 0) { time = 1; // get animation and transition end event } - translateTo(time, -to + origScrollTop); + VConsole.log("Animate " + time + " " + from + " " + to); + int translateTo = -to + origScrollTop; + int fromY = -from + origScrollTop; + if (androidWithBrokenScrollTop) { + fromY -= origScrollTop; + translateTo -= origScrollTop; + } + translateTo(time, fromY, translateTo); } private int getAnimationTimeForDistance(int dist) { @@ -200,16 +218,21 @@ public class TouchScrollDelegate implements NativePreviewHandler { * scrolltop, causing onscroll event. */ private void moveTransformationToScrolloffset() { - for (Element el : layers) { - Style style = el.getStyle(); - style.setProperty("webkitTransitionProperty", "none"); - style.setProperty("webkitTransform", "translate3d(0,0,0)"); + if (androidWithBrokenScrollTop) { + scrolledElement.setPropertyInt("_vScrollTop", finalScrollTop); + if (scrollHandler != null) { + scrollHandler.onScroll(null); + } + } else { + for (Element el : layers) { + Style style = el.getStyle(); + style.setProperty("webkitTransform", "translate3d(0,0,0)"); + } + scrolledElement.setScrollTop(finalScrollTop); } - scrolledElement.setScrollTop(finalScrollTop); activeScrollDelegate = null; handlerRegistration.removeHandler(); handlerRegistration = null; - } /** @@ -225,14 +248,7 @@ public class TouchScrollDelegate implements NativePreviewHandler { if (el.isOrHasChild(target) && el.getScrollHeight() > el.getClientHeight()) { scrolledElement = el; - NodeList childNodes = scrolledElement.getChildNodes(); - layers = new ArrayList(); - for (int i = 0; i < childNodes.getLength(); i++) { - Node item = childNodes.getItem(i); - if (item.getNodeType() == Node.ELEMENT_NODE) { - layers.add((Element) item); - } - } + layers = getElements(scrolledElement); return true; } @@ -240,10 +256,21 @@ public class TouchScrollDelegate implements NativePreviewHandler { return false; } + public static ArrayList getElements(Element scrolledElement2) { + NodeList childNodes = scrolledElement2.getChildNodes(); + ArrayList l = new ArrayList(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.getItem(i); + if (item.getNodeType() == Node.ELEMENT_NODE) { + l.add((Element) item); + } + } + return l; + } + private void onTouchMove(NativeEvent event) { if (!moved) { - Date date = new Date(); - long l = (date.getTime() - eventTimeStamps[0].getTime()); + double l = (getTimeStamp() - eventTimeStamps[0]); VConsole.log(l + " ms from start to move"); } boolean handleMove = readPositionAndSpeed(event); @@ -255,15 +282,15 @@ public class TouchScrollDelegate implements NativePreviewHandler { int overscroll = (deltaScrollTop + origScrollTop) - getMaxFinalY(); overscroll = overscroll / 2; - if (overscroll > scrolledElement.getClientHeight() / 2) { - overscroll = scrolledElement.getClientHeight() / 2; + if (overscroll > getMaxOverScroll()) { + overscroll = getMaxOverScroll(); } deltaScrollTop = getMaxFinalY() + overscroll - origScrollTop; } else if (finalPos < 0) { // spring effect at the beginning int overscroll = finalPos / 2; - if (-overscroll > scrolledElement.getClientHeight() / 2) { - overscroll = -scrolledElement.getClientHeight() / 2; + if (-overscroll > getMaxOverScroll()) { + overscroll = -getMaxOverScroll(); } deltaScrollTop = overscroll - origScrollTop; } @@ -276,16 +303,20 @@ public class TouchScrollDelegate implements NativePreviewHandler { private void quickSetScrollPosition(int deltaX, int deltaY) { deltaScrollPos = deltaY; - translateTo(0, -deltaScrollPos); + if (androidWithBrokenScrollTop) { + deltaY += origScrollTop; + translateTo(-deltaY); + } else { + translateTo(-deltaScrollPos); + } } private static final int EVENTS_FOR_SPEED_CALC = 3; public static final int SIGNIFICANT_MOVE_THRESHOLD = 3; private int[] yPositions = new int[EVENTS_FOR_SPEED_CALC]; - private Date[] eventTimeStamps = new Date[EVENTS_FOR_SPEED_CALC]; + private double[] eventTimeStamps = new double[EVENTS_FOR_SPEED_CALC]; private int nextEvent = 0; - private Date transitionStart; - private Date transitionDuration; + private Animation momentum; /** * @@ -293,12 +324,11 @@ public class TouchScrollDelegate implements NativePreviewHandler { * @return */ private boolean readPositionAndSpeed(NativeEvent event) { - Date now = new Date(); Touch touch = event.getChangedTouches().get(0); lastClientY = touch.getClientY(); int eventIndx = nextEvent++; eventIndx = eventIndx % EVENTS_FOR_SPEED_CALC; - eventTimeStamps[eventIndx] = now; + eventTimeStamps[eventIndx] = getTimeStamp(); yPositions[eventIndx] = lastClientY; return isMovedSignificantly(); } @@ -348,15 +378,11 @@ public class TouchScrollDelegate implements NativePreviewHandler { // VConsole.log("To max overscroll"); finalY = getMaxFinalY() + getMaxOverScroll(); int fixedPixelsToMove = finalY - currentY; - pixelsPerMs = pixelsPerMs * pixelsToMove / fixedPixelsToMove - / FRICTION; pixelsToMove = fixedPixelsToMove; } else if (finalY < 0 - getMaxOverScroll()) { // VConsole.log("to min overscroll"); finalY = -getMaxOverScroll(); int fixedPixelsToMove = finalY - currentY; - pixelsPerMs = pixelsPerMs * pixelsToMove / fixedPixelsToMove - / FRICTION; pixelsToMove = fixedPixelsToMove; } else { duration = (int) (Math.abs(pixelsPerMs / DECELERATION)); @@ -380,8 +406,13 @@ public class TouchScrollDelegate implements NativePreviewHandler { return; } - int translateY = -finalY + origScrollTop; - translateTo(duration, translateY); + int translateTo = -finalY + origScrollTop; + int fromY = -currentY + origScrollTop; + if (androidWithBrokenScrollTop) { + fromY -= origScrollTop; + translateTo -= origScrollTop; + } + translateTo(duration, fromY, translateTo); } private double calculateSpeed() { @@ -392,15 +423,14 @@ public class TouchScrollDelegate implements NativePreviewHandler { } int idx = nextEvent % EVENTS_FOR_SPEED_CALC; final int firstPos = yPositions[idx]; - final Date firstTs = eventTimeStamps[idx]; + final double firstTs = eventTimeStamps[idx]; idx += EVENTS_FOR_SPEED_CALC; idx--; idx = idx % EVENTS_FOR_SPEED_CALC; final int lastPos = yPositions[idx]; - final Date lastTs = eventTimeStamps[idx]; + final double lastTs = eventTimeStamps[idx]; // speed as in change of scrolltop == -speedOfTouchPos - return (firstPos - lastPos) - / (double) (lastTs.getTime() - firstTs.getTime()); + return (firstPos - lastPos) / (lastTs - firstTs); } @@ -411,28 +441,51 @@ public class TouchScrollDelegate implements NativePreviewHandler { * @param duration * @param translateY */ - private void translateTo(int duration, int translateY) { + private void translateTo(double translateY) { for (Element el : layers) { - final Style style = el.getStyle(); - if (duration > 0) { - style.setProperty("webkitTransitionDuration", duration + "ms"); - style.setProperty("webkitTransitionTimingFunction", - "cubic-bezier(0,0,0.25,1)"); - style.setProperty("webkitTransitionProperty", - "-webkit-transform"); - transitionOn = true; - transitionStart = new Date(); - transitionDuration = new Date(); - } else { - style.setProperty("webkitTransitionProperty", "none"); - } + Style style = el.getStyle(); style.setProperty("webkitTransform", "translate3d(0px," + translateY + "px,0px)"); } } + /** + * Note positive scrolltop moves layer up, positive translate moves layer + * down. + * + * @param duration + * @param translateY + */ + private void translateTo(int duration, final int fromY, final int finalY) { + if (duration > 0) { + transitionOn = true; + + momentum = new Animation() { + + @Override + protected void onUpdate(double progress) { + double translateY = (fromY + (finalY - fromY) * progress); + translateTo(translateY); + } + + @Override + protected double interpolate(double progress) { + return 1 + Math.pow(progress - 1, 3); + } + + @Override + protected void onComplete() { + super.onComplete(); + onTransitionEnd(); + } + }; + momentum.run(duration); + } + } + private int getMaxOverScroll() { - return scrolledElement.getClientHeight() / 4; + return androidWithBrokenScrollTop ? 0 : scrolledElement + .getClientHeight() / 3; } private int getMaxFinalY() { @@ -484,4 +537,15 @@ public class TouchScrollDelegate implements NativePreviewHandler { public void setElements(com.google.gwt.user.client.Element[] elements) { scrollableElements = elements; } + + /** + * long calcucation are not very efficient in GWT, so this helper method + * returns timestamp in double. + * + * @return + */ + public static double getTimeStamp() { + return Duration.currentTimeMillis(); + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index 6bbc2a6ceb..1d20784264 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -18,6 +18,7 @@ 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.NativeEvent; +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; @@ -512,6 +513,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, if (touchScrollDelegate == null) { touchScrollDelegate = new TouchScrollDelegate( scrollBodyPanel.getElement()); + touchScrollDelegate.setScrollHandler(this); } return touchScrollDelegate; @@ -4062,6 +4064,14 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, DOM.appendChild(container, preSpacer); DOM.appendChild(container, table); DOM.appendChild(container, postSpacer); + if (BrowserInfo.get().isTouchDevice()) { + NodeList childNodes = container.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Element item = (Element) childNodes.getItem(i); + item.getStyle().setProperty("webkitTransform", + "translate3d(0,0,0)"); + } + } } @@ -4607,7 +4617,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, public class VScrollTableRow extends Panel implements ActionOwner, Container { - private static final int TOUCHSCROLL_TIMEOUT = 70; + private static final int TOUCHSCROLL_TIMEOUT = 100; private static final int DRAGMODE_MULTIROW = 2; protected ArrayList childWidgets = new ArrayList(); private boolean selected = false; @@ -5281,9 +5291,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, } }; } - contextTouchTimeout.cancel(); - contextTouchTimeout - .schedule(TOUCH_CONTEXT_MENU_TIMEOUT); + if (contextTouchTimeout != null) { + contextTouchTimeout.cancel(); + contextTouchTimeout + .schedule(TOUCH_CONTEXT_MENU_TIMEOUT); + } } break; case Event.ONMOUSEDOWN: @@ -5440,8 +5452,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, int top = Util.getTouchOrMouseClientY(event); top += Window.getScrollTop(); left += Window.getScrollLeft(); - contextMenu = new ContextMenuDetails(this.getKey(), left, - top); + contextMenu = new ContextMenuDetails(getKey(), left, top); client.getContextMenu().showAt(this, left, top); } } -- cgit v1.2.3 From c558076a1981adabbe99c1ec3dbf869ecb27cace Mon Sep 17 00:00:00 2001 From: Jonatan Kronqvist Date: Thu, 19 Apr 2012 06:33:34 +0000 Subject: Implemented #8694 - API providing profiling info for TestBench 3.x svn changeset:23582/svn branch:6.8 --- .../terminal/gwt/client/ApplicationConnection.java | 32 ++++- .../gwt/server/AbstractApplicationPortlet.java | 8 ++ .../gwt/server/AbstractApplicationServlet.java | 6 + .../gwt/server/AbstractCommunicationManager.java | 22 +++- .../vaadin/terminal/gwt/server/RequestTimer.java | 138 +++++++++++++++++++++ 5 files changed, 199 insertions(+), 7 deletions(-) create mode 100644 src/com/vaadin/terminal/gwt/server/RequestTimer.java diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 7a3a28495a..93e2657eb4 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -224,12 +224,22 @@ public class ApplicationConnection { return ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::hasActiveRequest()() || ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::isExecutingDeferredCommands()(); } + var vi = ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::getVersionInfo()(); if (vi) { client.getVersionInfo = function() { return vi; } } + + client.getProfilingData = function() { + var pd = [ + ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::lastProcessingTime, + ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::totalProcessingTime + ]; + pd = pd.concat(ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::testBenchServerStatus); + return pd; + } client.getElementByPath = function(id) { return componentLocator.@com.vaadin.terminal.gwt.client.ComponentLocator::getElementByPath(Ljava/lang/String;)(id); @@ -632,6 +642,13 @@ public class ApplicationConnection { } int cssWaits = 0; + + protected int lastProcessingTime; + + protected int totalProcessingTime; + + private ValueMap testBenchServerStatus; + static final int MAX_CSS_WAITS = 100; protected void handleWhenCSSLoaded(final String jsonText, @@ -952,6 +969,13 @@ public class ApplicationConnection { json.getValueMap("typeMappings"), widgetSet); } + /* + * Hook for TestBench to get details about server status + */ + if (json.containsKey("tbss")) { + testBenchServerStatus = json.getValueMap("tbss"); + } + Command c = new Command() { public void execute() { VConsole.dirUIDL(json, configuration); @@ -1129,10 +1153,12 @@ public class ApplicationConnection { // TODO build profiling for widget impl loading time - final long prosessingTime = (new Date().getTime()) - - start.getTime(); + lastProcessingTime = (int) ((new Date().getTime()) - start + .getTime()); + totalProcessingTime += lastProcessingTime; + VConsole.log(" Processing time was " - + String.valueOf(prosessingTime) + "ms for " + + String.valueOf(lastProcessingTime) + "ms for " + jsonText.length() + " characters of JSON"); VConsole.log("Referenced paintables: " + idToPaintableDetail.size()); diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index acae039e8b..a5923cb47f 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -326,6 +326,11 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet protected void handleRequest(PortletRequest request, PortletResponse response) throws PortletException, IOException { + RequestTimer.RequestWrapper wrappedRequest = new RequestTimer.RequestWrapper( + request); + RequestTimer requestTimer = RequestTimer.get(wrappedRequest); + requestTimer.start(wrappedRequest); + RequestType requestType = getRequestType(request); if (requestType == RequestType.UNKNOWN) { @@ -490,6 +495,9 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet request, response); } + + requestTimer.stop(); + RequestTimer.set(wrappedRequest, requestTimer); } } } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index 13082cf1aa..04ea423004 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -401,6 +401,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + RequestTimer.RequestWrapper wrappedRequest = new RequestTimer.RequestWrapper( + request); + RequestTimer requestTimer = RequestTimer.get(wrappedRequest); + requestTimer.start(wrappedRequest); RequestType requestType = getRequestType(request); if (!ensureCookiesEnabled(requestType, request, response)) { @@ -549,6 +553,8 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements request, response); } + requestTimer.stop(); + RequestTimer.set(wrappedRequest, requestTimer); } } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index c0654359a1..9a6bccebb8 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -912,7 +912,7 @@ public abstract class AbstractCommunicationManager implements repaintAll = true; } - writeUidlResponce(callback, repaintAll, outWriter, window, + writeUidlResponse(request, callback, repaintAll, outWriter, window, analyzeLayouts); } @@ -922,9 +922,9 @@ public abstract class AbstractCommunicationManager implements } - public void writeUidlResponce(Callback callback, boolean repaintAll, - final PrintWriter outWriter, Window window, boolean analyzeLayouts) - throws PaintException { + public void writeUidlResponse(Request request, Callback callback, + boolean repaintAll, final PrintWriter outWriter, Window window, + boolean analyzeLayouts) throws PaintException { outWriter.print("\"changes\":["); ArrayList paintables = null; @@ -1205,6 +1205,20 @@ public abstract class AbstractCommunicationManager implements if (dragAndDropService != null) { dragAndDropService.printJSONResponse(outWriter); } + + writePerformanceDataForTestBench(request, outWriter); + } + + /** + * Adds the performance timing data used by TestBench 3 to the UIDL + * response. + */ + private void writePerformanceDataForTestBench(final Request request, + final PrintWriter outWriter) { + Long totalTime = (Long) request.getAttribute("TOTAL"); + Long lastRequestTime = (Long) request.getAttribute("LASTREQUEST"); + outWriter.write(String.format(", \"tbss\":[%d, %d]", totalTime, + lastRequestTime)); } private int getTimeoutInterval() { diff --git a/src/com/vaadin/terminal/gwt/server/RequestTimer.java b/src/com/vaadin/terminal/gwt/server/RequestTimer.java new file mode 100644 index 0000000000..3649ed3a80 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/server/RequestTimer.java @@ -0,0 +1,138 @@ +package com.vaadin.terminal.gwt.server; + +import javax.portlet.PortletRequest; +import javax.portlet.PortletSession; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +/** + * Times the handling of requests and stores the information as an attribute in + * the request. The timing info is later passed on to the client in the UIDL and + * the client provides JavaScript API for accessing this data from e.g. + * TestBench. + * + * @author Jonatan Kronqvist / Vaadin Ltd + */ +public class RequestTimer { + public static final String SESSION_ATTR_ID = "REQUESTTIMER"; + + private long requestStartTime = 0; + private long totalSessionTime = 0; + private long lastRequestTime = -1; + + /** + * This class acts as a proxy for setting and getting session and request + * attributes on HttpServletRequests and PortletRequests. Using this class + * we don't need to duplicate code everywhere. + */ + static class RequestWrapper { + private final HttpServletRequest servletRequest; + private final PortletRequest portletRequest; + + public RequestWrapper(HttpServletRequest servletRequest) { + this.servletRequest = servletRequest; + portletRequest = null; + } + + public RequestWrapper(PortletRequest portletRequest) { + this.portletRequest = portletRequest; + servletRequest = null; + } + + public void setAttribute(String name, Object value) { + if (servletRequest != null) { + servletRequest.setAttribute(name, value); + } else { + portletRequest.setAttribute(name, value); + } + } + + public void setSessionAttribute(String name, Object value) { + if (servletRequest != null) { + HttpSession session = servletRequest.getSession(); + if (session != null) { + session.setAttribute(name, value); + } + } else { + PortletSession portletSession = portletRequest + .getPortletSession(); + if (portletSession != null) { + portletSession.setAttribute(name, value); + } + } + } + + public Object getSessionAttribute(String name) { + if (servletRequest != null) { + HttpSession session = servletRequest.getSession(); + if (session != null) { + return session.getAttribute(name); + } + } else { + PortletSession portletSession = portletRequest + .getPortletSession(); + if (portletSession != null) { + return portletSession.getAttribute(name); + } + } + return null; + } + } + + /** + * Starts the timing of a request. This should be called before any + * processing of the request. + * + * @param request + * the request. + */ + public void start(RequestWrapper request) { + requestStartTime = System.nanoTime(); + request.setAttribute("TOTAL", totalSessionTime); + request.setAttribute("LASTREQUEST", lastRequestTime); + } + + /** + * Stops the timing of a request. This should be called when all processing + * of a request has finished. + */ + public void stop() { + // Measure and store the total handling time. This data can be + // used in TestBench 3 tests. + long time = (System.nanoTime() - requestStartTime) / 1000000; + lastRequestTime = time; + totalSessionTime += time; + } + + /** + * Returns a valid request timer for the specified request. Timers are + * session bound. + * + * @param request + * the request for which to get a valid timer. + * @return a valid timer. + */ + public static RequestTimer get(RequestWrapper request) { + RequestTimer timer = (RequestTimer) request + .getSessionAttribute(SESSION_ATTR_ID); + if (timer == null) { + timer = new RequestTimer(); + } + return timer; + } + + /** + * Associates the specified request timer with the specified request. Since + * {@link #get(RequestWrapper)} will, at one point or another, return a new + * instance, this method should be called to keep the request <-> timer + * association updated. + * + * @param request + * the request for which to set the timer. + * @param requestTimer + * the timer. + */ + public static void set(RequestWrapper request, RequestTimer requestTimer) { + request.setSessionAttribute(RequestTimer.SESSION_ATTR_ID, requestTimer); + } +} -- cgit v1.2.3 From 423a93b491612d54521f2d36be77256ddcdfa28d Mon Sep 17 00:00:00 2001 From: Jonatan Kronqvist Date: Thu, 19 Apr 2012 07:00:34 +0000 Subject: Added some comments for #8694 svn changeset:23583/svn branch:6.8 --- .../vaadin/terminal/gwt/client/ApplicationConnection.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 93e2657eb4..0603e80c93 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -643,10 +643,23 @@ public class ApplicationConnection { int cssWaits = 0; + /** + * Holds the time spent rendering the last request + */ protected int lastProcessingTime; + /** + * Holds the total time spent rendering requests during the lifetime of the + * session. + */ protected int totalProcessingTime; + /** + * Holds the timing information from the server-side. How much time was + * spent servicing the last request and how much time has been spent + * servicing the session so far. These values are always one request behind, + * since they cannot be measured before the request is finished. + */ private ValueMap testBenchServerStatus; static final int MAX_CSS_WAITS = 100; -- cgit v1.2.3 From 0418eab9bd85e107e3b0b31f11e36377b586e2cc Mon Sep 17 00:00:00 2001 From: Jonatan Kronqvist Date: Thu, 19 Apr 2012 11:14:49 +0000 Subject: Added the license notice to a new file added in #8694 svn changeset:23589/svn branch:6.8 --- src/com/vaadin/terminal/gwt/server/RequestTimer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/vaadin/terminal/gwt/server/RequestTimer.java b/src/com/vaadin/terminal/gwt/server/RequestTimer.java index 3649ed3a80..5ed89c2d29 100644 --- a/src/com/vaadin/terminal/gwt/server/RequestTimer.java +++ b/src/com/vaadin/terminal/gwt/server/RequestTimer.java @@ -1,3 +1,7 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + package com.vaadin.terminal.gwt.server; import javax.portlet.PortletRequest; -- cgit v1.2.3 From 3e090564a903aa1f39ef212d21382ffeab43e6cd Mon Sep 17 00:00:00 2001 From: Automerge Date: Thu, 19 Apr 2012 13:07:40 +0000 Subject: [merge from 6.7] Test case and fix for #8625: Firefox and IE9 need an overflow hack to prevent unwanted scrollbars with nested TabSheets in some cases svn changeset:23592/svn branch:6.8 --- .../vaadin/terminal/gwt/client/ui/VTabsheet.java | 9 +++- .../tabsheet/ScrollbarsInNestedTabsheets.html | 32 ++++++++++++ .../tabsheet/ScrollbarsInNestedTabsheets.java | 58 ++++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 tests/testbench/com/vaadin/tests/components/tabsheet/ScrollbarsInNestedTabsheets.html create mode 100644 tests/testbench/com/vaadin/tests/components/tabsheet/ScrollbarsInNestedTabsheets.java diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java index 7b9b900289..f1a5b31379 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java @@ -1257,7 +1257,14 @@ public class VTabsheet extends VTabsheetBase implements Focusable, */ iLayout(); client.runDescendentsLayout(this); - + /* + * Firefox and IE9 need a nudge to prevent unwanted scrollbars with + * Chameleon theme (#8625) + */ + if (BrowserInfo.get().isFirefox() || BrowserInfo.get().isIE9()) { + Util.setStyleTemporarily((Element) tp.getElement() + .getFirstChildElement(), "overflow", ""); + } return false; } else { /* diff --git a/tests/testbench/com/vaadin/tests/components/tabsheet/ScrollbarsInNestedTabsheets.html b/tests/testbench/com/vaadin/tests/components/tabsheet/ScrollbarsInNestedTabsheets.html new file mode 100644 index 0000000000..f5579c9875 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/tabsheet/ScrollbarsInNestedTabsheets.html @@ -0,0 +1,32 @@ + + + + + + +ScrollbarsInNestedTabsheets + + + + + + + + + + + + + + + + + + + + + + +
ScrollbarsInNestedTabsheets
open/run/ScrollbarsInNestedTabsheets?restartApplication
mouseClickvaadin=runScrollbarsInNestedTabsheets::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VTabsheet[0]/VTabsheetPanel[0]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]27,8
screenCaptureshould-not-have-scrollbars
+ + diff --git a/tests/testbench/com/vaadin/tests/components/tabsheet/ScrollbarsInNestedTabsheets.java b/tests/testbench/com/vaadin/tests/components/tabsheet/ScrollbarsInNestedTabsheets.java new file mode 100644 index 0000000000..de250539ff --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/tabsheet/ScrollbarsInNestedTabsheets.java @@ -0,0 +1,58 @@ +package com.vaadin.tests.components.tabsheet; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.DateField; +import com.vaadin.ui.Label; +import com.vaadin.ui.Layout; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; + +@SuppressWarnings("serial") +public class ScrollbarsInNestedTabsheets extends TestBase { + + @Override + public void setup() { + setTheme("chameleon"); + final Label l = new Label("Select Sub Tab 2"); + final TabSheet t = new TabSheet(); + final TabSheet t2 = getTabSheet(); + t.addTab(t2, "Main Tab"); + addComponent(l); + addComponent(t); + } + + private TabSheet getTabSheet() { + final TabSheet t = new TabSheet(); + t.addTab(getDummyLayout1(), "Sub Tab 1"); + t.addTab(getDummyLayout2(), "Sub Tab 2"); + + return t; + } + + private Layout getDummyLayout1() { + final VerticalLayout l = new VerticalLayout(); + l.addComponent(new DateField("Date")); + + return l; + } + + private Layout getDummyLayout2() { + final VerticalLayout l = new VerticalLayout(); + l.addComponent(new DateField("Date")); + l.addComponent(new TextField("TextField")); + + return l; + } + + @Override + protected String getDescription() { + return "Nested tabsheets show unwanted scrollbars with Chameleon theme when the inner tabsheet is resized"; + } + + @Override + protected Integer getTicketNumber() { + return 8625; + } + +} \ No newline at end of file -- cgit v1.2.3 From de45cafb0f9eaa3bbac6bde4da065915f2c1c4c2 Mon Sep 17 00:00:00 2001 From: Automerge Date: Thu, 19 Apr 2012 13:07:45 +0000 Subject: [merge from 6.7] Skipping "scroll selected/focused row into view" on touch devices as it breaks androids with broken scrolltop and should be obsolete on touch devices anyway svn changeset:23593/svn branch:6.8 --- src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index 1d20784264..a022a2bd83 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -6501,6 +6501,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, * The row to ensure is visible */ private void ensureRowIsVisible(VScrollTableRow row) { + if (BrowserInfo.get().isTouchDevice()) { + // Skip due to android devices that have broken scrolltop will may + // get odd scrolling here. + return; + } Util.scrollIntoViewVertically(row.getElement()); } -- cgit v1.2.3 From 1abcab4585409df811fd2f93840bcab686a9d5a6 Mon Sep 17 00:00:00 2001 From: Automerge Date: Thu, 19 Apr 2012 13:07:50 +0000 Subject: [merge from 6.7] * fixed timing issue that might leave scroll "outside" of the viewport on ios devices when scrolling furiously while animation is still ongoing. svn changeset:23594/svn branch:6.8 --- .../gwt/client/ui/TouchScrollDelegate.java | 90 +++++++++++----------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java index 0341a527b7..d4b59ed23a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java +++ b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java @@ -72,6 +72,7 @@ public class TouchScrollDelegate implements NativePreviewHandler { private Element scrolledElement; private int origScrollTop; private HandlerRegistration handlerRegistration; + private double lastAnimatedTranslateY; private int lastClientY; private int deltaScrollPos; private boolean transitionOn = false; @@ -125,25 +126,8 @@ public class TouchScrollDelegate implements NativePreviewHandler { public void onTouchStart(TouchStartEvent event) { if (activeScrollDelegate == null && event.getTouches().length() == 1) { - - Touch touch = event.getTouches().get(0); - if (detectScrolledElement(touch)) { - VConsole.log("TouchDelegate takes over"); - event.stopPropagation(); - handlerRegistration = Event.addNativePreviewHandler(this); - activeScrollDelegate = this; - origY = touch.getClientY(); - yPositions[0] = origY; - eventTimeStamps[0] = getTimeStamp(); - nextEvent = 1; - - origScrollTop = getScrollTop(); - VConsole.log("ST" + origScrollTop); - - moved = false; - // event.preventDefault(); - // event.stopPropagation(); - } + NativeEvent nativeEvent = event.getNativeEvent(); + doTouchStart(nativeEvent); } else { /* * Touch scroll is currenly on (possibly bouncing). Ignore. @@ -151,29 +135,38 @@ public class TouchScrollDelegate implements NativePreviewHandler { } } + private void doTouchStart(NativeEvent nativeEvent) { + if (transitionOn) { + momentum.cancel(); + } + Touch touch = nativeEvent.getTouches().get(0); + if (detectScrolledElement(touch)) { + VConsole.log("TouchDelegate takes over"); + nativeEvent.stopPropagation(); + handlerRegistration = Event.addNativePreviewHandler(this); + activeScrollDelegate = this; + origY = touch.getClientY(); + yPositions[0] = origY; + eventTimeStamps[0] = getTimeStamp(); + nextEvent = 1; + + origScrollTop = getScrollTop(); + VConsole.log("ST" + origScrollTop); + + moved = false; + // event.preventDefault(); + // event.stopPropagation(); + } + } + private int getScrollTop() { if (androidWithBrokenScrollTop) { if (scrolledElement.getPropertyJSO("_vScrollTop") != null) { return scrolledElement.getPropertyInt("_vScrollTop"); - } else { - return 0; - } - } else { - if (transitionOn) { - // TODO calculate current position of ongoing - // transition, - // fix to that and start scroll from there. Another - // option - // is to investigate if we can get even close the same - // framerate with scheduler based impl instead of using - // transitions (GWT examples has impl of this, with jsni - // though). This is very smooth on native ipad, now we - // ignore touch starts during animation. - return scrolledElement.getScrollTop(); - } else { - return scrolledElement.getScrollTop(); } + return 0; } + return scrolledElement.getScrollTop(); } private void onTransitionEnd() { @@ -186,7 +179,6 @@ public class TouchScrollDelegate implements NativePreviewHandler { } else { moveTransformationToScrolloffset(); } - transitionOn = false; } private void animateToScrollPosition(int to, int from) { @@ -437,9 +429,6 @@ public class TouchScrollDelegate implements NativePreviewHandler { /** * Note positive scrolltop moves layer up, positive translate moves layer * down. - * - * @param duration - * @param translateY */ private void translateTo(double translateY) { for (Element el : layers) { @@ -454,7 +443,6 @@ public class TouchScrollDelegate implements NativePreviewHandler { * down. * * @param duration - * @param translateY */ private void translateTo(int duration, final int fromY, final int finalY) { if (duration > 0) { @@ -464,8 +452,9 @@ public class TouchScrollDelegate implements NativePreviewHandler { @Override protected void onUpdate(double progress) { - double translateY = (fromY + (finalY - fromY) * progress); - translateTo(translateY); + lastAnimatedTranslateY = (fromY + (finalY - fromY) + * progress); + translateTo(lastAnimatedTranslateY); } @Override @@ -476,8 +465,17 @@ public class TouchScrollDelegate implements NativePreviewHandler { @Override protected void onComplete() { super.onComplete(); + transitionOn = false; onTransitionEnd(); } + + @Override + protected void onCancel() { + int delta = (int) (finalY - lastAnimatedTranslateY); + finalScrollTop -= delta; + moveTransformationToScrolloffset(); + transitionOn = false; + } }; momentum.run(duration); } @@ -494,14 +492,18 @@ public class TouchScrollDelegate implements NativePreviewHandler { } public void onPreviewNativeEvent(NativePreviewEvent event) { + int typeInt = event.getTypeInt(); if (transitionOn) { /* * TODO allow starting new events. See issue in onTouchStart */ event.cancel(); + + if (typeInt == Event.ONTOUCHSTART) { + doTouchStart(event.getNativeEvent()); + } return; } - int typeInt = event.getTypeInt(); switch (typeInt) { case Event.ONTOUCHMOVE: if (!event.isCanceled()) { -- cgit v1.2.3 From 14c4453d28cce7a61dae1bc118cdf5c4cf7e7ab4 Mon Sep 17 00:00:00 2001 From: Automerge Date: Fri, 20 Apr 2012 13:07:11 +0000 Subject: [merge from 6.7] #8407 Handle the case of a 503 response without a Retry-After header svn changeset:23603/svn branch:6.8 --- .../terminal/gwt/client/ApplicationConnection.java | 42 ++++++++++++++-------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 0603e80c93..82971860b5 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -524,21 +524,26 @@ public class ApplicationConnection { return; case 503: - // We'll assume msec instead of the usual seconds - int delay = Integer.parseInt(response - .getHeader("Retry-After")); - VConsole.log("503, retrying in " + delay + "msec"); - (new Timer() { - @Override - public void run() { - // TODO why? Here used to be "activeRequests--;" - // but can't see why exactly - hasActiveRequest = false; - doUidlRequest(uri, payload, synchronous); - } - }).schedule(delay); - return; - + /* + * We'll assume msec instead of the usual seconds. If + * there's no Retry-After header, handle the error like + * a 500, as per RFC 2616 section 10.5.4. + */ + String delay = response.getHeader("Retry-After"); + if (delay != null) { + VConsole.log("503, retrying in " + delay + "msec"); + (new Timer() { + @Override + public void run() { + // TODO why? Here used to be + // "activeRequests--;" + // but can't see why exactly + hasActiveRequest = false; + doUidlRequest(uri, payload, synchronous); + } + }).schedule(Integer.parseInt(delay)); + return; + } } if ((statusCode / 100) == 4) { @@ -549,6 +554,13 @@ public class ApplicationConnection { + statusCode, statusCode); endRequest(); return; + } else if ((statusCode / 100) == 5) { + // Something's wrong on the server, there's nothing the + // client can do except maybe try again. + showCommunicationError("Server error. Error code: " + + statusCode, statusCode); + endRequest(); + return; } String contentType = response.getHeader("Content-Type"); -- cgit v1.2.3 From 96267f034e67b0c301e858342271e484998db7ed Mon Sep 17 00:00:00 2001 From: Automerge Date: Fri, 20 Apr 2012 13:07:16 +0000 Subject: [merge from 6.7] Moved Mattis touchscroll fixes to 6.8 svn changeset:23604/svn branch:6.8 --- .../gwt/client/ui/FocusableScrollPanel.java | 27 +-- .../gwt/client/ui/TouchScrollDelegate.java | 268 ++++++++------------- .../terminal/gwt/client/ui/VScrollTable.java | 28 +-- 3 files changed, 109 insertions(+), 214 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java index 96cb4b8a35..1025752ca9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java @@ -3,8 +3,6 @@ */ package com.vaadin.terminal.gwt.client.ui; -import java.util.ArrayList; - import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.DivElement; @@ -24,7 +22,6 @@ import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.impl.FocusImpl; import com.vaadin.terminal.gwt.client.BrowserInfo; -import com.vaadin.terminal.gwt.client.VConsole; /** * A scrollhandlers similar to {@link ScrollPanel}. @@ -139,11 +136,7 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements * @return the vertical scroll position, in pixels */ public int getScrollPosition() { - if (getElement().getPropertyJSO("_vScrollTop") != null) { - return getElement().getPropertyInt("_vScrollTop"); - } else { - return getElement().getScrollTop(); - } + return getElement().getScrollTop(); } /** @@ -163,23 +156,7 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements * the new vertical scroll position, in pixels */ public void setScrollPosition(int position) { - if (isAndroidWithBrokenScrollTop()) { - ArrayList elements = TouchScrollDelegate - .getElements(getElement()); - for (com.google.gwt.dom.client.Element el : elements) { - final Style style = el.getStyle(); - style.setProperty("webkitTransform", "translate3d(0px," - + -position + "px,0px)"); - } - getElement().setPropertyInt("_vScrollTop", position); - } else { - getElement().setScrollTop(position); - } - } - - private boolean isAndroidWithBrokenScrollTop() { - return BrowserInfo.getBrowserString().contains("Android 3") - || BrowserInfo.getBrowserString().contains("Android 4"); + getElement().setScrollTop(position); } public void onScroll(ScrollEvent event) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java index d4b59ed23a..3c08741de5 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java +++ b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java @@ -4,22 +4,19 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.ArrayList; +import java.util.Date; -import com.google.gwt.animation.client.Animation; -import com.google.gwt.core.client.Duration; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; 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.Touch; -import com.google.gwt.event.dom.client.ScrollHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.Event.NativePreviewHandler; -import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.VConsole; /** @@ -67,34 +64,27 @@ public class TouchScrollDelegate implements NativePreviewHandler { private static final double FRICTION = 0.002; private static final double DECELERATION = 0.002; private static final int MAX_DURATION = 1500; + private int origX; private int origY; private Element[] scrollableElements; private Element scrolledElement; private int origScrollTop; private HandlerRegistration handlerRegistration; - private double lastAnimatedTranslateY; private int lastClientY; + private double pixxelsPerMs; + private boolean transitionPending = false; private int deltaScrollPos; private boolean transitionOn = false; private int finalScrollTop; private ArrayList layers; private boolean moved; - private ScrollHandler scrollHandler; private static TouchScrollDelegate activeScrollDelegate; - private static final boolean androidWithBrokenScrollTop = BrowserInfo - .getBrowserString().contains("Android 3") - || BrowserInfo.getBrowserString().contains("Android 4"); - public TouchScrollDelegate(Element... elements) { scrollableElements = elements; } - public void setScrollHandler(ScrollHandler scrollHandler) { - this.scrollHandler = scrollHandler; - } - public static TouchScrollDelegate getActiveScrollDelegate() { return activeScrollDelegate; } @@ -126,8 +116,37 @@ public class TouchScrollDelegate implements NativePreviewHandler { public void onTouchStart(TouchStartEvent event) { if (activeScrollDelegate == null && event.getTouches().length() == 1) { - NativeEvent nativeEvent = event.getNativeEvent(); - doTouchStart(nativeEvent); + + Touch touch = event.getTouches().get(0); + if (detectScrolledElement(touch)) { + VConsole.log("TouchDelegate takes over"); + event.stopPropagation(); + handlerRegistration = Event.addNativePreviewHandler(this); + activeScrollDelegate = this; + hookTransitionEndListener(scrolledElement + .getFirstChildElement()); + origX = touch.getClientX(); + origY = touch.getClientY(); + yPositions[0] = origY; + eventTimeStamps[0] = new Date(); + nextEvent = 1; + + if (transitionOn) { + // TODO calculate current position of ongoing transition, + // fix to that and start scroll from there. Another option + // is to investigate if we can get even close the same + // framerate with scheduler based impl instead of using + // transitions (GWT examples has impl of this, with jsni + // though). This is very smooth on native ipad, now we + // ignore touch starts during animation. + origScrollTop = scrolledElement.getScrollTop(); + } else { + origScrollTop = scrolledElement.getScrollTop(); + } + moved = false; + // event.preventDefault(); + // event.stopPropagation(); + } } else { /* * Touch scroll is currenly on (possibly bouncing). Ignore. @@ -135,39 +154,16 @@ public class TouchScrollDelegate implements NativePreviewHandler { } } - private void doTouchStart(NativeEvent nativeEvent) { - if (transitionOn) { - momentum.cancel(); - } - Touch touch = nativeEvent.getTouches().get(0); - if (detectScrolledElement(touch)) { - VConsole.log("TouchDelegate takes over"); - nativeEvent.stopPropagation(); - handlerRegistration = Event.addNativePreviewHandler(this); - activeScrollDelegate = this; - origY = touch.getClientY(); - yPositions[0] = origY; - eventTimeStamps[0] = getTimeStamp(); - nextEvent = 1; - - origScrollTop = getScrollTop(); - VConsole.log("ST" + origScrollTop); - - moved = false; - // event.preventDefault(); - // event.stopPropagation(); - } - } - - private int getScrollTop() { - if (androidWithBrokenScrollTop) { - if (scrolledElement.getPropertyJSO("_vScrollTop") != null) { - return scrolledElement.getPropertyInt("_vScrollTop"); - } - return 0; + private native void hookTransitionEndListener(Element element) + /*-{ + if(!element.hasTransitionEndListener) { + var that = this; + element.addEventListener("webkitTransitionEnd",function(event){ + that.@com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate::onTransitionEnd()(); + },false); + element.hasTransitionEndListener = true; } - return scrolledElement.getScrollTop(); - } + }-*/; private void onTransitionEnd() { if (finalScrollTop < 0) { @@ -179,6 +175,7 @@ public class TouchScrollDelegate implements NativePreviewHandler { } else { moveTransformationToScrolloffset(); } + transitionOn = false; } private void animateToScrollPosition(int to, int from) { @@ -187,14 +184,7 @@ public class TouchScrollDelegate implements NativePreviewHandler { if (time <= 0) { time = 1; // get animation and transition end event } - VConsole.log("Animate " + time + " " + from + " " + to); - int translateTo = -to + origScrollTop; - int fromY = -from + origScrollTop; - if (androidWithBrokenScrollTop) { - fromY -= origScrollTop; - translateTo -= origScrollTop; - } - translateTo(time, fromY, translateTo); + translateTo(time, -to + origScrollTop); } private int getAnimationTimeForDistance(int dist) { @@ -210,21 +200,16 @@ public class TouchScrollDelegate implements NativePreviewHandler { * scrolltop, causing onscroll event. */ private void moveTransformationToScrolloffset() { - if (androidWithBrokenScrollTop) { - scrolledElement.setPropertyInt("_vScrollTop", finalScrollTop); - if (scrollHandler != null) { - scrollHandler.onScroll(null); - } - } else { - for (Element el : layers) { - Style style = el.getStyle(); - style.setProperty("webkitTransform", "translate3d(0,0,0)"); - } - scrolledElement.setScrollTop(finalScrollTop); + for (Element el : layers) { + Style style = el.getStyle(); + style.setProperty("webkitTransitionProperty", "none"); + style.setProperty("webkitTransform", "translate3d(0,0,0)"); } + scrolledElement.setScrollTop(finalScrollTop); activeScrollDelegate = null; handlerRegistration.removeHandler(); handlerRegistration = null; + } /** @@ -240,7 +225,14 @@ public class TouchScrollDelegate implements NativePreviewHandler { if (el.isOrHasChild(target) && el.getScrollHeight() > el.getClientHeight()) { scrolledElement = el; - layers = getElements(scrolledElement); + NodeList childNodes = scrolledElement.getChildNodes(); + layers = new ArrayList(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.getItem(i); + if (item.getNodeType() == Node.ELEMENT_NODE) { + layers.add((Element) item); + } + } return true; } @@ -248,21 +240,10 @@ public class TouchScrollDelegate implements NativePreviewHandler { return false; } - public static ArrayList getElements(Element scrolledElement2) { - NodeList childNodes = scrolledElement2.getChildNodes(); - ArrayList l = new ArrayList(); - for (int i = 0; i < childNodes.getLength(); i++) { - Node item = childNodes.getItem(i); - if (item.getNodeType() == Node.ELEMENT_NODE) { - l.add((Element) item); - } - } - return l; - } - private void onTouchMove(NativeEvent event) { if (!moved) { - double l = (getTimeStamp() - eventTimeStamps[0]); + Date date = new Date(); + long l = (date.getTime() - eventTimeStamps[0].getTime()); VConsole.log(l + " ms from start to move"); } boolean handleMove = readPositionAndSpeed(event); @@ -274,15 +255,15 @@ public class TouchScrollDelegate implements NativePreviewHandler { int overscroll = (deltaScrollTop + origScrollTop) - getMaxFinalY(); overscroll = overscroll / 2; - if (overscroll > getMaxOverScroll()) { - overscroll = getMaxOverScroll(); + if (overscroll > scrolledElement.getClientHeight() / 2) { + overscroll = scrolledElement.getClientHeight() / 2; } deltaScrollTop = getMaxFinalY() + overscroll - origScrollTop; } else if (finalPos < 0) { // spring effect at the beginning int overscroll = finalPos / 2; - if (-overscroll > getMaxOverScroll()) { - overscroll = -getMaxOverScroll(); + if (-overscroll > scrolledElement.getClientHeight() / 2) { + overscroll = -scrolledElement.getClientHeight() / 2; } deltaScrollTop = overscroll - origScrollTop; } @@ -295,20 +276,16 @@ public class TouchScrollDelegate implements NativePreviewHandler { private void quickSetScrollPosition(int deltaX, int deltaY) { deltaScrollPos = deltaY; - if (androidWithBrokenScrollTop) { - deltaY += origScrollTop; - translateTo(-deltaY); - } else { - translateTo(-deltaScrollPos); - } + translateTo(0, -deltaScrollPos); } private static final int EVENTS_FOR_SPEED_CALC = 3; public static final int SIGNIFICANT_MOVE_THRESHOLD = 3; private int[] yPositions = new int[EVENTS_FOR_SPEED_CALC]; - private double[] eventTimeStamps = new double[EVENTS_FOR_SPEED_CALC]; + private Date[] eventTimeStamps = new Date[EVENTS_FOR_SPEED_CALC]; private int nextEvent = 0; - private Animation momentum; + private Date transitionStart; + private Date transitionDuration; /** * @@ -316,11 +293,12 @@ public class TouchScrollDelegate implements NativePreviewHandler { * @return */ private boolean readPositionAndSpeed(NativeEvent event) { + Date now = new Date(); Touch touch = event.getChangedTouches().get(0); lastClientY = touch.getClientY(); int eventIndx = nextEvent++; eventIndx = eventIndx % EVENTS_FOR_SPEED_CALC; - eventTimeStamps[eventIndx] = getTimeStamp(); + eventTimeStamps[eventIndx] = now; yPositions[eventIndx] = lastClientY; return isMovedSignificantly(); } @@ -370,11 +348,15 @@ public class TouchScrollDelegate implements NativePreviewHandler { // VConsole.log("To max overscroll"); finalY = getMaxFinalY() + getMaxOverScroll(); int fixedPixelsToMove = finalY - currentY; + pixelsPerMs = pixelsPerMs * pixelsToMove / fixedPixelsToMove + / FRICTION; pixelsToMove = fixedPixelsToMove; } else if (finalY < 0 - getMaxOverScroll()) { // VConsole.log("to min overscroll"); finalY = -getMaxOverScroll(); int fixedPixelsToMove = finalY - currentY; + pixelsPerMs = pixelsPerMs * pixelsToMove / fixedPixelsToMove + / FRICTION; pixelsToMove = fixedPixelsToMove; } else { duration = (int) (Math.abs(pixelsPerMs / DECELERATION)); @@ -398,13 +380,8 @@ public class TouchScrollDelegate implements NativePreviewHandler { return; } - int translateTo = -finalY + origScrollTop; - int fromY = -currentY + origScrollTop; - if (androidWithBrokenScrollTop) { - fromY -= origScrollTop; - translateTo -= origScrollTop; - } - translateTo(duration, fromY, translateTo); + int translateY = -finalY + origScrollTop; + translateTo(duration, translateY); } private double calculateSpeed() { @@ -415,75 +392,47 @@ public class TouchScrollDelegate implements NativePreviewHandler { } int idx = nextEvent % EVENTS_FOR_SPEED_CALC; final int firstPos = yPositions[idx]; - final double firstTs = eventTimeStamps[idx]; + final Date firstTs = eventTimeStamps[idx]; idx += EVENTS_FOR_SPEED_CALC; idx--; idx = idx % EVENTS_FOR_SPEED_CALC; final int lastPos = yPositions[idx]; - final double lastTs = eventTimeStamps[idx]; + final Date lastTs = eventTimeStamps[idx]; // speed as in change of scrolltop == -speedOfTouchPos - return (firstPos - lastPos) / (lastTs - firstTs); + return (firstPos - lastPos) + / (double) (lastTs.getTime() - firstTs.getTime()); } /** * Note positive scrolltop moves layer up, positive translate moves layer * down. + * + * @param duration + * @param translateY */ - private void translateTo(double translateY) { + private void translateTo(int duration, int translateY) { for (Element el : layers) { - Style style = el.getStyle(); + final Style style = el.getStyle(); + if (duration > 0) { + style.setProperty("webkitTransitionDuration", duration + "ms"); + style.setProperty("webkitTransitionTimingFunction", + "cubic-bezier(0,0,0.25,1)"); + style.setProperty("webkitTransitionProperty", + "-webkit-transform"); + transitionOn = true; + transitionStart = new Date(); + transitionDuration = new Date(); + } else { + style.setProperty("webkitTransitionProperty", "none"); + } style.setProperty("webkitTransform", "translate3d(0px," + translateY + "px,0px)"); } } - /** - * Note positive scrolltop moves layer up, positive translate moves layer - * down. - * - * @param duration - */ - private void translateTo(int duration, final int fromY, final int finalY) { - if (duration > 0) { - transitionOn = true; - - momentum = new Animation() { - - @Override - protected void onUpdate(double progress) { - lastAnimatedTranslateY = (fromY + (finalY - fromY) - * progress); - translateTo(lastAnimatedTranslateY); - } - - @Override - protected double interpolate(double progress) { - return 1 + Math.pow(progress - 1, 3); - } - - @Override - protected void onComplete() { - super.onComplete(); - transitionOn = false; - onTransitionEnd(); - } - - @Override - protected void onCancel() { - int delta = (int) (finalY - lastAnimatedTranslateY); - finalScrollTop -= delta; - moveTransformationToScrolloffset(); - transitionOn = false; - } - }; - momentum.run(duration); - } - } - private int getMaxOverScroll() { - return androidWithBrokenScrollTop ? 0 : scrolledElement - .getClientHeight() / 3; + return scrolledElement.getClientHeight() / 4; } private int getMaxFinalY() { @@ -492,18 +441,14 @@ public class TouchScrollDelegate implements NativePreviewHandler { } public void onPreviewNativeEvent(NativePreviewEvent event) { - int typeInt = event.getTypeInt(); if (transitionOn) { /* * TODO allow starting new events. See issue in onTouchStart */ event.cancel(); - - if (typeInt == Event.ONTOUCHSTART) { - doTouchStart(event.getNativeEvent()); - } return; } + int typeInt = event.getTypeInt(); switch (typeInt) { case Event.ONTOUCHMOVE: if (!event.isCanceled()) { @@ -539,15 +484,4 @@ public class TouchScrollDelegate implements NativePreviewHandler { public void setElements(com.google.gwt.user.client.Element[] elements) { scrollableElements = elements; } - - /** - * long calcucation are not very efficient in GWT, so this helper method - * returns timestamp in double. - * - * @return - */ - public static double getTimeStamp() { - return Duration.currentTimeMillis(); - } - } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index a022a2bd83..6bbc2a6ceb 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -18,7 +18,6 @@ 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.NativeEvent; -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; @@ -513,7 +512,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, if (touchScrollDelegate == null) { touchScrollDelegate = new TouchScrollDelegate( scrollBodyPanel.getElement()); - touchScrollDelegate.setScrollHandler(this); } return touchScrollDelegate; @@ -4064,14 +4062,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, DOM.appendChild(container, preSpacer); DOM.appendChild(container, table); DOM.appendChild(container, postSpacer); - if (BrowserInfo.get().isTouchDevice()) { - NodeList childNodes = container.getChildNodes(); - for (int i = 0; i < childNodes.getLength(); i++) { - Element item = (Element) childNodes.getItem(i); - item.getStyle().setProperty("webkitTransform", - "translate3d(0,0,0)"); - } - } } @@ -4617,7 +4607,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, public class VScrollTableRow extends Panel implements ActionOwner, Container { - private static final int TOUCHSCROLL_TIMEOUT = 100; + private static final int TOUCHSCROLL_TIMEOUT = 70; private static final int DRAGMODE_MULTIROW = 2; protected ArrayList childWidgets = new ArrayList(); private boolean selected = false; @@ -5291,11 +5281,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, } }; } - if (contextTouchTimeout != null) { - contextTouchTimeout.cancel(); - contextTouchTimeout - .schedule(TOUCH_CONTEXT_MENU_TIMEOUT); - } + contextTouchTimeout.cancel(); + contextTouchTimeout + .schedule(TOUCH_CONTEXT_MENU_TIMEOUT); } break; case Event.ONMOUSEDOWN: @@ -5452,7 +5440,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, int top = Util.getTouchOrMouseClientY(event); top += Window.getScrollTop(); left += Window.getScrollLeft(); - contextMenu = new ContextMenuDetails(getKey(), left, top); + contextMenu = new ContextMenuDetails(this.getKey(), left, + top); client.getContextMenu().showAt(this, left, top); } } @@ -6501,11 +6490,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, * The row to ensure is visible */ private void ensureRowIsVisible(VScrollTableRow row) { - if (BrowserInfo.get().isTouchDevice()) { - // Skip due to android devices that have broken scrolltop will may - // get odd scrolling here. - return; - } Util.scrollIntoViewVertically(row.getElement()); } -- cgit v1.2.3 From 6608a575e342c0fcd3ae29245ecd406cea0fb562 Mon Sep 17 00:00:00 2001 From: Automerge Date: Mon, 23 Apr 2012 09:06:37 +0000 Subject: [merge from 6.7] doUidlRequest() should not set hasActiveRequest=false when retrying a request that returned a 503 svn changeset:23609/svn branch:6.8 --- src/com/vaadin/terminal/gwt/client/ApplicationConnection.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 82971860b5..4c6fc8462b 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -535,10 +535,6 @@ public class ApplicationConnection { (new Timer() { @Override public void run() { - // TODO why? Here used to be - // "activeRequests--;" - // but can't see why exactly - hasActiveRequest = false; doUidlRequest(uri, payload, synchronous); } }).schedule(Integer.parseInt(delay)); -- cgit v1.2.3 From 7d2f7c99f5e5ee07af0b06bb7f6c894959372d9f Mon Sep 17 00:00:00 2001 From: Automerge Date: Mon, 23 Apr 2012 09:06:42 +0000 Subject: [merge from 6.7] Fix #8550 in 6.7 after all svn changeset:23610/svn branch:6.8 --- .../gwt/client/ui/FocusableScrollPanel.java | 27 ++- .../gwt/client/ui/TouchScrollDelegate.java | 268 +++++++++++++-------- .../terminal/gwt/client/ui/VScrollTable.java | 28 ++- 3 files changed, 214 insertions(+), 109 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java index 1025752ca9..96cb4b8a35 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/FocusableScrollPanel.java @@ -3,6 +3,8 @@ */ package com.vaadin.terminal.gwt.client.ui; +import java.util.ArrayList; + import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.DivElement; @@ -22,6 +24,7 @@ import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.impl.FocusImpl; import com.vaadin.terminal.gwt.client.BrowserInfo; +import com.vaadin.terminal.gwt.client.VConsole; /** * A scrollhandlers similar to {@link ScrollPanel}. @@ -136,7 +139,11 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements * @return the vertical scroll position, in pixels */ public int getScrollPosition() { - return getElement().getScrollTop(); + if (getElement().getPropertyJSO("_vScrollTop") != null) { + return getElement().getPropertyInt("_vScrollTop"); + } else { + return getElement().getScrollTop(); + } } /** @@ -156,7 +163,23 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements * the new vertical scroll position, in pixels */ public void setScrollPosition(int position) { - getElement().setScrollTop(position); + if (isAndroidWithBrokenScrollTop()) { + ArrayList elements = TouchScrollDelegate + .getElements(getElement()); + for (com.google.gwt.dom.client.Element el : elements) { + final Style style = el.getStyle(); + style.setProperty("webkitTransform", "translate3d(0px," + + -position + "px,0px)"); + } + getElement().setPropertyInt("_vScrollTop", position); + } else { + getElement().setScrollTop(position); + } + } + + private boolean isAndroidWithBrokenScrollTop() { + return BrowserInfo.getBrowserString().contains("Android 3") + || BrowserInfo.getBrowserString().contains("Android 4"); } public void onScroll(ScrollEvent event) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java index 3c08741de5..d4b59ed23a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java +++ b/src/com/vaadin/terminal/gwt/client/ui/TouchScrollDelegate.java @@ -4,19 +4,22 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.ArrayList; -import java.util.Date; +import com.google.gwt.animation.client.Animation; +import com.google.gwt.core.client.Duration; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; 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.Touch; +import com.google.gwt.event.dom.client.ScrollHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Event.NativePreviewEvent; import com.google.gwt.user.client.Event.NativePreviewHandler; +import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.VConsole; /** @@ -64,27 +67,34 @@ public class TouchScrollDelegate implements NativePreviewHandler { private static final double FRICTION = 0.002; private static final double DECELERATION = 0.002; private static final int MAX_DURATION = 1500; - private int origX; private int origY; private Element[] scrollableElements; private Element scrolledElement; private int origScrollTop; private HandlerRegistration handlerRegistration; + private double lastAnimatedTranslateY; private int lastClientY; - private double pixxelsPerMs; - private boolean transitionPending = false; private int deltaScrollPos; private boolean transitionOn = false; private int finalScrollTop; private ArrayList layers; private boolean moved; + private ScrollHandler scrollHandler; private static TouchScrollDelegate activeScrollDelegate; + private static final boolean androidWithBrokenScrollTop = BrowserInfo + .getBrowserString().contains("Android 3") + || BrowserInfo.getBrowserString().contains("Android 4"); + public TouchScrollDelegate(Element... elements) { scrollableElements = elements; } + public void setScrollHandler(ScrollHandler scrollHandler) { + this.scrollHandler = scrollHandler; + } + public static TouchScrollDelegate getActiveScrollDelegate() { return activeScrollDelegate; } @@ -116,37 +126,8 @@ public class TouchScrollDelegate implements NativePreviewHandler { public void onTouchStart(TouchStartEvent event) { if (activeScrollDelegate == null && event.getTouches().length() == 1) { - - Touch touch = event.getTouches().get(0); - if (detectScrolledElement(touch)) { - VConsole.log("TouchDelegate takes over"); - event.stopPropagation(); - handlerRegistration = Event.addNativePreviewHandler(this); - activeScrollDelegate = this; - hookTransitionEndListener(scrolledElement - .getFirstChildElement()); - origX = touch.getClientX(); - origY = touch.getClientY(); - yPositions[0] = origY; - eventTimeStamps[0] = new Date(); - nextEvent = 1; - - if (transitionOn) { - // TODO calculate current position of ongoing transition, - // fix to that and start scroll from there. Another option - // is to investigate if we can get even close the same - // framerate with scheduler based impl instead of using - // transitions (GWT examples has impl of this, with jsni - // though). This is very smooth on native ipad, now we - // ignore touch starts during animation. - origScrollTop = scrolledElement.getScrollTop(); - } else { - origScrollTop = scrolledElement.getScrollTop(); - } - moved = false; - // event.preventDefault(); - // event.stopPropagation(); - } + NativeEvent nativeEvent = event.getNativeEvent(); + doTouchStart(nativeEvent); } else { /* * Touch scroll is currenly on (possibly bouncing). Ignore. @@ -154,16 +135,39 @@ public class TouchScrollDelegate implements NativePreviewHandler { } } - private native void hookTransitionEndListener(Element element) - /*-{ - if(!element.hasTransitionEndListener) { - var that = this; - element.addEventListener("webkitTransitionEnd",function(event){ - that.@com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate::onTransitionEnd()(); - },false); - element.hasTransitionEndListener = true; + private void doTouchStart(NativeEvent nativeEvent) { + if (transitionOn) { + momentum.cancel(); + } + Touch touch = nativeEvent.getTouches().get(0); + if (detectScrolledElement(touch)) { + VConsole.log("TouchDelegate takes over"); + nativeEvent.stopPropagation(); + handlerRegistration = Event.addNativePreviewHandler(this); + activeScrollDelegate = this; + origY = touch.getClientY(); + yPositions[0] = origY; + eventTimeStamps[0] = getTimeStamp(); + nextEvent = 1; + + origScrollTop = getScrollTop(); + VConsole.log("ST" + origScrollTop); + + moved = false; + // event.preventDefault(); + // event.stopPropagation(); + } + } + + private int getScrollTop() { + if (androidWithBrokenScrollTop) { + if (scrolledElement.getPropertyJSO("_vScrollTop") != null) { + return scrolledElement.getPropertyInt("_vScrollTop"); + } + return 0; } - }-*/; + return scrolledElement.getScrollTop(); + } private void onTransitionEnd() { if (finalScrollTop < 0) { @@ -175,7 +179,6 @@ public class TouchScrollDelegate implements NativePreviewHandler { } else { moveTransformationToScrolloffset(); } - transitionOn = false; } private void animateToScrollPosition(int to, int from) { @@ -184,7 +187,14 @@ public class TouchScrollDelegate implements NativePreviewHandler { if (time <= 0) { time = 1; // get animation and transition end event } - translateTo(time, -to + origScrollTop); + VConsole.log("Animate " + time + " " + from + " " + to); + int translateTo = -to + origScrollTop; + int fromY = -from + origScrollTop; + if (androidWithBrokenScrollTop) { + fromY -= origScrollTop; + translateTo -= origScrollTop; + } + translateTo(time, fromY, translateTo); } private int getAnimationTimeForDistance(int dist) { @@ -200,16 +210,21 @@ public class TouchScrollDelegate implements NativePreviewHandler { * scrolltop, causing onscroll event. */ private void moveTransformationToScrolloffset() { - for (Element el : layers) { - Style style = el.getStyle(); - style.setProperty("webkitTransitionProperty", "none"); - style.setProperty("webkitTransform", "translate3d(0,0,0)"); + if (androidWithBrokenScrollTop) { + scrolledElement.setPropertyInt("_vScrollTop", finalScrollTop); + if (scrollHandler != null) { + scrollHandler.onScroll(null); + } + } else { + for (Element el : layers) { + Style style = el.getStyle(); + style.setProperty("webkitTransform", "translate3d(0,0,0)"); + } + scrolledElement.setScrollTop(finalScrollTop); } - scrolledElement.setScrollTop(finalScrollTop); activeScrollDelegate = null; handlerRegistration.removeHandler(); handlerRegistration = null; - } /** @@ -225,14 +240,7 @@ public class TouchScrollDelegate implements NativePreviewHandler { if (el.isOrHasChild(target) && el.getScrollHeight() > el.getClientHeight()) { scrolledElement = el; - NodeList childNodes = scrolledElement.getChildNodes(); - layers = new ArrayList(); - for (int i = 0; i < childNodes.getLength(); i++) { - Node item = childNodes.getItem(i); - if (item.getNodeType() == Node.ELEMENT_NODE) { - layers.add((Element) item); - } - } + layers = getElements(scrolledElement); return true; } @@ -240,10 +248,21 @@ public class TouchScrollDelegate implements NativePreviewHandler { return false; } + public static ArrayList getElements(Element scrolledElement2) { + NodeList childNodes = scrolledElement2.getChildNodes(); + ArrayList l = new ArrayList(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.getItem(i); + if (item.getNodeType() == Node.ELEMENT_NODE) { + l.add((Element) item); + } + } + return l; + } + private void onTouchMove(NativeEvent event) { if (!moved) { - Date date = new Date(); - long l = (date.getTime() - eventTimeStamps[0].getTime()); + double l = (getTimeStamp() - eventTimeStamps[0]); VConsole.log(l + " ms from start to move"); } boolean handleMove = readPositionAndSpeed(event); @@ -255,15 +274,15 @@ public class TouchScrollDelegate implements NativePreviewHandler { int overscroll = (deltaScrollTop + origScrollTop) - getMaxFinalY(); overscroll = overscroll / 2; - if (overscroll > scrolledElement.getClientHeight() / 2) { - overscroll = scrolledElement.getClientHeight() / 2; + if (overscroll > getMaxOverScroll()) { + overscroll = getMaxOverScroll(); } deltaScrollTop = getMaxFinalY() + overscroll - origScrollTop; } else if (finalPos < 0) { // spring effect at the beginning int overscroll = finalPos / 2; - if (-overscroll > scrolledElement.getClientHeight() / 2) { - overscroll = -scrolledElement.getClientHeight() / 2; + if (-overscroll > getMaxOverScroll()) { + overscroll = -getMaxOverScroll(); } deltaScrollTop = overscroll - origScrollTop; } @@ -276,16 +295,20 @@ public class TouchScrollDelegate implements NativePreviewHandler { private void quickSetScrollPosition(int deltaX, int deltaY) { deltaScrollPos = deltaY; - translateTo(0, -deltaScrollPos); + if (androidWithBrokenScrollTop) { + deltaY += origScrollTop; + translateTo(-deltaY); + } else { + translateTo(-deltaScrollPos); + } } private static final int EVENTS_FOR_SPEED_CALC = 3; public static final int SIGNIFICANT_MOVE_THRESHOLD = 3; private int[] yPositions = new int[EVENTS_FOR_SPEED_CALC]; - private Date[] eventTimeStamps = new Date[EVENTS_FOR_SPEED_CALC]; + private double[] eventTimeStamps = new double[EVENTS_FOR_SPEED_CALC]; private int nextEvent = 0; - private Date transitionStart; - private Date transitionDuration; + private Animation momentum; /** * @@ -293,12 +316,11 @@ public class TouchScrollDelegate implements NativePreviewHandler { * @return */ private boolean readPositionAndSpeed(NativeEvent event) { - Date now = new Date(); Touch touch = event.getChangedTouches().get(0); lastClientY = touch.getClientY(); int eventIndx = nextEvent++; eventIndx = eventIndx % EVENTS_FOR_SPEED_CALC; - eventTimeStamps[eventIndx] = now; + eventTimeStamps[eventIndx] = getTimeStamp(); yPositions[eventIndx] = lastClientY; return isMovedSignificantly(); } @@ -348,15 +370,11 @@ public class TouchScrollDelegate implements NativePreviewHandler { // VConsole.log("To max overscroll"); finalY = getMaxFinalY() + getMaxOverScroll(); int fixedPixelsToMove = finalY - currentY; - pixelsPerMs = pixelsPerMs * pixelsToMove / fixedPixelsToMove - / FRICTION; pixelsToMove = fixedPixelsToMove; } else if (finalY < 0 - getMaxOverScroll()) { // VConsole.log("to min overscroll"); finalY = -getMaxOverScroll(); int fixedPixelsToMove = finalY - currentY; - pixelsPerMs = pixelsPerMs * pixelsToMove / fixedPixelsToMove - / FRICTION; pixelsToMove = fixedPixelsToMove; } else { duration = (int) (Math.abs(pixelsPerMs / DECELERATION)); @@ -380,8 +398,13 @@ public class TouchScrollDelegate implements NativePreviewHandler { return; } - int translateY = -finalY + origScrollTop; - translateTo(duration, translateY); + int translateTo = -finalY + origScrollTop; + int fromY = -currentY + origScrollTop; + if (androidWithBrokenScrollTop) { + fromY -= origScrollTop; + translateTo -= origScrollTop; + } + translateTo(duration, fromY, translateTo); } private double calculateSpeed() { @@ -392,47 +415,75 @@ public class TouchScrollDelegate implements NativePreviewHandler { } int idx = nextEvent % EVENTS_FOR_SPEED_CALC; final int firstPos = yPositions[idx]; - final Date firstTs = eventTimeStamps[idx]; + final double firstTs = eventTimeStamps[idx]; idx += EVENTS_FOR_SPEED_CALC; idx--; idx = idx % EVENTS_FOR_SPEED_CALC; final int lastPos = yPositions[idx]; - final Date lastTs = eventTimeStamps[idx]; + final double lastTs = eventTimeStamps[idx]; // speed as in change of scrolltop == -speedOfTouchPos - return (firstPos - lastPos) - / (double) (lastTs.getTime() - firstTs.getTime()); + return (firstPos - lastPos) / (lastTs - firstTs); } /** * Note positive scrolltop moves layer up, positive translate moves layer * down. - * - * @param duration - * @param translateY */ - private void translateTo(int duration, int translateY) { + private void translateTo(double translateY) { for (Element el : layers) { - final Style style = el.getStyle(); - if (duration > 0) { - style.setProperty("webkitTransitionDuration", duration + "ms"); - style.setProperty("webkitTransitionTimingFunction", - "cubic-bezier(0,0,0.25,1)"); - style.setProperty("webkitTransitionProperty", - "-webkit-transform"); - transitionOn = true; - transitionStart = new Date(); - transitionDuration = new Date(); - } else { - style.setProperty("webkitTransitionProperty", "none"); - } + Style style = el.getStyle(); style.setProperty("webkitTransform", "translate3d(0px," + translateY + "px,0px)"); } } + /** + * Note positive scrolltop moves layer up, positive translate moves layer + * down. + * + * @param duration + */ + private void translateTo(int duration, final int fromY, final int finalY) { + if (duration > 0) { + transitionOn = true; + + momentum = new Animation() { + + @Override + protected void onUpdate(double progress) { + lastAnimatedTranslateY = (fromY + (finalY - fromY) + * progress); + translateTo(lastAnimatedTranslateY); + } + + @Override + protected double interpolate(double progress) { + return 1 + Math.pow(progress - 1, 3); + } + + @Override + protected void onComplete() { + super.onComplete(); + transitionOn = false; + onTransitionEnd(); + } + + @Override + protected void onCancel() { + int delta = (int) (finalY - lastAnimatedTranslateY); + finalScrollTop -= delta; + moveTransformationToScrolloffset(); + transitionOn = false; + } + }; + momentum.run(duration); + } + } + private int getMaxOverScroll() { - return scrolledElement.getClientHeight() / 4; + return androidWithBrokenScrollTop ? 0 : scrolledElement + .getClientHeight() / 3; } private int getMaxFinalY() { @@ -441,14 +492,18 @@ public class TouchScrollDelegate implements NativePreviewHandler { } public void onPreviewNativeEvent(NativePreviewEvent event) { + int typeInt = event.getTypeInt(); if (transitionOn) { /* * TODO allow starting new events. See issue in onTouchStart */ event.cancel(); + + if (typeInt == Event.ONTOUCHSTART) { + doTouchStart(event.getNativeEvent()); + } return; } - int typeInt = event.getTypeInt(); switch (typeInt) { case Event.ONTOUCHMOVE: if (!event.isCanceled()) { @@ -484,4 +539,15 @@ public class TouchScrollDelegate implements NativePreviewHandler { public void setElements(com.google.gwt.user.client.Element[] elements) { scrollableElements = elements; } + + /** + * long calcucation are not very efficient in GWT, so this helper method + * returns timestamp in double. + * + * @return + */ + public static double getTimeStamp() { + return Duration.currentTimeMillis(); + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index 6bbc2a6ceb..a022a2bd83 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -18,6 +18,7 @@ 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.NativeEvent; +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; @@ -512,6 +513,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, if (touchScrollDelegate == null) { touchScrollDelegate = new TouchScrollDelegate( scrollBodyPanel.getElement()); + touchScrollDelegate.setScrollHandler(this); } return touchScrollDelegate; @@ -4062,6 +4064,14 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, DOM.appendChild(container, preSpacer); DOM.appendChild(container, table); DOM.appendChild(container, postSpacer); + if (BrowserInfo.get().isTouchDevice()) { + NodeList childNodes = container.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Element item = (Element) childNodes.getItem(i); + item.getStyle().setProperty("webkitTransform", + "translate3d(0,0,0)"); + } + } } @@ -4607,7 +4617,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, public class VScrollTableRow extends Panel implements ActionOwner, Container { - private static final int TOUCHSCROLL_TIMEOUT = 70; + private static final int TOUCHSCROLL_TIMEOUT = 100; private static final int DRAGMODE_MULTIROW = 2; protected ArrayList childWidgets = new ArrayList(); private boolean selected = false; @@ -5281,9 +5291,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, } }; } - contextTouchTimeout.cancel(); - contextTouchTimeout - .schedule(TOUCH_CONTEXT_MENU_TIMEOUT); + if (contextTouchTimeout != null) { + contextTouchTimeout.cancel(); + contextTouchTimeout + .schedule(TOUCH_CONTEXT_MENU_TIMEOUT); + } } break; case Event.ONMOUSEDOWN: @@ -5440,8 +5452,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, int top = Util.getTouchOrMouseClientY(event); top += Window.getScrollTop(); left += Window.getScrollLeft(); - contextMenu = new ContextMenuDetails(this.getKey(), left, - top); + contextMenu = new ContextMenuDetails(getKey(), left, top); client.getContextMenu().showAt(this, left, top); } } @@ -6490,6 +6501,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, * The row to ensure is visible */ private void ensureRowIsVisible(VScrollTableRow row) { + if (BrowserInfo.get().isTouchDevice()) { + // Skip due to android devices that have broken scrolltop will may + // get odd scrolling here. + return; + } Util.scrollIntoViewVertically(row.getElement()); } -- cgit v1.2.3 From fc36ea595e473c00ccb135ece3439d0441561117 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 24 Apr 2012 11:51:20 +0000 Subject: Fail build if Maven deployment fails (#8638) svn changeset:23620/svn branch:6.8 --- build/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index 1fdcc0ee25..a6a75b8918 100644 --- a/build/build.xml +++ b/build/build.xml @@ -895,7 +895,7 @@ Publishing ${output-dir}/WebContent/WEB-INF/lib/${lib-jar-name} to Maven repository - + -- cgit v1.2.3 From 1b2117fcf2fe62c67f29a913c60d93c358f3198c Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 24 Apr 2012 12:24:50 +0000 Subject: Increased debug window default size (#8523) svn changeset:23621/svn branch:6.8 --- .../vaadin/terminal/gwt/client/VDebugConsole.java | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java index c43581b000..19b478b098 100644 --- a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java +++ b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java @@ -170,6 +170,9 @@ public class VDebugConsole extends VOverlay implements Console { private static final String help = "Drag title=move, shift-drag=resize, doubleclick title=min/max." + "Use debug=quiet to log only to browser console."; + private static final int DEFAULT_WIDTH = 650; + private static final int DEFAULT_HEIGHT = 400; + public VDebugConsole() { super(false, false); getElement().getStyle().setOverflow(Overflow.HIDDEN); @@ -291,10 +294,20 @@ public class VDebugConsole extends VOverlay implements Console { height = Integer.parseInt(split[3]); autoScrollValue = Boolean.valueOf(split[4]); } else { - width = 400; - height = 150; - top = Window.getClientHeight() - 160; - left = Window.getClientWidth() - 410; + int windowHeight = Window.getClientHeight(); + int windowWidth = Window.getClientWidth(); + width = DEFAULT_WIDTH; + height = DEFAULT_HEIGHT; + + if (height > windowHeight / 2) { + height = windowHeight / 2; + } + if (width > windowWidth / 2) { + width = windowWidth / 2; + } + + top = windowHeight - (height + 10); + left = windowWidth - (width + 10); } setPixelSize(width, height); setPopupPosition(left, top); -- cgit v1.2.3 From 032f760be4c0bb84ea35a3faabcac721a764a56f Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Tue, 24 Apr 2012 13:41:05 +0000 Subject: Wrap javascript callback entry points in $entry (#8699) svn changeset:23623/svn branch:6.8 --- .../terminal/gwt/client/ApplicationConnection.java | 24 +++++++++++----------- .../terminal/gwt/client/HistoryImplIEVaadin.java | 4 ++-- src/com/vaadin/terminal/gwt/client/Util.java | 4 ++-- .../gwt/client/ui/UploadIFrameOnloadStrategy.java | 4 ++-- .../client/ui/UploadIFrameOnloadStrategyIE.java | 4 ++-- .../terminal/gwt/client/ui/VCustomLayout.java | 4 ++-- .../gwt/client/ui/VDragAndDropWrapper.java | 20 +++++++++--------- .../gwt/client/ui/VDragAndDropWrapperIE.java | 20 +++++++++--------- .../vaadin/terminal/gwt/client/ui/VTextField.java | 4 ++-- src/com/vaadin/terminal/gwt/client/ui/VVideo.java | 6 +++--- 10 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 4c6fc8462b..de7ad83b54 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -220,10 +220,10 @@ public class ApplicationConnection { /*-{ var ap = this; var client = {}; - client.isActive = function() { + client.isActive = $entry(function() { return ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::hasActiveRequest()() || ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::isExecutingDeferredCommands()(); - } + }); var vi = ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::getVersionInfo()(); if (vi) { @@ -232,21 +232,21 @@ public class ApplicationConnection { } } - client.getProfilingData = function() { + client.getProfilingData = $entry(function() { var pd = [ ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::lastProcessingTime, ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::totalProcessingTime ]; pd = pd.concat(ap.@com.vaadin.terminal.gwt.client.ApplicationConnection::testBenchServerStatus); return pd; - } + }); - client.getElementByPath = function(id) { + client.getElementByPath = $entry(function(id) { return componentLocator.@com.vaadin.terminal.gwt.client.ComponentLocator::getElementByPath(Ljava/lang/String;)(id); - } - client.getPathForElement = function(element) { + }); + client.getPathForElement = $entry(function(element) { return componentLocator.@com.vaadin.terminal.gwt.client.ComponentLocator::getPathForElement(Lcom/google/gwt/user/client/Element;)(element); - } + }); if (!$wnd.vaadin.clients) { $wnd.vaadin.clients = {}; @@ -292,22 +292,22 @@ public class ApplicationConnection { if ($wnd.vaadin.forceSync) { oldSync = $wnd.vaadin.forceSync; } - $wnd.vaadin.forceSync = function() { + $wnd.vaadin.forceSync = $entry(function() { if (oldSync) { oldSync(); } app.@com.vaadin.terminal.gwt.client.ApplicationConnection::sendPendingVariableChanges()(); - } + }); var oldForceLayout; if ($wnd.vaadin.forceLayout) { oldForceLayout = $wnd.vaadin.forceLayout; } - $wnd.vaadin.forceLayout = function() { + $wnd.vaadin.forceLayout = $entry(function() { if (oldForceLayout) { oldForceLayout(); } app.@com.vaadin.terminal.gwt.client.ApplicationConnection::forceLayout()(); - } + }); }-*/; /** diff --git a/src/com/vaadin/terminal/gwt/client/HistoryImplIEVaadin.java b/src/com/vaadin/terminal/gwt/client/HistoryImplIEVaadin.java index 217013095a..0571959339 100644 --- a/src/com/vaadin/terminal/gwt/client/HistoryImplIEVaadin.java +++ b/src/com/vaadin/terminal/gwt/client/HistoryImplIEVaadin.java @@ -139,9 +139,9 @@ public class HistoryImplIEVaadin extends HistoryImpl { /*-{ var historyImplRef = this; - $wnd.__gwt_onHistoryLoad = function(token) { + $wnd.__gwt_onHistoryLoad = $entry(function(token) { historyImplRef.@com.google.gwt.user.client.impl.HistoryImpl::newItemOnEvent(Ljava/lang/String;)(token); - }; + }); }-*/; protected native void navigateFrame(String token) diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java index e033e5adfe..b9baf362e4 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -282,9 +282,9 @@ public class Util { */ public native static void addPngFix(Element el) /*-{ - el.attachEvent("onload", function() { + el.attachEvent("onload", $entry(function() { @com.vaadin.terminal.gwt.client.Util::doIE6PngFix(Lcom/google/gwt/user/client/Element;)(el); - },false); + }),false); }-*/; private native static void doPngFix(Element el, String blankImageUrl) diff --git a/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategy.java b/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategy.java index eabb21eb4f..455a9bf601 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategy.java +++ b/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategy.java @@ -8,9 +8,9 @@ public class UploadIFrameOnloadStrategy { native void hookEvents(com.google.gwt.dom.client.Element iframe, VUpload upload) /*-{ - iframe.onload = function() { + iframe.onload = $entry(function() { upload.@com.vaadin.terminal.gwt.client.ui.VUpload::onSubmitComplete()(); - }; + }); }-*/; /** diff --git a/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategyIE.java b/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategyIE.java index f4b41b0646..b23d82fa22 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategyIE.java +++ b/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategyIE.java @@ -13,11 +13,11 @@ public class UploadIFrameOnloadStrategyIE extends UploadIFrameOnloadStrategy { @Override native void hookEvents(Element iframe, VUpload upload) /*-{ - iframe.onreadystatechange = function() { + iframe.onreadystatechange = $entry(function() { if (iframe.readyState == 'complete') { upload.@com.vaadin.terminal.gwt.client.ui.VUpload::onSubmitComplete()(); } - }; + }); }-*/; @Override diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java index 2a40cd0fe3..f4aacf3ea2 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomLayout.java @@ -479,9 +479,9 @@ public class VCustomLayout extends ComplexPanel implements Paintable, private native void publishResizedFunction(Element element) /*-{ var self = this; - element.notifyChildrenOfSizeChange = function() { + element.notifyChildrenOfSizeChange = $entry(function() { self.@com.vaadin.terminal.gwt.client.ui.VCustomLayout::notifyChildrenOfSizeChange()(); - }; + }); }-*/; /** diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java index 072754e0ce..ff649ebeb1 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java @@ -560,9 +560,9 @@ public class VDragAndDropWrapper extends VCustomComponent implements protected native void hookHtml5DragStart(Element el) /*-{ var me = this; - el.addEventListener("dragstart", function(ev) { + el.addEventListener("dragstart", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragStart(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }, false); + }), false); }-*/; /** @@ -574,21 +574,21 @@ public class VDragAndDropWrapper extends VCustomComponent implements /*-{ var me = this; - el.addEventListener("dragenter", function(ev) { + el.addEventListener("dragenter", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragEnter(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }, false); + }), false); - el.addEventListener("dragleave", function(ev) { + el.addEventListener("dragleave", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragLeave(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }, false); + }), false); - el.addEventListener("dragover", function(ev) { + el.addEventListener("dragover", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragOver(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }, false); + }), false); - el.addEventListener("drop", function(ev) { + el.addEventListener("drop", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragDrop(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }, false); + }), false); }-*/; public boolean updateDropDetails(VDragEvent drag) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperIE.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperIE.java index ce4a19462f..30483545e9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperIE.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperIE.java @@ -39,9 +39,9 @@ public class VDragAndDropWrapperIE extends VDragAndDropWrapper { /*-{ var me = this; - el.attachEvent("ondragstart", function(ev) { + el.attachEvent("ondragstart", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragStart(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }); + })); }-*/; @Override @@ -49,21 +49,21 @@ public class VDragAndDropWrapperIE extends VDragAndDropWrapper { /*-{ var me = this; - el.attachEvent("ondragenter", function(ev) { + el.attachEvent("ondragenter", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragEnter(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }); + })); - el.attachEvent("ondragleave", function(ev) { + el.attachEvent("ondragleave", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragLeave(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }); + })); - el.attachEvent("ondragover", function(ev) { + el.attachEvent("ondragover", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragOver(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }); + })); - el.attachEvent("ondrop", function(ev) { + el.attachEvent("ondrop", $entry(function(ev) { return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragDrop(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); - }); + })); }-*/; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java index 44ee7c11df..d1e4f7ca5b 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java @@ -357,9 +357,9 @@ public class VTextField extends TextBoxBase implements Paintable, Field, protected native void attachCutEventListener(Element el) /*-{ var me = this; - el.oncut = function() { + el.oncut = $entry(function() { me.@com.vaadin.terminal.gwt.client.ui.VTextField::onCut()(); - }; + }); }-*/; protected native void detachCutEventListener(Element el) diff --git a/src/com/vaadin/terminal/gwt/client/ui/VVideo.java b/src/com/vaadin/terminal/gwt/client/ui/VVideo.java index 92b93ac96b..8599ffb279 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VVideo.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VVideo.java @@ -52,9 +52,9 @@ public class VVideo extends VMediaBase { private native void updateDimensionsWhenMetadataLoaded(Element el) /*-{ var self = this; - el.addEventListener('loadedmetadata', function(e) { - $entry(self.@com.vaadin.terminal.gwt.client.ui.VVideo::updateElementDynamicSize(II)(el.videoWidth, el.videoHeight)); - }, false); + el.addEventListener('loadedmetadata', $entry(function(e) { + self.@com.vaadin.terminal.gwt.client.ui.VVideo::updateElementDynamicSize(II)(el.videoWidth, el.videoHeight); + }), false); }-*/; -- cgit v1.2.3