committags/8.0.0.alpha411c3f8bd9e
- Test and its UI class are added (both V8 and V7). Required functionality should be available via modern GWT version. commit729dbf96fe
- About update release notes. No need to be included. commit675f38349c
- V8 already contains correct Import-Packages section which uses osgi.javax.servlet.version variable whise version is 3.0.0 at the moment. commit5da7c052f5
- Use Vaadin plugin 7.7.0 from 7.7.0.alpha1. Is not applicable. commit1df80001ab
- Updated tutorial to Vaadin 7.7.0. Is not applicable. The tutorial already contains correct links and updated source code snippets. commit8b4f0ed8a8
- set-property-fallback name="user.agent" value="safari". Is already there. commit28ed04e827
- Fix animation end listeners so they are always removed. Is already there. commit408253bc3f
- Use servlet context classloader when finding servlet class for websockets. Is already there. commit7a6f250d89
- Fire actions before removing menu from the DOM. Is already there. commit9b66c6eb9b
- Do not run test on IE8 as IE8 is broken. Transplanted. commit3faa43ff39
- 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. commite0c1f91a3d
- 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. commit83a1b8a096
- Update DOM and update escalator row count in the correct order. Transplanted. commit45f2fba8ff
- Prevent editor from being canceled while it is being saved. Transplanted to compatibility package. Is not applicable to modern Grid. commitad67f7f43a
- Delete broken stylesheet and revert to default style until a new stylesheet is created. Is already there. commitc970a78d42
- Always show loading indicator for JavaScript RPC. Transplanted. commit2aad341606
- Make test independent of any converters present in the factory. It's already there. commitc9ad48430b
- Do not include yuicompressor for Sass compiler. Transplanted. Exclusion is added into vaadin/pom.xml commit52d01a68e9
- Test for Firefox download disconnecting push channel. Transplanted. commit4bc375d1d2
- Handle encoded URL characters correctly when constructing widget set name. Transplanted. commit17ba88eaf8
- Update version to 7.7-SNAPSHOT. Is not applicable. commit47b7b13e5c
- Ensure Firefox always updates the grid scrollbar. Transplanted. Made changes in the logic to the test for modern Grid component. commit4d851ba21d
- Calculate column widths immediately if there is data. Transplanted to both client side modules. commit8f0b1a1dd0
- Skip Maven enforcer plugin during demo validation. Transplanted (one build file is affected). commit62815353e1
- Build demos from 7.7 branch (now for master branch). FW8 demos are added (one build file is affected). commit815d72115d
- Make test pass on all browsers. Transplanted to both V7 and V8 version tests. commit516c428ca1
- Use widget set specified by init parameter. Transplanted to the one UIProvider class. commitb00c580ed7
- 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. commit7dd91cf057
- Fix regression that broke widget set compilation in 7.7.1. It's already there. commitc665731b0b
- Ensure temporary layout manager state is cleared at the end of a layout phase. Transplanted to the one LayoutManager class. commit57a965251a
- Fix assertion error when column widths are calculated. Transplanted to both versions of the client Grid widget. commitc5c52684eb
- 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. commit6033e13c20
- Make initially disabled grid work when enabled. Transplanted to both client side modules. commita2d6e4fb4b
- Use requestAnimationFrame when scrolling in Grid. Transplanted to both client side modules. commitfe9438e7b7
- Specify branch also for Sampler. Is not applicable for master branch. commit1ec5d8ef7c
- Update to Chrome 53. Is already there. commit961851bfbc
- Updated link to new step 1 video in tutorial. Is already there. commit41dc2fe161
- Revert "Use widget set specified by init parameter. Transplanted to the one UIProvider class. commit092b4f7f31
- Use widget set specified by init parameter. Transplanted to the common server side classes. commit977cec7e31
- Fix widget set builder to create widget set in correct location. Transplanted to the one ClassPathExplorer class file. commit6c12ad89ea
- Format project pom files using correct settings. Is not transplanted: only formatting changes for POM files. commit0aad93ecc1
- Add tests for widgetset compilation in different modes. Transplanted. New test projects. commit0a3a1ef832
- Use versions-maven-plugin 2.3 to avoid NPE while setting project version. Is already there. Change-Id: Ie3a5088f25de1772f01ea30c4a5eba0b169ee0ab
@@ -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]; |
@@ -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"); | |||
} |
@@ -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)) { |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); |
@@ -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) { |
@@ -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><td></code>. | |||
* <li>a cell on that same row, the click event is the parent | |||
* <code><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(); | |||
} |
@@ -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(); |
@@ -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; | |||
} | |||
} |
@@ -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(); |
@@ -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><td></code>. | |||
* <li>a cell on that same row, the click event is the parent | |||
* <code><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; | |||
} |
@@ -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 | |||
*/ |
@@ -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)); |
@@ -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); | |||
} | |||
} |
@@ -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> |
@@ -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") | |||
} |
@@ -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"]) |
@@ -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 ""; | |||
} |
@@ -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; | |||
} | |||
@@ -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 |
@@ -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; |
@@ -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(); | |||
} |
@@ -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> |
@@ -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 { | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |
@@ -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> |
@@ -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 { | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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> |
@@ -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 { | |||
} | |||
} |
@@ -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> |
@@ -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(); | |||
} | |||
} |
@@ -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> |
@@ -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 { | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |
@@ -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> |
@@ -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 { | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |
@@ -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> |
@@ -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> |
@@ -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 { | |||
} | |||
} |
@@ -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> |
@@ -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"); | |||
} | |||
} |
@@ -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> |
@@ -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 { | |||
} | |||
} |
@@ -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> |
@@ -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"); | |||
} | |||
} |
@@ -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> |
@@ -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); | |||
} | |||
} |
@@ -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)); | |||
} | |||
} |
@@ -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()); | |||
} | |||
/** |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -81,6 +81,11 @@ public class GridCellFocusOnResetSizeWidget | |||
} | |||
handler.resetDataAndSize(size); | |||
} | |||
@Override | |||
public boolean isWaitingForData() { | |||
return false; | |||
} | |||
} | |||
private class Col extends Grid.Column<String, String[]> { |
@@ -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( |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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>() { | |||
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
}); | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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(); |
@@ -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"); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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"); |
@@ -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"); | |||
} | |||
} |