Browse Source

Migrating 7.7.1, 7.7.2, 7.7.3 to V8.

commit 11c3f8bd9e - Test and its UI class
are added (both V8 and V7). Required functionality should be available
via modern GWT version.

commit 729dbf96fe - About update release
notes. No need to be included.

commit 675f38349c - V8 already contains
correct Import-Packages section which uses osgi.javax.servlet.version
variable whise version is 3.0.0 at the moment.

commit 5da7c052f5 - Use Vaadin plugin
7.7.0 from 7.7.0.alpha1. Is not applicable.

commit 1df80001ab - Updated tutorial to
Vaadin 7.7.0. Is not applicable. The tutorial already contains correct
links and updated source code snippets.

commit 8b4f0ed8a8 - set-property-fallback
name="user.agent" value="safari". Is already there.

commit 28ed04e827 - Fix animation end
listeners so they are always removed. Is already there.

commit 408253bc3f - Use servlet context
classloader when finding servlet class for websockets. Is already there.

commit 7a6f250d89 - Fire actions before
removing menu from the DOM. Is already there.

commit 9b66c6eb9b - Do not run test on IE8
as IE8 is broken. Transplanted.

commit 3faa43ff39 - Discard for DateField
when the data source contains null. It is not applicable for V8 (There
is no anymore discard method in DateField (and no datasource suport in
field)). Transplanted for DateField in compatibility.

commit e0c1f91a3d - Fix ComboBox paging
when number of items equals page length. It's already done by another
fix which replaced ComboBox in compatibility package to the V7 version.

commit 83a1b8a096 - Update DOM and update
escalator row count in the correct order. Transplanted.

commit 45f2fba8ff - Prevent editor from
being canceled while it is being saved. Transplanted to compatibility
package. Is not applicable to modern Grid.

commit ad67f7f43a - Delete broken
stylesheet and revert to default style until a new stylesheet is
created. Is already there.

commit c970a78d42 - Always show loading
indicator for JavaScript RPC. Transplanted.

commit 2aad341606 - Make test independent
of any converters present in the factory. It's already there.

commit c9ad48430b - Do not include
yuicompressor for Sass compiler. Transplanted. Exclusion is added into
vaadin/pom.xml

commit 52d01a68e9 - Test for Firefox
download disconnecting push channel. Transplanted.

commit 4bc375d1d2 - Handle encoded URL
characters correctly when constructing widget set name. Transplanted.

commit 17ba88eaf8 - Update version to
7.7-SNAPSHOT. Is not applicable.

commit 47b7b13e5c - Ensure Firefox always
updates the grid scrollbar. Transplanted. Made changes in the logic to
the test for modern Grid component.

commit 4d851ba21d - Calculate column
widths immediately if there is data. Transplanted to both client side
modules.

commit 8f0b1a1dd0 - Skip Maven enforcer
plugin during demo validation. Transplanted (one build file is
affected).

commit 62815353e1 - Build demos from 7.7
branch (now for master branch). FW8 demos are added (one build file is
affected).

commit 815d72115d - Make test pass on all
browsers. Transplanted to both V7 and V8 version tests.

commit 516c428ca1 - Use widget set
specified by init parameter. Transplanted to the one UIProvider class.

commit b00c580ed7 - Use correct column
index when calculating min width during resize. Transplanted into both
client side classes (main and compatibility) as is. Test for V7 is
transplanted as is. Test for V8 is written from scratch based on V7
version.

commit 7dd91cf057 - Fix regression that
broke widget set compilation in 7.7.1. It's already there.

commit c665731b0b - Ensure temporary
layout manager state is cleared at the end of a layout phase.
Transplanted to the one LayoutManager class.

commit 57a965251a - Fix assertion error
when column widths are calculated. Transplanted to both versions of the
client Grid widget.

commit c5c52684eb - Format Java files
using Eclipse Neon and Vaadin settings. Only formatting changes. Is not
transplanted.

f5d06d8771 - Change javadoc to a style
Eclipse formatter can handle. Transplanted to both versions of the
client Grid widget.

commit 6033e13c20 - Make initially
disabled grid work when enabled. Transplanted to both client side
modules.

commit a2d6e4fb4b - Use
requestAnimationFrame when scrolling in Grid. Transplanted to both
client side modules.

commit fe9438e7b7 - Specify branch also
for Sampler. Is not applicable for master branch.

commit 1ec5d8ef7c - Update to Chrome 53.
Is already there.

commit 961851bfbc - Updated link to new
step 1 video in tutorial. Is already there.

commit 41dc2fe161 - Revert "Use widget set
specified by init parameter. Transplanted to the one UIProvider class.

commit 092b4f7f31 - Use widget set
specified by init parameter. Transplanted to the common server side
classes.

commit 977cec7e31 - Fix widget set builder
to create widget set in correct location. Transplanted to the one
ClassPathExplorer class file.

commit 6c12ad89ea - Format project pom
files using correct settings. Is not transplanted: only formatting
changes for POM files.

commit 0aad93ecc1 - Add tests for
widgetset compilation in different modes. Transplanted. New test
projects.

commit 0a3a1ef832 - Use
versions-maven-plugin 2.3 to avoid NPE while setting project version. Is
already there.

Change-Id: Ie3a5088f25de1772f01ea30c4a5eba0b169ee0ab
tags/8.0.0.alpha4
Denis Anisimov 7 years ago
parent
commit
43bb825f0e
79 changed files with 2401 additions and 197 deletions
  1. 12
    13
      client/src/main/java/com/vaadin/client/AnimationUtil.java
  2. 8
    0
      client/src/main/java/com/vaadin/client/LayoutManager.java
  3. 3
    2
      client/src/main/java/com/vaadin/client/communication/ServerRpcQueue.java
  4. 14
    1
      client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java
  5. 10
    0
      client/src/main/java/com/vaadin/client/data/DataSource.java
  6. 59
    12
      client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java
  7. 5
    0
      client/src/main/java/com/vaadin/client/widget/grid/datasources/ListDataSource.java
  8. 17
    14
      client/src/main/java/com/vaadin/client/widgets/Escalator.java
  9. 16
    30
      client/src/main/java/com/vaadin/client/widgets/Grid.java
  10. 6
    1
      compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java
  11. 59
    12
      compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java
  12. 8
    3
      compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/datasources/ListDataSource.java
  13. 58
    72
      compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java
  14. 19
    0
      compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java
  15. 17
    1
      compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java
  16. 106
    0
      compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/grid/ItemSetChangeDuringEditorCommit.java
  17. 47
    1
      pom.xml
  18. 1
    0
      scripts/BuildDemos.py
  19. 2
    0
      scripts/BuildHelpers.py
  20. 5
    2
      server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java
  21. 10
    3
      server/src/main/java/com/vaadin/server/UIProvider.java
  22. 10
    0
      server/src/main/java/com/vaadin/server/VaadinServlet.java
  23. 17
    4
      server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java
  24. 9
    9
      server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java
  25. 58
    0
      test/addon-using-init-param-widget-set/pom.xml
  26. 25
    0
      test/addon-using-init-param-widget-set/src/main/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetUI.java
  27. 15
    0
      test/addon-using-init-param-widget-set/src/test/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetIT.java
  28. 52
    0
      test/addon-using-no-defined-widget-set/pom.xml
  29. 24
    0
      test/addon-using-no-defined-widget-set/src/main/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetUI.java
  30. 14
    0
      test/addon-using-no-defined-widget-set/src/test/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetIT.java
  31. 52
    0
      test/addon-using-own-widget-set/pom.xml
  32. 26
    0
      test/addon-using-own-widget-set/src/main/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetUI.java
  33. 7
    0
      test/addon-using-own-widget-set/src/main/resources/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSet.gwt.xml
  34. 15
    0
      test/addon-using-own-widget-set/src/test/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetIT.java
  35. 34
    0
      test/default-widget-set/pom.xml
  36. 15
    0
      test/default-widget-set/src/main/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetUI.java
  37. 11
    0
      test/default-widget-set/src/test/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetIT.java
  38. 45
    0
      test/own-widget-set/pom.xml
  39. 17
    0
      test/own-widget-set/src/main/java/com/vaadin/test/ownwidgetset/OwnWidgetSetUI.java
  40. 14
    0
      test/own-widget-set/src/test/java/com/vaadin/test/ownwidgetset/OwnWidgetSetIT.java
  41. 143
    0
      test/pom.xml
  42. 44
    0
      test/space in directory/pom.xml
  43. 17
    0
      test/space in directory/src/main/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryUI.java
  44. 5
    0
      test/space in directory/src/main/resources/com/vaadin/test/spaceindirectory/SpaceInDirectory.gwt.xml
  45. 15
    0
      test/space in directory/src/test/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryIT.java
  46. 45
    0
      test/vaadinservletconfiguration-widget-set/pom.xml
  47. 16
    0
      test/vaadinservletconfiguration-widget-set/src/main/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetUI.java
  48. 5
    0
      test/vaadinservletconfiguration-widget-set/src/main/resources/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSet.gwt.xml
  49. 14
    0
      test/vaadinservletconfiguration-widget-set/src/test/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetIT.java
  50. 32
    0
      test/widget-set-testutil/pom.xml
  51. 39
    0
      test/widget-set-testutil/src/main/java/com/vaadin/test/widgetset/AbstractTestWidgetSetUI.java
  52. 59
    0
      test/widget-set-testutil/src/test/java/com/vaadin/test/defaultwidgetset/AbstractWidgetSetIT.java
  53. 5
    10
      uitest-common/src/main/java/com/vaadin/tests/tb3/AbstractTB3Test.java
  54. 44
    0
      uitest/src/main/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDown.java
  55. 5
    1
      uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnHiding.java
  56. 58
    0
      uitest/src/main/java/com/vaadin/tests/components/grid/InitiallyDisabledGrid.java
  57. 38
    0
      uitest/src/main/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicator.java
  58. 30
    0
      uitest/src/main/java/com/vaadin/tests/core/SpecialCharactersEncodingUI.java
  59. 93
    0
      uitest/src/main/java/com/vaadin/tests/resources/DownloadWithPush.java
  60. 5
    0
      uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridCellFocusOnResetSizeWidget.java
  61. 12
    6
      uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridClientColumnRendererConnector.java
  62. 99
    0
      uitest/src/main/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValue.java
  63. 64
    0
      uitest/src/main/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDown.java
  64. 60
    0
      uitest/src/main/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGrid.java
  65. 9
    0
      uitest/src/main/java/com/vaadin/v7/tests/components/grid/basicfeatures/GridBasicFeatures.java
  66. 30
    0
      uitest/src/main/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUI.java
  67. 11
    0
      uitest/src/main/resources/com/vaadin/tests/components/javascriptcomponent/JSComponent.js
  68. 44
    0
      uitest/src/test/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java
  69. 40
    0
      uitest/src/test/java/com/vaadin/tests/components/grid/GridColumnHidingTest.java
  70. 45
    0
      uitest/src/test/java/com/vaadin/tests/components/grid/InitiallyDisabledGridTest.java
  71. 29
    0
      uitest/src/test/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicatorTest.java
  72. 11
    0
      uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabsheetScrollIntoViewTest.java
  73. 37
    0
      uitest/src/test/java/com/vaadin/tests/core/SpecialCharactersEncodingUITest.java
  74. 85
    0
      uitest/src/test/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValueTest.java
  75. 44
    0
      uitest/src/test/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java
  76. 34
    0
      uitest/src/test/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGridTest.java
  77. 21
    0
      uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnResizeTest.java
  78. 35
    0
      uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java
  79. 37
    0
      uitest/src/test/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUITest.java

+ 12
- 13
client/src/main/java/com/vaadin/client/AnimationUtil.java View File

@@ -19,7 +19,6 @@ import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
import com.vaadin.client.AnimationUtil.AnimationEndListener;

/**
* Utility methods for working with CSS transitions and animations.
@@ -67,15 +66,15 @@ public class AnimationUtil {
listener.@com.vaadin.client.AnimationUtil.AnimationEndListener::onAnimationEnd(Lcom/google/gwt/dom/client/NativeEvent;)(e);
});
callbackFunc.listener = listener;
elem.addEventListener(@com.vaadin.client.AnimationUtil::ANIMATION_END_EVENT_NAME, callbackFunc, false);
// Store function reference for later removal
if(!elem._vaadin_animationend_callbacks) {
elem._vaadin_animationend_callbacks = [];
}
elem._vaadin_animationend_callbacks.push(callbackFunc);
return callbackFunc;
}-*/;

@@ -138,7 +137,7 @@ public class AnimationUtil {
return event.mozAnimationName;
else if(event.oAnimationName)
return event.oAnimationName;
return "";
}-*/;

