Conflicts: server/src/com/vaadin/data/RpcDataProviderExtension.java uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridEditorTest.java Change-Id: I9e7907c9caf839fd043444db0505f9853f020a6atags/7.6.0.alpha4
@@ -0,0 +1 @@ | |||
Just ordinary contents here |
@@ -0,0 +1 @@ | |||
Just ordinary contents here |
@@ -0,0 +1 @@ | |||
Just ordinary contents here |
@@ -21,6 +21,11 @@ $v-grid-details-marker-width: first-number($v-grid-border) * 2 !default; | |||
$v-grid-details-marker-color: $v-selection-color !default; | |||
$v-grid-details-border-top: valo-border($color: $v-grid-border-color-source, $strength: 0.3) !default; | |||
$v-grid-details-border-top-stripe: valo-border($color: $v-grid-row-stripe-background-color, $strength: 0.3) !default; | |||
$v-grid-border-size: 1px !default; | |||
$v-grid-border: $v-grid-border-size solid #ddd !default; | |||
$v-grid-cell-vertical-border: $v-grid-border !default; | |||
$v-grid-cell-horizontal-border: $v-grid-cell-vertical-border !default; | |||
$v-grid-details-border-bottom: $v-grid-cell-horizontal-border !default; | |||
$v-grid-details-border-bottom-stripe: $v-grid-cell-horizontal-border !default; | |||
@@ -30,6 +30,7 @@ public class BrowserInfo { | |||
private static final String BROWSER_OPERA = "op"; | |||
private static final String BROWSER_IE = "ie"; | |||
private static final String BROWSER_EDGE = "edge"; | |||
private static final String BROWSER_FIREFOX = "ff"; | |||
private static final String BROWSER_SAFARI = "sa"; | |||
@@ -171,6 +172,13 @@ public class BrowserInfo { | |||
minorVersionClass = majorVersionClass | |||
+ browserDetails.getBrowserMinorVersion(); | |||
browserEngineClass = ENGINE_TRIDENT; | |||
} else if (browserDetails.isEdge()) { | |||
browserIdentifier = BROWSER_EDGE; | |||
majorVersionClass = browserIdentifier | |||
+ getBrowserMajorVersion(); | |||
minorVersionClass = majorVersionClass | |||
+ browserDetails.getBrowserMinorVersion(); | |||
browserEngineClass = ""; | |||
} else if (browserDetails.isOpera()) { | |||
browserIdentifier = BROWSER_OPERA; | |||
majorVersionClass = browserIdentifier | |||
@@ -225,6 +233,10 @@ public class BrowserInfo { | |||
return browserDetails.isIE(); | |||
} | |||
public boolean isEdge() { | |||
return browserDetails.isEdge(); | |||
} | |||
public boolean isFirefox() { | |||
return browserDetails.isFirefox(); | |||
} | |||
@@ -245,6 +257,10 @@ public class BrowserInfo { | |||
return isIE() && getBrowserMajorVersion() == 10; | |||
} | |||
public boolean isIE11() { | |||
return isIE() && getBrowserMajorVersion() == 11; | |||
} | |||
public boolean isChrome() { | |||
return browserDetails.isChrome(); | |||
} |
@@ -155,10 +155,10 @@ public class ComputedStyle { | |||
* the property to retrieve | |||
* @return the double value of the property | |||
*/ | |||
public final int getDoubleProperty(String name) { | |||
public final double getDoubleProperty(String name) { | |||
Profiler.enter("ComputedStyle.getDoubleProperty"); | |||
String value = getProperty(name); | |||
int result = parseDoubleNative(value); | |||
double result = parseDoubleNative(value); | |||
Profiler.leave("ComputedStyle.getDoubleProperty"); | |||
return result; | |||
} | |||
@@ -275,9 +275,60 @@ public class ComputedStyle { | |||
* @return the value from the string before any non-numeric characters or | |||
* NaN if the value cannot be parsed as a number | |||
*/ | |||
private static native int parseDoubleNative(final String value) | |||
private static native double parseDoubleNative(final String value) | |||
/*-{ | |||
return parseFloat(value); | |||
}-*/; | |||
/** | |||
* Returns the sum of the top and bottom border width | |||
* | |||
* @since 7.5.3 | |||
* @return the sum of the top and bottom border | |||
*/ | |||
public double getBorderHeight() { | |||
double borderHeight = getDoubleProperty("borderTopWidth"); | |||
borderHeight += getDoubleProperty("borderBottomWidth"); | |||
return borderHeight; | |||
} | |||
/** | |||
* Returns the sum of the left and right border width | |||
* | |||
* @since 7.5.3 | |||
* @return the sum of the left and right border | |||
*/ | |||
public double getBorderWidth() { | |||
double borderWidth = getDoubleProperty("borderLeftWidth"); | |||
borderWidth += getDoubleProperty("borderRightWidth"); | |||
return borderWidth; | |||
} | |||
/** | |||
* Returns the sum of the top and bottom padding | |||
* | |||
* @since 7.5.3 | |||
* @return the sum of the top and bottom padding | |||
*/ | |||
public double getPaddingHeight() { | |||
double paddingHeight = getDoubleProperty("paddingTop"); | |||
paddingHeight += getDoubleProperty("paddingBottom"); | |||
return paddingHeight; | |||
} | |||
/** | |||
* Returns the sum of the top and bottom padding | |||
* | |||
* @since 7.5.3 | |||
* @return the sum of the left and right padding | |||
*/ | |||
public double getPaddingWidth() { | |||
double paddingWidth = getDoubleProperty("paddingLeft"); | |||
paddingWidth += getDoubleProperty("paddingRight"); | |||
return paddingWidth; | |||
} | |||
} |
@@ -283,8 +283,7 @@ public class ResourceLoader { | |||
* @since 7.2.4 | |||
*/ | |||
public static boolean supportsInOrderScriptExecution() { | |||
return BrowserInfo.get().isIE() | |||
&& BrowserInfo.get().getBrowserMajorVersion() >= 11; | |||
return BrowserInfo.get().isIE11() || BrowserInfo.get().isEdge(); | |||
} | |||
/** | |||
@@ -486,10 +485,11 @@ public class ResourceLoader { | |||
addOnloadHandler(linkElement, new ResourceLoadListener() { | |||
@Override | |||
public void onLoad(ResourceLoadEvent event) { | |||
// Chrome && IE fires load for errors, must check | |||
// Chrome, IE, Edge all fire load for errors, must check | |||
// stylesheet data | |||
if (BrowserInfo.get().isChrome() | |||
|| BrowserInfo.get().isIE()) { | |||
|| BrowserInfo.get().isIE() | |||
|| BrowserInfo.get().isEdge()) { | |||
int styleSheetLength = getStyleSheetLength(url); | |||
// Error if there's an empty stylesheet | |||
if (styleSheetLength == 0) { |
@@ -34,6 +34,7 @@ import com.google.gwt.core.client.Scheduler.ScheduledCommand; | |||
import com.google.gwt.dom.client.Element; | |||
import com.google.gwt.dom.client.NativeEvent; | |||
import com.google.gwt.user.client.Timer; | |||
import com.google.gwt.user.client.ui.CheckBox; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.client.ComponentConnector; | |||
import com.vaadin.client.ConnectorHierarchyChangeEvent; | |||
@@ -476,8 +477,7 @@ public class GridConnector extends AbstractHasComponentsConnector implements | |||
/** | |||
* Class for handling scrolling issues with open details. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
* @since 7.5.2 | |||
*/ | |||
private class LazyDetailsScroller implements DeferredWorker { | |||
@@ -507,7 +507,6 @@ public class GridConnector extends AbstractHasComponentsConnector implements | |||
/** | |||
* Inform LazyDetailsScroller that a details row has opened on a row. | |||
* | |||
* @since | |||
* @param rowIndex | |||
* index of row with details now open | |||
*/ | |||
@@ -685,6 +684,26 @@ public class GridConnector extends AbstractHasComponentsConnector implements | |||
public void recalculateColumnWidths() { | |||
getWidget().recalculateColumnWidths(); | |||
} | |||
@Override | |||
public void setSelectAll(boolean allSelected) { | |||
if (selectionModel instanceof SelectionModel.Multi | |||
&& selectionModel.getSelectionColumnRenderer() != null) { | |||
final Widget widget; | |||
try { | |||
HeaderRow defaultHeaderRow = getWidget() | |||
.getDefaultHeaderRow(); | |||
if (defaultHeaderRow != null) { | |||
widget = defaultHeaderRow.getCell( | |||
getWidget().getColumn(0)).getWidget(); | |||
((CheckBox) widget).setValue(allSelected, false); | |||
} | |||
} catch (Exception e) { | |||
getLogger().warning( | |||
"Problems finding select all checkbox."); | |||
} | |||
} | |||
} | |||
}); | |||
getWidget().addSelectionHandler(internalSelectionChangeHandler); |
@@ -74,7 +74,7 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements | |||
style.setPosition(Position.FIXED); | |||
style.setTop(0, Unit.PX); | |||
style.setLeft(0, Unit.PX); | |||
if (browserInfo.isIE()) { | |||
if (browserInfo.isIE() || browserInfo.isEdge()) { | |||
// for #15294: artificially hide little bit more the | |||
// focusElement, otherwise IE will make the window to scroll | |||
// into it when focused |
@@ -599,7 +599,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, | |||
+ "]"); | |||
Element menuFirstChild = menu.getElement().getFirstChildElement(); | |||
final int naturalMenuWidth = menuFirstChild.getOffsetWidth(); | |||
final int naturalMenuWidth = WidgetUtil | |||
.getRequiredWidth(menuFirstChild); | |||
if (popupOuterPadding == -1) { | |||
popupOuterPadding = WidgetUtil | |||
@@ -611,13 +612,20 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, | |||
menuFirstChild.getStyle().setWidth(100, Unit.PCT); | |||
} | |||
if (BrowserInfo.get().isIE()) { | |||
if (BrowserInfo.get().isIE() | |||
&& BrowserInfo.get().getBrowserMajorVersion() < 11) { | |||
// Must take margin,border,padding manually into account for | |||
// menu element as we measure the element child and set width to | |||
// the element parent | |||
int naturalMenuOuterWidth = naturalMenuWidth | |||
+ getMarginBorderPaddingWidth(menu.getElement()); | |||
/* | |||
* IE requires us to specify the width for the container | |||
* element. Otherwise it will be 100% wide | |||
*/ | |||
int rootWidth = Math.max(desiredWidth, naturalMenuWidth) | |||
- popupOuterPadding; | |||
int rootWidth = Math.max(desiredWidth - popupOuterPadding, | |||
naturalMenuOuterWidth); | |||
getContainerElement().getStyle().setWidth(rootWidth, Unit.PX); | |||
} | |||
@@ -1283,6 +1291,16 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, | |||
sinkEvents(Event.ONPASTE); | |||
} | |||
private static int getMarginBorderPaddingWidth(Element element) { | |||
final ComputedStyle s = new ComputedStyle(element); | |||
int[] margin = s.getMargin(); | |||
int[] border = s.getBorder(); | |||
int[] padding = s.getPadding(); | |||
return margin[1] + margin[3] + border[1] + border[3] + padding[1] | |||
+ padding[3]; | |||
} | |||
/* | |||
* (non-Javadoc) | |||
* |
@@ -22,7 +22,6 @@ import java.util.List; | |||
import com.google.gwt.aria.client.Roles; | |||
import com.google.gwt.dom.client.Element; | |||
import com.google.gwt.dom.client.Style.Overflow; | |||
import com.google.gwt.event.dom.client.ClickEvent; | |||
import com.google.gwt.event.dom.client.ClickHandler; | |||
import com.google.gwt.user.client.DOM; | |||
@@ -327,22 +326,6 @@ public class VFormLayout extends SimplePanel { | |||
requiredFieldIndicator = null; | |||
} | |||
} | |||
// Workaround for IE weirdness, sometimes returns bad height in some | |||
// circumstances when Caption is empty. See #1444 | |||
// IE7 bugs more often. I wonder what happens when IE8 arrives... | |||
// FIXME: This could be unnecessary for IE8+ | |||
if (BrowserInfo.get().isIE()) { | |||
if (isEmpty) { | |||
setHeight("0px"); | |||
getElement().getStyle().setOverflow(Overflow.HIDDEN); | |||
} else { | |||
setHeight(""); | |||
getElement().getStyle().clearOverflow(); | |||
} | |||
} | |||
} | |||
/** |
@@ -22,8 +22,6 @@ import java.util.logging.Logger; | |||
import com.google.gwt.animation.client.Animation; | |||
import com.google.gwt.aria.client.Roles; | |||
import com.google.gwt.core.client.JavaScriptObject; | |||
import com.google.gwt.core.client.Scheduler; | |||
import com.google.gwt.core.client.Scheduler.ScheduledCommand; | |||
import com.google.gwt.dom.client.Document; | |||
import com.google.gwt.dom.client.Element; | |||
import com.google.gwt.dom.client.IFrameElement; | |||
@@ -473,17 +471,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { | |||
if (isAnimationEnabled()) { | |||
new ResizeAnimation().run(POPUP_PANEL_ANIMATION_DURATION); | |||
} else { | |||
if (BrowserInfo.get().isIE8()) { | |||
Scheduler.get().scheduleFinally(new ScheduledCommand() { | |||
@Override | |||
public void execute() { | |||
positionOrSizeUpdated(1.0); | |||
} | |||
}); | |||
} else { | |||
positionOrSizeUpdated(1.0); | |||
} | |||
positionOrSizeUpdated(1.0); | |||
} | |||
current = null; | |||
} |
@@ -322,7 +322,7 @@ public class VRichTextArea extends Composite implements Field, KeyPressHandler, | |||
if ("<br>".equals(result)) { | |||
result = ""; | |||
} | |||
} else if (browser.isWebkit()) { | |||
} else if (browser.isWebkit() || browser.isEdge()) { | |||
if ("<br>".equals(result) || "<div><br></div>".equals(result)) { | |||
result = ""; | |||
} |
@@ -1295,8 +1295,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets, | |||
if (uidl.hasVariable("selected")) { | |||
final Set<String> selectedKeys = uidl | |||
.getStringArrayVariableAsSet("selected"); | |||
removeUnselectedRowKeys(selectedKeys); | |||
// Do not update focus if there is a single selected row | |||
// that is the same as the previous selection. This prevents | |||
// unwanted scrolling (#18247). | |||
boolean rowsUnSelected = removeUnselectedRowKeys(selectedKeys); | |||
boolean updateFocus = rowsUnSelected || selectedRowKeys.size() == 0 | |||
|| focusedRow == null; | |||
if (scrollBody != null) { | |||
Iterator<Widget> iterator = scrollBody.iterator(); | |||
while (iterator.hasNext()) { | |||
@@ -1313,7 +1317,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, | |||
selected = true; | |||
keyboardSelectionOverRowFetchInProgress = true; | |||
} | |||
if (selected && selectedKeys.size() == 1) { | |||
if (selected && selectedKeys.size() == 1 && updateFocus) { | |||
/* | |||
* If a single item is selected, move focus to the | |||
* selected row. (#10522) | |||
@@ -1338,14 +1342,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets, | |||
return keyboardSelectionOverRowFetchInProgress; | |||
} | |||
private void removeUnselectedRowKeys(final Set<String> selectedKeys) { | |||
private boolean removeUnselectedRowKeys(final Set<String> selectedKeys) { | |||
List<String> unselectedKeys = new ArrayList<String>(0); | |||
for (String key : selectedRowKeys) { | |||
if (!selectedKeys.contains(key)) { | |||
unselectedKeys.add(key); | |||
} | |||
} | |||
selectedRowKeys.removeAll(unselectedKeys); | |||
return selectedRowKeys.removeAll(unselectedKeys); | |||
} | |||
/** For internal use only. May be removed or replaced in the future. */ |
@@ -61,11 +61,12 @@ import com.google.gwt.user.client.ui.impl.FocusImpl; | |||
import com.vaadin.client.ApplicationConnection; | |||
import com.vaadin.client.BrowserInfo; | |||
import com.vaadin.client.ComponentConnector; | |||
import com.vaadin.client.ComputedStyle; | |||
import com.vaadin.client.Focusable; | |||
import com.vaadin.client.TooltipInfo; | |||
import com.vaadin.client.WidgetUtil; | |||
import com.vaadin.client.VCaption; | |||
import com.vaadin.client.VTooltip; | |||
import com.vaadin.client.WidgetUtil; | |||
import com.vaadin.client.ui.aria.AriaHelper; | |||
import com.vaadin.shared.AbstractComponentState; | |||
import com.vaadin.shared.ComponentConstants; | |||
@@ -1227,8 +1228,13 @@ public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware | |||
public void updateContentNodeHeight() { | |||
if (!isDynamicHeight()) { | |||
int contentHeight = getOffsetHeight(); | |||
contentHeight -= DOM.getElementPropertyInt(deco, "offsetHeight"); | |||
contentHeight -= deco.getOffsetHeight(); | |||
contentHeight -= tb.getOffsetHeight(); | |||
ComputedStyle cs = new ComputedStyle(contentNode); | |||
contentHeight -= Math.ceil(cs.getPaddingHeight()); | |||
contentHeight -= Math.ceil(cs.getBorderHeight()); | |||
if (contentHeight < 0) { | |||
contentHeight = 0; | |||
} |
@@ -224,16 +224,16 @@ public class VTextArea extends VTextField implements DragImageModifier { | |||
protected boolean browserSupportsMaxLengthAttribute() { | |||
BrowserInfo info = BrowserInfo.get(); | |||
if (info.isFirefox() && info.isBrowserVersionNewerOrEqual(4, 0)) { | |||
if (info.isFirefox()) { | |||
return true; | |||
} | |||
if (info.isSafari() && info.isBrowserVersionNewerOrEqual(5, 0)) { | |||
if (info.isSafari()) { | |||
return true; | |||
} | |||
if (info.isIE() && info.isBrowserVersionNewerOrEqual(10, 0)) { | |||
if (info.isIE10() || info.isIE11() || info.isEdge()) { | |||
return true; | |||
} | |||
if (info.isAndroid() && info.isBrowserVersionNewerOrEqual(2, 3)) { | |||
if (info.isAndroid()) { | |||
return true; | |||
} | |||
return false; |
@@ -18,7 +18,6 @@ package com.vaadin.client.ui; | |||
import java.util.ArrayList; | |||
import com.google.gwt.core.client.Scheduler; | |||
import com.google.gwt.core.client.Scheduler.ScheduledCommand; | |||
import com.google.gwt.dom.client.Element; | |||
import com.google.gwt.event.dom.client.HasScrollHandlers; | |||
@@ -44,8 +43,8 @@ import com.vaadin.client.ConnectorMap; | |||
import com.vaadin.client.Focusable; | |||
import com.vaadin.client.LayoutManager; | |||
import com.vaadin.client.Profiler; | |||
import com.vaadin.client.WidgetUtil; | |||
import com.vaadin.client.VConsole; | |||
import com.vaadin.client.WidgetUtil; | |||
import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; | |||
import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler; | |||
import com.vaadin.client.ui.ui.UIConnector; | |||
@@ -515,13 +514,6 @@ public class VUI extends SimplePanel implements ResizeHandler, | |||
public void focusStoredElement() { | |||
if (storedFocus != null) { | |||
storedFocus.focus(); | |||
Scheduler.get().scheduleDeferred(new ScheduledCommand() { | |||
@Override | |||
public void execute() { | |||
storedFocus.focus(); | |||
} | |||
}); | |||
} | |||
} | |||
@@ -562,17 +562,10 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, | |||
} | |||
private static void focusTopmostModalWindow() { | |||
// If we call focus() directly without scheduling, it does not work in | |||
// IE and FF. | |||
Scheduler.get().scheduleDeferred(new ScheduledCommand() { | |||
@Override | |||
public void execute() { | |||
VWindow topmost = getTopmostWindow(); | |||
if ((topmost != null) && (topmost.vaadinModality)) { | |||
topmost.focus(); | |||
} | |||
} | |||
}); | |||
VWindow topmost = getTopmostWindow(); | |||
if ((topmost != null) && (topmost.vaadinModality)) { | |||
topmost.focus(); | |||
} | |||
} | |||
@Override | |||
@@ -762,11 +755,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, | |||
modalityCurtain.removeFromParent(); | |||
if (BrowserInfo.get().isIE()) { | |||
// IE leaks memory in certain cases unless we release the reference | |||
// (#9197) | |||
modalityCurtain = null; | |||
} | |||
// IE leaks memory in certain cases unless we release the reference | |||
// (#9197) | |||
modalityCurtain = null; | |||
} | |||
/* | |||
@@ -1375,7 +1366,11 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, | |||
@Override | |||
public void focus() { | |||
contentPanel.focus(); | |||
// We don't want to use contentPanel.focus() as that will use a timer in | |||
// Chrome/Safari and ultimately run focus events in the wrong order when | |||
// opening a modal window and focusing some other component at the same | |||
// time | |||
contentPanel.getElement().focus(); | |||
} | |||
private int getDecorationHeight() { |
@@ -268,8 +268,13 @@ public class DateCellDayEvent extends FocusableHTML implements | |||
} | |||
int endX = event.getClientX(); | |||
int endY = event.getClientY(); | |||
int xDiff = startX - endX; | |||
int yDiff = startY - endY; | |||
int xDiff = 0, yDiff = 0; | |||
if (startX != -1 && startY != -1) { | |||
// Drag started | |||
xDiff = startX - endX; | |||
yDiff = startY - endY; | |||
} | |||
startX = -1; | |||
startY = -1; | |||
mouseMoveStarted = false; |
@@ -392,8 +392,11 @@ public class SimpleDayCell extends FocusableFlowPanel implements | |||
int endX = event.getClientX(); | |||
int endY = event.getClientY(); | |||
int xDiff = startX - endX; | |||
int yDiff = startY - endY; | |||
int xDiff = 0, yDiff = 0; | |||
if (startX != -1 && startY != -1) { | |||
xDiff = startX - endX; | |||
yDiff = startY - endY; | |||
} | |||
startX = -1; | |||
startY = -1; | |||
prevDayDiff = 0; |
@@ -72,6 +72,7 @@ import com.vaadin.client.ui.ShortcutActionHandler; | |||
import com.vaadin.client.ui.VNotification; | |||
import com.vaadin.client.ui.VOverlay; | |||
import com.vaadin.client.ui.VUI; | |||
import com.vaadin.client.ui.VWindow; | |||
import com.vaadin.client.ui.layout.MayScrollChildren; | |||
import com.vaadin.client.ui.window.WindowConnector; | |||
import com.vaadin.server.Page.Styles; | |||
@@ -677,6 +678,19 @@ public class UIConnector extends AbstractSingleComponentContainerConnector | |||
if (c instanceof WindowConnector) { | |||
WindowConnector wc = (WindowConnector) c; | |||
wc.setWindowOrderAndPosition(); | |||
VWindow window = wc.getWidget(); | |||
if (!window.isAttached()) { | |||
// Attach so that all widgets inside the Window are attached | |||
// when their onStateChange is run | |||
// Made invisible here for legacy reasons and made visible | |||
// at the end of stateChange. This dance could probably be | |||
// removed | |||
window.setVisible(false); | |||
window.show(); | |||
} | |||
} | |||
} | |||
@@ -17,6 +17,8 @@ package com.vaadin.client.ui.window; | |||
import java.util.logging.Logger; | |||
import com.google.gwt.core.client.Scheduler; | |||
import com.google.gwt.core.client.Scheduler.ScheduledCommand; | |||
import com.google.gwt.dom.client.Element; | |||
import com.google.gwt.dom.client.NativeEvent; | |||
import com.google.gwt.dom.client.Node; | |||
@@ -354,10 +356,6 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector | |||
if (state.modal != window.vaadinModality) { | |||
window.setVaadinModality(!window.vaadinModality); | |||
} | |||
if (!window.isAttached()) { | |||
window.setVisible(false); // hide until possible centering | |||
window.show(); | |||
} | |||
boolean resizeable = state.resizable | |||
&& state.windowMode == WindowMode.NORMAL; | |||
window.setResizable(resizeable); | |||
@@ -407,7 +405,13 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector | |||
window.centered = state.centered; | |||
// Ensure centering before setting visible (#16486) | |||
if (window.centered && getState().windowMode != WindowMode.MAXIMIZED) { | |||
window.center(); | |||
Scheduler.get().scheduleFinally(new ScheduledCommand() { | |||
@Override | |||
public void execute() { | |||
getWidget().center(); | |||
} | |||
}); | |||
} | |||
window.setVisible(true); | |||
@@ -56,6 +56,8 @@ import com.vaadin.client.widgets.Grid; | |||
public class MultiSelectionRenderer<T> extends | |||
ClickableRenderer<Boolean, CheckBox> { | |||
private static final String SELECTION_CHECKBOX_CLASSNAME = "-selection-checkbox"; | |||
/** The size of the autoscroll area, both top and bottom. */ | |||
private static final int SCROLL_AREA_GRADIENT_PX = 100; | |||
@@ -591,6 +593,8 @@ public class MultiSelectionRenderer<T> extends | |||
@Override | |||
public CheckBox createWidget() { | |||
final CheckBox checkBox = GWT.create(CheckBox.class); | |||
checkBox.setStylePrimaryName(grid.getStylePrimaryName() | |||
+ SELECTION_CHECKBOX_CLASSNAME); | |||
CheckBoxEventHandler handler = new CheckBoxEventHandler(checkBox); | |||
// Sink events |
@@ -1475,6 +1475,9 @@ public class Escalator extends Widget implements RequiresResize, | |||
cellElem.addClassName("frozen"); | |||
position.set(cellElem, scroller.lastScrollLeft, 0); | |||
} | |||
if (columnConfiguration.frozenColumns > 0 && col == columnConfiguration.frozenColumns - 1) { | |||
cellElem.addClassName("last-frozen"); | |||
} | |||
} | |||
referenceRow = paintInsertRow(referenceRow, tr, row); | |||
@@ -1732,6 +1735,14 @@ public class Escalator extends Widget implements RequiresResize, | |||
} | |||
public void setColumnFrozen(int column, boolean frozen) { | |||
toggleFrozenColumnClass(column, frozen, "frozen"); | |||
if (frozen) { | |||
updateFreezePosition(column, scroller.lastScrollLeft); | |||
} | |||
} | |||
private void toggleFrozenColumnClass(int column, boolean frozen, String className) { | |||
final NodeList<TableRowElement> childRows = root.getRows(); | |||
for (int row = 0; row < childRows.getLength(); row++) { | |||
@@ -1742,16 +1753,16 @@ public class Escalator extends Widget implements RequiresResize, | |||
TableCellElement cell = tr.getCells().getItem(column); | |||
if (frozen) { | |||
cell.addClassName("frozen"); | |||
cell.addClassName(className); | |||
} else { | |||
cell.removeClassName("frozen"); | |||
cell.removeClassName(className); | |||
position.reset(cell); | |||
} | |||
} | |||
} | |||
if (frozen) { | |||
updateFreezePosition(column, scroller.lastScrollLeft); | |||
} | |||
public void setColumnLastFrozen(int column, boolean lastFrozen) { | |||
toggleFrozenColumnClass(column, lastFrozen, "last-frozen"); | |||
} | |||
public void updateFreezePosition(int column, double scrollLeft) { | |||
@@ -4309,6 +4320,17 @@ public class Escalator extends Widget implements RequiresResize, | |||
firstUnaffectedCol = oldCount; | |||
} | |||
if (oldCount > 0) { | |||
header.setColumnLastFrozen(oldCount - 1, false); | |||
body.setColumnLastFrozen(oldCount - 1, false); | |||
footer.setColumnLastFrozen(oldCount - 1, false); | |||
} | |||
if (count > 0) { | |||
header.setColumnLastFrozen(count - 1, true); | |||
body.setColumnLastFrozen(count - 1, true); | |||
footer.setColumnLastFrozen(count - 1, true); | |||
} | |||
for (int col = firstAffectedCol; col < firstUnaffectedCol; col++) { | |||
header.setColumnFrozen(col, frozen); | |||
body.setColumnFrozen(col, frozen); | |||
@@ -5619,14 +5641,29 @@ public class Escalator extends Widget implements RequiresResize, | |||
horizontalScrollbar.setScrollbarThickness(scrollbarThickness); | |||
horizontalScrollbar | |||
.addVisibilityHandler(new ScrollbarBundle.VisibilityHandler() { | |||
private boolean queued = false; | |||
@Override | |||
public void visibilityChanged( | |||
ScrollbarBundle.VisibilityChangeEvent event) { | |||
if (queued) { | |||
return; | |||
} | |||
queued = true; | |||
/* | |||
* We either lost or gained a scrollbar. In any case, we | |||
* need to change the height, if it's defined by rows. | |||
*/ | |||
applyHeightByRows(); | |||
Scheduler.get().scheduleFinally(new ScheduledCommand() { | |||
@Override | |||
public void execute() { | |||
applyHeightByRows(); | |||
queued = false; | |||
} | |||
}); | |||
} | |||
}); | |||
@@ -216,6 +216,8 @@ public class Grid<T> extends ResizeComposite implements | |||
HasSelectionHandlers<T>, SubPartAware, DeferredWorker, Focusable, | |||
com.google.gwt.user.client.ui.Focusable, HasWidgets, HasEnabled { | |||
private static final String SELECT_ALL_CHECKBOX_CLASSNAME = "-select-all-checkbox"; | |||
/** | |||
* Enum describing different sections of Grid. | |||
*/ | |||
@@ -2535,6 +2537,7 @@ public class Grid<T> extends ResizeComposite implements | |||
private boolean initDone = false; | |||
private boolean selected = false; | |||
private CheckBox selectAllCheckBox; | |||
SelectionColumn(final Renderer<Boolean> selectColumnRenderer) { | |||
super(selectColumnRenderer); | |||
@@ -2559,41 +2562,57 @@ public class Grid<T> extends ResizeComposite implements | |||
* exist. | |||
*/ | |||
final SelectionModel.Multi<T> model = (Multi<T>) getSelectionModel(); | |||
final CheckBox checkBox = GWT.create(CheckBox.class); | |||
checkBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() { | |||
@Override | |||
public void onValueChange(ValueChangeEvent<Boolean> event) { | |||
if (event.getValue()) { | |||
fireEvent(new SelectAllEvent<T>(model)); | |||
selected = true; | |||
} else { | |||
model.deselectAll(); | |||
selected = false; | |||
} | |||
} | |||
}); | |||
checkBox.setValue(selected); | |||
selectionCell.setWidget(checkBox); | |||
// Select all with space when "select all" cell is active | |||
addHeaderKeyUpHandler(new HeaderKeyUpHandler() { | |||
@Override | |||
public void onKeyUp(GridKeyUpEvent event) { | |||
if (event.getNativeKeyCode() != KeyCodes.KEY_SPACE) { | |||
return; | |||
} | |||
HeaderRow targetHeaderRow = getHeader().getRow( | |||
event.getFocusedCell().getRowIndex()); | |||
if (!targetHeaderRow.isDefault()) { | |||
return; | |||
if (selectAllCheckBox == null) { | |||
selectAllCheckBox = GWT.create(CheckBox.class); | |||
selectAllCheckBox.setStylePrimaryName(getStylePrimaryName() | |||
+ SELECT_ALL_CHECKBOX_CLASSNAME); | |||
selectAllCheckBox | |||
.addValueChangeHandler(new ValueChangeHandler<Boolean>() { | |||
@Override | |||
public void onValueChange( | |||
ValueChangeEvent<Boolean> event) { | |||
if (event.getValue()) { | |||
fireEvent(new SelectAllEvent<T>(model)); | |||
selected = true; | |||
} else { | |||
model.deselectAll(); | |||
selected = false; | |||
} | |||
} | |||
}); | |||
selectAllCheckBox.setValue(selected); | |||
// Select all with space when "select all" cell is active | |||
addHeaderKeyUpHandler(new HeaderKeyUpHandler() { | |||
@Override | |||
public void onKeyUp(GridKeyUpEvent event) { | |||
if (event.getNativeKeyCode() != KeyCodes.KEY_SPACE) { | |||
return; | |||
} | |||
HeaderRow targetHeaderRow = getHeader().getRow( | |||
event.getFocusedCell().getRowIndex()); | |||
if (!targetHeaderRow.isDefault()) { | |||
return; | |||
} | |||
if (event.getFocusedCell().getColumn() == SelectionColumn.this) { | |||
// Send events to ensure state is updated | |||
selectAllCheckBox.setValue( | |||
!selectAllCheckBox.getValue(), true); | |||
} | |||
} | |||
if (event.getFocusedCell().getColumn() == SelectionColumn.this) { | |||
// Send events to ensure row selection state is | |||
// updated | |||
checkBox.setValue(!checkBox.getValue(), true); | |||
}); | |||
} else { | |||
for (HeaderRow row : header.getRows()) { | |||
if (row.getCell(this).getType() == GridStaticCellType.WIDGET) { | |||
// Detach from old header. | |||
row.getCell(this).setText(""); | |||
} | |||
} | |||
}); | |||
} | |||
selectionCell.setWidget(selectAllCheckBox); | |||
} | |||
@Override | |||
@@ -2655,7 +2674,6 @@ public class Grid<T> extends ResizeComposite implements | |||
super.setEditable(editable); | |||
return this; | |||
} | |||
} | |||
/** | |||
@@ -6927,11 +6945,21 @@ public class Grid<T> extends ResizeComposite implements | |||
if (args.getIndicesLength() == 0) { | |||
return editor.editorOverlay; | |||
} else if (args.getIndicesLength() == 1 | |||
&& args.getIndex(0) < columns.size()) { | |||
escalator | |||
.scrollToColumn(args.getIndex(0), ScrollDestination.ANY, 0); | |||
return editor.getWidget(columns.get(args.getIndex(0))).getElement(); | |||
} else if (args.getIndicesLength() == 1) { | |||
int index = args.getIndex(0); | |||
if (index >= columns.size()) { | |||
return null; | |||
} | |||
escalator.scrollToColumn(index, ScrollDestination.ANY, 0); | |||
Widget widget = editor.getWidget(columns.get(index)); | |||
if (widget != null) { | |||
return widget.getElement(); | |||
} | |||
// No widget for the column. | |||
return null; | |||
} | |||
return null; |
@@ -56,6 +56,8 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase { | |||
private static final String ANDROID_MOTOROLA_3_0 = "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13"; | |||
private static final String ANDROID_GALAXY_NEXUS_4_0_4_CHROME = "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19"; | |||
private static final String EDGE_WINDOWS_10 = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240"; | |||
public void testSafari3() { | |||
VBrowserDetails bd = new VBrowserDetails(SAFARI3_WINDOWS); | |||
assertWebKit(bd); | |||
@@ -423,6 +425,14 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase { | |||
assertWindows(bd, true); | |||
} | |||
public void testEdgeWindows10() { | |||
VBrowserDetails bd = new VBrowserDetails(EDGE_WINDOWS_10); | |||
assertEdge(bd); | |||
assertBrowserMajorVersion(bd, 12); | |||
assertBrowserMinorVersion(bd, 10240); | |||
assertWindows(bd, false); | |||
} | |||
/* | |||
* Helper methods below | |||
*/ | |||
@@ -484,6 +494,7 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase { | |||
assertFalse(browserDetails.isIE()); | |||
assertFalse(browserDetails.isOpera()); | |||
assertFalse(browserDetails.isSafari()); | |||
assertFalse(browserDetails.isEdge()); | |||
} | |||
private void assertChrome(VBrowserDetails browserDetails) { | |||
@@ -493,6 +504,7 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase { | |||
assertFalse(browserDetails.isIE()); | |||
assertFalse(browserDetails.isOpera()); | |||
assertFalse(browserDetails.isSafari()); | |||
assertFalse(browserDetails.isEdge()); | |||
} | |||
private void assertIE(VBrowserDetails browserDetails) { | |||
@@ -502,6 +514,7 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase { | |||
assertTrue(browserDetails.isIE()); | |||
assertFalse(browserDetails.isOpera()); | |||
assertFalse(browserDetails.isSafari()); | |||
assertFalse(browserDetails.isEdge()); | |||
} | |||
private void assertOpera(VBrowserDetails browserDetails) { | |||
@@ -511,6 +524,7 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase { | |||
assertFalse(browserDetails.isIE()); | |||
assertTrue(browserDetails.isOpera()); | |||
assertFalse(browserDetails.isSafari()); | |||
assertFalse(browserDetails.isEdge()); | |||
} | |||
private void assertSafari(VBrowserDetails browserDetails) { | |||
@@ -520,6 +534,17 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase { | |||
assertFalse(browserDetails.isIE()); | |||
assertFalse(browserDetails.isOpera()); | |||
assertTrue(browserDetails.isSafari()); | |||
assertFalse(browserDetails.isEdge()); | |||
} | |||
private void assertEdge(VBrowserDetails browserDetails) { | |||
// Browser | |||
assertFalse(browserDetails.isFirefox()); | |||
assertFalse(browserDetails.isChrome()); | |||
assertFalse(browserDetails.isIE()); | |||
assertFalse(browserDetails.isOpera()); | |||
assertFalse(browserDetails.isSafari()); | |||
assertTrue(browserDetails.isEdge()); | |||
} | |||
private void assertMacOSX(VBrowserDetails browserDetails) { |
@@ -23,5 +23,5 @@ | |||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.codeserver.CodeServer"/> | |||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-noprecompile -strict -bindAddress 0.0.0.0 com.vaadin.DefaultWidgetSet com.vaadin.tests.widgetset.TestingWidgetSet"/> | |||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="vaadin"/> | |||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx512M -XX:MaxPermSize=256M"/> | |||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx1G -XX:MaxPermSize=256M"/> | |||
</launchConfiguration> |
@@ -12,14 +12,51 @@ except Exception as e: | |||
from requests.auth import HTTPDigestAuth | |||
from os.path import join, expanduser, basename | |||
from BuildHelpers import parser, getArgs | |||
from time import sleep | |||
parser.add_argument("--deployUrl", help="Wildfly management URL") | |||
parser.add_argument("--deployUser", help="Deployment user", default=None) | |||
parser.add_argument("--deployPass", help="Deployment password", default=None) | |||
serverUp = None | |||
def testServer(): | |||
global serverUp | |||
if serverUp is not None: | |||
return serverUp | |||
print("Checking server status") | |||
i = 0 | |||
request = {"operation" : "read-attribute", "name" : "server-state"} | |||
serverUp = False | |||
while not serverUp and i < 2: | |||
try: | |||
print("Trying on url %s" % (getUrl())) | |||
result = doPostJson(url=getUrl(), auth=getAuth(), data=json.dumps(request)) | |||
response = result.json() | |||
if "outcome" not in response or response["outcome"] != "success": | |||
# Failure | |||
raise Exception(response) | |||
elif "result" not in response or response["result"] != "running": | |||
# Another failure | |||
raise Exception(response) | |||
# All OK | |||
serverUp = True | |||
print("Got server connection.") | |||
except Exception as e: | |||
print("Exception while checking server state: ", e) | |||
print("Server connection failed, retrying in 5 seconds.") | |||
i = i + 1 | |||
sleep(5) | |||
return serverUp | |||
# Helper for handling the full deployment | |||
# name should end with .war | |||
def deployWar(warFile, name=None): | |||
if not testServer(): | |||
raise Exception("Server not up. Skipping deployment.") | |||
return | |||
if name is None: | |||
name = basename(warFile).replace('.war', "-%s.war" % (getArgs().version.split('-')[0])) | |||
@@ -0,0 +1,53 @@ | |||
#coding=UTF-8 | |||
import argparse, cgi | |||
parser = argparse.ArgumentParser(description="Post-publish report generator") | |||
parser.add_argument("version", type=str, help="Vaadin version that was just built") | |||
parser.add_argument("buildResultUrl", type=str, help="URL for the build result page") | |||
args = parser.parse_args() | |||
(major, minor, maintenance) = args.version.split(".", 2) | |||
prerelease = "." in maintenance | |||
if prerelease: | |||
maintenance = maintenance.split('.')[0] | |||
content = """<html> | |||
<head></head> | |||
<body> | |||
<table> | |||
""" | |||
if not prerelease: | |||
content += "<tr><td><a href='http://vaadin.com/download/release/{maj}.{min}/{ver}/'>Check {ver} is published to vaadin.com/download</td></tr>".format(maj=major, min=minor, ver=args.version) | |||
else: | |||
content += "<tr><td><a href='http://vaadin.com/download/prerelease/{maj}.{min}/{maj}.{min}.{main}/{ver}'>Check {ver} is published as prerelease to vaadin.com/download</td></tr>".format(maj=major, min=minor, main=maintenance, ver=args.version) | |||
content += """ | |||
<tr><td>Verify Latest Vaadin 7: <iframe src="http://vaadin.com/download/LATEST7"></iframe></td></tr> | |||
<tr><td>Verify Vaadin 7 Version List: <iframe src="http://vaadin.com/download/VERSIONS_7"></iframe></td></tr> | |||
<tr><td>Verify Latest Vaadin 7.5: <iframe src="http://vaadin.com/download/release/7.5/LATEST"></iframe></td></tr> | |||
<tr><td>Verify Latest Vaadin 7.6: <iframe src="http://vaadin.com/download/release/7.6/LATEST"></iframe></td></tr> | |||
<tr><td>Verify Latest Vaadin 6: <iframe src="http://vaadin.com/download/LATEST"></iframe></td></tr> | |||
<tr><td>Verify Latest Vaadin 7 Prerelease: <iframe src="http://vaadin.com/download/PRERELEASES"></iframe></td></tr>""" | |||
if not prerelease: | |||
content += '<tr><td><a href="https://dev.vaadin.com/admin/ticket/versions">Set latest version to default</a></td></tr>' | |||
content += """ | |||
<tr><td><a href="http://test.vaadin.com/{version}/run/LabelModes?restartApplication">Verify uploaded to test.vaadin.com</a></td></tr> | |||
<tr><td><a href="https://github.com/vaadin/vaadin/tags">Verify tags pushed to GitHub</a></td></tr>""".format(version=args.version) | |||
if not prerelease: | |||
content += '<tr><td><a href="http://vaadin.com/api">Verify API version list updated</a></td></tr>' | |||
content += """ | |||
<tr><td><a href="https://dev.vaadin.com/query?status=pending-release&component=Core+Framework&resolution=fixed&milestone=Vaadin {version}&col=id&col=summary&col=component&col=milestone&col=status&col=type">Batch update tickets in Trac</a></td></tr> | |||
<tr><td><a href="{url}">Publish result page (See test results, pin and tag build and dependencies)</a></td></tr> | |||
</table> | |||
</body> | |||
</html>""".format(url=args.buildResultUrl, version=args.version) | |||
f = open("result/report.html", 'w') | |||
f.write(content) |
@@ -9,6 +9,7 @@ parser.add_argument("version", type=str, help="Vaadin version that was just buil | |||
parser.add_argument("deployUrl", type=str, help="Base url of the deployment server") | |||
parser.add_argument("buildResultUrl", type=str, help="URL for the build result page") | |||
parser.add_argument("stagingRepo", type=str, help="URL for the staging repository") | |||
parser.add_argument("tbapiUrl", type=str, help="URL for the TestBench API build") | |||
args = parser.parse_args() | |||
@@ -35,12 +36,48 @@ content += cgi.escape(""" <ibiblio name="vaadin-staging" usepoms="true" m2compat | |||
root="{repoUrl}" />""".format(repoUrl=args.stagingRepo)) | |||
content += """</pre> | |||
</td></tr> | |||
<tr><td><a href="https://dev.vaadin.com/milestone/Vaadin {version}">Trac Milestone</a></td></tr> | |||
<tr><td><a href="https://dev.vaadin.com/milestone/Vaadin {version}">Close Trac Milestone</a></td></tr> | |||
<tr><td><a href="https://dev.vaadin.com/query?status=pending-release&component=Core+Framework&resolution=fixed&col=id&col=summary&col=component&col=milestone&col=status&col=type">Verify pending release tickets still have milestone {version}</a></td></tr> | |||
<tr><td><a href="https://dev.vaadin.com/admin/ticket/versions">Add version {version} to Trac</td></tr> | |||
<tr><td><a href="{url}">Staging result page (See test results, pin and tag build and dependencies)</a></td></tr> | |||
<tr><td>Commands to tag all repositories (warning: do not run as a single script but set variables and check before any push commands - this has not been tested yet and the change IDs are missing)</td></tr> | |||
<tr><td><pre> | |||
VERSION={version} | |||
GERRIT_USER=[fill in your gerrit username] | |||
FRAMEWORK_REVISION=[fill in framework revision] | |||
SCREENSHOTS_REVISION=[fill in screenshot repository revision] | |||
ARCHETYPES_REVISION=[fill in maven-integration repository revision] | |||
PLUGIN_REVISION=[fill in maven plug-in repository revision] | |||
git clone ssh://$GERRIT_USER@dev.vaadin.com:29418/vaadin | |||
cd vaadin | |||
git tag -a -m"$VERSION" $VERSION $FRAMEWORK_REVISION | |||
git push --tags | |||
cd .. | |||
git clone ssh://$GERRIT_USER@dev.vaadin.com:29418/vaadin-screenshots | |||
cd vaadin-screenshots | |||
git tag -a -m"$VERSION" $VERSION $SCREENSHOTS_REVISION | |||
git push --tags | |||
cd .. | |||
git clone ssh://$GERRIT_USER@dev.vaadin.com:29418/maven-integration | |||
cd maven-integration | |||
git tag -a -m"$VERSION" $VERSION $ARCHETYPES_REVISION | |||
git push --tags | |||
cd .. | |||
git clone ssh://$GERRIT_USER@dev.vaadin.com:29418/maven-plugin | |||
cd maven-plugin | |||
git tag -a -m"$VERSION" $VERSION $PLUGIN_REVISION | |||
git push --tags | |||
cd .. | |||
</pre></td></tr> | |||
<tr><td><a href="{tbapi}">Build and publish TestBench API for version {version} if proceeding</a></td></tr> | |||
</table> | |||
</body> | |||
</html>""".format(url=args.buildResultUrl, repoUrl=args.stagingRepo, version=args.version) | |||
</html>""".format(url=args.buildResultUrl, repoUrl=args.stagingRepo, version=args.version, tbapi=args.tbapiUrl) | |||
f = open("result/report.html", 'w') | |||
f.write(content) |
@@ -36,7 +36,7 @@ | |||
<!-- Google App Engine --> | |||
<dependency org="com.google.appengine" name="appengine-api-1.0-sdk" | |||
rev="1.2.1" conf="build-provided,ide,test -> default" /> | |||
rev="1.7.7" conf="build-provided,ide,test -> default" /> | |||
<!-- Bean Validation API --> | |||
<dependency org="javax.validation" name="validation-api" |
@@ -28,6 +28,7 @@ import java.lang.reflect.Method; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.net.URLConnection; | |||
import java.net.URLDecoder; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
@@ -694,17 +695,20 @@ public class VaadinServlet extends HttpServlet implements Constants { | |||
return false; | |||
} | |||
String decodedRequestURI = URLDecoder.decode(request.getRequestURI(), | |||
"UTF-8"); | |||
if ((request.getContextPath() != null) | |||
&& (request.getRequestURI().startsWith("/VAADIN/"))) { | |||
serveStaticResourcesInVAADIN(request.getRequestURI(), request, | |||
response); | |||
&& (decodedRequestURI.startsWith("/VAADIN/"))) { | |||
serveStaticResourcesInVAADIN(decodedRequestURI, request, response); | |||
return true; | |||
} else if (request.getRequestURI().startsWith( | |||
request.getContextPath() + "/VAADIN/")) { | |||
} | |||
String decodedContextPath = URLDecoder.decode(request.getContextPath(), | |||
"UTF-8"); | |||
if (decodedRequestURI.startsWith(decodedContextPath + "/VAADIN/")) { | |||
serveStaticResourcesInVAADIN( | |||
request.getRequestURI().substring( | |||
request.getContextPath().length()), request, | |||
response); | |||
decodedRequestURI.substring(decodedContextPath.length()), | |||
request, response); | |||
return true; | |||
} | |||
@@ -125,6 +125,20 @@ public class WebBrowser implements Serializable { | |||
return browserDetails.isIE(); | |||
} | |||
/** | |||
* Tests whether the user is using Edge. | |||
* | |||
* @return true if the user is using Edge, false if the user is not using | |||
* Edge or if no information on the browser is present | |||
*/ | |||
public boolean isEdge() { | |||
if (browserDetails == null) { | |||
return false; | |||
} | |||
return browserDetails.isEdge(); | |||
} | |||
/** | |||
* Tests whether the user is using Safari. | |||
* |
@@ -274,6 +274,13 @@ public class AtmospherePushConnection implements PushConnection { | |||
public void disconnect() { | |||
assert isConnected(); | |||
if (resource == null) { | |||
// Already disconnected. Should not happen but if it does, we don't | |||
// want to cause NPEs | |||
getLogger() | |||
.fine("AtmospherePushConnection.disconnect() called twice, this should not happen"); | |||
return; | |||
} | |||
if (resource.isResumed()) { | |||
// This can happen for long polling because of | |||
// http://dev.vaadin.com/ticket/16919 |
@@ -269,7 +269,7 @@ public class FileUploadHandler implements RequestHandler { | |||
streamVariable = uI.getConnectorTracker().getStreamVariable( | |||
connectorId, variableName); | |||
String secKey = uI.getConnectorTracker().getSeckey(streamVariable); | |||
if (!secKey.equals(parts[3])) { | |||
if (secKey == null || !secKey.equals(parts[3])) { | |||
// TODO Should rethink error handling | |||
return true; | |||
} |
@@ -1167,6 +1167,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, | |||
private int selectionLimit = DEFAULT_MAX_SELECTIONS; | |||
private boolean allSelected; | |||
@Override | |||
public boolean select(final Object... itemIds) | |||
throws IllegalArgumentException { | |||
@@ -1212,6 +1214,9 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, | |||
} | |||
fireSelectionEvent(oldSelection, selection); | |||
} | |||
updateAllSelectedState(); | |||
return selectionWillChange; | |||
} | |||
@@ -1277,6 +1282,9 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, | |||
selection.removeAll(itemIds); | |||
fireSelectionEvent(oldSelection, selection); | |||
} | |||
updateAllSelectedState(); | |||
return hasCommonElements; | |||
} | |||
@@ -1357,6 +1365,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, | |||
fireSelectionEvent(oldSelection, selection); | |||
} | |||
updateAllSelectedState(); | |||
return changed; | |||
} | |||
@@ -1370,6 +1380,13 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, | |||
"Vararg array of itemIds may not be null"); | |||
} | |||
} | |||
private void updateAllSelectedState() { | |||
if (allSelected != selection.size() >= selectionLimit) { | |||
allSelected = selection.size() >= selectionLimit; | |||
grid.getRpcProxy(GridClientRpc.class).setSelectAll(allSelected); | |||
} | |||
} | |||
} | |||
/** | |||
@@ -3648,10 +3665,21 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, | |||
safeConverter.getPresentationType(), locale); | |||
} | |||
JsonValue encodedValue = renderer.encode(presentationValue); | |||
JsonValue encodedValue; | |||
try { | |||
encodedValue = renderer.encode(presentationValue); | |||
} catch (Exception e) { | |||
getLogger().log(Level.SEVERE, "Unable to encode data", e); | |||
encodedValue = renderer.encode(null); | |||
} | |||
return encodedValue; | |||
} | |||
private static Logger getLogger() { | |||
return Logger.getLogger(AbstractRenderer.class.getName()); | |||
} | |||
} | |||
/** |
@@ -15,6 +15,8 @@ | |||
*/ | |||
package com.vaadin.ui; | |||
import com.vaadin.shared.ui.orderedlayout.HorizontalLayoutState; | |||
/** | |||
* Horizontal layout | |||
* | |||
@@ -48,4 +50,9 @@ public class HorizontalLayout extends AbstractOrderedLayout { | |||
addComponents(children); | |||
} | |||
@Override | |||
protected HorizontalLayoutState getState() { | |||
return (HorizontalLayoutState) super.getState(); | |||
} | |||
} |
@@ -15,6 +15,8 @@ | |||
*/ | |||
package com.vaadin.ui; | |||
import com.vaadin.shared.ui.orderedlayout.VerticalLayoutState; | |||
/** | |||
* Vertical layout | |||
* | |||
@@ -48,4 +50,9 @@ public class VerticalLayout extends AbstractOrderedLayout { | |||
this(); | |||
addComponents(children); | |||
} | |||
@Override | |||
protected VerticalLayoutState getState() { | |||
return (VerticalLayoutState) super.getState(); | |||
} | |||
} |
@@ -58,7 +58,7 @@ public class ImageRenderer extends ClickableRenderer<Resource> { | |||
if (!(resource == null || resource instanceof ExternalResource || resource instanceof ThemeResource)) { | |||
throw new IllegalArgumentException( | |||
"ImageRenderer only supports ExternalResource and ThemeResource (" | |||
+ resource.getClass().getSimpleName() + "given )"); | |||
+ resource.getClass().getSimpleName() + " given)"); | |||
} | |||
return encode(ResourceReference.create(resource, this, null), |
@@ -15,50 +15,136 @@ | |||
*/ | |||
package com.vaadin.server.communication; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.verifyZeroInteractions; | |||
import static org.mockito.Mockito.when; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.mockito.Mockito; | |||
import org.mockito.Mock; | |||
import org.mockito.MockitoAnnotations; | |||
import com.vaadin.server.ClientConnector; | |||
import com.vaadin.server.ServletPortletHelper; | |||
import com.vaadin.server.StreamVariable; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.server.VaadinResponse; | |||
import com.vaadin.server.VaadinSession; | |||
import com.vaadin.ui.ConnectorTracker; | |||
import com.vaadin.ui.UI; | |||
/** | |||
* Tests whether we get infinite loop if InputStream is already read (#10096) | |||
*/ | |||
public class FileUploadHandlerTest { | |||
private FileUploadHandler handler; | |||
private VaadinRequest request; | |||
@Mock private VaadinResponse response; | |||
@Mock private StreamVariable streamVariable; | |||
@Mock private ClientConnector clientConnector; | |||
@Mock private VaadinRequest request; | |||
@Mock private UI ui; | |||
@Mock private ConnectorTracker connectorTracker; | |||
@Mock private VaadinSession session; | |||
@Mock private OutputStream responseOutput; | |||
private int uiId = 123; | |||
private final String connectorId = "connectorId"; | |||
private final String variableName = "name"; | |||
private final String expectedSecurityKey = "key"; | |||
@Before | |||
public void setup() throws Exception { | |||
MockitoAnnotations.initMocks(this); | |||
handler = new FileUploadHandler(); | |||
InputStream inputStream = new InputStream() { | |||
private int counter = 0; | |||
mockRequest(); | |||
mockConnectorTracker(); | |||
mockUi(); | |||
when(clientConnector.isConnectorEnabled()).thenReturn(true); | |||
when(streamVariable.getOutputStream()).thenReturn(mock(OutputStream.class)); | |||
when(response.getOutputStream()).thenReturn(responseOutput); | |||
} | |||
private void mockConnectorTracker() { | |||
when(connectorTracker.getSeckey(streamVariable)).thenReturn(expectedSecurityKey); | |||
when(connectorTracker.getStreamVariable(connectorId, variableName)).thenReturn(streamVariable); | |||
when(connectorTracker.getConnector(connectorId)).thenReturn(clientConnector); | |||
} | |||
private void mockRequest() throws IOException { | |||
when(request.getPathInfo()).thenReturn("/" + ServletPortletHelper.UPLOAD_URL_PREFIX + uiId + "/"+ connectorId + "/" + variableName + "/" + expectedSecurityKey); | |||
when(request.getInputStream()).thenReturn(createInputStream("foobar")); | |||
when(request.getHeader("Content-Length")).thenReturn("6"); | |||
when(request.getContentType()).thenReturn("foobar"); | |||
} | |||
private InputStream createInputStream(final String content) { | |||
return new InputStream() { | |||
int counter = 0; | |||
byte[] msg = content.getBytes(); | |||
@Override | |||
public int read() throws IOException { | |||
counter++; | |||
if (counter > 6) { | |||
throw new RuntimeException( | |||
"-1 is ignored by FileUploadHandler"); | |||
if(counter > msg.length + 1) { | |||
throw new AssertionError("-1 was ignored by FileUploadHandler."); | |||
} | |||
if(counter >= msg.length) { | |||
counter++; | |||
return -1; | |||
} | |||
return -1; | |||
} | |||
return msg[counter++]; | |||
} | |||
}; | |||
request = Mockito.mock(VaadinRequest.class); | |||
Mockito.when(request.getInputStream()).thenReturn(inputStream); | |||
Mockito.when(request.getHeader("Content-Length")).thenReturn("211"); | |||
} | |||
private void mockUi() { | |||
when(ui.getConnectorTracker()).thenReturn(connectorTracker); | |||
when(session.getUIById(uiId)).thenReturn(ui); | |||
} | |||
/** | |||
* Tests whether we get infinite loop if InputStream is already read (#10096) | |||
*/ | |||
@Test(expected = IOException.class) | |||
public void testStreamEnded() throws IOException { | |||
public void exceptionIsThrownOnUnexpectedEnd() throws IOException { | |||
when(request.getInputStream()).thenReturn(createInputStream("")); | |||
when(request.getHeader("Content-Length")).thenReturn("1"); | |||
handler.doHandleSimpleMultipartFileUpload(null, request, null, null, | |||
null, null, null); | |||
} | |||
@Test | |||
public void responseIsSentOnCorrectSecurityKey() throws IOException { | |||
when(connectorTracker.getSeckey(streamVariable)).thenReturn(expectedSecurityKey); | |||
handler.handleRequest(session, request, response); | |||
verify(responseOutput).close(); | |||
} | |||
@Test | |||
public void responseIsNotSentOnIncorrectSecurityKey() throws IOException { | |||
when(connectorTracker.getSeckey(streamVariable)).thenReturn("another key expected"); | |||
handler.handleRequest(session, request, response); | |||
verifyZeroInteractions(responseOutput); | |||
} | |||
@Test | |||
public void responseIsNotSentOnMissingSecurityKey() throws IOException { | |||
when(connectorTracker.getSeckey(streamVariable)).thenReturn(null); | |||
handler.handleRequest(session, request, response); | |||
verifyZeroInteractions(responseOutput); | |||
} | |||
} |
@@ -41,6 +41,7 @@ public class VBrowserDetails implements Serializable { | |||
private boolean isFirefox = false; | |||
private boolean isOpera = false; | |||
private boolean isIE = false; | |||
private boolean isEdge = false; | |||
private boolean isPhantomJS = false; | |||
private boolean isWindowsPhone; | |||
@@ -88,6 +89,16 @@ public class VBrowserDetails implements Serializable { | |||
isSafari = !isChrome && !isIE && userAgent.indexOf("safari") != -1; | |||
isFirefox = userAgent.indexOf(" firefox/") != -1; | |||
isPhantomJS = userAgent.indexOf("phantomjs/") != -1; | |||
if (userAgent.indexOf(" edge/") != -1) { | |||
isEdge = true; | |||
isChrome = false; | |||
isOpera = false; | |||
isIE = false; | |||
isSafari = false; | |||
isFirefox = false; | |||
isWebKit = false; | |||
isGecko = false; | |||
} | |||
// chromeframe | |||
isChromeFrameCapable = userAgent.indexOf("chromeframe") != -1; | |||
@@ -115,6 +126,8 @@ public class VBrowserDetails implements Serializable { | |||
tmp = tmp.replaceFirst("([0-9]+\\.[0-9]+).*", "$1"); | |||
browserEngineVersion = Float.parseFloat(tmp); | |||
} | |||
} else if (isEdge) { | |||
browserEngineVersion = 0; | |||
} | |||
} catch (Exception e) { | |||
// Browser engine version parsing failed | |||
@@ -158,6 +171,9 @@ public class VBrowserDetails implements Serializable { | |||
i = userAgent.indexOf("opera/") + 6; | |||
} | |||
parseVersionString(safeSubstring(userAgent, i, i + 5)); | |||
} else if (isEdge) { | |||
int i = userAgent.indexOf(" edge/") + 6; | |||
parseVersionString(safeSubstring(userAgent, i, i + 8)); | |||
} | |||
} catch (Exception e) { | |||
// Browser version parsing failed | |||
@@ -372,6 +388,15 @@ public class VBrowserDetails implements Serializable { | |||
return isIE; | |||
} | |||
/** | |||
* Tests if the browser is Edge. | |||
* | |||
* @return true if it is Edge, false otherwise | |||
*/ | |||
public boolean isEdge() { | |||
return isEdge; | |||
} | |||
/** | |||
* Tests if the browser is PhantomJS. | |||
* |
@@ -55,4 +55,15 @@ public interface GridClientRpc extends ClientRpc { | |||
* Command client Grid to recalculate column widths. | |||
*/ | |||
public void recalculateColumnWidths(); | |||
/** | |||
* Informs the Grid that all items have been selected or not selected on the | |||
* server side. | |||
* | |||
* @since 7.5.3 | |||
* @param allSelected | |||
* <code>true</code> to check the select all checkbox, | |||
* <code>false</code> to uncheck it. | |||
*/ | |||
public void setSelectAll(boolean allSelected); | |||
} |
@@ -404,7 +404,8 @@ | |||
<antcall target="integration-test-osgi" /> | |||
<antcall target="integration-test-tomcat7apacheproxy" /> | |||
<antcall target="integration-test-websphere8" /> | |||
<antcall target="integration-test-websphereportal8" /> | |||
<!-- Currently the test system does not have a server for automatic testing of WebSphere Portal 8 --> | |||
<!-- <antcall target="integration-test-websphereportal8" /> --> | |||
</parallel> | |||
</target> |
@@ -31,7 +31,7 @@ | |||
rev="4.2.0.Final" conf="build,ide -> default" /> | |||
<!-- Google App Engine --> | |||
<dependency org="com.google.appengine" name="appengine-api-1.0-sdk" | |||
rev="1.2.1" conf="build-provided,ide -> default" /> | |||
rev="1.7.7" conf="build-provided,ide -> default" /> | |||
<!-- LIBRARY DEPENDENCIES (compile time) --> | |||
<!-- Project modules --> |
@@ -40,7 +40,7 @@ public class VerifyBrowserVersionTest extends MultiBrowserTest { | |||
// Chrome version does not necessarily match the desired version | |||
// because of auto updates... | |||
browserIdentifier = getExpectedUserAgentString(getDesiredCapabilities()) | |||
+ "43"; | |||
+ "44"; | |||
} else { | |||
browserIdentifier = getExpectedUserAgentString(desiredCapabilities) | |||
+ desiredCapabilities.getVersion(); |
@@ -5,17 +5,27 @@ import java.text.SimpleDateFormat; | |||
import java.util.Locale; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||
import com.vaadin.ui.Calendar; | |||
import com.vaadin.ui.components.calendar.CalendarComponentEvents; | |||
import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClick; | |||
import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClickHandler; | |||
import com.vaadin.ui.components.calendar.event.BasicEvent; | |||
public class NullEventMoveHandler extends AbstractTestUI { | |||
public class NullEventMoveHandler extends AbstractTestUIWithLog { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
Calendar calendar = getCalendar(); | |||
calendar.setHandler((CalendarComponentEvents.EventMoveHandler) null); | |||
calendar.setHandler(new EventClickHandler() { | |||
@Override | |||
public void eventClick(EventClick event) { | |||
log("Clicked on " + event.getCalendarEvent().getCaption()); | |||
} | |||
}); | |||
addComponent(calendar); | |||
} |
@@ -3,6 +3,7 @@ package com.vaadin.tests.components.calendar; | |||
import static org.hamcrest.core.Is.is; | |||
import static org.junit.Assert.assertThat; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import org.openqa.selenium.By; | |||
import org.openqa.selenium.WebElement; | |||
@@ -22,12 +23,26 @@ public class NullEventMoveHandlerTest extends DndActionsTest { | |||
assertEventCannotBeMoved(); | |||
} | |||
@Test | |||
public void eventIsClickableWhenNotMovableInMonthView() { | |||
getEvent().click(); | |||
Assert.assertEquals("1. Clicked on foo", getLogRow(0)); | |||
} | |||
@Test | |||
public void eventIsNotMovableInWeekView() { | |||
openWeekView(); | |||
assertEventCannotBeMoved(); | |||
} | |||
@Test | |||
public void eventIsClickableWhenNotMovableInWeekView() { | |||
openWeekView(); | |||
getEvent().findElement(By.className("v-calendar-event-caption")) | |||
.click(); | |||
Assert.assertEquals("1. Clicked on foo", getLogRow(0)); | |||
} | |||
private void assertEventCannotBeMoved() { | |||
int originalPosition = getEventXPosition(); | |||
@@ -0,0 +1,40 @@ | |||
package com.vaadin.tests.components.combobox; | |||
import com.vaadin.annotations.Theme; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||
import com.vaadin.ui.ComboBox; | |||
import com.vaadin.ui.HorizontalLayout; | |||
@Theme("valo") | |||
public class ComboboxPopupScrolling extends AbstractTestUIWithLog { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
ComboBox combobox = new ComboBox("100px wide combobox"); | |||
combobox.setWidth("100px"); | |||
combobox.addItem("AMERICAN SAMOA"); | |||
combobox.addItem("ANTIGUA AND BARBUDA"); | |||
ComboBox combobox2 = new ComboBox("250px wide combobox"); | |||
combobox2.setWidth("250px"); | |||
combobox2.addItem("AMERICAN SAMOA"); | |||
combobox2.addItem("ANTIGUA AND BARBUDA"); | |||
ComboBox combobox3 = new ComboBox("Undefined wide combobox"); | |||
combobox3.setWidth(null); | |||
combobox3.addItem("AMERICAN SAMOA"); | |||
combobox3.addItem("ANTIGUA AND BARBUDA"); | |||
ComboBox combobox4 = new ComboBox("Another 100px wide combobox"); | |||
combobox4.setWidth("100px"); | |||
for (int i = 0; i < 10; i++) { | |||
combobox4.addItem("AMERICAN SAMOA " + i); | |||
combobox4.addItem("ANTIGUA AND BARBUDA " + i); | |||
} | |||
HorizontalLayout hl = new HorizontalLayout(combobox, combobox2, | |||
combobox3, combobox4); | |||
addComponent(hl); | |||
} | |||
} |
@@ -0,0 +1,60 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.combobox; | |||
import org.junit.Test; | |||
import org.openqa.selenium.By; | |||
import org.openqa.selenium.WebElement; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class ComboboxPopupScrollingTest extends MultiBrowserTest { | |||
@Test | |||
public void testNoScrollbarsValo() { | |||
testNoScrollbars("valo"); | |||
} | |||
@Test | |||
public void testNoScrollbarsChameleon() { | |||
testNoScrollbars("chameleon"); | |||
} | |||
@Test | |||
public void testNoScrollbarsRuno() { | |||
testNoScrollbars("runo"); | |||
} | |||
@Test | |||
public void testNoScrollbarsReindeer() { | |||
testNoScrollbars("reindeer"); | |||
} | |||
private void testNoScrollbars(String theme) { | |||
openTestURL("theme=" + theme); | |||
for (CustomComboBoxElement cb : $(CustomComboBoxElement.class).all()) { | |||
String caption = cb.getCaption(); | |||
cb.openPopup(); | |||
WebElement popup = cb.getSuggestionPopup(); | |||
WebElement scrollable = popup.findElement(By | |||
.className("v-filterselect-suggestmenu")); | |||
assertNoHorizontalScrollbar(scrollable, caption); | |||
assertNoVerticalScrollbar(scrollable, caption); | |||
} | |||
} | |||
} |
@@ -0,0 +1,40 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.combobox; | |||
import org.openqa.selenium.WebElement; | |||
import com.vaadin.testbench.By; | |||
import com.vaadin.testbench.elements.ComboBoxElement; | |||
import com.vaadin.testbench.elementsbase.ServerClass; | |||
@ServerClass("com.vaadin.ui.ComboBox") | |||
public class CustomComboBoxElement extends ComboBoxElement { | |||
private static org.openqa.selenium.By bySuggestionPopup = By | |||
.vaadin("#popup"); | |||
public WebElement getSuggestionPopup() { | |||
ensurePopupOpen(); | |||
return findElement(bySuggestionPopup); | |||
} | |||
private void ensurePopupOpen() { | |||
if (!isElementPresent(bySuggestionPopup)) { | |||
openPopup(); | |||
} | |||
} | |||
} |
@@ -23,7 +23,6 @@ import org.junit.Assert; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.openqa.selenium.By; | |||
import org.openqa.selenium.JavascriptExecutor; | |||
import org.openqa.selenium.Keys; | |||
import org.openqa.selenium.StaleElementReferenceException; | |||
import org.openqa.selenium.WebDriver; | |||
@@ -313,10 +312,6 @@ public class GridDetailsLocationTest extends MultiBrowserTest { | |||
checkBoxElement.click(5, 5); | |||
} | |||
private Object executeScript(String string, Object... param) { | |||
return ((JavascriptExecutor) getDriver()).executeScript(string, param); | |||
} | |||
private void scrollAndToggle(int row) { | |||
setRow(row); | |||
getScrollAndToggle().click(); |
@@ -0,0 +1,43 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.grid; | |||
import com.vaadin.server.ClassResource; | |||
import com.vaadin.server.Resource; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||
import com.vaadin.tests.integration.FlagSeResource; | |||
import com.vaadin.ui.Grid; | |||
import com.vaadin.ui.renderers.ImageRenderer; | |||
public class GridWithBrokenRenderer extends AbstractTestUIWithLog { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
final Grid grid = new Grid(); | |||
grid.addColumn("short", String.class); | |||
grid.addColumn("icon", Resource.class); | |||
grid.addColumn("country", String.class); | |||
grid.getColumn("icon").setRenderer(new ImageRenderer()); | |||
addComponent(grid); | |||
grid.addRow("FI", new ClassResource("fi.gif"), "Finland"); | |||
grid.addRow("SE", new FlagSeResource(), "Sweden"); | |||
} | |||
} |
@@ -0,0 +1,41 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.grid; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import com.vaadin.testbench.elements.GridElement; | |||
import com.vaadin.tests.tb3.SingleBrowserTest; | |||
public class GridWithBrokenRendererTest extends SingleBrowserTest { | |||
@Test | |||
public void ensureRendered() { | |||
openTestURL(); | |||
GridElement grid = $(GridElement.class).first(); | |||
assertRow(grid, 0, "FI", "", "Finland"); | |||
assertRow(grid, 1, "SE", "", "Sweden"); | |||
} | |||
private void assertRow(GridElement grid, int row, String... texts) { | |||
for (int column = 0; column < texts.length; column++) { | |||
Assert.assertEquals("Cell " + row + "," + column, texts[column], | |||
grid.getCell(row, column).getText()); | |||
} | |||
} | |||
} |
@@ -792,6 +792,26 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> { | |||
c.setColumnReorderingAllowed(value); | |||
} | |||
}); | |||
createClickAction("Select all", "State", new Command<Grid, String>() { | |||
@Override | |||
public void execute(Grid c, String value, Object data) { | |||
SelectionModel selectionModel = c.getSelectionModel(); | |||
if (selectionModel instanceof SelectionModel.Multi) { | |||
((SelectionModel.Multi) selectionModel).selectAll(); | |||
} | |||
} | |||
}, null); | |||
createClickAction("Select none", "State", new Command<Grid, String>() { | |||
@Override | |||
public void execute(Grid c, String value, Object data) { | |||
SelectionModel selectionModel = c.getSelectionModel(); | |||
if (selectionModel instanceof SelectionModel.Multi) { | |||
((SelectionModel.Multi) selectionModel).deselectAll(); | |||
} | |||
} | |||
}, null); | |||
} | |||
protected void createHeaderActions() { |
@@ -207,6 +207,8 @@ public abstract class GridEditorTest extends GridBasicFeaturesTest { | |||
assertTrue("Noneditable cell should contain v-grid-cell classname", | |||
classNames.contains("v-grid-cell")); | |||
assertNoErrorNotifications(); | |||
} | |||
@Test |
@@ -20,8 +20,10 @@ import static org.junit.Assert.assertTrue; | |||
import org.junit.Test; | |||
import org.openqa.selenium.Keys; | |||
import org.openqa.selenium.WebDriver; | |||
import org.openqa.selenium.WebElement; | |||
import org.openqa.selenium.interactions.Actions; | |||
import org.openqa.selenium.support.ui.ExpectedCondition; | |||
import com.vaadin.testbench.By; | |||
import com.vaadin.testbench.elements.GridElement; | |||
@@ -335,6 +337,62 @@ public class GridSelectionTest extends GridBasicFeaturesTest { | |||
getRow(5).isSelected()); | |||
} | |||
@Test | |||
public void testSelectionCheckBoxesHaveStyleNames() { | |||
openTestURL(); | |||
setSelectionModelMulti(); | |||
assertTrue( | |||
"Selection column CheckBox should have the proper style name set", | |||
getGridElement().getCell(0, 0).findElement(By.tagName("span")) | |||
.getAttribute("class") | |||
.contains("v-grid-selection-checkbox")); | |||
GridCellElement header = getGridElement().getHeaderCell(0, 0); | |||
assertTrue("Select all CheckBox should have the proper style name set", | |||
header.findElement(By.tagName("span")).getAttribute("class") | |||
.contains("v-grid-select-all-checkbox")); | |||
} | |||
@Test | |||
public void testServerSideSelectTogglesSelectAllCheckBox() { | |||
openTestURL(); | |||
setSelectionModelMulti(); | |||
GridCellElement header = getGridElement().getHeaderCell(0, 0); | |||
WebElement selectAll = header.findElement(By.tagName("input")); | |||
selectMenuPath("Component", "State", "Select all"); | |||
waitUntilCheckBoxValue(selectAll, true); | |||
assertTrue("Select all CheckBox wasn't selected as expected", | |||
selectAll.isSelected()); | |||
selectMenuPath("Component", "State", "Select none"); | |||
waitUntilCheckBoxValue(selectAll, false); | |||
assertFalse("Select all CheckBox was selected unexpectedly", | |||
selectAll.isSelected()); | |||
selectMenuPath("Component", "State", "Select all"); | |||
waitUntilCheckBoxValue(selectAll, true); | |||
getGridElement().getCell(5, 0).click(); | |||
waitUntilCheckBoxValue(selectAll, false); | |||
assertFalse("Select all CheckBox was selected unexpectedly", | |||
selectAll.isSelected()); | |||
} | |||
private void waitUntilCheckBoxValue(final WebElement checkBoxElememnt, | |||
final boolean expectedValue) { | |||
waitUntil(new ExpectedCondition<Boolean>() { | |||
@Override | |||
public Boolean apply(WebDriver input) { | |||
return expectedValue ? checkBoxElememnt.isSelected() | |||
: !checkBoxElememnt.isSelected(); | |||
} | |||
}, 5); | |||
} | |||
private void setSelectionModelMulti() { | |||
selectMenuPath("Component", "State", "Selection mode", "multi"); | |||
} |
@@ -0,0 +1,43 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.tabsheet; | |||
import com.vaadin.annotations.Theme; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.ui.Label; | |||
import com.vaadin.ui.TabSheet; | |||
import com.vaadin.ui.UI; | |||
import com.vaadin.ui.VerticalSplitPanel; | |||
import com.vaadin.ui.themes.ValoTheme; | |||
@Theme("valo") | |||
public class TabSheetInSplitPanel extends UI { | |||
@Override | |||
protected void init(VaadinRequest request) { | |||
VerticalSplitPanel verticalSplitter = new VerticalSplitPanel(); | |||
setContent(verticalSplitter); | |||
verticalSplitter.setSizeFull(); | |||
TabSheet t = new TabSheet(); | |||
t.setHeight("100%"); | |||
t.addTab(new Label("Hello in tab"), "Hello tab"); | |||
t.setStyleName(ValoTheme.TABSHEET_FRAMED); | |||
verticalSplitter.addComponent(t); | |||
verticalSplitter.addComponent(new Label("Hello")); | |||
} | |||
} |
@@ -0,0 +1,43 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.tabsheet; | |||
import java.util.List; | |||
import org.junit.Test; | |||
import org.openqa.selenium.By; | |||
import org.openqa.selenium.WebElement; | |||
import com.vaadin.testbench.elements.TabSheetElement; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class TabSheetInSplitPanelTest extends MultiBrowserTest { | |||
@Test | |||
public void ensureNoScrollbars() { | |||
openTestURL(); | |||
TabSheetElement ts = $(TabSheetElement.class).first(); | |||
List<WebElement> scrollables = ts.findElements(By | |||
.xpath("//*[contains(@class,'v-scrollable')]")); | |||
for (WebElement scrollable : scrollables) { | |||
assertNoHorizontalScrollbar(scrollable, | |||
"Element should not have a horizontal scrollbar"); | |||
assertNoVerticalScrollbar(scrollable, | |||
"Element should not have a vertical scrollbar"); | |||
} | |||
} | |||
} |
@@ -0,0 +1,51 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.treetable; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.TreeTable; | |||
public class TreeTableScrollOnExpand extends AbstractTestUI { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
TreeTable t = new TreeTable(); | |||
t.setSelectable(true); | |||
t.setImmediate(true); | |||
t.setSizeFull(); | |||
t.addContainerProperty("Name", String.class, "null"); | |||
for (int i = 1; i <= 100; i++) { | |||
String parentID = "Item " + i; | |||
Object parent = t.addItem(new Object[] { parentID }, parentID); | |||
String childID = "Item " + (100 + i); | |||
Object child = t.addItem(new Object[] { childID }, childID); | |||
t.getContainerDataSource().setParent(childID, parentID); | |||
} | |||
addComponent(t); | |||
} | |||
@Override | |||
public Integer getTicketNumber() { | |||
return 18247; | |||
} | |||
@Override | |||
public String getTestDescription() { | |||
return "After selecting an item and scrolling it out of view, TreeTable should not scroll to the " | |||
+ "selected item when expanding an item."; | |||
} | |||
} |
@@ -0,0 +1,46 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.treetable; | |||
import static org.junit.Assert.assertEquals; | |||
import java.io.IOException; | |||
import org.junit.Test; | |||
import org.openqa.selenium.By; | |||
import org.openqa.selenium.WebElement; | |||
import com.vaadin.testbench.elements.TreeTableElement; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class TreeTableScrollOnExpandTest extends MultiBrowserTest { | |||
@Test | |||
public void testScrollOnExpand() throws InterruptedException, IOException { | |||
openTestURL(); | |||
TreeTableElement tt = $(TreeTableElement.class).first(); | |||
tt.getRow(0).click(); | |||
tt.scroll(300); | |||
sleep(1000); | |||
tt.getRow(20).toggleExpanded(); | |||
// Need to wait a bit to avoid accepting the case where the TreeTable is | |||
// in the desired state only for a short while. | |||
sleep(1000); | |||
WebElement focusedRow = getDriver().findElement( | |||
By.className("v-table-focus")); | |||
assertEquals("Item 21", focusedRow.getText()); | |||
} | |||
} |
@@ -0,0 +1,49 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.window; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Grid; | |||
import com.vaadin.ui.Window; | |||
public class GridInWindow extends AbstractTestUIWithLog { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
final Grid grid = new Grid(); | |||
grid.addColumn("Hidable column").setHidable(true); | |||
grid.addRow("Close and reopen and it vanishes"); | |||
Button popupButton = new Button("Open PopUp", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(Button.ClickEvent event) { | |||
Window subWindow = new Window("Sub-window"); | |||
subWindow.setContent(grid); | |||
subWindow.setWidth(600, Unit.PIXELS); | |||
subWindow.setWidth(400, Unit.PIXELS); | |||
getUI().addWindow(subWindow); | |||
} | |||
}); | |||
addComponent(popupButton); | |||
} | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.window; | |||
import org.junit.Test; | |||
import com.vaadin.testbench.elements.ButtonElement; | |||
import com.vaadin.tests.tb3.SingleBrowserTest; | |||
import com.vaadin.tests.tb3.newelements.WindowElement; | |||
public class GridInWindowTest extends SingleBrowserTest { | |||
@Test | |||
public void ensureAttachInHierachyChange() { | |||
openTestURL("debug"); | |||
$(ButtonElement.class).first().click(); | |||
assertNoErrorNotifications(); | |||
$(WindowElement.class).first().close(); | |||
assertNoErrorNotifications(); | |||
$(ButtonElement.class).first().click(); | |||
assertNoErrorNotifications(); | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.window; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
import com.vaadin.ui.TextArea; | |||
import com.vaadin.ui.Window; | |||
public class OpenModalWindowAndFocusField extends AbstractTestUIWithLog { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
Button button = new Button("Open modal and focus textarea"); | |||
button.setId("openFocus"); | |||
button.addClickListener(new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
open(true); | |||
} | |||
}); | |||
addComponent(button); | |||
button = new Button("Only open modal"); | |||
button.setId("open"); | |||
button.addClickListener(new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
open(false); | |||
} | |||
}); | |||
addComponent(button); | |||
} | |||
private void open(boolean focus) { | |||
Window wind = new Window(); | |||
wind.setModal(true); | |||
TextArea ta = new TextArea(); | |||
wind.setContent(ta); | |||
addWindow(wind); | |||
if (focus) { | |||
ta.focus(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,48 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.window; | |||
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.TextAreaElement; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class OpenModalWindowAndFocusFieldTest extends MultiBrowserTest { | |||
@Test | |||
public void openModalAndFocusField() { | |||
openTestURL(); | |||
$(ButtonElement.class).id("openFocus").click(); | |||
TextAreaElement textArea = $(TextAreaElement.class).first(); | |||
assertElementsEquals(textArea, getActiveElement()); | |||
} | |||
@Test | |||
public void openModal() { | |||
openTestURL(); | |||
$(ButtonElement.class).id("open").click(); | |||
// WindowElement window = $(WindowElement.class).first(); | |||
WebElement windowFocusElement = findElement(By | |||
.xpath("//div[@class='v-window-contents']/div[@class='v-scrollable']")); | |||
assertElementsEquals(windowFocusElement, getActiveElement()); | |||
} | |||
} |
@@ -0,0 +1,94 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.push; | |||
import java.util.concurrent.ExecutorService; | |||
import java.util.concurrent.Executors; | |||
import com.vaadin.annotations.Push; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.shared.communication.PushMode; | |||
import com.vaadin.shared.ui.ui.Transport; | |||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
@Push(value = PushMode.MANUAL, transport = Transport.LONG_POLLING) | |||
public class ManualLongPollingPushUI extends AbstractTestUIWithLog { | |||
ExecutorService executor = Executors.newFixedThreadPool(1); | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
Button b = new Button("Manual push after 1s", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
executor.submit(new Runnable() { | |||
@Override | |||
public void run() { | |||
try { | |||
Thread.sleep(1000); | |||
} catch (InterruptedException e) { | |||
e.printStackTrace(); | |||
} | |||
access(new Runnable() { | |||
@Override | |||
public void run() { | |||
log("Logged after 1s, followed by manual push"); | |||
push(); | |||
} | |||
}); | |||
} | |||
}); | |||
} | |||
}); | |||
addComponent(b); | |||
b = new Button("Double manual push after 1s", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
executor.submit(new Runnable() { | |||
@Override | |||
public void run() { | |||
try { | |||
Thread.sleep(1000); | |||
} catch (InterruptedException e) { | |||
e.printStackTrace(); | |||
} | |||
access(new Runnable() { | |||
@Override | |||
public void run() { | |||
log("First message logged after 1s, followed by manual push"); | |||
push(); | |||
log("Second message logged after 1s, followed by manual push"); | |||
push(); | |||
} | |||
}); | |||
} | |||
}); | |||
} | |||
}); | |||
addComponent(b); | |||
} | |||
} |
@@ -0,0 +1,54 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.push; | |||
import org.junit.Test; | |||
import org.openqa.selenium.WebDriver; | |||
import org.openqa.selenium.support.ui.ExpectedCondition; | |||
import com.vaadin.testbench.elements.ButtonElement; | |||
import com.vaadin.tests.tb3.SingleBrowserTest; | |||
public class ManualLongPollingPushUITest extends SingleBrowserTest { | |||
@Test | |||
public void doubleManualPushDoesNotFreezeApplication() { | |||
openTestURL(); | |||
$(ButtonElement.class).caption("Double manual push after 1s").first() | |||
.click(); | |||
waitUntilLogText("2. Second message logged after 1s, followed by manual push"); | |||
$(ButtonElement.class).caption("Manual push after 1s").first().click(); | |||
waitUntilLogText("3. Logged after 1s, followed by manual push"); | |||
} | |||
private void waitUntilLogText(final String expected) { | |||
waitUntil(new ExpectedCondition<Boolean>() { | |||
private String actual; | |||
@Override | |||
public Boolean apply(WebDriver arg0) { | |||
actual = getLogRow(0); | |||
return expected.equals(actual); | |||
} | |||
@Override | |||
public String toString() { | |||
return String.format("log text to become '%s' (was: '%s')", | |||
expected, actual); | |||
} | |||
}); | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.resources; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import com.vaadin.tests.tb3.SingleBrowserTest; | |||
public class SpecialCharsInThemeResources extends SingleBrowserTest { | |||
@Test | |||
public void loadThemeResource() { | |||
loadResource("/VAADIN/themes/tests-tickets/ordinary.txt"); | |||
checkSource(); | |||
} | |||
@Test | |||
public void loadThemeResourceWithPercentage() { | |||
loadResource("/VAADIN/themes/tests-tickets/percentagein%2520name.txt"); | |||
checkSource(); | |||
} | |||
@Test | |||
public void loadThemeResourceWithSpecialChars() { | |||
loadResource("/VAADIN/themes/tests-tickets/folder%20with%20space/resource%20with%20special%20$chars@.txt"); | |||
checkSource(); | |||
} | |||
private void loadResource(String path) { | |||
getDriver().get(getBaseURL() + path); | |||
} | |||
private void checkSource() { | |||
String source = getDriver().getPageSource(); | |||
Assert.assertTrue("Incorrect contents (was: " + source + ")", | |||
source.contains("Just ordinary contents here")); | |||
} | |||
} |
@@ -50,6 +50,7 @@ import org.openqa.selenium.interactions.Keyboard; | |||
import org.openqa.selenium.interactions.Mouse; | |||
import org.openqa.selenium.interactions.internal.Coordinates; | |||
import org.openqa.selenium.internal.Locatable; | |||
import org.openqa.selenium.internal.WrapsElement; | |||
import org.openqa.selenium.remote.DesiredCapabilities; | |||
import org.openqa.selenium.remote.HttpCommandExecutor; | |||
import org.openqa.selenium.remote.RemoteWebDriver; | |||
@@ -368,8 +369,8 @@ public abstract class AbstractTB3Test extends ParallelTest { | |||
* {@link org.openqa.selenium.JavascriptExecutor#executeScript(String, Object...)} | |||
* returns | |||
*/ | |||
protected Object executeScript(String script) { | |||
return ((JavascriptExecutor) getDriver()).executeScript(script); | |||
protected Object executeScript(String script, Object... args) { | |||
return ((JavascriptExecutor) getDriver()).executeScript(script, args); | |||
} | |||
/** | |||
@@ -1105,4 +1106,93 @@ public abstract class AbstractTB3Test extends ParallelTest { | |||
return isElementPresent(By.className("v-debugwindow")); | |||
} | |||
protected void assertNoHorizontalScrollbar(WebElement element, | |||
String errorMessage) { | |||
// IE rounds clientWidth/clientHeight down and scrollHeight/scrollWidth | |||
// up, so using clientWidth/clientHeight will fail if the element height | |||
// is not an integer | |||
int clientWidth = getClientWidth(element); | |||
int scrollWidth = getScrollWidth(element); | |||
boolean hasScrollbar = scrollWidth > clientWidth; | |||
Assert.assertFalse( | |||
"The element should not have a horizontal scrollbar (scrollWidth: " | |||
+ scrollWidth + ", clientWidth: " + clientWidth + "): " | |||
+ errorMessage, hasScrollbar); | |||
} | |||
protected void assertNoVerticalScrollbar(WebElement element, | |||
String errorMessage) { | |||
// IE rounds clientWidth/clientHeight down and scrollHeight/scrollWidth | |||
// up, so using clientWidth/clientHeight will fail if the element height | |||
// is not an integer | |||
int clientHeight = getClientHeight(element); | |||
int scrollHeight = getScrollHeight(element); | |||
boolean hasScrollbar = scrollHeight > clientHeight; | |||
Assert.assertFalse( | |||
"The element should not have a vertical scrollbar (scrollHeight: " | |||
+ scrollHeight + ", clientHeight: " + clientHeight | |||
+ "): " + errorMessage, hasScrollbar); | |||
} | |||
protected int getScrollHeight(WebElement element) { | |||
return ((Number) executeScript("return arguments[0].scrollHeight;", | |||
element)).intValue(); | |||
} | |||
protected int getScrollWidth(WebElement element) { | |||
return ((Number) executeScript("return arguments[0].scrollWidth;", | |||
element)).intValue(); | |||
} | |||
/** | |||
* Returns client height rounded up instead of as double because of IE9 | |||
* issues: https://dev.vaadin.com/ticket/18469 | |||
*/ | |||
protected int getClientHeight(WebElement e) { | |||
String script; | |||
if (BrowserUtil.isIE8(getDesiredCapabilities())) { | |||
script = "return arguments[0].clientHeight;"; // | |||
} else { | |||
script = "var cs = window.getComputedStyle(arguments[0]);" | |||
+ "return Math.ceil(parseFloat(cs.height)+parseFloat(cs.paddingTop)+parseFloat(cs.paddingBottom));"; | |||
} | |||
return ((Number) executeScript(script, e)).intValue(); | |||
} | |||
/** | |||
* Returns client width rounded up instead of as double because of IE9 | |||
* issues: https://dev.vaadin.com/ticket/18469 | |||
*/ | |||
protected int getClientWidth(WebElement e) { | |||
String script; | |||
if (BrowserUtil.isIE8(getDesiredCapabilities())) { | |||
script = "return arguments[0].clientWidth;"; | |||
} else { | |||
script = "var cs = window.getComputedStyle(arguments[0]);" | |||
+ "var h = parseFloat(cs.width)+parseFloat(cs.paddingLeft)+parseFloat(cs.paddingRight);" | |||
+ "return Math.ceil(h);"; | |||
} | |||
return ((Number) executeScript(script, e)).intValue(); | |||
} | |||
protected void assertElementsEquals(WebElement expectedElement, | |||
WebElement actualElement) { | |||
while (expectedElement instanceof WrapsElement) { | |||
expectedElement = ((WrapsElement) expectedElement) | |||
.getWrappedElement(); | |||
} | |||
while (actualElement instanceof WrapsElement) { | |||
actualElement = ((WrapsElement) actualElement).getWrappedElement(); | |||
} | |||
Assert.assertEquals(expectedElement, actualElement); | |||
} | |||
protected WebElement getActiveElement() { | |||
return (WebElement) executeScript("return document.activeElement;"); | |||
} | |||
} |
@@ -14,6 +14,7 @@ public class WindowElement extends com.vaadin.testbench.elements.WindowElement { | |||
private final String restoreBoxClass = "v-window-restorebox"; | |||
private final String maximizeBoxClass = "v-window-maximizebox"; | |||
private final String closeBoxClass = "v-window-closebox"; | |||
public void restore() { | |||
if (isMaximized()) { | |||
@@ -63,4 +64,13 @@ public class WindowElement extends com.vaadin.testbench.elements.WindowElement { | |||
public String getCaption() { | |||
return findElement(By.className("v-window-header")).getText(); | |||
} | |||
private WebElement getCloseButton() { | |||
return findElement(By.className(closeBoxClass)); | |||
} | |||
public void close() { | |||
getCloseButton().click(); | |||
} | |||
} |