@@ -146,22 +145,22 @@ public class AnimationUtil {
public static native String getAnimationName(ComputedStyle cstyle)
/*-{
var cs = cstyle.@com.vaadin.client.ComputedStyle::computedStyle;
if(!cs.getPropertyValue)
return "";
if(cs.getPropertyValue("-webkit-animation-name"))
return cs.getPropertyValue("-webkit-animation-name");
else if(cs.getPropertyValue("animation-name"))
return cs.getPropertyValue("animation-name");
else if(cs.getPropertyValue("-moz-animation-name"))
return cs.getPropertyValue("-moz-animation-name");
else if(cs.getPropertyValue("-o-animation-name"))
return cs.getPropertyValue("-o-animation-name");
return "";
}-*/;

@@ -176,7 +175,7 @@ public class AnimationUtil {
'MozAnimation': 'animationend',
'WebkitAnimation': 'webkitAnimationEnd'
}
for(var a in anims){
if( el.style[a] !== undefined ){
return anims[a];
@@ -195,7 +194,7 @@ public class AnimationUtil {
'mozAnimation',
'webkitAnimation'
]
for(var i=0; i < anims.length; i++) {
if( el.style[anims[i]] !== undefined ){
return anims[i];

+ 8
- 0
client/src/main/java/com/vaadin/client/LayoutManager.java View File

@@ -600,6 +600,14 @@ public class LayoutManager {
}
Profiler.leave("layout PostLayoutListener");

// Ensure temporary variables are cleaned
if (!pendingOverflowFixes.isEmpty()) {
getLogger().warning(
"pendingOverflowFixes is not empty at the end of doLayout: "
+ pendingOverflowFixes.dump());
pendingOverflowFixes = FastStringSet.create();
}

getLogger().info("Total layout phase time: "
+ totalDuration.elapsedMillis() + "ms");
}

+ 3
- 2
client/src/main/java/com/vaadin/client/communication/ServerRpcQueue.java View File

@@ -226,10 +226,11 @@ public class ServerRpcQueue {
*/
public boolean showLoadingIndicator() {
for (MethodInvocation invocation : getAll()) {
if (isLegacyVariableChange(invocation)) {
if (isLegacyVariableChange(invocation)
|| isJavascriptRpc(invocation)) {
// Always show loading indicator for legacy requests
return true;
} else if (!isJavascriptRpc(invocation)) {
} else {
Type type = new Type(invocation.getInterfaceName(), null);
Method method = type.getMethod(invocation.getMethodName());
if (!TypeDataStore.isNoLoadingIndicator(method)) {

+ 14
- 1
client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java View File

@@ -378,7 +378,7 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> {
}

private void handleMissingRows(Range range) {
if (range.isEmpty()) {
if (range.isEmpty() || !canFetchData()) {
return;
}
currentRequestCallback = new RequestRowsCallback<>(this, range);
@@ -794,4 +794,17 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> {
protected boolean isPinned(T row) {
return pinnedRows.containsKey(getRowKey(row));
}

/**
* Checks if it is possible to currently fetch data from the remote data
* source.
*
* @return <code>true</code> if it is ok to try to fetch data,
* <code>false</code> if it is known that fetching data will fail
* and should not be tried right now.
* @since 7.7.2
*/
protected boolean canFetchData() {
return true;
}
}

+ 10
- 0
client/src/main/java/com/vaadin/client/data/DataSource.java View File

@@ -217,4 +217,14 @@ public interface DataSource<T> {
* means that the row is not currently in this data source's cache.
*/
public RowHandle<T> getHandle(T row);

/**
* Checks whether this data source is currently waiting for more rows to
* become available.
*
* @return <code>true</code> if waiting for data; otherwise
* <code>false</code>
* @since 7.7.2
*/
public boolean isWaitingForData();
}

+ 59
- 12
client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java View File

@@ -16,6 +16,8 @@

package com.vaadin.client.widget.escalator;

import com.google.gwt.animation.client.AnimationScheduler;
import com.google.gwt.animation.client.AnimationScheduler.AnimationSupportDetector;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
@@ -31,6 +33,7 @@ import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.Timer;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.DeferredWorker;
import com.vaadin.client.WidgetUtil;
import com.vaadin.client.widget.grid.events.ScrollEvent;
@@ -47,6 +50,9 @@ import com.vaadin.client.widget.grid.events.ScrollHandler;
*/
public abstract class ScrollbarBundle implements DeferredWorker {

private static final boolean supportsRequestAnimationFrame = new AnimationSupportDetector()
.isNativelySupported();

private class ScrollEventFirer {
private final ScheduledCommand fireEventCommand = new ScheduledCommand() {
@Override
@@ -91,7 +97,17 @@ public abstract class ScrollbarBundle implements DeferredWorker {
* We'll gather all the scroll events, and only fire once, once
* everything has calmed down.
*/
Scheduler.get().scheduleDeferred(fireEventCommand);
if (supportsRequestAnimationFrame) {
// Chrome MUST use this as deferred commands will sometimes
// be run with a 300+ ms delay when scrolling.
AnimationScheduler.get().requestAnimationFrame(
timestamp -> fireEventCommand.execute());
} else {
// Does not support requestAnimationFrame and the fallback
// uses a delay of 16ms, we stick to the old deferred
// command which uses a delay of 0ms
Scheduler.get().scheduleDeferred(fireEventCommand);
}
isBeingFired = true;
}
}
@@ -449,13 +465,25 @@ public abstract class ScrollbarBundle implements DeferredWorker {
* set either <code>overflow-x</code> or <code>overflow-y</code> to "
* <code>scroll</code>" in the scrollbar's direction.
* <p>
* This is an IE8 workaround, since it doesn't always show scrollbars with
* <code>overflow: auto</code> enabled.
* This method is an IE8 workaround, since it doesn't always show scrollbars
* with <code>overflow: auto</code> enabled.
* <p>
* Firefox on the other hand loses pending scroll events when the scrollbar
* is hidden, so the event must be fired manually.
* <p>
* When IE8 support is dropped, this should really be simplified.
*/
protected void forceScrollbar(boolean enable) {
if (enable) {
root.getStyle().clearDisplay();
} else {
if (BrowserInfo.get().isFirefox()) {
/*
* This is related to the Firefox workaround in setScrollSize
* for setScrollPos(0)
*/
scrollEventFirer.scheduleEvent();
}
root.getStyle().setDisplay(Display.NONE);
}
internalForceScrollbar(enable);
@@ -603,21 +631,37 @@ public abstract class ScrollbarBundle implements DeferredWorker {
* This needs to be made step-by-step because IE8 flat-out refuses to
* fire a scroll event when the scroll size becomes smaller than the
* offset size. All other browser need to suffer alongside.
*
* This really should be changed to not use any temporary scroll
* handlers at all once IE8 support is dropped, like now done only for
* Firefox.
*/

boolean newScrollSizeIsSmallerThanOffsetSize = px <= getOffsetSize();
boolean scrollSizeBecomesSmallerThanOffsetSize = showsScrollHandle()
&& newScrollSizeIsSmallerThanOffsetSize;
if (scrollSizeBecomesSmallerThanOffsetSize && getScrollPos() != 0) {
// must be a field because Java insists.
scrollSizeTemporaryScrollHandler = addScrollHandler(
new ScrollHandler() {
@Override
public void onScroll(ScrollEvent event) {
setScrollSizeNow(px);
}
});
/*
* For whatever reason, Firefox loses the scroll event in this case
* and the onscroll handler is never called (happens when reducing
* size from 1000 items to 1 while being scrolled a bit down, see
* #19802). Based on the comment above, only IE8 should really use
* 'delayedSizeSet'
*/
boolean delayedSizeSet = !BrowserInfo.get().isFirefox();
if (delayedSizeSet) {
scrollSizeTemporaryScrollHandler = addScrollHandler(
new ScrollHandler() {
@Override
public void onScroll(ScrollEvent event) {
setScrollSizeNow(px);
}
});
}
setScrollPos(0);
if (!delayedSizeSet) {
setScrollSizeNow(px);
}
} else {
setScrollSizeNow(px);
}
@@ -863,7 +907,10 @@ public abstract class ScrollbarBundle implements DeferredWorker {

@Override
public boolean isWorkPending() {
// Need to include scrollEventFirer.isBeingFired as it might use
// requestAnimationFrame - which is not automatically checked
return scrollSizeTemporaryScrollHandler != null
|| offsetSizeTemporaryScrollHandler != null;
|| offsetSizeTemporaryScrollHandler != null
|| scrollEventFirer.isBeingFired;
}
}

+ 5
- 0
client/src/main/java/com/vaadin/client/widget/grid/datasources/ListDataSource.java View File

@@ -457,6 +457,11 @@ public class ListDataSource<T> implements DataSource<T> {
};
}

@Override
public boolean isWaitingForData() {
return false;
}

private Stream<DataChangeHandler> getHandlers() {
Set<DataChangeHandler> copy = new LinkedHashSet<>(changeHandlers);
return copy.stream();

+ 17
- 14
client/src/main/java/com/vaadin/client/widgets/Escalator.java View File

@@ -672,13 +672,13 @@ public class Escalator extends Widget
/*-{
var vScroll = esc.@com.vaadin.client.widgets.Escalator::verticalScrollbar;
var vScrollElem = vScroll.@com.vaadin.client.widget.escalator.ScrollbarBundle::getElement()();
var hScroll = esc.@com.vaadin.client.widgets.Escalator::horizontalScrollbar;
var hScrollElem = hScroll.@com.vaadin.client.widget.escalator.ScrollbarBundle::getElement()();
return $entry(function(e) {
var target = e.target;
// in case the scroll event was native (i.e. scrollbars were dragged, or
// the scrollTop/Left was manually modified), the bundles have old cache
// values. We need to make sure that the caches are kept up to date.
@@ -699,29 +699,29 @@ public class Escalator extends Widget
return $entry(function(e) {
var deltaX = e.deltaX ? e.deltaX : -0.5*e.wheelDeltaX;
var deltaY = e.deltaY ? e.deltaY : -0.5*e.wheelDeltaY;
// Delta mode 0 is in pixels; we don't need to do anything...
// A delta mode of 1 means we're scrolling by lines instead of pixels
// We need to scale the number of lines by the default line height
if(e.deltaMode === 1) {
var brc = esc.@com.vaadin.client.widgets.Escalator::body;
deltaY *= brc.@com.vaadin.client.widgets.Escalator.AbstractRowContainer::getDefaultRowHeight()();
}
// Other delta modes aren't supported
if((e.deltaMode !== undefined) && (e.deltaMode >= 2 || e.deltaMode < 0)) {
var msg = "Unsupported wheel delta mode \"" + e.deltaMode + "\"";
// Print warning message
esc.@com.vaadin.client.widgets.Escalator::logWarning(*)(msg);
}
// IE8 has only delta y
if (isNaN(deltaY)) {
deltaY = -0.5*e.wheelDelta;
}
@com.vaadin.client.widgets.Escalator.JsniUtil::moveScrollFromEvent(*)(esc, deltaX, deltaY, e);
});
}-*/;
@@ -4170,6 +4170,11 @@ public class Escalator extends Widget
frozenColumns += numberOfColumns;
}

// Add to DOM
header.paintInsertColumns(index, numberOfColumns, frozen);
body.paintInsertColumns(index, numberOfColumns, frozen);
footer.paintInsertColumns(index, numberOfColumns, frozen);

// this needs to be before the scrollbar adjustment.
boolean scrollbarWasNeeded = horizontalScrollbar
.getOffsetSize() < horizontalScrollbar.getScrollSize();
@@ -4177,14 +4182,12 @@ public class Escalator extends Widget
boolean scrollbarIsNowNeeded = horizontalScrollbar
.getOffsetSize() < horizontalScrollbar.getScrollSize();
if (!scrollbarWasNeeded && scrollbarIsNowNeeded) {
// This might as a side effect move rows around (when scrolled
// all the way down) and require the DOM to be up to date, i.e.
// the column to be added
body.verifyEscalatorCount();
}

// Add to DOM
header.paintInsertColumns(index, numberOfColumns, frozen);
body.paintInsertColumns(index, numberOfColumns, frozen);
footer.paintInsertColumns(index, numberOfColumns, frozen);

// fix initial width
if (header.getRowCount() > 0 || body.getRowCount() > 0
|| footer.getRowCount() > 0) {

+ 16
- 30
client/src/main/java/com/vaadin/client/widgets/Grid.java View File

@@ -3163,7 +3163,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
rescheduleCount = 0;
Scheduler.get().scheduleDeferred(this);
}
} else if (dataIsBeingFetched) {
} else if (currentDataAvailable.isEmpty()
&& dataSource.isWaitingForData()) {
Scheduler.get().scheduleDeferred(this);
} else {
calculate();
@@ -3199,7 +3200,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
isScheduled = false;
rescheduleCount = 0;

assert !dataIsBeingFetched : "Trying to calculate column widths even though data is still being fetched.";
assert !(currentDataAvailable.isEmpty() && dataSource
.isWaitingForData()) : "Trying to calculate column widths without data while data is still being fetched.";

if (columnsAreGuaranteedToBeWiderThanGrid()) {
applyColumnWidths();
@@ -4060,21 +4062,15 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

private final Editor<T> editor = GWT.create(Editor.class);

private boolean dataIsBeingFetched = false;

/**
* The cell a click event originated from
* <p>
* This is a workaround to make Chrome work like Firefox. In Chrome,
* normally if you start a drag on one cell and release on:
* <ul>
* <li>that same cell, the click event is that {@code
*
<td>}.
* <li>a cell on that same row, the click event is the parent {@code
*
<tr>
* }.
* <li>that same cell, the click event is that <code>&lt;td></code>.
* <li>a cell on that same row, the click event is the parent
* <code>&lt;tr></code>.
* <li>a cell on another row, the click event is the table section ancestor
* ({@code <thead>}, {@code <tbody>} or {@code <tfoot>}).
* </ul>
@@ -5672,7 +5668,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
initialWidth = col.getWidthActual();

minCellWidth = escalator.getMinCellWidth(
getColumns().indexOf(col));
getVisibleColumns().indexOf(col));
for (Column<?, T> c : getVisibleColumns()) {
if (selectionColumn == c) {
// Don't modify selection column.
@@ -5681,8 +5677,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

if (c.getWidth() < 0) {
c.setWidth(c.getWidthActual());
fireEvent(new ColumnResizeEvent<>(
c));
fireEvent(
new ColumnResizeEvent<>(c));
}
}

@@ -5907,7 +5903,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
public void onRowVisibilityChange(
RowVisibilityChangeEvent event) {
if (dataSource != null && dataSource.size() != 0) {
dataIsBeingFetched = true;
dataSource.ensureAvailability(
event.getFirstVisibleRow(),
event.getVisibleRowCount());
@@ -5947,12 +5942,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
}
});

addDataAvailableHandler(new DataAvailableHandler() {
@Override
public void onDataAvailable(DataAvailableEvent event) {
dataIsBeingFetched = false;
}
});
}

@Override
@@ -6291,8 +6280,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
* @return A unmodifiable list of the columns in the grid
*/
public List<Column<?, T>> getColumns() {
return Collections
.unmodifiableList(new ArrayList<>(columns));
return Collections.unmodifiableList(new ArrayList<>(columns));
}

/**
@@ -6717,8 +6705,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
int oldSize = body.getRowCount();

// Hide all details.
Set<Integer> oldDetails = new HashSet<>(
visibleDetails);
Set<Integer> oldDetails = new HashSet<>(visibleDetails);
for (int i : oldDetails) {
setDetailsVisible(i, false);
}
@@ -6734,7 +6721,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
}

if (newSize > 0) {
dataIsBeingFetched = true;
Range visibleRowRange = escalator
.getVisibleRowRange();
dataSource.ensureAvailability(
@@ -7829,7 +7815,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override
public void execute() {
if (!dataIsBeingFetched) {
if (!dataSource.isWaitingForData()) {
handler.onDataAvailable(
new DataAvailableEvent(currentDataAvailable));
}
@@ -8108,8 +8094,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
*/
private void sort(boolean userOriginated) {
refreshHeader();
fireEvent(new SortEvent<>(this,
Collections.unmodifiableList(sortOrder), userOriginated));
fireEvent(new SortEvent<>(this, Collections.unmodifiableList(sortOrder),
userOriginated));
}

private int getLastVisibleRowIndex() {
@@ -8150,7 +8136,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

@Override
public boolean isWorkPending() {
return escalator.isWorkPending() || dataIsBeingFetched
return escalator.isWorkPending() || dataSource.isWaitingForData()
|| autoColumnWidthsRecalculator.isScheduled()
|| editor.isWorkPending();
}

+ 6
- 1
compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java View File

@@ -73,7 +73,7 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector {
registerRpc(DataProviderRpc.class, new DataProviderRpc() {
@Override
public void setRowData(int firstRow, JsonArray rowArray) {
ArrayList<JsonObject> rows = new ArrayList<JsonObject>(
ArrayList<JsonObject> rows = new ArrayList<>(
rowArray.length());
for (int i = 0; i < rowArray.length(); i++) {
JsonObject rowObject = rowArray.getObject(i);
@@ -240,6 +240,11 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector {
droppedRowKeys.set(droppedRowKeys.length(), getRowKey(row));
}
}

@Override
protected boolean canFetchData() {
return isEnabled();
}
}

private final RpcDataSource dataSource = new RpcDataSource();

+ 59
- 12
compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java View File

@@ -16,6 +16,8 @@

package com.vaadin.v7.client.widget.escalator;

import com.google.gwt.animation.client.AnimationScheduler;
import com.google.gwt.animation.client.AnimationScheduler.AnimationSupportDetector;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
@@ -31,6 +33,7 @@ import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.Timer;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.DeferredWorker;
import com.vaadin.client.WidgetUtil;
import com.vaadin.v7.client.widget.grid.events.ScrollEvent;
@@ -47,6 +50,9 @@ import com.vaadin.v7.client.widget.grid.events.ScrollHandler;
*/
public abstract class ScrollbarBundle implements DeferredWorker {

private static final boolean supportsRequestAnimationFrame = new AnimationSupportDetector()
.isNativelySupported();

private class ScrollEventFirer {
private final ScheduledCommand fireEventCommand = new ScheduledCommand() {
@Override
@@ -91,7 +97,17 @@ public abstract class ScrollbarBundle implements DeferredWorker {
* We'll gather all the scroll events, and only fire once, once
* everything has calmed down.
*/
Scheduler.get().scheduleDeferred(fireEventCommand);
if (supportsRequestAnimationFrame) {
// Chrome MUST use this as deferred commands will sometimes
// be run with a 300+ ms delay when scrolling.
AnimationScheduler.get().requestAnimationFrame(
timestamp -> fireEventCommand.execute());
} else {
// Does not support requestAnimationFrame and the fallback
// uses a delay of 16ms, we stick to the old deferred
// command which uses a delay of 0ms
Scheduler.get().scheduleDeferred(fireEventCommand);
}
isBeingFired = true;
}
}
@@ -449,13 +465,25 @@ public abstract class ScrollbarBundle implements DeferredWorker {
* set either <code>overflow-x</code> or <code>overflow-y</code> to "
* <code>scroll</code>" in the scrollbar's direction.
* <p>
* This is an IE8 workaround, since it doesn't always show scrollbars with
* <code>overflow: auto</code> enabled.
* This method is an IE8 workaround, since it doesn't always show scrollbars
* with <code>overflow: auto</code> enabled.
* <p>
* Firefox on the other hand loses pending scroll events when the scrollbar
* is hidden, so the event must be fired manually.
* <p>
* When IE8 support is dropped, this should really be simplified.
*/
protected void forceScrollbar(boolean enable) {
if (enable) {
root.getStyle().clearDisplay();
} else {
if (BrowserInfo.get().isFirefox()) {
/*
* This is related to the Firefox workaround in setScrollSize
* for setScrollPos(0)
*/
scrollEventFirer.scheduleEvent();
}
root.getStyle().setDisplay(Display.NONE);
}
internalForceScrollbar(enable);
@@ -603,21 +631,37 @@ public abstract class ScrollbarBundle implements DeferredWorker {
* This needs to be made step-by-step because IE8 flat-out refuses to
* fire a scroll event when the scroll size becomes smaller than the
* offset size. All other browser need to suffer alongside.
*
* This really should be changed to not use any temporary scroll
* handlers at all once IE8 support is dropped, like now done only for
* Firefox.
*/

boolean newScrollSizeIsSmallerThanOffsetSize = px <= getOffsetSize();
boolean scrollSizeBecomesSmallerThanOffsetSize = showsScrollHandle()
&& newScrollSizeIsSmallerThanOffsetSize;
if (scrollSizeBecomesSmallerThanOffsetSize && getScrollPos() != 0) {
// must be a field because Java insists.
scrollSizeTemporaryScrollHandler = addScrollHandler(
new ScrollHandler() {
@Override
public void onScroll(ScrollEvent event) {
setScrollSizeNow(px);
}
});
/*
* For whatever reason, Firefox loses the scroll event in this case
* and the onscroll handler is never called (happens when reducing
* size from 1000 items to 1 while being scrolled a bit down, see
* #19802). Based on the comment above, only IE8 should really use
* 'delayedSizeSet'
*/
boolean delayedSizeSet = !BrowserInfo.get().isFirefox();
if (delayedSizeSet) {
scrollSizeTemporaryScrollHandler = addScrollHandler(
new ScrollHandler() {
@Override
public void onScroll(ScrollEvent event) {
setScrollSizeNow(px);
}
});
}
setScrollPos(0);
if (!delayedSizeSet) {
setScrollSizeNow(px);
}
} else {
setScrollSizeNow(px);
}
@@ -863,7 +907,10 @@ public abstract class ScrollbarBundle implements DeferredWorker {

@Override
public boolean isWorkPending() {
// Need to include scrollEventFirer.isBeingFired as it might use
// requestAnimationFrame - which is not automatically checked
return scrollSizeTemporaryScrollHandler != null
|| offsetSizeTemporaryScrollHandler != null;
|| offsetSizeTemporaryScrollHandler != null
|| scrollEventFirer.isBeingFired;
}
}

+ 8
- 3
compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/datasources/ListDataSource.java View File

@@ -344,7 +344,7 @@ public class ListDataSource<T> implements DataSource<T> {
if (datasource == null) {
throw new IllegalArgumentException("datasource cannot be null");
}
ds = new ArrayList<T>(datasource);
ds = new ArrayList<>(datasource);
wrapper = new ListWrapper();
}

@@ -358,9 +358,9 @@ public class ListDataSource<T> implements DataSource<T> {
*/
public ListDataSource(T... rows) {
if (rows == null) {
ds = new ArrayList<T>();
ds = new ArrayList<>();
} else {
ds = new ArrayList<T>(Arrays.asList(rows));
ds = new ArrayList<>(Arrays.asList(rows));
}
wrapper = new ListWrapper();
}
@@ -457,6 +457,11 @@ public class ListDataSource<T> implements DataSource<T> {
};
}

@Override
public boolean isWaitingForData() {
return false;
}

private Stream<DataChangeHandler> getHandlers() {
Set<DataChangeHandler> copy = new LinkedHashSet<>(changeHandlers);
return copy.stream();

+ 58
- 72
compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java View File

@@ -442,14 +442,14 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
*/
public abstract static class StaticRow<CELLTYPE extends StaticCell> {

private Map<Column<?, ?>, CELLTYPE> cells = new HashMap<Column<?, ?>, CELLTYPE>();
private Map<Column<?, ?>, CELLTYPE> cells = new HashMap<>();

private StaticSection<?> section;

/**
* Map from set of spanned columns to cell meta data.
*/
private Map<Set<Column<?, ?>>, CELLTYPE> cellGroups = new HashMap<Set<Column<?, ?>>, CELLTYPE>();
private Map<Set<Column<?, ?>>, CELLTYPE> cellGroups = new HashMap<>();

/**
* A custom style name for the row or null if none is set.
@@ -497,7 +497,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
"You can't merge less than 2 columns together.");
}

HashSet<Column<?, ?>> columnGroup = new HashSet<Column<?, ?>>();
HashSet<Column<?, ?>> columnGroup = new HashSet<>();
// NOTE: this doesn't care about hidden columns, those are
// filtered in calculateColspans()
for (Column<?, ?> column : columns) {
@@ -591,7 +591,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
private boolean checkMergedCellIsContinuous(
Set<Column<?, ?>> mergedCell) {
// no matter if hidden or not, just check for continuous order
final List<Column<?, ?>> columnOrder = new ArrayList<Column<?, ?>>(
final List<Column<?, ?>> columnOrder = new ArrayList<>(
section.grid.getColumns());

if (!columnOrder.containsAll(mergedCell)) {
@@ -661,7 +661,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
*/
void detach() {
// Avoid calling detach twice for a merged cell
HashSet<CELLTYPE> cells = new HashSet<CELLTYPE>();
HashSet<CELLTYPE> cells = new HashSet<>();
for (Column<?, ?> column : getSection().grid.getColumns()) {
cells.add(getCell(column));
}
@@ -673,7 +673,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

private Grid<?> grid;

private List<ROWTYPE> rows = new ArrayList<ROWTYPE>();
private List<ROWTYPE> rows = new ArrayList<>();

private boolean visible = true;

@@ -1337,8 +1337,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
// Should only be added to the DOM when there's a message to show
private DivElement message = DivElement.as(DOM.createDiv());

private Map<Column<?, T>, Widget> columnToWidget = new HashMap<Column<?, T>, Widget>();
private List<HandlerRegistration> focusHandlers = new ArrayList<HandlerRegistration>();
private Map<Column<?, T>, Widget> columnToWidget = new HashMap<>();
private List<HandlerRegistration> focusHandlers = new ArrayList<>();

private boolean enabled = false;
private State state = State.INACTIVE;
@@ -1433,7 +1433,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
};

/** A set of all the columns that display an error flag. */
private final Set<Column<?, T>> columnErrors = new HashSet<Grid.Column<?, T>>();
private final Set<Column<?, T>> columnErrors = new HashSet<>();
private boolean buffered = true;

/** Original position of editor */
@@ -1629,7 +1629,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
throw new IllegalStateException(
"Cannot cancel edit: editor is not in edit mode");
}
handler.cancel(new EditorRequestImpl<T>(grid, rowIndex,
handler.cancel(new EditorRequestImpl<>(grid, rowIndex,
focusedColumnIndex, null));
doCancel();
}
@@ -1675,7 +1675,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
state = State.SAVING;
setButtonsEnabled(false);
saveTimeout.schedule(SAVE_TIMEOUT_MS);
EditorRequest<T> request = new EditorRequestImpl<T>(grid, rowIndex,
EditorRequest<T> request = new EditorRequestImpl<>(grid, rowIndex,
focusedColumnIndex, saveRequestCallback);
handler.save(request);
updateSelectionCheckboxesAsNeeded(true);
@@ -1739,7 +1739,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
if (state == State.ACTIVATING) {
state = State.BINDING;
bindTimeout.schedule(BIND_TIMEOUT_MS);
EditorRequest<T> request = new EditorRequestImpl<T>(grid,
EditorRequest<T> request = new EditorRequestImpl<>(grid,
rowIndex, columnIndex, bindRequestCallback);
handler.bind(request);
grid.getEscalator().setScrollLocked(Direction.VERTICAL,
@@ -2270,7 +2270,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
extends KeyEvent<HANDLER> {

private Grid<?> grid;
private final Type<HANDLER> associatedType = new Type<HANDLER>(
private final Type<HANDLER> associatedType = new Type<>(
getBrowserEventType(), this);
private final CellReference<?> targetCell;

@@ -2330,7 +2330,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

private Grid<?> grid;
private final CellReference<?> targetCell;
private final Type<HANDLER> associatedType = new Type<HANDLER>(
private final Type<HANDLER> associatedType = new Type<>(
getBrowserEventType(), this);

public AbstractGridMouseEvent(Grid<?> grid,
@@ -2408,7 +2408,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
*/
private static final double DETAILS_ROW_INITIAL_HEIGHT = 50;

private EventCellReference<T> eventCell = new EventCellReference<T>(this);
private EventCellReference<T> eventCell = new EventCellReference<>(this);
private GridKeyDownEvent keyDown = new GridKeyDownEvent(this, eventCell);
private GridKeyUpEvent keyUp = new GridKeyUpEvent(this, eventCell);
private GridKeyPressEvent keyPress = new GridKeyPressEvent(this, eventCell);
@@ -2882,7 +2882,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
public void onValueChange(
ValueChangeEvent<Boolean> event) {
if (event.getValue()) {
fireEvent(new SelectAllEvent<T>(model));
fireEvent(new SelectAllEvent<>(model));
selected = true;
} else {
model.deselectAll();
@@ -3167,7 +3167,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
rescheduleCount = 0;
Scheduler.get().scheduleDeferred(this);
}
} else if (dataIsBeingFetched) {
} else if (currentDataAvailable.isEmpty()
&& dataSource.isWaitingForData()) {
Scheduler.get().scheduleDeferred(this);
} else {
calculate();
@@ -3203,7 +3204,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
isScheduled = false;
rescheduleCount = 0;

assert !dataIsBeingFetched : "Trying to calculate column widths even though data is still being fetched.";
assert !(currentDataAvailable.isEmpty() && dataSource
.isWaitingForData()) : "Trying to calculate column widths without data while data is still being fetched.";

if (columnsAreGuaranteedToBeWiderThanGrid()) {
applyColumnWidths();
@@ -3232,7 +3234,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

/* Step 1: Apply all column widths as they are. */

Map<Integer, Double> selfWidths = new LinkedHashMap<Integer, Double>();
Map<Integer, Double> selfWidths = new LinkedHashMap<>();
List<Column<?, T>> columns = getVisibleColumns();
for (int index = 0; index < columns.size(); index++) {
selfWidths.put(index, columns.get(index).getWidth());
@@ -3246,7 +3248,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
* violated, fix it.
*/

Map<Integer, Double> constrainedWidths = new LinkedHashMap<Integer, Double>();
Map<Integer, Double> constrainedWidths = new LinkedHashMap<>();
for (int index = 0; index < columns.size(); index++) {
Column<?, T> column = columns.get(index);

@@ -3271,9 +3273,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
boolean defaultExpandRatios = true;
int totalRatios = 0;
double reservedPixels = 0;
final Set<Column<?, T>> columnsToExpand = new HashSet<Column<?, T>>();
List<Column<?, T>> nonFixedColumns = new ArrayList<Column<?, T>>();
Map<Integer, Double> columnSizes = new HashMap<Integer, Double>();
final Set<Column<?, T>> columnsToExpand = new HashSet<>();
List<Column<?, T>> nonFixedColumns = new ArrayList<>();
Map<Integer, Double> columnSizes = new HashMap<>();
final List<Column<?, T>> visibleColumns = getVisibleColumns();

/*
@@ -3536,7 +3538,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

private static final String STRIPE_CLASSNAME = "stripe";

private final Map<Element, Widget> elementToWidgetMap = new HashMap<Element, Widget>();
private final Map<Element, Widget> elementToWidgetMap = new HashMap<>();

@Override
public void init(Spacer spacer) {
@@ -3918,7 +3920,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
private final class ColumnHider {

/** Map from columns to their hiding toggles, component might change */
private HashMap<Column<?, T>, MenuItem> columnToHidingToggleMap = new HashMap<Grid.Column<?, T>, MenuItem>();
private HashMap<Column<?, T>, MenuItem> columnToHidingToggleMap = new HashMap<>();

/**
* When column is being hidden with a toggle, do not refresh toggles for
@@ -4017,7 +4019,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
/**
* List of columns in the grid. Order defines the visible order.
*/
private List<Column<?, T>> columns = new ArrayList<Column<?, T>>();
private List<Column<?, T>> columns = new ArrayList<>();

/**
* The datasource currently in use. <em>Note:</em> it is <code>null</code>
@@ -4041,7 +4043,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
* Current sort order. The (private) sort() method reads this list to
* determine the order in which to present rows.
*/
private List<SortOrder> sortOrder = new ArrayList<SortOrder>();
private List<SortOrder> sortOrder = new ArrayList<>();

private Renderer<Boolean> selectColumnRenderer = null;

@@ -4064,21 +4066,15 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

private final Editor<T> editor = GWT.create(Editor.class);

private boolean dataIsBeingFetched = false;

/**
* The cell a click event originated from
* <p>
* This is a workaround to make Chrome work like Firefox. In Chrome,
* normally if you start a drag on one cell and release on:
* <ul>
* <li>that same cell, the click event is that {@code
*
<td>}.
* <li>a cell on that same row, the click event is the parent {@code
*
<tr>
* }.
* <li>that same cell, the click event is that <code>&lt;td></code>.
* <li>a cell on that same row, the click event is the parent
* <code>&lt;tr></code>.
* <li>a cell on another row, the click event is the table section ancestor
* ({@code <thead>}, {@code <tbody>} or {@code <tfoot>}).
* </ul>
@@ -4099,7 +4095,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
private DetailsGenerator detailsGenerator = DetailsGenerator.NULL;
private GridSpacerUpdater gridSpacerUpdater = new GridSpacerUpdater();
/** A set keeping track of the indices of all currently open details */
private Set<Integer> visibleDetails = new HashSet<Integer>();
private Set<Integer> visibleDetails = new HashSet<>();

private boolean columnReorderingAllowed;

@@ -4149,7 +4145,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
* Map of possible drop positions for the column and the corresponding
* column index.
*/
private final TreeMap<Double, Integer> possibleDropPositions = new TreeMap<Double, Integer>();
private final TreeMap<Double, Integer> possibleDropPositions = new TreeMap<>();
/**
* Makes sure that drag cancel doesn't cause anything unwanted like sort
*/
@@ -4348,7 +4344,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
&& latestColumnDropIndex != (draggedColumnIndex
+ colspan)) {
List<Column<?, T>> columns = getColumns();
List<Column<?, T>> reordered = new ArrayList<Column<?, T>>();
List<Column<?, T>> reordered = new ArrayList<>();
if (draggedColumnIndex < latestColumnDropIndex) {
reordered.addAll(columns.subList(0, draggedColumnIndex));
reordered.addAll(
@@ -4476,8 +4472,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
int leftBound = -1;
int rightBound = getColumnCount() + 1;

final HashSet<Integer> unavailableColumnDropIndices = new HashSet<Integer>();
final List<StaticRow<?>> rows = new ArrayList<StaticRow<?>>();
final HashSet<Integer> unavailableColumnDropIndices = new HashSet<>();
final List<StaticRow<?>> rows = new ArrayList<>();
rows.addAll(header.getRows());
rows.addAll(footer.getRows());
for (StaticRow<?> row : rows) {
@@ -5063,7 +5059,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
grid.header.updateColSpans();
grid.footer.updateColSpans();
scheduleColumnWidthRecalculator();
this.grid.fireEvent(new ColumnVisibilityChangeEvent<T>(this,
this.grid.fireEvent(new ColumnVisibilityChangeEvent<>(this,
hidden, userOriginated));
}
}
@@ -5717,7 +5713,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
initialWidth = col.getWidthActual();

minCellWidth = escalator.getMinCellWidth(
getColumns().indexOf(col));
getVisibleColumns().indexOf(col));
for (Column<?, T> c : getVisibleColumns()) {
if (selectionColumn == c) {
// Don't modify selection column.
@@ -5726,8 +5722,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

if (c.getWidth() < 0) {
c.setWidth(c.getWidthActual());
fireEvent(new ColumnResizeEvent<T>(
c));
fireEvent(
new ColumnResizeEvent<>(c));
}
}

@@ -5737,7 +5733,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

@Override
public void onComplete() {
fireEvent(new ColumnResizeEvent<T>(col));
fireEvent(new ColumnResizeEvent<>(col));

WidgetUtil.setTextSelectionEnabled(
getElement(), true);
@@ -5819,7 +5815,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
escalator.getColumnConfiguration().setColumnWidth(colIndex,
minWidth);

fireEvent(new ColumnResizeEvent<T>(column));
fireEvent(new ColumnResizeEvent<>(column));
}
}

@@ -5937,7 +5933,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
public void onRowVisibilityChange(
RowVisibilityChangeEvent event) {
if (dataSource != null && dataSource.size() != 0) {
dataIsBeingFetched = true;
dataSource.ensureAvailability(
event.getFirstVisibleRow(),
event.getVisibleRowCount());
@@ -5977,12 +5972,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
}
});

addDataAvailableHandler(new DataAvailableHandler() {
@Override
public void onDataAvailable(DataAvailableEvent event) {
dataIsBeingFetched = false;
}
});
}

@Override
@@ -6229,7 +6218,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
column.reapplyWidth();

// Sink all renderer events
Set<String> events = new HashSet<String>();
Set<String> events = new HashSet<>();
events.addAll(getConsumedEventsForRenderer(column.getRenderer()));

if (column.isHidable()) {
@@ -6321,8 +6310,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
* @return A unmodifiable list of the columns in the grid
*/
public List<Column<?, T>> getColumns() {
return Collections
.unmodifiableList(new ArrayList<Column<?, T>>(columns));
return Collections.unmodifiableList(new ArrayList<>(columns));
}

/**
@@ -6334,7 +6322,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
* @return A unmodifiable list of the currently visible columns in the grid
*/
public List<Column<?, T>> getVisibleColumns() {
ArrayList<Column<?, T>> visible = new ArrayList<Column<?, T>>();
ArrayList<Column<?, T>> visible = new ArrayList<>();
for (Column<?, T> c : columns) {
if (!c.isHidden()) {
visible.add(c);
@@ -6749,8 +6737,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
int oldSize = body.getRowCount();

// Hide all details.
Set<Integer> oldDetails = new HashSet<Integer>(
visibleDetails);
Set<Integer> oldDetails = new HashSet<>(visibleDetails);
for (int i : oldDetails) {
setDetailsVisible(i, false);
}
@@ -6766,7 +6753,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
}

if (newSize > 0) {
dataIsBeingFetched = true;
Range visibleRowRange = escalator
.getVisibleRowRange();
dataSource.ensureAvailability(
@@ -7123,7 +7109,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
}

private Set<String> getConsumedEventsForRenderer(Renderer<?> renderer) {
Set<String> events = new HashSet<String>();
Set<String> events = new HashSet<>();
if (renderer instanceof ComplexRenderer) {
Collection<String> consumedEvents = ((ComplexRenderer<?>) renderer)
.getConsumedEvents();
@@ -7295,7 +7281,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
w = editor.getWidget(getColumn(editor.focusedColumnIndex));
}

EditorDomEvent<T> editorEvent = new EditorDomEvent<T>(event,
EditorDomEvent<T> editorEvent = new EditorDomEvent<>(event,
getEventCell(), w);

return getEditor().getEventHandler().handleEvent(editorEvent);
@@ -7366,8 +7352,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
private Point rowEventTouchStartingPoint;
private CellStyleGenerator<T> cellStyleGenerator;
private RowStyleGenerator<T> rowStyleGenerator;
private RowReference<T> rowReference = new RowReference<T>(this);
private CellReference<T> cellReference = new CellReference<T>(rowReference);
private RowReference<T> rowReference = new RowReference<>(this);
private CellReference<T> cellReference = new CellReference<>(rowReference);
private RendererCellReference rendererCellReference = new RendererCellReference(
(RowReference<Object>) rowReference);

@@ -7909,7 +7895,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override
public void execute() {
if (!dataIsBeingFetched) {
if (!dataSource.isWaitingForData()) {
handler.onDataAvailable(
new DataAvailableEvent(currentDataAvailable));
}
@@ -8188,8 +8174,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
*/
private void sort(boolean userOriginated) {
refreshHeader();
fireEvent(new SortEvent<T>(this,
Collections.unmodifiableList(sortOrder), userOriginated));
fireEvent(new SortEvent<>(this, Collections.unmodifiableList(sortOrder),
userOriginated));
}

private int getLastVisibleRowIndex() {
@@ -8230,7 +8216,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

@Override
public boolean isWorkPending() {
return escalator.isWorkPending() || dataIsBeingFetched
return escalator.isWorkPending() || dataSource.isWaitingForData()
|| autoColumnWidthsRecalculator.isScheduled()
|| editor.isWorkPending();
}
@@ -8270,7 +8256,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
// Trigger ComplexRenderer.destroy for old content
conf.removeColumns(0, conf.getColumnCount());

List<Column<?, T>> newOrder = new ArrayList<Column<?, T>>();
List<Column<?, T>> newOrder = new ArrayList<>();
if (selectionColumn != null) {
newOrder.add(selectionColumn);
}
@@ -8548,7 +8534,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,

@Override
protected void onDetach() {
Set<Integer> details = new HashSet<Integer>(visibleDetails);
Set<Integer> details = new HashSet<>(visibleDetails);
for (int row : details) {
setDetailsVisible(row, false);
}
@@ -8958,7 +8944,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>,
if (container != null) {
Cell cell = container.getCell(element);
if (cell != null) {
EventCellReference<T> cellRef = new EventCellReference<T>(this);
EventCellReference<T> cellRef = new EventCellReference<>(this);
cellRef.set(cell, getSectionFromContainer(container));
return cellRef;
}

+ 19
- 0
compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java View File

@@ -635,6 +635,25 @@ public class DateField extends AbstractField<Date> implements
}
}

@Override
public void discard() {
Property prop = getPropertyDataSource();
if (prop != null) {
Object value = prop.getValue();
if (!isValid() && value == null) {
// If the user entered an invalid value in the date field
// getInternalValue() returns null.
// If the datasource also contains null, then
// updateValueFromDataSource() will then not clear the internal
// state
// and error indicators (ticket #8069).
setInternalValue(null);
} else {
super.discard();
}
}
}

/*
* only fires the event if preventValueChangeEvent flag is false
*/

+ 17
- 1
compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java View File

@@ -4560,6 +4560,11 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,

private Object editedItemId = null;
private boolean editorActive = false;
/**
* True while the editor is storing the field values, i.e. commiting the
* field group.
*/
private boolean editorSaving = false;
private FieldGroup editorFieldGroup = new CustomFieldGroup();

private CellStyleGenerator cellStyleGenerator;
@@ -6902,7 +6907,12 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* @see FieldGroup#commit()
*/
public void saveEditor() throws CommitException {
editorFieldGroup.commit();
try {
editorSaving = true;
editorFieldGroup.commit();
} finally {
editorSaving = false;
}
}

/**
@@ -6910,6 +6920,12 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* possible unsaved changes in the editor fields.
*/
public void cancelEditor() {
if (editorSaving) {
// If the editor is already saving the values, it's too late to
// cancel it. This prevents item set changes from propagating during
// save, causing discard to be run during commit.
return;
}
if (isEditorActive()) {
getEditorRpc()
.cancel(getContainerDataSource().indexOfId(editedItemId));

+ 106
- 0
compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/grid/ItemSetChangeDuringEditorCommit.java View File

@@ -0,0 +1,106 @@
package com.vaadin.v7.tests.server.component.grid;

import org.junit.Assert;
import org.junit.Test;

import com.vaadin.server.ServerRpcManager.RpcInvocationException;
import com.vaadin.server.ServerRpcMethodInvocation;
import com.vaadin.tests.util.MockUI;
import com.vaadin.ui.UI;
import com.vaadin.v7.data.fieldgroup.FieldGroup;
import com.vaadin.v7.data.fieldgroup.FieldGroup.CommitException;
import com.vaadin.v7.data.util.IndexedContainer;
import com.vaadin.v7.shared.ui.grid.EditorServerRpc;
import com.vaadin.v7.ui.Grid;
import com.vaadin.v7.ui.TextField;

public class ItemSetChangeDuringEditorCommit {

private static class IndexedContainerImpl extends IndexedContainer {

public IndexedContainerImpl() {
}

@Override
public void fireItemSetChange() {
super.fireItemSetChange();
}
}

@Test
public void itemSetChangeDoesNotInterruptCommit()
throws RpcInvocationException, CommitException {
UI ui = new MockUI();
final IndexedContainerImpl indexedContainer = new IndexedContainerImpl();
indexedContainer.addContainerProperty("firstName", String.class,
"first");
indexedContainer.addContainerProperty("lastName", String.class, "last");
indexedContainer.addItem();
indexedContainer.addItem();

Grid grid = new Grid();
ui.setContent(grid);
grid.setContainerDataSource(indexedContainer);
grid.setEditorEnabled(true);
grid.getEditorFieldGroup()
.addCommitHandler(new FieldGroup.CommitHandler() {
@Override
public void preCommit(FieldGroup.CommitEvent commitEvent)
throws FieldGroup.CommitException {
}

@Override
public void postCommit(FieldGroup.CommitEvent commitEvent)
throws FieldGroup.CommitException {
indexedContainer.fireItemSetChange();
}
});

editItem(grid, 0);
((TextField) grid.getEditorFieldGroup().getField("firstName"))
.setValue("New first");
((TextField) grid.getEditorFieldGroup().getField("lastName"))
.setValue("New last");
grid.saveEditor();

Assert.assertEquals("New first", indexedContainer
.getContainerProperty(grid.getEditedItemId(), "firstName")
.getValue());
Assert.assertEquals("New last", indexedContainer
.getContainerProperty(grid.getEditedItemId(), "lastName")
.getValue());

grid.cancelEditor();
Assert.assertFalse(grid.isEditorActive());

editItem(grid, 0);
Assert.assertEquals("New first",
((TextField) grid.getEditorFieldGroup().getField("firstName"))
.getValue());
Assert.assertEquals("New last",
((TextField) grid.getEditorFieldGroup().getField("lastName"))
.getValue());
saveEditor(grid, 0);
}

private void editItem(Grid grid, int itemIndex)
throws RpcInvocationException {
ServerRpcMethodInvocation invocation = new ServerRpcMethodInvocation(
grid.getConnectorId(), EditorServerRpc.class, "bind", 1);
invocation.setParameters(new Object[] { itemIndex });
grid.getRpcManager(EditorServerRpc.class.getName())
.applyInvocation(invocation);
Assert.assertTrue(grid.isEditorActive());

}

private void saveEditor(Grid grid, int itemIndex)
throws RpcInvocationException {
ServerRpcMethodInvocation invocation = new ServerRpcMethodInvocation(
grid.getConnectorId(), EditorServerRpc.class, "save", 1);
invocation.setParameters(new Object[] { itemIndex });
grid.getRpcManager(EditorServerRpc.class.getName())
.applyInvocation(invocation);

}
}

+ 47
- 1
pom.xml View File

@@ -13,13 +13,14 @@
<version>8.0-SNAPSHOT</version>

<prerequisites>
<maven>3.0.5</maven>
<maven>3.1.0</maven>
</prerequisites>

<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<!-- Used version numbers for dependencies -->
<liferay.portal.version>6.0.2</liferay.portal.version>
@@ -43,6 +44,9 @@

<!-- Dependency unpack directory -->
<dependency.unpack.directory>${project.build.directory}/dependency-unpack</dependency.unpack.directory>
<jetty.version>9.3.7.v20160115</jetty.version>
<phantomjs.version>2.1.1</phantomjs.version>
</properties>

<!-- TODO: remove this after maven plugin has been released -->
@@ -135,6 +139,14 @@
<groupId>com.vaadin</groupId>
<artifactId>vaadin-sass-compiler</artifactId>
<version>${vaadin.sass.version}</version>
<exclusions>
<!-- No need to have the minifier included for development
mode on-the-fly compilation -->
<exclusion>
<groupId>com.yahoo.platform.yui</groupId>
<artifactId>yuicompressor</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.carrotsearch</groupId>
@@ -339,6 +351,15 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<groupId>com.github.klieber</groupId>
<artifactId>phantomjs-maven-plugin</artifactId>
<version>0.7</version>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
@@ -436,6 +457,25 @@
<ignore></ignore>
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
com.github.klieber
</groupId>
<artifactId>
phantomjs-maven-plugin
</artifactId>
<versionRange>
[0.7,)
</versionRange>
<goals>
<goal>install</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
@@ -502,6 +542,12 @@
</build>

<profiles>
<profile>
<id>slowtest</id>
<modules>
<module>test</module>
</modules>
</profile>
<profile>
<id>release</id>
<activation>

+ 1
- 0
scripts/BuildDemos.py View File

@@ -18,6 +18,7 @@ from xml.etree.ElementTree import ElementTree
demos = {
"dashboard" : "https://github.com/vaadin/dashboard-demo.git",
"addressbook" : "https://github.com/vaadin/addressbook.git",
"framework8-demo" : "https://github.com/vaadin/framework8-demo",
"sampler" : "demos/sampler"
# "my-demo" : ("my_demo_url_or_path", "my-demo-dev-branch")
}

+ 2
- 0
scripts/BuildHelpers.py View File

@@ -77,6 +77,8 @@ def mavenValidate(artifactId, mvnCmd = mavenCmd, logFile = sys.stdout, version =
print("Do maven clean package validate")
cmd = [mvnCmd]
cmd.append("-Dvaadin.version=%s" % (version))
# Enforcer does not always seem to take vaadin.version into account, skip until this can be resolved
cmd.append("-Denforcer.skip=true")
if mavenParams is not None:
cmd.extend(mavenParams.strip('"').split(" "))
cmd.extend(["clean", "package", "validate"])

+ 5
- 2
server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java View File

@@ -122,11 +122,14 @@ public @interface VaadinServletConfiguration {

/**
* The default widgetset to use for the servlet. The default value is
* <code>com.vaadin.DefaultWidgetSet</code>.
* <code>""</code>, which will cause
* <code>com.vaadin.DefaultWidgetSet</code> to be used unless overridden by
* an init parameter or unless an automatically generated
* <code>AppWidgetset</code> is used.
*
* @return the default widgetset name
*/
@InitParameterName(VaadinServlet.PARAMETER_WIDGETSET)
public String widgetset() default VaadinServlet.DEFAULT_WIDGETSET;
public String widgetset() default "";

}

+ 10
- 3
server/src/main/java/com/vaadin/server/UIProvider.java View File

@@ -178,15 +178,22 @@ public abstract class UIProvider implements Serializable {
return new WidgetsetInfoImpl(uiWidgetset.value());
}

// Second case: We might have an init parameter, use that
String initParameterWidgetSet = event.getService()
.getDeploymentConfiguration().getWidgetset(null);
if (initParameterWidgetSet != null) {
return new WidgetsetInfoImpl(initParameterWidgetSet);
}

// Find the class AppWidgetset in the default package if one exists
WidgetsetInfo info = getWidgetsetClassInfo();

// Second case: we have a generated class called APP_WIDGETSET_NAME
// Third case: we have a generated class called APP_WIDGETSET_NAME
if (info != null) {
return info;
}

// third case: we have an AppWidgetset.gwt.xml file
// Fourth case: we have an AppWidgetset.gwt.xml file
else {
InputStream resource = event.getUIClass()
.getResourceAsStream("/" + APP_WIDGETSET_NAME + ".gwt.xml");
@@ -195,7 +202,7 @@ public abstract class UIProvider implements Serializable {
}
}

// fourth case: we are using the default widgetset
// fifth case: we are using the default widgetset
return null;
}


+ 10
- 0
server/src/main/java/com/vaadin/server/VaadinServlet.java View File

@@ -268,6 +268,16 @@ public class VaadinServlet extends HttpServlet implements Constants {
stringValue = value.toString();
}

if (VaadinServlet.PARAMETER_WIDGETSET.equals(name.value())
&& method.getDefaultValue().equals(stringValue)) {
// Do not set the widgetset to anything so that the
// framework can fallback to the default. Setting
// anything to the init parameter will force that into
// use and e.g. AppWidgetset will not be used even
// though it is found.
continue;
}

initParameters.setProperty(name.value(), stringValue);
} catch (Exception e) {
// This should never happen

+ 17
- 4
server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java View File

@@ -223,8 +223,21 @@ public class ClassPathExplorer {

if (!widgetsets.containsKey(classname)) {
String packagePath = packageName.replaceAll("\\.", "/");
String basePath = location.getFile()
.replaceAll("/" + packagePath + "$", "");

String basePath = location.getFile();
if (basePath.endsWith("/" + packagePath)) {
basePath = basePath.replaceAll("/" + packagePath + "$",
"");
} else if (basePath.endsWith("/" + packagePath + "/")) {
basePath = basePath.replaceAll("/" + packagePath + "/$",
"");
} else {
throw new IllegalStateException(
"Error trying to find base path, location ("
+ location.getFile()
+ ") does not end in expected '/"
+ packagePath + "'");
}
try {
URL url = new URL(location.getProtocol(),
location.getHost(), location.getPort(),
@@ -453,8 +466,8 @@ public class ClassPathExplorer {
&& !dirs[i].getPath().contains(File.separator + ".")) {
String key = dirs[i].getCanonicalPath() + "/" + name
+ dirs[i].getName();
locations.put(key,
dirs[i].getCanonicalFile().toURI().toURL());
URL url = dirs[i].getCanonicalFile().toURI().toURL();
locations.put(key, url);
}
} catch (Exception ioe) {
return;

+ 9
- 9
server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java View File

@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Reader;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collection;
import java.util.HashSet;
@@ -44,7 +45,8 @@ import java.util.regex.Pattern;
*/
public class WidgetSetBuilder {

public static void main(String[] args) throws IOException {
public static void main(String[] args)
throws IOException, URISyntaxException {
if (args.length == 0) {
printUsage();
} else {
@@ -55,7 +57,7 @@ public class WidgetSetBuilder {
}

public static void updateWidgetSet(final String widgetset)
throws IOException, FileNotFoundException {
throws IOException, FileNotFoundException, URISyntaxException {
boolean changed = false;

Map<String, URL> availableWidgetSets = ClassPathExplorer
@@ -69,9 +71,8 @@ public class WidgetSetBuilder {
.getWidgetsetSourceDirectory(widgetsetFileName);
}

String wsFullPath = sourceUrl.getFile() + "/" + widgetsetFileName;

File widgetsetFile = new File(wsFullPath);
File widgetsetFile = new File(new File(sourceUrl.toURI()),
widgetsetFileName);
if (!widgetsetFile.exists()) {
// create empty gwt module file
File parent = widgetsetFile.getParentFile();
@@ -136,7 +137,7 @@ public class WidgetSetBuilder {

changed = changed || !content.equals(originalContent);
if (changed) {
commitChanges(wsFullPath, content);
commitChanges(widgetsetFile, content);
}
} else {
System.out
@@ -152,11 +153,10 @@ public class WidgetSetBuilder {
return content.replaceFirst("<inherits name=\"" + ws + "\"[^/]*/>", "");
}

private static void commitChanges(String widgetsetfilename, String content)
private static void commitChanges(File widgetsetFile, String content)
throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(widgetsetfilename)));
new OutputStreamWriter(new FileOutputStream(widgetsetFile)));
bufferedWriter.write(content);
bufferedWriter.close();
}

+ 58
- 0
test/addon-using-init-param-widget-set/pom.xml View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<artifactId>vaadin-test-addon-using-init-param-widget-set</artifactId>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<!-- Included to ensure AppWidgetset is an option -->
<dependency>
<groupId>com.vaadin.addon</groupId>
<artifactId>vaadin-context-menu</artifactId>
<version>0.7.4</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiled</artifactId>
<version>${project.version}</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>resources</goal>
<goal>update-widgetset</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

+ 25
- 0
test/addon-using-init-param-widget-set/src/main/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetUI.java View File

@@ -0,0 +1,25 @@
package com.vaadin.test.addonusinginitparamwidgetset;

import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

import com.vaadin.addon.contextmenu.ContextMenu;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.test.widgetset.AbstractTestWidgetSetUI;
import com.vaadin.ui.AbstractComponent;

public class AddonUsingInitParamWidgetSetUI extends AbstractTestWidgetSetUI {

@Override
protected void init(VaadinRequest vaadinRequest) {
super.init(vaadinRequest);
new ContextMenu((AbstractComponent) getContent(), true);
}

@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true, initParams = @WebInitParam(name = "widgetset", value = "com.vaadin.DefaultWidgetSet"))
@VaadinServletConfiguration(ui = AddonUsingInitParamWidgetSetUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}

+ 15
- 0
test/addon-using-init-param-widget-set/src/test/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetIT.java View File

@@ -0,0 +1,15 @@
package com.vaadin.test.addonusinginitparamwidgetset;

import org.junit.Test;

import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT;

public class AddonUsingInitParamWidgetSetIT extends AbstractWidgetSetIT {

@Test
public void appStartsUserCanInteract() {
testAppStartsUserCanInteract("com.vaadin.DefaultWidgetSet");
assertUnknownComponentShown("com.vaadin.addon.contextmenu.ContextMenu");
}

}

+ 52
- 0
test/addon-using-no-defined-widget-set/pom.xml View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<artifactId>vaadin-test-addon-using-no-defined-widget-set</artifactId>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin.addon</groupId>
<artifactId>vaadin-context-menu</artifactId>
<version>0.7.4</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>resources</goal>
<goal>update-widgetset</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

+ 24
- 0
test/addon-using-no-defined-widget-set/src/main/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetUI.java View File

@@ -0,0 +1,24 @@
package com.vaadin.test.addonusingnodefinedwidgetset;

import javax.servlet.annotation.WebServlet;

import com.vaadin.addon.contextmenu.ContextMenu;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.test.widgetset.AbstractTestWidgetSetUI;
import com.vaadin.ui.AbstractComponent;

public class AddonUsingNoDefinedWidgetSetUI extends AbstractTestWidgetSetUI {

@Override
protected void init(VaadinRequest vaadinRequest) {
super.init(vaadinRequest);
new ContextMenu((AbstractComponent) getContent(), true);
}

@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = AddonUsingNoDefinedWidgetSetUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}

+ 14
- 0
test/addon-using-no-defined-widget-set/src/test/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetIT.java View File

@@ -0,0 +1,14 @@
package com.vaadin.test.addonusingnodefinedwidgetset;

import org.junit.Test;

import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT;

public class AddonUsingNoDefinedWidgetSetIT extends AbstractWidgetSetIT {

@Test
public void appStartsUserCanInteract() {
testAppStartsUserCanInteract("AppWidgetset");
assertNoUnknownComponentShown();
}
}

+ 52
- 0
test/addon-using-own-widget-set/pom.xml View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<artifactId>vaadin-test-addon-using-own-widget-set</artifactId>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin.addon</groupId>
<artifactId>vaadin-context-menu</artifactId>
<version>0.7.4</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>resources</goal>
<goal>update-widgetset</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

+ 26
- 0
test/addon-using-own-widget-set/src/main/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetUI.java View File

@@ -0,0 +1,26 @@
package com.vaadin.test.addonusingownwidgetset;

import javax.servlet.annotation.WebServlet;

import com.vaadin.addon.contextmenu.ContextMenu;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.Widgetset;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.test.widgetset.AbstractTestWidgetSetUI;
import com.vaadin.ui.AbstractComponent;

@Widgetset("com.vaadin.test.addonusingownwidgetset.AddonUsingOwnWidgetSet")
public class AddonUsingOwnWidgetSetUI extends AbstractTestWidgetSetUI {

@Override
protected void init(VaadinRequest vaadinRequest) {
super.init(vaadinRequest);
new ContextMenu((AbstractComponent) getContent(), true);
}

@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = AddonUsingOwnWidgetSetUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}

+ 7
- 0
test/addon-using-own-widget-set/src/main/resources/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSet.gwt.xml View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd">
<module>
<inherits name="com.vaadin.DefaultWidgetSet" />

<inherits name="com.vaadin.addon.contextmenu.WidgetSet" />
</module>

+ 15
- 0
test/addon-using-own-widget-set/src/test/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetIT.java View File

@@ -0,0 +1,15 @@
package com.vaadin.test.addonusingownwidgetset;

import org.junit.Test;

import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT;

public class AddonUsingOwnWidgetSetIT extends AbstractWidgetSetIT {

@Test
public void appStartsUserCanInteract() {
testAppStartsUserCanInteract(
"com.vaadin.test.addonusingownwidgetset.AddonUsingOwnWidgetSet");
assertNoUnknownComponentShown();
}
}

+ 34
- 0
test/default-widget-set/pom.xml View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<artifactId>vaadin-test-default-widget-set</artifactId>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiled</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>


</project>

+ 15
- 0
test/default-widget-set/src/main/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetUI.java View File

@@ -0,0 +1,15 @@
package com.vaadin.test.defaultwidgetset;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinServlet;
import com.vaadin.test.widgetset.AbstractTestWidgetSetUI;

public class DefaultWidgetSetUI extends AbstractTestWidgetSetUI {

@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = DefaultWidgetSetUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}

+ 11
- 0
test/default-widget-set/src/test/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetIT.java View File

@@ -0,0 +1,11 @@
package com.vaadin.test.defaultwidgetset;

import org.junit.Test;

public abstract class DefaultWidgetSetIT extends AbstractWidgetSetIT {

@Test
public void appStartsUserCanInteract() {
testAppStartsUserCanInteract("com.vaadin.DefaultWidgetSet");
}
}

+ 45
- 0
test/own-widget-set/pom.xml View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<artifactId>vaadin-test-own-widget-set</artifactId>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>resources</goal>
<goal>update-widgetset</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

+ 17
- 0
test/own-widget-set/src/main/java/com/vaadin/test/ownwidgetset/OwnWidgetSetUI.java View File

@@ -0,0 +1,17 @@
package com.vaadin.test.ownwidgetset;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.Widgetset;
import com.vaadin.server.VaadinServlet;
import com.vaadin.test.widgetset.AbstractTestWidgetSetUI;

@Widgetset("com.vaadin.test.ownwidgetset.OwnWidgetSet")
public class OwnWidgetSetUI extends AbstractTestWidgetSetUI {

@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = OwnWidgetSetUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}

+ 14
- 0
test/own-widget-set/src/test/java/com/vaadin/test/ownwidgetset/OwnWidgetSetIT.java View File

@@ -0,0 +1,14 @@
package com.vaadin.test.ownwidgetset;

import org.junit.Test;

import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT;

public class OwnWidgetSetIT extends AbstractWidgetSetIT {

@Test
public void appStartsUserCanInteract() {
testAppStartsUserCanInteract(
"com.vaadin.test.ownwidgetset.OwnWidgetSet");
}
}

+ 143
- 0
test/pom.xml View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-root</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<artifactId>vaadin-test</artifactId>
<name>vaadin-test</name>
<packaging>pom</packaging>
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>

<repositories>
<repository>
<id>vaadin-addons</id>
<url>http://maven.vaadin.com/vaadin-addons</url>
</repository>
</repositories>

<dependencies>

<!-- API DEPENDENCIES -->
<!-- Project modules -->
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-themes</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Servlet 3.0 API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>


<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-testbench</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<modules>
<module>widget-set-testutil</module>
<module>default-widget-set</module>
<module>own-widget-set</module>
<module>addon-using-own-widget-set</module>
<module>addon-using-no-defined-widget-set</module>
<module>addon-using-init-param-widget-set</module>
<module>space in directory</module>
<module>vaadinservletconfiguration-widget-set</module>
</modules>

<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
<scanIntervalSeconds>-1</scanIntervalSeconds>
<stopPort>8081</stopPort>
<stopWait>5</stopWait>
<stopKey>foo</stopKey>
</configuration>
<executions>
<!-- start and stop jetty (running our app) when running
integration tests -->
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.klieber</groupId>
<artifactId>phantomjs-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>install</goal>
</goals>
<configuration>
<version>${phantomjs.version}</version>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<phantomjs.binary.path>${phantomjs.binary}</phantomjs.binary.path>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>

+ 44
- 0
test/space in directory/pom.xml View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<artifactId>vaadin-test-space-in-directory</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>resources</goal>
<goal>update-widgetset</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

+ 17
- 0
test/space in directory/src/main/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryUI.java View File

@@ -0,0 +1,17 @@
package com.vaadin.test.spaceindirectory;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.Widgetset;
import com.vaadin.server.VaadinServlet;
import com.vaadin.test.widgetset.AbstractTestWidgetSetUI;

@Widgetset("com.vaadin.test.spaceindirectory.SpaceInDirectory")
public class SpaceInDirectoryUI extends AbstractTestWidgetSetUI {

@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = SpaceInDirectoryUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}

+ 5
- 0
test/space in directory/src/main/resources/com/vaadin/test/spaceindirectory/SpaceInDirectory.gwt.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd">
<module>
<inherits name="com.vaadin.DefaultWidgetSet" />
</module>

+ 15
- 0
test/space in directory/src/test/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryIT.java View File

@@ -0,0 +1,15 @@
package com.vaadin.test.spaceindirectory;

import org.junit.Test;

import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT;

public class SpaceInDirectoryIT extends AbstractWidgetSetIT {

@Test
public void appStartsUserCanInteract() {
testAppStartsUserCanInteract(
"com.vaadin.test.spaceindirectory.SpaceInDirectory");

}
}

+ 45
- 0
test/vaadinservletconfiguration-widget-set/pom.xml View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<artifactId>vaadin-test-vaadinservletconfiguration-widget-set</artifactId>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>resources</goal>
<goal>update-widgetset</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

+ 16
- 0
test/vaadinservletconfiguration-widget-set/src/main/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetUI.java View File

@@ -0,0 +1,16 @@
package com.vaadin.test.vaadinservletconfigurationwidgetset;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinServlet;
import com.vaadin.test.widgetset.AbstractTestWidgetSetUI;

public class VaadinServletConfigurationWidgetSetUI
extends AbstractTestWidgetSetUI {

@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = VaadinServletConfigurationWidgetSetUI.class, productionMode = false, widgetset = "com.vaadin.test.vaadinservletconfigurationwidgetset.VaadinServletConfigurationWidgetSet")
public static class MyUIServlet extends VaadinServlet {
}
}

+ 5
- 0
test/vaadinservletconfiguration-widget-set/src/main/resources/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSet.gwt.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd">
<module>
<inherits name="com.vaadin.DefaultWidgetSet" />
</module>

+ 14
- 0
test/vaadinservletconfiguration-widget-set/src/test/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetIT.java View File

@@ -0,0 +1,14 @@
package com.vaadin.test.vaadinservletconfigurationwidgetset;

import org.junit.Test;

import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT;

public class VaadinServletConfigurationWidgetSetIT extends AbstractWidgetSetIT {

@Test
public void appStartsUserCanInteract() {
testAppStartsUserCanInteract(
"com.vaadin.test.vaadinservletconfigurationwidgetset.VaadinServletConfigurationWidgetSet");
}
}

+ 32
- 0
test/widget-set-testutil/pom.xml View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-test</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<artifactId>vaadin-test-widget-set-testutil</artifactId>
<packaging>jar</packaging>

<dependencies>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>

+ 39
- 0
test/widget-set-testutil/src/main/java/com/vaadin/test/widgetset/AbstractTestWidgetSetUI.java View File

@@ -0,0 +1,39 @@
package com.vaadin.test.widgetset;

import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

public abstract class AbstractTestWidgetSetUI extends UI {

@Override
protected void init(VaadinRequest vaadinRequest) {
final VerticalLayout layout = new VerticalLayout();
final Label widgetsetInfo = new Label();
widgetsetInfo.setId("widgetsetinfo");
final TextField name = new TextField();
name.setCaption("Type your name here:");

Button button = new Button("Click Me");
button.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent clickEvent) {
layout.addComponent(
new Label("Thanks " + name.getValue() + ", it works!"));
}
});

getPage().getJavaScript().execute(
"widgetsetinfo.innerText=document.querySelector('iframe').id;");
layout.addComponents(widgetsetInfo, name, button);
layout.setMargin(true);
layout.setSpacing(true);

setContent(layout);
}

}

+ 59
- 0
test/widget-set-testutil/src/test/java/com/vaadin/test/defaultwidgetset/AbstractWidgetSetIT.java View File

@@ -0,0 +1,59 @@
package com.vaadin.test.defaultwidgetset;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.phantomjs.PhantomJSDriver;

import com.vaadin.testbench.ScreenshotOnFailureRule;
import com.vaadin.testbench.TestBenchTestCase;
import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.LabelElement;
import com.vaadin.testbench.elements.TextFieldElement;

public abstract class AbstractWidgetSetIT extends TestBenchTestCase {

@Rule
public ScreenshotOnFailureRule rule = new ScreenshotOnFailureRule(this,
true);

@Before
public void setup() {
// Screenshot rule tears down the driver
setDriver(new PhantomJSDriver());
}

protected void testAppStartsUserCanInteract(String expectedWidgetSet) {
getDriver().get("http://localhost:8080");

TextFieldElement nameInput = $(TextFieldElement.class).first();
nameInput.setValue("John Dåe");

$(ButtonElement.class).first().click();

Assert.assertEquals("Label shown", 2,
$(LabelElement.class).all().size());

Assert.assertEquals("Thanks John Dåe, it works!",
$(LabelElement.class).get(1).getText());

Assert.assertEquals(expectedWidgetSet,
findElement(By.id("widgetsetinfo")).getText());

}

protected void assertNoUnknownComponentShown() {
Assert.assertEquals(0,
findElements(By.className("vaadin-unknown-caption")).size());
}

protected void assertUnknownComponentShown(String componentClass) {
WebElement unknownComponentCaption = findElement(
By.className("vaadin-unknown-caption"));
Assert.assertTrue(unknownComponentCaption.getText().contains(
"does not contain implementation for " + componentClass));
}

}

+ 5
- 10
uitest-common/src/main/java/com/vaadin/tests/tb3/AbstractTB3Test.java View File

@@ -1015,17 +1015,12 @@ public abstract class AbstractTB3Test extends ParallelTest {
return loadingIndicator.isDisplayed();
}

protected void waitUntilLoadingIndicatorNotVisible() {
waitUntil(new ExpectedCondition<Boolean>() {

@Override
public Boolean apply(WebDriver input) {
WebElement loadingIndicator = input
.findElement(By.className("v-loading-indicator"));
protected void waitUntilLoadingIndicatorVisible() {
waitUntil(input -> isLoadingIndicatorVisible());
}

return !loadingIndicator.isDisplayed();
}
});
protected void waitUntilLoadingIndicatorNotVisible() {
waitUntil(input -> !isLoadingIndicatorVisible());
}

/**

+ 44
- 0
uitest/src/main/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDown.java View File

@@ -0,0 +1,44 @@
package com.vaadin.tests.components.grid;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.data.DataSource;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.Button;
import com.vaadin.ui.Grid;

@Theme("valo")
public class GridApplyFilterWhenScrolledDown extends AbstractTestUI {

@Override
protected void setup(VaadinRequest request) {
Grid<String> grid = new Grid<>();

grid.addColumn("Name", Function.identity());

List<String> data = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
data.add("Name " + i);
}

data.add("Test");
grid.setItems(data);

addComponent(grid);
Button button = new Button("Filter Test item",
event -> filter(grid.getDataSource(), data));
addComponent(button);
}

private void filter(DataSource<String> dataSource, List<String> data) {
String last = data.get(data.size() - 1);
data.clear();
data.add(last);
dataSource.refreshAll();
}

}

+ 5
- 1
uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnHiding.java View File

@@ -41,10 +41,14 @@ public class GridColumnHiding extends AbstractTestUI {
grid.addColumnVisibilityChangeListener(event -> visibilityChangeLabel
.setValue(event.getColumn().isHidden() + ""));

Button toggleHidden = new Button("Toggle all column hidden state",
event -> grid.getColumns().forEach(
column -> column.setHidden(!column.isHidden())));

grid.setItems(Arrays.asList(Person.createTestPerson1(),
Person.createTestPerson2()));

addComponents(grid, toggleNameColumn, toggleAgeColumn,
toggleEmailColumn, visibilityChangeLabel);
toggleEmailColumn, visibilityChangeLabel, toggleHidden);
}
}

+ 58
- 0
uitest/src/main/java/com/vaadin/tests/components/grid/InitiallyDisabledGrid.java View File

@@ -0,0 +1,58 @@
package com.vaadin.tests.components.grid;

import java.util.ArrayList;
import java.util.Collection;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.data.bean.Person;
import com.vaadin.ui.Button;
import com.vaadin.ui.Grid;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

public class InitiallyDisabledGrid extends UI {

@Override
protected void init(VaadinRequest request) {
VerticalLayout layout = new VerticalLayout();
setContent(layout);
layout.setSizeFull();
layout.setWidth("600px");
layout.setHeight("600px");
final Grid<Person> grid = createGrid();
Button button = new Button("Enable/Disable",
event -> grid.setEnabled(!grid.isEnabled()));

layout.addComponent(button);
VerticalLayout l = new VerticalLayout();
l.setSizeFull();
l.addComponent(grid);

layout.addComponent(l);
layout.setExpandRatio(l, 1.0f);
}

private Grid<Person> createGrid() {
// Have some data
Collection<Person> people = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Person person = new Person();
person.setFirstName("First " + i);
person.setLastName("Last " + i);
people.add(person);
}
// Have a container of some type to contain the data

// Create a grid bound to the container
Grid<Person> grid = new Grid<>();
grid.setSizeFull();
grid.setItems(people);
grid.addColumn("firstName", Person::getFirstName);
grid.addColumn("lastNAme", Person::getLastName);

grid.setEnabled(false);

return grid;
}

}

+ 38
- 0
uitest/src/main/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicator.java View File

@@ -0,0 +1,38 @@
package com.vaadin.tests.components.javascriptcomponent;

import com.vaadin.annotations.JavaScript;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.AbstractJavaScriptComponent;
import com.vaadin.ui.JavaScriptFunction;
import com.vaadin.ui.Label;

import elemental.json.JsonArray;

public class JSComponentLoadingIndicator extends AbstractTestUI {

@JavaScript({ "JSComponent.js" })
public class JSComponent extends AbstractJavaScriptComponent {
public JSComponent() {
addFunction("test", new JavaScriptFunction() {
@Override
public void call(JsonArray arguments) {
try {
Thread.sleep(1000);
Label label = new Label("pong");
label.addStyleName("pong");
addComponent(label);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}

@Override
protected void setup(VaadinRequest request) {
addComponent(new JSComponent());
}

}

+ 30
- 0
uitest/src/main/java/com/vaadin/tests/core/SpecialCharactersEncodingUI.java View File

@@ -0,0 +1,30 @@
package com.vaadin.tests.core;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.Label;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.TextField;

public class SpecialCharactersEncodingUI extends AbstractTestUI {

public static String textWithZwnj = "\ufeffछुट्‌याउनेछन् क्ष क्‌ष क्‍ष";

@Override
protected void setup(VaadinRequest request) {
MenuBar menubar = new MenuBar();
menubar.setId("menubar");
addComponent(menubar);
menubar.addItem(textWithZwnj, null);

Label label = new Label(textWithZwnj);
label.setId("label");
addComponent(label);

TextField f = new TextField("Textfield", textWithZwnj);
f.setId("textfield");
addComponent(f);

}

}

+ 93
- 0
uitest/src/main/java/com/vaadin/tests/resources/DownloadWithPush.java View File

@@ -0,0 +1,93 @@
package com.vaadin.tests.resources;

import java.io.IOException;
import java.io.InputStream;

import com.vaadin.annotations.Push;
import com.vaadin.server.DownloadStream;
import com.vaadin.server.Resource;
import com.vaadin.server.StreamResource;
import com.vaadin.server.StreamResource.StreamSource;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;

@Push
public class DownloadWithPush extends AbstractTestUIWithLog {

private static class GeneratedStream extends InputStream {
int read = 0;
int next = 'a';
private final int size;

public GeneratedStream(int size) {
this.size = size;
}

@Override
public int read() throws IOException {
if (available() == 0) {
return -1;
}

read++;
next++;
if (next > 'z') {
next = 'a';
}
return next;
}

@Override
public int available() throws IOException {
return size - read;
}
}

private final class DownloadResoure extends StreamResource {
private DownloadResoure(StreamSource streamSource, String filename) {
super(streamSource, filename);
}

@Override
public DownloadStream getStream() {
DownloadStream ds = super.getStream();
ds.setParameter("Content-Disposition",
"attachment; filename=" + getFilename() + ";");
return ds;
}
}

private Resource hugeFileResource = createResource();;
private int fileSize = 300 * (1024 * 1024);

@Override
protected void setup(VaadinRequest request) {
Button b = new Button("Download a "
+ String.format("%.1f", fileSize / 1024.0 / 1024.0) + "MB file",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
getUI().getPage().open(hugeFileResource, "", false);
}
});
addComponent(b);
}

private Resource createResource() {
Resource hugeFileResource = new DownloadResoure(new StreamSource() {
@Override
public InputStream getStream() {
return new GeneratedStream(fileSize);
}
}, "hugefile.txt");
return hugeFileResource;
}

@Override
protected Integer getTicketNumber() {
return 19709;
}

}

+ 5
- 0
uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridCellFocusOnResetSizeWidget.java View File

@@ -81,6 +81,11 @@ public class GridCellFocusOnResetSizeWidget
}
handler.resetDataAndSize(size);
}

@Override
public boolean isWaitingForData() {
return false;
}
}

private class Col extends Grid.Column<String, String[]> {

+ 12
- 6
uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridClientColumnRendererConnector.java View File

@@ -69,6 +69,7 @@ public class GridClientColumnRendererConnector
private int numberOfRows;
private DataChangeHandler dataChangeHandler;
private int latency;
private Timer timer;

public DelayedDataSource(DataSource<String> ds, int latency) {
this.ds = ds;
@@ -78,7 +79,7 @@ public class GridClientColumnRendererConnector
@Override
public void ensureAvailability(final int firstRowIndex,
final int numberOfRows) {
new Timer() {
timer = new Timer() {

@Override
public void run() {
@@ -87,8 +88,10 @@ public class GridClientColumnRendererConnector
dataChangeHandler.dataUpdated(firstRowIndex, numberOfRows);
dataChangeHandler.dataAvailable(firstRowIndex,
numberOfRows);
timer = null;
}
}.schedule(latency);
};
timer.schedule(latency);
}

@Override
@@ -117,6 +120,11 @@ public class GridClientColumnRendererConnector
// TODO Auto-generated method stub (henrik paul: 17.6.)
return null;
}

@Override
public boolean isWaitingForData() {
return timer != null;
}
}

@Override
@@ -211,8 +219,7 @@ public class GridClientColumnRendererConnector
@SuppressWarnings("unchecked")
public void triggerClientSortingTest() {
Grid<String> grid = getWidget();
ListSorter<String> sorter = new ListSorter<>(
grid);
ListSorter<String> sorter = new ListSorter<>(grid);

// Make sorter sort the numbers in natural order
sorter.setComparator(
@@ -236,8 +243,7 @@ public class GridClientColumnRendererConnector
@SuppressWarnings("unchecked")
public void shuffle() {
Grid<String> grid = getWidget();
ListSorter<String> shuffler = new ListSorter<>(
grid);
ListSorter<String> shuffler = new ListSorter<>(grid);

// Make shuffler return random order
shuffler.setComparator(

+ 99
- 0
uitest/src/main/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValue.java View File

@@ -0,0 +1,99 @@
package com.vaadin.v7.tests.components.datefield;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.v7.data.util.ObjectProperty;
import com.vaadin.v7.ui.DateField;

/**
* Test to demonstrate how discarding of field value works with various valid
* and invalid data sources. Previously (Ticket #8069) the case where the
* content of the datasource was null was not handled correctly. This value is a
* valid data source value for the field, but discard did not actually discard
* the value or remove error markers in this cases.
*
* @author Vaadin Ltd
*
*/
public class DateFieldDiscardValue extends AbstractTestUI {

public static final String PROP_NONULL = "A field with a valid date in the data source property";
public static final String PROP_NULL_VALUE = "A field with a null value in the data source property";
public static final String PROP_NULL = "A field with a null datasource property";

@Override
protected void setup(VaadinRequest request) {
String dateFormat = "dd/MM/yy";

final DateField df = new DateField(PROP_NONULL);
df.setDateFormat(dateFormat);
df.setBuffered(true);
Date date = null;
try {
date = new SimpleDateFormat(dateFormat).parse("25/07/16");
} catch (ParseException e1) {
// This cannot happen
}
ObjectProperty<Date> prop = new ObjectProperty<>(date, Date.class);
df.setPropertyDataSource(prop);
Button button = new Button("Discard 1");
button.addClickListener(new ClickListener() {

@Override
public void buttonClick(ClickEvent event) {
df.discard();
}

});
VerticalLayout layout = new VerticalLayout();
HorizontalLayout hLayout = new HorizontalLayout(df, button);
layout.addComponent(hLayout);

final DateField df1 = new DateField(PROP_NULL_VALUE);
df1.setDateFormat(dateFormat);
df1.setBuffered(true);

prop = new ObjectProperty<>(null, Date.class);
df1.setPropertyDataSource(prop);
button = new Button("Discard 2");
button.addClickListener(new ClickListener() {

@Override
public void buttonClick(ClickEvent event) {
df1.discard();
}

});
hLayout = new HorizontalLayout(df1, button);
layout.addComponent(hLayout);

final DateField df2 = new DateField(PROP_NULL);
df2.setDateFormat(dateFormat);
df2.setBuffered(true);
df2.setPropertyDataSource(null);
button = new Button("Discard 3");
button.addClickListener(new ClickListener() {

@Override
public void buttonClick(ClickEvent event) {
df2.discard();
}

});
hLayout = new HorizontalLayout(df2, button);
layout.addComponent(hLayout);

setContent(layout);

}

}

+ 64
- 0
uitest/src/main/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDown.java View File

@@ -0,0 +1,64 @@
package com.vaadin.v7.tests.components.grid;

import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.UI;
import com.vaadin.ui.themes.ValoTheme;
import com.vaadin.v7.data.Container.Filterable;
import com.vaadin.v7.data.Item;
import com.vaadin.v7.data.util.filter.SimpleStringFilter;
import com.vaadin.v7.event.FieldEvents.TextChangeEvent;
import com.vaadin.v7.event.FieldEvents.TextChangeListener;
import com.vaadin.v7.ui.Grid;
import com.vaadin.v7.ui.Grid.HeaderRow;
import com.vaadin.v7.ui.TextField;

@Theme("valo")
public class GridApplyFilterWhenScrolledDown extends UI {

private Grid grid = new Grid();

@Override
protected void init(VaadinRequest vaadinRequest) {

grid.addColumn("Name", String.class);

HeaderRow appendHeaderRow = grid.appendHeaderRow();
TextField filter = getColumnFilter("Name");
appendHeaderRow.getCell("Name").setComponent(filter);

for (int i = 0; i < 1000; i++) {
Item addItem = grid.getContainerDataSource().addItem(i);
addItem.getItemProperty("Name").setValue("Name " + i);

}

Item addItem = grid.getContainerDataSource().addItem(1000);
addItem.getItemProperty("Name").setValue("Test");

// grid.scrollToStart();
setContent(grid);
}

private TextField getColumnFilter(final Object columnId) {
TextField filter = new TextField();
filter.setWidth("100%");
filter.addStyleName(ValoTheme.TEXTFIELD_TINY);
filter.addTextChangeListener(new TextChangeListener() {
SimpleStringFilter filter = null;

@Override
public void textChange(TextChangeEvent event) {
Filterable f = (Filterable) grid.getContainerDataSource();
if (filter != null) {
f.removeContainerFilter(filter);
}
filter = new SimpleStringFilter(columnId, event.getText(), true,
true);
f.addContainerFilter(filter);
}
});
return filter;
}

}

+ 60
- 0
uitest/src/main/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGrid.java View File

@@ -0,0 +1,60 @@
package com.vaadin.v7.tests.components.grid;

import java.util.ArrayList;
import java.util.Collection;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.data.bean.Person;
import com.vaadin.ui.Button;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.v7.data.util.BeanItemContainer;
import com.vaadin.v7.ui.Grid;

public class InitiallyDisabledGrid extends UI {

@Override
protected void init(VaadinRequest request) {
VerticalLayout layout = new VerticalLayout();
setContent(layout);
layout.setSizeFull();
layout.setWidth("600px");
layout.setHeight("600px");
final Grid grid = createGrid();
Button button = new Button("Enable/Disable",
event -> grid.setEnabled(!grid.isEnabled()));

layout.addComponent(button);
VerticalLayout l = new VerticalLayout();
l.setSizeFull();
l.addComponent(grid);

layout.addComponent(l);
layout.setExpandRatio(l, 1.0f);
}

private Grid createGrid() {
// Have some data
Collection<Person> people = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Person person = new Person();
person.setFirstName("First " + i);
person.setLastName("Last " + i);
people.add(person);
}
// Have a container of some type to contain the data
BeanItemContainer<Person> container = new BeanItemContainer<>(
Person.class, people);

// Create a grid bound to the container
Grid grid = new Grid(container);
grid.setSizeFull();
grid.setColumns("firstName", "lastName");

grid.setEnabled(false);

return grid;

}

}

+ 9
- 0
uitest/src/main/java/com/vaadin/v7/tests/components/grid/basicfeatures/GridBasicFeatures.java View File

@@ -1233,6 +1233,15 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> {

}
});
createBooleanAction("Toggle all column hidden state", "Columns", false,
new Command<Grid, Boolean>() {
@Override
public void execute(Grid c, Boolean value, Object data) {
for (Column col : grid.getColumns()) {
col.setHidden(!col.isHidden());
}
}
});
createBooleanAction("All columns resizable", "Columns", false,
new Command<Grid, Boolean>() {


+ 30
- 0
uitest/src/main/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUI.java View File

@@ -0,0 +1,30 @@
package com.vaadin.v7.tests.core;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.Label;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.TextField;

public class SpecialCharactersEncodingUI extends AbstractTestUI {

public static String textWithZwnj = "\ufeffछुट्‌याउनेछन् क्ष क्‌ष क्‍ष";

@Override
protected void setup(VaadinRequest request) {
MenuBar menubar = new MenuBar();
menubar.setId("menubar");
addComponent(menubar);
menubar.addItem(textWithZwnj, null);

Label label = new Label(textWithZwnj);
label.setId("label");
addComponent(label);

TextField f = new TextField("Textfield", textWithZwnj);
f.setId("textfield");
addComponent(f);

}

}

+ 11
- 0
uitest/src/main/resources/com/vaadin/tests/components/javascriptcomponent/JSComponent.js View File

@@ -0,0 +1,11 @@
com_vaadin_tests_components_javascriptcomponent_JSComponentLoadingIndicator_JSComponent = function()
{
var connector = this;
var e = this.getElement();

e.innerText="click me to ping server";
e.id="js";
e.addEventListener("click", function() {
connector.test();
});
}

+ 44
- 0
uitest/src/test/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java View File

@@ -0,0 +1,44 @@
package com.vaadin.tests.components.grid;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;

import com.vaadin.testbench.By;
import com.vaadin.testbench.TestBenchElement;
import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.GridElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class GridApplyFilterWhenScrolledDownTest extends MultiBrowserTest {

@Test
public void scrolledCorrectly() throws InterruptedException {
openTestURL();
final GridElement grid = $(GridElement.class).first();
grid.scrollToRow(50);
$(ButtonElement.class).first().click();
final TestBenchElement gridBody = grid.getBody();
// Can't use element API because it scrolls
waitUntil(new ExpectedCondition<Boolean>() {

@Override
public Boolean apply(WebDriver input) {
return gridBody.findElements(By.className("v-grid-row"))
.size() == 1;
}
});
WebElement cell = gridBody.findElements(By.className("v-grid-cell"))
.get(0);
Assert.assertEquals("Test", cell.getText());

int gridHeight = grid.getSize().getHeight();
int scrollerHeight = grid.getVerticalScroller().getSize().getHeight();
Assert.assertTrue(
"Scroller height is " + scrollerHeight
+ ", should be smaller than grid height: " + gridHeight,
scrollerHeight < gridHeight);
}
}

+ 40
- 0
uitest/src/test/java/com/vaadin/tests/components/grid/GridColumnHidingTest.java View File

@@ -15,15 +15,20 @@
*/
package com.vaadin.tests.components.grid;

import static org.junit.Assert.assertEquals;

import java.util.List;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

import com.vaadin.testbench.By;
import com.vaadin.testbench.customelements.GridElement;
import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.GridElement.GridCellElement;
import com.vaadin.testbench.elements.LabelElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

@@ -119,6 +124,30 @@ public class GridColumnHidingTest extends MultiBrowserTest {
"custom age column caption".equals(elements.get(1).getText()));
}

@Test
public void testShrinkColumnToZeroWithHiddenColumn() {
openTestURL();

// hide all
$(ButtonElement.class).get(3).click();

ButtonElement toggleNameColumn = $(ButtonElement.class).get(0);
ButtonElement toggleEmailColumn = $(ButtonElement.class).get(2);

// Show
toggleNameColumn.click();
toggleEmailColumn.click();

GridElement gridElement = $(GridElement.class).first();

GridCellElement cell = gridElement.getCell(0, 1);
dragResizeColumn(1, 0, -cell.getSize().getWidth());
assertGreaterOrEqual("Cell got too small.", cell.getSize().getWidth(),
10);
assertEquals(gridElement.getCell(0, 0).getLocation().getY(),
gridElement.getCell(0, 1).getLocation().getY());
}

protected WebElement getSidebarOpenButton(GridElement grid) {
List<WebElement> elements = grid
.findElements(By.className("v-grid-sidebar-button"));
@@ -146,4 +175,15 @@ public class GridColumnHidingTest extends MultiBrowserTest {
By.className("v-grid-sidebar-popup"));
return elements.isEmpty() ? null : elements.get(0);
}

private void dragResizeColumn(int columnIndex, int posX, int offset) {
GridElement gridElement = $(GridElement.class).first();

GridCellElement headerCell = gridElement.getHeaderCell(0, columnIndex);
Dimension size = headerCell.getSize();
new Actions(getDriver())
.moveToElement(headerCell, size.getWidth() + posX,
size.getHeight() / 2)
.clickAndHold().moveByOffset(offset, 0).release().perform();
}
}

+ 45
- 0
uitest/src/test/java/com/vaadin/tests/components/grid/InitiallyDisabledGridTest.java View File

@@ -0,0 +1,45 @@
package com.vaadin.tests.components.grid;

import java.util.List;

import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.By;
import com.vaadin.testbench.customelements.GridElement;
import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.GridElement.GridCellElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class InitiallyDisabledGridTest extends SingleBrowserTest {

@Test
public void columnsExpanded() {
openTestURL();

List<WebElement> cells = findElements(By.className("v-grid-cell"));
WebElement col0 = cells.get(0);
WebElement col1 = cells.get(1);
Assert.assertTrue(col0.getSize().getWidth() > 250);
Assert.assertTrue(col1.getSize().getWidth() > 250);
}

@Test
@Ignore
/*
* The test fails at the moment because of issues related (or exactly the
* same) as https://github.com/vaadin/framework8-issues/issues/286. It
* should be enabled once it's fixed.
*/
public void worksWhenEnabled() {
openTestURL();
$(ButtonElement.class).first().click();

GridElement grid = $(GridElement.class).first();
grid.scrollToRow(80);
GridCellElement col0 = grid.getCell(80, 0);
Assert.assertEquals("First 80", col0.getText());
}
}

+ 29
- 0
uitest/src/test/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicatorTest.java View File

@@ -0,0 +1,29 @@
package com.vaadin.tests.components.javascriptcomponent;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.By;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class JSComponentLoadingIndicatorTest extends SingleBrowserTest {

@Test
public void ensureLoadingIndicatorShown() {
openTestURL();
testBench().disableWaitForVaadin();

WebElement js = findElement(By.id("js"));
js.click();
waitUntilLoadingIndicatorVisible();
waitUntilLoadingIndicatorNotVisible();
Assert.assertEquals(1, findElements(By.className("pong")).size());

js.click();
waitUntilLoadingIndicatorVisible();
waitUntilLoadingIndicatorNotVisible();
Assert.assertEquals(2, findElements(By.className("pong")).size());
}

}

+ 11
- 0
uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabsheetScrollIntoViewTest.java View File

@@ -21,13 +21,24 @@ import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;

import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.TabSheetElement;
import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class TabsheetScrollIntoViewTest extends MultiBrowserTest {

@Override
public List<DesiredCapabilities> getBrowsersToTest() {
List<DesiredCapabilities> browsers = super.getBrowsersToTest();
// For whatever reason, IE8 never returns from the
// $(TabSheetElement.class).first() call
browsers.remove(Browser.IE8.getDesiredCapabilities());
return browsers;
}

@Test
public void scrollIntoView() {
openTestURL();

+ 37
- 0
uitest/src/test/java/com/vaadin/tests/core/SpecialCharactersEncodingUITest.java View File

@@ -0,0 +1,37 @@
package com.vaadin.tests.core;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.By;
import com.vaadin.testbench.elements.LabelElement;
import com.vaadin.testbench.elements.MenuBarElement;
import com.vaadin.testbench.elements.TextFieldElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class SpecialCharactersEncodingUITest extends SingleBrowserTest {

@Test
public void checkEncoding() {
openTestURL();
String textFieldValue = $(TextFieldElement.class).id("textfield")
.getValue();
Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj,
textFieldValue);
LabelElement label = $(LabelElement.class).id("label");
String labelValue = getHtml(label); // getText() strips some characters
Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj,
labelValue);

MenuBarElement menubar = $(MenuBarElement.class).first();
WebElement menuItem = menubar
.findElement(By.className("v-menubar-menuitem-caption"));
Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj,
getHtml(menuItem));
}

private String getHtml(WebElement element) {
return element.getAttribute("innerHTML");
}
}

+ 85
- 0
uitest/src/test/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValueTest.java View File

@@ -0,0 +1,85 @@
package com.vaadin.v7.tests.components.datefield;

import static org.junit.Assert.assertEquals;

import java.util.List;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.DateFieldElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class DateFieldDiscardValueTest extends SingleBrowserTest {

@Test
public void discardWhenDatasourceContentNonNullInvalidValue() {
discardWorks(DateFieldDiscardValue.PROP_NONULL, "1", "123", "25/07/16");
}

@Test
public void discardWhenDatasourceContentNonNullValidValue() {
discardWorks(DateFieldDiscardValue.PROP_NONULL, "1", "24/07/16",
"25/07/16");
}

@Test
public void discardWhenDatasourceContentNullInvalidValue() {
discardWorks(DateFieldDiscardValue.PROP_NULL_VALUE, "2", "123", "");
}

@Test
public void discardWhenDatasourceContentNullValidValue() {
discardWorks(DateFieldDiscardValue.PROP_NULL_VALUE, "2", "24/07/16",
"");
}

@Test
public void discardWhenDatasourceNull() {
// If the data source is null, discard should do nothing.
discardDoesntWork(DateFieldDiscardValue.PROP_NULL, "3", "123");
}

private void discardWorks(String caption, String id, String dateValue,
String resultValue) {
openTestURL();

ButtonElement discardButton = $(ButtonElement.class)
.caption("Discard " + id).first();
DateFieldElement dateField = $(DateFieldElement.class).caption(caption)
.first();
dateField.setValue(dateValue);

discardButton.click();

assertEquals(resultValue, dateField.getValue());

List<WebElement> elements = driver
.findElements(By.className("v-errorindicator"));

assertEquals(0, elements.size());
}

private void discardDoesntWork(String caption, String id,
String dateValue) {
openTestURL();

ButtonElement discardButton = $(ButtonElement.class)
.caption("Discard " + id).first();
DateFieldElement dateField = $(DateFieldElement.class).caption(caption)
.first();
dateField.setValue(dateValue);

discardButton.click();

assertEquals(dateValue, dateField.getValue());

List<WebElement> elements = driver
.findElements(By.className("v-errorindicator"));

assertEquals(1, elements.size());
}

}

+ 44
- 0
uitest/src/test/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java View File

@@ -0,0 +1,44 @@
package com.vaadin.v7.tests.components.grid;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;

import com.vaadin.testbench.By;
import com.vaadin.testbench.TestBenchElement;
import com.vaadin.testbench.elements.GridElement;
import com.vaadin.testbench.elements.TextFieldElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class GridApplyFilterWhenScrolledDownTest extends MultiBrowserTest {

@Test
public void scrolledCorrectly() throws InterruptedException {
openTestURL();
final GridElement grid = $(GridElement.class).first();
grid.scrollToRow(50);
$(TextFieldElement.class).first().setValue("Test");
final TestBenchElement gridBody = grid.getBody();
// Can't use element API because it scrolls
waitUntil(new ExpectedCondition<Boolean>() {

@Override
public Boolean apply(WebDriver input) {
return gridBody.findElements(By.className("v-grid-row"))
.size() == 1;
}
});
WebElement cell = gridBody.findElements(By.className("v-grid-cell"))
.get(0);
Assert.assertEquals("Test", cell.getText());

int gridHeight = grid.getSize().getHeight();
int scrollerHeight = grid.getVerticalScroller().getSize().getHeight();
Assert.assertTrue(
"Scroller height is " + scrollerHeight
+ ", should be smaller than grid height: " + gridHeight,
scrollerHeight < gridHeight);
}
}

+ 34
- 0
uitest/src/test/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGridTest.java View File

@@ -0,0 +1,34 @@
package com.vaadin.v7.tests.components.grid;

import org.junit.Assert;
import org.junit.Test;

import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.GridElement;
import com.vaadin.testbench.elements.GridElement.GridCellElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class InitiallyDisabledGridTest extends SingleBrowserTest {

@Test
public void columnsExpanded() {
openTestURL();

GridElement grid = $(GridElement.class).first();
GridCellElement col0 = grid.getCell(0, 0);
GridCellElement col1 = grid.getCell(0, 1);
Assert.assertTrue(col0.getSize().getWidth() > 250);
Assert.assertTrue(col1.getSize().getWidth() > 250);
}

@Test
public void worksWhenEnabled() {
openTestURL();
$(ButtonElement.class).first().click();

GridElement grid = $(GridElement.class).first();
grid.scrollToRow(80);
GridCellElement col0 = grid.getCell(80, 0);
Assert.assertEquals("First 80", col0.getText());
}
}

+ 21
- 0
uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnResizeTest.java View File

@@ -146,4 +146,25 @@ public class GridColumnResizeTest extends GridBasicFeaturesTest {
assertGreaterOrEqual("Cell got too small.", cell.getSize().getWidth(),
10);
}

@Test
public void testShrinkColumnToZeroWithHiddenColumn() {
openTestURL();
selectMenuPath("Component", "Columns",
"Toggle all column hidden state");
// Hides although already hidden
selectMenuPath("Component", "Columns", "Column 0", "Hidden");
// Shows
selectMenuPath("Component", "Columns", "Column 0", "Hidden");
// Hides although already hidden
selectMenuPath("Component", "Columns", "Column 2", "Hidden");
// Shows
selectMenuPath("Component", "Columns", "Column 2", "Hidden");
GridCellElement cell = getGridElement().getCell(0, 1);
dragResizeColumn(1, 0, -cell.getSize().getWidth());
assertGreaterOrEqual("Cell got too small.", cell.getSize().getWidth(),
10);
assertEquals(getGridElement().getCell(0, 0).getLocation().getY(),
getGridElement().getCell(0, 1).getLocation().getY());
}
}

+ 35
- 0
uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java View File

@@ -21,9 +21,11 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.vaadin.testbench.elements.GridElement;
import com.vaadin.testbench.parallel.TestCategory;
import com.vaadin.v7.tests.components.grid.basicfeatures.GridBasicFeaturesTest;

@@ -295,6 +297,35 @@ public class GridColumnVisibilityTest extends GridBasicFeaturesTest {
verifyColumnNotFrozen(2);
}

@Test
public void showColumnAndScrollbarWhenScrolledDownAndVisibleRowsChange()
throws Exception {
// Set a (un)suitable height
selectMenuPath("Component", "Size", "HeightMode Row");
selectMenuPath("Component", "Size", "Height by Rows", "4.33 rows");

toggleAllColumnsHidable();

// Hide all but the first 3
getSidebarOpenButton().click();
for (int i = 3; i < 12; i++) {
getColumnHidingToggle(i).click();
}

getSidebarOpenButton().click();

// Scroll all the way to the end
$(GridElement.class).first().scrollToRow(999);

// Show the fourth column
getSidebarOpenButton().click();
getColumnHidingToggle(3).click();

// Make sure that the new column contains the data it should
Assert.assertEquals("(999, 3)",
getGridElement().getCell(999, 3).getText());
}

private void verifyColumnFrozen(int index) {
assertTrue(getGridElement().getHeaderCell(0, index).isFrozen());
}
@@ -307,6 +338,10 @@ public class GridColumnVisibilityTest extends GridBasicFeaturesTest {
selectMenuPath("Component", "Columns", "Column " + index, "Hidable");
}

private void toggleAllColumnsHidable() {
selectMenuPath("Component", "Columns", "All columns hidable");
}

private void addRemoveColumn(int index) {
selectMenuPath("Component", "Columns", "Column " + index,
"Add / Remove");

+ 37
- 0
uitest/src/test/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUITest.java View File

@@ -0,0 +1,37 @@
package com.vaadin.v7.tests.core;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.By;
import com.vaadin.testbench.elements.LabelElement;
import com.vaadin.testbench.elements.MenuBarElement;
import com.vaadin.testbench.elements.TextFieldElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class SpecialCharactersEncodingUITest extends SingleBrowserTest {

@Test
public void checkEncoding() {
openTestURL();
String textFieldValue = $(TextFieldElement.class).id("textfield")
.getValue();
Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj,
textFieldValue);
LabelElement label = $(LabelElement.class).id("label");
String labelValue = getHtml(label); // getText() strips some characters
Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj,
labelValue);

MenuBarElement menubar = $(MenuBarElement.class).first();
WebElement menuItem = menubar
.findElement(By.className("v-menubar-menuitem-caption"));
Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj,
getHtml(menuItem));
}

private String getHtml(WebElement element) {
return element.getAttribute("innerHTML");
}
}

Loading…
Cancel
Save