diff options
author | Leif Åstrand <leif@vaadin.com> | 2015-03-23 08:20:23 +0200 |
---|---|---|
committer | Leif Åstrand <leif@vaadin.com> | 2015-03-23 08:20:23 +0200 |
commit | 20d5456c3d5fb825783d7311ebd797c9ae8690f9 (patch) | |
tree | 9401f94b7d84209bdc991c15995512c56e50d03f | |
parent | 16c67cfab9b3dd2dbf324caa612fa3a2d15550d0 (diff) | |
parent | 04272699b8f429a2bc3b8f0a41e20a604213895e (diff) | |
download | vaadin-framework-20d5456c3d5fb825783d7311ebd797c9ae8690f9.tar.gz vaadin-framework-20d5456c3d5fb825783d7311ebd797c9ae8690f9.zip |
Merge remote-tracking branch 'origin/master' into grid-7.5
Change-Id: I53218c269f0701cddd8279bf25c493950144f4cb
25 files changed, 894 insertions, 481 deletions
diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index efae20187e..8c558c9fa1 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -47,8 +47,7 @@ @version-minor@</a></li> <li><a href="#incompatible">Incompatible or Behavior-altering Changes in @version-minor@</a></li> - <li><a href="#knownissues">Known Issues</a></li> - <li><a href="#limitations">Limitations</a></li> + <li><a href="#knownissues">Known Issues and Limitations</a></li> <li><a href="#vaadin">Vaadin Installation</a></li> <li><a href="#package">Package Contents</a></li> <li><a href="#migrating">Migrating from Vaadin 6</a></li> @@ -90,7 +89,7 @@ <h2 id="enhancements">Enhancements in Vaadin @version-minor@</h2> - <p>The @version-minor@ includes many major and minor + <p>Vaadin @version-minor@ includes many major and minor enhancements. Below is a list of the most notable changes:</p> <ul> @@ -137,16 +136,12 @@ <li>Window's accessibility shortcut was moved to server-side. Now setCloseShortcut overrides the default value, while addCloseShortcut can be used to add more than one shortcut key for closing the window. The protected value closeShortcut in Window was removed.</li> </ul> - <h3 id="knownissues">Known Issues</h3> + <h3 id="knownissues">Known Issues and Limitations</h3> <ul> <li>Drag'n'drop in a Table doesn't work on touch devices running Internet Explorer (Windows Phone, Surface) (<a href="http://dev.vaadin.com/ticket/13737">#13737</a>) </li> - </ul> - - <h3 id="limitations">Limitations</h3> - <ul> <li><p>It is currently not possible to specify <tt>font-size</tt> as <tt>em</tt> or <tt>%</tt>, or layout component sizes with <tt>em</tt> (<a @@ -155,17 +150,29 @@ because it results in fractional component sizes in many cases, which might cause unwanted 1px gaps between components.</p> </li> - <li>Push is currently not supported in portals (See <a - href="http://dev.vaadin.com/ticket/11493">#11493</a>) - </li> - <li>HTTP session can not be invalidated while using - push over websockets on Tomcat 7 (<a href="http://dev.vaadin.com/ticket/11721">#11721</a>) - </li> - <li>Cookies are not available while using websockets (<a - href="http://dev.vaadin.com/ticket/11808">#11808</a>) + <li>Up-to-date information about compatibility issues with push functionality is available in + <a href="https://vaadin.com/wiki/-/wiki/Main/Working+around+push+issues">this wiki page.</a> + <br /> + The most prominent limitations are: + <ul> + <li>HTTP proxies can prevent push requests from working + properly. To mitigate the issues, avoid using streaming + and configure your proxy so it allows response headers + to pass through before the whole response is received. + <a href="http://dev.vaadin.com/ticket/17075">#17075</a> + should make long-polling work seamlessly with all proxies. + </li> + <li>HTTP session can not be invalidated while using + push over websockets on Tomcat 7 (<a href="http://dev.vaadin.com/ticket/11721">#11721</a>) + </li> + <li>Cookies are not available while using websockets (<a + href="http://dev.vaadin.com/ticket/11808">#11808</a>) + </li> + <li>Push is currently not supported in portals (See <a + href="http://dev.vaadin.com/ticket/11493">#11493</a>) + </li> + </ul> </li> - <li>Not all proxies are compatible with websockets or streaming. - Use long polling to avoid these problems.</li> </ul> <h2 id="vaadin">Vaadin Installation</h2> diff --git a/client/src/com/vaadin/client/VTooltip.java b/client/src/com/vaadin/client/VTooltip.java index a9406935dc..453563370c 100644 --- a/client/src/com/vaadin/client/VTooltip.java +++ b/client/src/com/vaadin/client/VTooltip.java @@ -20,7 +20,17 @@ import com.google.gwt.aria.client.RelevantValue; import com.google.gwt.aria.client.Roles; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Display; -import com.google.gwt.event.dom.client.*; +import com.google.gwt.event.dom.client.BlurEvent; +import com.google.gwt.event.dom.client.BlurHandler; +import com.google.gwt.event.dom.client.DomEvent; +import com.google.gwt.event.dom.client.FocusEvent; +import com.google.gwt.event.dom.client.FocusHandler; +import com.google.gwt.event.dom.client.KeyDownEvent; +import com.google.gwt.event.dom.client.KeyDownHandler; +import com.google.gwt.event.dom.client.MouseDownEvent; +import com.google.gwt.event.dom.client.MouseDownHandler; +import com.google.gwt.event.dom.client.MouseMoveEvent; +import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Timer; @@ -378,8 +388,7 @@ public class VTooltip extends VOverlay { } private class TooltipEventHandler implements MouseMoveHandler, - KeyDownHandler, FocusHandler, BlurHandler, MouseDownHandler, - MouseUpHandler, TouchStartHandler { + KeyDownHandler, FocusHandler, BlurHandler, MouseDownHandler { /** * Current element hovered @@ -392,11 +401,6 @@ public class VTooltip extends VOverlay { private boolean handledByFocus; /** - * Indicates whether the tooltip is being called after a touch event. - */ - private boolean touchInitiated = false; - - /** * Locate the tooltip for given element * * @param element @@ -446,19 +450,7 @@ public class VTooltip extends VOverlay { @Override public void onMouseMove(MouseMoveEvent mme) { - if (!touchInitiated) { - handleShowHide(mme, false); - } - } - - @Override - public void onMouseUp(MouseUpEvent event) { - touchInitiated = false; - } - - @Override - public void onTouchStart(TouchStartEvent te) { - touchInitiated = true; + handleShowHide(mme, false); } @Override @@ -558,11 +550,9 @@ public class VTooltip extends VOverlay { Profiler.enter("VTooltip.connectHandlersToWidget"); widget.addDomHandler(tooltipEventHandler, MouseMoveEvent.getType()); widget.addDomHandler(tooltipEventHandler, MouseDownEvent.getType()); - widget.addDomHandler(tooltipEventHandler, MouseUpEvent.getType()); widget.addDomHandler(tooltipEventHandler, KeyDownEvent.getType()); widget.addDomHandler(tooltipEventHandler, FocusEvent.getType()); widget.addDomHandler(tooltipEventHandler, BlurEvent.getType()); - widget.addDomHandler(tooltipEventHandler, TouchStartEvent.getType()); Profiler.leave("VTooltip.connectHandlersToWidget"); } diff --git a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java index 46ad289488..24a0438476 100644 --- a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java +++ b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java @@ -35,7 +35,6 @@ import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.metadata.NoDataException; import com.vaadin.client.metadata.Type; import com.vaadin.client.metadata.TypeData; -import com.vaadin.client.ui.datefield.PopupDateFieldConnector; import com.vaadin.client.ui.ui.UIConnector; import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.ComponentConstants; @@ -404,7 +403,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector * updated in another widget in addition to the one returned by the * <code>Connector</code>'s {@link #getWidget()}, or if the prefix should be * different. For example see - * {@link PopupDateFieldConnector#setWidgetStyleNameWithPrefix(String, String, boolean)} + * {@link com.vaadin.client.ui.datefield.DateFieldConnector#setWidgetStyleNameWithPrefix(String, String, boolean)} * </p> * * @param styleName diff --git a/client/src/com/vaadin/client/ui/datefield/DateFieldConnector.java b/client/src/com/vaadin/client/ui/datefield/DateFieldConnector.java new file mode 100644 index 0000000000..042b8db8e2 --- /dev/null +++ b/client/src/com/vaadin/client/ui/datefield/DateFieldConnector.java @@ -0,0 +1,219 @@ +/* + * 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.client.ui.datefield; + +import java.util.Date; + +import com.google.gwt.event.logical.shared.CloseEvent; +import com.google.gwt.event.logical.shared.CloseHandler; +import com.google.gwt.user.client.ui.PopupPanel; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.DateTimeService; +import com.vaadin.client.UIDL; +import com.vaadin.client.communication.StateChangeEvent; +import com.vaadin.client.ui.VCalendarPanel.FocusChangeListener; +import com.vaadin.client.ui.VCalendarPanel.TimeChangeListener; +import com.vaadin.client.ui.VPopupCalendar; +import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.datefield.PopupDateFieldState; +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.ui.DateField; +import com.vaadin.ui.PopupDateField; + +@Connect(DateField.class) +public class DateFieldConnector extends TextualDateConnector { + + /* + * (non-Javadoc) + * + * @see com.vaadin.client.ui.AbstractConnector#init() + */ + @Override + protected void init() { + getWidget().popup.addCloseHandler(new CloseHandler<PopupPanel>() { + + @Override + public void onClose(CloseEvent<PopupPanel> event) { + /* + * FIXME This is a hack so we do not have to rewrite half of the + * datefield so values are not sent while selecting a date + * (#6252). + * + * The datefield will now only set the date UIDL variables while + * the user is selecting year/month/date/time and not send them + * directly. Only when the user closes the popup (by clicking on + * a day/enter/clicking outside of popup) then the new value is + * communicated to the server. + */ + if (getWidget().isImmediate()) { + getConnection().sendPendingVariableChanges(); + } + } + }); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.client.ui.VTextualDate#updateFromUIDL(com.vaadin + * .client.UIDL, com.vaadin.client.ApplicationConnection) + */ + @Override + @SuppressWarnings("deprecation") + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + + String oldLocale = getWidget().getCurrentLocale(); + + getWidget().parsable = uidl.getBooleanAttribute("parsable"); + + super.updateFromUIDL(uidl, client); + + getWidget().calendar.setDateTimeService(getWidget() + .getDateTimeService()); + getWidget().calendar.setShowISOWeekNumbers(getWidget() + .isShowISOWeekNumbers()); + if (getWidget().calendar.getResolution() != getWidget() + .getCurrentResolution()) { + boolean hasSelectedDate = false; + getWidget().calendar.setResolution(getWidget() + .getCurrentResolution()); + if (getWidget().calendar.getDate() != null + && getWidget().getCurrentDate() != null) { + hasSelectedDate = true; + getWidget().calendar.setDate((Date) getWidget() + .getCurrentDate().clone()); + } + // force re-render when changing resolution only + getWidget().calendar.renderCalendar(hasSelectedDate); + } + + // Force re-render of calendar if locale has changed (#12153) + if (!getWidget().getCurrentLocale().equals(oldLocale)) { + getWidget().calendar.renderCalendar(); + } + + if (getWidget().getCurrentResolution().getCalendarField() <= Resolution.MONTH + .getCalendarField()) { + getWidget().calendar + .setFocusChangeListener(new FocusChangeListener() { + @Override + public void focusChanged(Date date) { + + getWidget().updateValue(date); + getWidget().buildDate(); + Date date2 = getWidget().calendar.getDate(); + date2.setYear(date.getYear()); + date2.setMonth(date.getMonth()); + } + }); + } else { + getWidget().calendar.setFocusChangeListener(null); + } + + if (getWidget().getCurrentResolution().getCalendarField() > Resolution.DAY + .getCalendarField()) { + getWidget().calendar + .setTimeChangeListener(new TimeChangeListener() { + @Override + public void changed(int hour, int min, int sec, int msec) { + Date d = getWidget().getDate(); + if (d == null) { + // date currently null, use the value from + // calendarPanel + // (~ client time at the init of the widget) + d = (Date) getWidget().calendar.getDate() + .clone(); + } + d.setHours(hour); + d.setMinutes(min); + d.setSeconds(sec); + DateTimeService.setMilliseconds(d, msec); + + // Always update time changes to the server + getWidget().updateValue(d); + + // Update text field + getWidget().buildDate(); + } + }); + } + + if (getWidget().isReadonly()) { + getWidget().calendarToggle.addStyleName(VPopupCalendar.CLASSNAME + + "-button-readonly"); + } else { + getWidget().calendarToggle.removeStyleName(VPopupCalendar.CLASSNAME + + "-button-readonly"); + } + + getWidget().setDescriptionForAssistiveDevices( + getState().descriptionForAssistiveDevices); + + getWidget().setTextFieldTabIndex(); + } + + @Override + public VPopupCalendar getWidget() { + return (VPopupCalendar) super.getWidget(); + } + + @Override + public PopupDateFieldState getState() { + return (PopupDateFieldState) super.getState(); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + getWidget().setTextFieldEnabled(getState().textFieldEnabled); + getWidget().setRangeStart(nullSafeDateClone(getState().rangeStart)); + getWidget().setRangeEnd(nullSafeDateClone(getState().rangeEnd)); + } + + private Date nullSafeDateClone(Date date) { + if (date == null) { + return null; + } else { + return (Date) date.clone(); + } + } + + @Override + protected void setWidgetStyleName(String styleName, boolean add) { + super.setWidgetStyleName(styleName, add); + + // update the style change to popup calendar widget + getWidget().popup.setStyleName(styleName, add); + } + + @Override + protected void setWidgetStyleNameWithPrefix(String prefix, + String styleName, boolean add) { + super.setWidgetStyleNameWithPrefix(prefix, styleName, add); + + // update the style change to popup calendar widget with the correct + // prefix + if (!styleName.startsWith("-")) { + getWidget().popup.setStyleName(getWidget().getStylePrimaryName() + + "-popup-" + styleName, add); + } else { + getWidget().popup.setStyleName(getWidget().getStylePrimaryName() + + "-popup" + styleName, add); + } + } + +} diff --git a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java index 7bcaaba04e..31232177d3 100644 --- a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java +++ b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java @@ -1,12 +1,12 @@ /* * 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 @@ -16,203 +16,10 @@ package com.vaadin.client.ui.datefield; -import java.util.Date; - -import com.google.gwt.event.logical.shared.CloseEvent; -import com.google.gwt.event.logical.shared.CloseHandler; -import com.google.gwt.user.client.ui.PopupPanel; -import com.vaadin.client.ApplicationConnection; -import com.vaadin.client.DateTimeService; -import com.vaadin.client.UIDL; -import com.vaadin.client.communication.StateChangeEvent; -import com.vaadin.client.ui.VCalendarPanel.FocusChangeListener; -import com.vaadin.client.ui.VCalendarPanel.TimeChangeListener; -import com.vaadin.client.ui.VPopupCalendar; import com.vaadin.shared.ui.Connect; -import com.vaadin.shared.ui.datefield.PopupDateFieldState; -import com.vaadin.shared.ui.datefield.Resolution; -import com.vaadin.ui.DateField; - -@Connect(DateField.class) -public class PopupDateFieldConnector extends TextualDateConnector { - - /* - * (non-Javadoc) - * - * @see com.vaadin.client.ui.AbstractConnector#init() - */ - @Override - protected void init() { - getWidget().popup.addCloseHandler(new CloseHandler<PopupPanel>() { - - @Override - public void onClose(CloseEvent<PopupPanel> event) { - /* - * FIXME This is a hack so we do not have to rewrite half of the - * datefield so values are not sent while selecting a date - * (#6252). - * - * The datefield will now only set the date UIDL variables while - * the user is selecting year/month/date/time and not send them - * directly. Only when the user closes the popup (by clicking on - * a day/enter/clicking outside of popup) then the new value is - * communicated to the server. - */ - if (getWidget().isImmediate()) { - getConnection().sendPendingVariableChanges(); - } - } - }); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.client.ui.VTextualDate#updateFromUIDL(com.vaadin - * .client.UIDL, com.vaadin.client.ApplicationConnection) - */ - @Override - @SuppressWarnings("deprecation") - public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - - String oldLocale = getWidget().getCurrentLocale(); - - getWidget().parsable = uidl.getBooleanAttribute("parsable"); - - super.updateFromUIDL(uidl, client); - - getWidget().calendar.setDateTimeService(getWidget() - .getDateTimeService()); - getWidget().calendar.setShowISOWeekNumbers(getWidget() - .isShowISOWeekNumbers()); - if (getWidget().calendar.getResolution() != getWidget() - .getCurrentResolution()) { - boolean hasSelectedDate = false; - getWidget().calendar.setResolution(getWidget() - .getCurrentResolution()); - if (getWidget().calendar.getDate() != null - && getWidget().getCurrentDate() != null) { - hasSelectedDate = true; - getWidget().calendar.setDate((Date) getWidget() - .getCurrentDate().clone()); - } - // force re-render when changing resolution only - getWidget().calendar.renderCalendar(hasSelectedDate); - } - - // Force re-render of calendar if locale has changed (#12153) - if (!getWidget().getCurrentLocale().equals(oldLocale)) { - getWidget().calendar.renderCalendar(); - } - - if (getWidget().getCurrentResolution().getCalendarField() <= Resolution.MONTH - .getCalendarField()) { - getWidget().calendar - .setFocusChangeListener(new FocusChangeListener() { - @Override - public void focusChanged(Date date) { - - getWidget().updateValue(date); - getWidget().buildDate(); - Date date2 = getWidget().calendar.getDate(); - date2.setYear(date.getYear()); - date2.setMonth(date.getMonth()); - } - }); - } else { - getWidget().calendar.setFocusChangeListener(null); - } - - if (getWidget().getCurrentResolution().getCalendarField() > Resolution.DAY - .getCalendarField()) { - getWidget().calendar - .setTimeChangeListener(new TimeChangeListener() { - @Override - public void changed(int hour, int min, int sec, int msec) { - Date d = getWidget().getDate(); - if (d == null) { - // date currently null, use the value from - // calendarPanel - // (~ client time at the init of the widget) - d = (Date) getWidget().calendar.getDate() - .clone(); - } - d.setHours(hour); - d.setMinutes(min); - d.setSeconds(sec); - DateTimeService.setMilliseconds(d, msec); - - // Always update time changes to the server - getWidget().updateValue(d); - - // Update text field - getWidget().buildDate(); - } - }); - } - - if (getWidget().isReadonly()) { - getWidget().calendarToggle.addStyleName(VPopupCalendar.CLASSNAME - + "-button-readonly"); - } else { - getWidget().calendarToggle.removeStyleName(VPopupCalendar.CLASSNAME - + "-button-readonly"); - } - - getWidget().setDescriptionForAssistiveDevices( - getState().descriptionForAssistiveDevices); - - getWidget().setTextFieldTabIndex(); - } - - @Override - public VPopupCalendar getWidget() { - return (VPopupCalendar) super.getWidget(); - } - - @Override - public PopupDateFieldState getState() { - return (PopupDateFieldState) super.getState(); - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - getWidget().setTextFieldEnabled(getState().textFieldEnabled); - getWidget().setRangeStart(nullSafeDateClone(getState().rangeStart)); - getWidget().setRangeEnd(nullSafeDateClone(getState().rangeEnd)); - } - - private Date nullSafeDateClone(Date date) { - if (date == null) { - return null; - } else { - return (Date) date.clone(); - } - } - - @Override - protected void setWidgetStyleName(String styleName, boolean add) { - super.setWidgetStyleName(styleName, add); - - // update the style change to popup calendar widget - getWidget().popup.setStyleName(styleName, add); - } - - @Override - protected void setWidgetStyleNameWithPrefix(String prefix, - String styleName, boolean add) { - super.setWidgetStyleNameWithPrefix(prefix, styleName, add); +import com.vaadin.ui.PopupDateField; - // update the style change to popup calendar widget with the correct - // prefix - if (!styleName.startsWith("-")) { - getWidget().popup.setStyleName(getWidget().getStylePrimaryName() - + "-popup-" + styleName, add); - } else { - getWidget().popup.setStyleName(getWidget().getStylePrimaryName() - + "-popup" + styleName, add); - } - } +@Connect(PopupDateField.class) +public class PopupDateFieldConnector extends DateFieldConnector { } diff --git a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java index 616667c367..b97cf73989 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java @@ -22,12 +22,9 @@ import com.google.gwt.aria.client.Roles; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; -import com.google.gwt.event.dom.client.BlurEvent; -import com.google.gwt.event.dom.client.BlurHandler; -import com.google.gwt.event.dom.client.FocusEvent; -import com.google.gwt.event.dom.client.FocusHandler; -import com.google.gwt.event.shared.HandlerRegistration; -import com.google.gwt.user.client.*; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.BrowserInfo; @@ -47,7 +44,6 @@ import com.vaadin.shared.ui.AlignmentInfo; public final class Slot extends SimplePanel { private static final String ALIGN_CLASS_PREFIX = "v-align-"; - private static final int TOUCH_ERROR_MESSAGE_HIDE_DELAY = 200; private final VAbstractOrderedLayout layout; @@ -59,13 +55,8 @@ public final class Slot extends SimplePanel { private Element captionText; private Icon icon; private Element errorIcon; - private Element errorMessage; private Element requiredIcon; - private HandlerRegistration focusRegistration; - private HandlerRegistration blurRegistration; - private boolean labelClicked = false; - private ElementResizeListener captionResizeListener; private ElementResizeListener widgetResizeListener; @@ -591,21 +582,9 @@ public final class Slot extends SimplePanel { errorIcon.setClassName("v-errorindicator"); } caption.appendChild(errorIcon); - - if(BrowserInfo.get().isTouchDevice()) { - addFocusHandlerToWidget(error, widget); - addBlurHandlerToWidget(widget); - } - - } else { - if (errorIcon != null) { - errorIcon.removeFromParent(); - errorIcon = null; - } - - if (errorMessage != null) { - removeErrorMessageAndHandlers(); - } + } else if (errorIcon != null) { + errorIcon.removeFromParent(); + errorIcon = null; } if (caption != null) { @@ -672,81 +651,6 @@ public final class Slot extends SimplePanel { } } - private void removeErrorMessageAndHandlers() { - errorMessage.removeFromParent(); - errorMessage = null; - - if (focusRegistration != null) { - focusRegistration.removeHandler(); - focusRegistration = null; - } - - if(blurRegistration != null) { - blurRegistration.removeHandler(); - blurRegistration = null; - } - } - - private void addFocusHandlerToWidget(final String error, Widget widget) { - focusRegistration = widget.addHandler(new FocusHandler() { - @Override - public void onFocus(FocusEvent event) { - if(labelClicked) { - labelClicked = false; - return; - } - if (errorMessage == null) { - errorMessage = DOM.createDiv(); - errorMessage.setClassName("v-touch-error-message"); - } - errorMessage.setInnerHTML(error); - captionWrap.appendChild(errorMessage); - } - }, FocusEvent.getType()); - } - - private void addBlurHandlerToWidget(final Widget widget) { - blurRegistration = widget.addHandler(new BlurHandler() { - @Override - public void onBlur(BlurEvent event) { - if(errorMessage != null) { - addClickHandlerToErrorMessage(widget); - } - scheduleErrorMessageHide(TOUCH_ERROR_MESSAGE_HIDE_DELAY); - } - }, BlurEvent.getType()); - } - - private void scheduleErrorMessageHide(int delay) { - //Delaying hiding to allow error message click handler - //do his job and return the focus back if error message was tapped - Timer hideTimer = new Timer() { - @Override - public void run() { - if(errorMessage != null) { - errorMessage.removeFromParent(); - errorMessage = null; - } - } - }; - hideTimer.schedule(delay); - } - - private void addClickHandlerToErrorMessage(final Widget widget) { - Event.sinkEvents(errorMessage, Event.ONCLICK); - Event.setEventListener(errorMessage, new EventListener() { - @Override - public void onBrowserEvent(Event event) { - if(Event.ONCLICK == event.getTypeInt()) { - errorMessage.removeFromParent(); - errorMessage = null; - labelClicked = true; - widget.getElement().focus(); - } - } - }); - } - /** * Does the slot have a caption */ diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index 9e1da113bf..804ad45f92 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -847,6 +847,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector /** * Loads the new theme and removes references to the old theme * + * @since 7.4.3 * @param oldTheme * The name of the old theme * @param newTheme @@ -856,7 +857,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector * @param newThemeUrl * The url of the new theme */ - private void replaceTheme(final String oldTheme, final String newTheme, + protected void replaceTheme(final String oldTheme, final String newTheme, String oldThemeUrl, final String newThemeUrl) { LinkElement tagToReplace = null; @@ -961,10 +962,11 @@ public class UIConnector extends AbstractSingleComponentContainerConnector * Activates the new theme. Assumes the theme has been loaded and taken into * use in the browser. * - * @since 7.3 + * @since 7.4.3 * @param newTheme + * The name of the new theme */ - private void activateTheme(String newTheme) { + protected void activateTheme(String newTheme) { if (activeTheme != null) { getWidget().getParent().removeStyleName(activeTheme); VOverlay.getOverlayContainer(getConnection()).removeClassName( diff --git a/eclipse/Super Development Mode (vaadin).launch b/eclipse/Super Development Mode (vaadin).launch index 9f4da19a74..361a456e96 100644 --- a/eclipse/Super Development Mode (vaadin).launch +++ b/eclipse/Super Development Mode (vaadin).launch @@ -21,7 +21,7 @@ </listAttribute> <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> <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 -bindAddress 0.0.0.0 com.vaadin.DefaultWidgetSet com.vaadin.tests.widgetset.TestingWidgetSet"/> +<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"/> </launchConfiguration> diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java index c570d22086..ea937d279e 100644 --- a/server/src/com/vaadin/server/communication/PushHandler.java +++ b/server/src/com/vaadin/server/communication/PushHandler.java @@ -356,9 +356,13 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { "Could not get session. This should never happen", e); return; } catch (SessionExpiredException e) { + // This happens at least if the server is restarted without + // preserving the session. After restart the client reconnects, gets + // a session expired notification and then closes the connection and + // ends up here getLogger() - .log(Level.SEVERE, - "Session expired before push was disconnected. This should never happen", + .log(Level.FINER, + "Session expired before push disconnect event was received", e); return; } @@ -383,9 +387,9 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { if (ui == null) { getLogger() - .log(Level.SEVERE, + .log(Level.FINE, "Could not get UI. This should never happen," - + " except when reloading in Firefox -" + + " except when reloading in Firefox and Chrome -" + " see http://dev.vaadin.com/ticket/14251."); return; } else { diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/com/vaadin/ui/Slider.java index fab6e33cae..99e1e8d5e9 100644 --- a/server/src/com/vaadin/ui/Slider.java +++ b/server/src/com/vaadin/ui/Slider.java @@ -343,4 +343,14 @@ public class Slider extends AbstractField<Double> { return Double.class; } + @Override + public void clear() { + super.setValue(Double.valueOf(getState().minValue)); + } + + @Override + public boolean isEmpty() { + // Slider is never really "empty" + return false; + } } diff --git a/server/src/com/vaadin/ui/declarative/DesignFormatter.java b/server/src/com/vaadin/ui/declarative/DesignFormatter.java index d2fbf2c765..728b3d1077 100644 --- a/server/src/com/vaadin/ui/declarative/DesignFormatter.java +++ b/server/src/com/vaadin/ui/declarative/DesignFormatter.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; import java.util.Collections; import java.util.Date; import java.util.Locale; @@ -28,6 +29,7 @@ import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import com.vaadin.data.util.converter.Converter; +import com.vaadin.data.util.converter.StringToBigDecimalConverter; import com.vaadin.data.util.converter.StringToDoubleConverter; import com.vaadin.data.util.converter.StringToFloatConverter; import com.vaadin.event.ShortcutAction; @@ -67,8 +69,8 @@ public class DesignFormatter implements Serializable { */ protected void mapDefaultTypes() { // numbers use standard toString/valueOf approach - for (Class<?> c : new Class<?>[] { Integer.class, Byte.class, - Short.class, Long.class, BigDecimal.class }) { + for (Class<?> c : new Class<?>[] { Byte.class, Short.class, + Integer.class, Long.class }) { DesignToStringConverter<?> conv = new DesignToStringConverter(c); converterMap.put(c, conv); try { @@ -110,21 +112,37 @@ public class DesignFormatter implements Serializable { converterMap.put(boolean.class, booleanConverter); // floats and doubles use formatters - DecimalFormatSymbols symbols = new DecimalFormatSymbols(new Locale( - "en_US")); + final DecimalFormatSymbols symbols = new DecimalFormatSymbols( + new Locale("en_US")); final DecimalFormat fmt = new DecimalFormat("0.###", symbols); fmt.setGroupingUsed(false); - converterMap.put(Float.class, new StringToFloatConverter() { + + Converter<String, ?> floatConverter = new StringToFloatConverter() { @Override - protected java.text.NumberFormat getFormat(Locale locale) { + protected NumberFormat getFormat(Locale locale) { return fmt; }; - }); - converterMap.put(Double.class, new StringToDoubleConverter() { + }; + converterMap.put(Float.class, floatConverter); + converterMap.put(float.class, floatConverter); + + Converter<String, ?> doubleConverter = new StringToDoubleConverter() { @Override - protected java.text.NumberFormat getFormat(Locale locale) { + protected NumberFormat getFormat(Locale locale) { return fmt; }; + }; + converterMap.put(Double.class, doubleConverter); + converterMap.put(double.class, doubleConverter); + + final DecimalFormat bigDecimalFmt = new DecimalFormat("0.###", symbols); + bigDecimalFmt.setGroupingUsed(false); + bigDecimalFmt.setParseBigDecimal(true); + converterMap.put(BigDecimal.class, new StringToBigDecimalConverter() { + @Override + protected NumberFormat getFormat(Locale locale) { + return bigDecimalFmt; + }; }); // strings do nothing @@ -169,7 +187,7 @@ public class DesignFormatter implements Serializable { }; converterMap.put(Character.class, charConverter); - converterMap.put(Character.TYPE, charConverter); + converterMap.put(char.class, charConverter); converterMap.put(Date.class, new DesignDateConverter()); converterMap.put(ShortcutAction.class, diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignToStringConverter.java b/server/src/com/vaadin/ui/declarative/converters/DesignToStringConverter.java index d80119bea1..0c6cf55bed 100644 --- a/server/src/com/vaadin/ui/declarative/converters/DesignToStringConverter.java +++ b/server/src/com/vaadin/ui/declarative/converters/DesignToStringConverter.java @@ -64,7 +64,8 @@ public class DesignToStringConverter<TYPE> implements Converter<String, TYPE> { * must be public and static method that returns an object of * passed type. */ - public DesignToStringConverter(Class<? extends TYPE> type, String staticMethodName) { + public DesignToStringConverter(Class<? extends TYPE> type, + String staticMethodName) { this.type = type; this.staticMethodName = staticMethodName; } @@ -81,7 +82,7 @@ public class DesignToStringConverter<TYPE> implements Converter<String, TYPE> { } catch (IllegalArgumentException e) { throw new Converter.ConversionException(e); } catch (InvocationTargetException e) { - throw new Converter.ConversionException(e); + throw new Converter.ConversionException(e.getCause()); } catch (NoSuchMethodException e) { throw new Converter.ConversionException(e); } catch (SecurityException e) { diff --git a/server/tests/src/com/vaadin/tests/design/DesignFormatterTest.java b/server/tests/src/com/vaadin/tests/design/DesignFormatterTest.java index c7909751a1..05b2484767 100644 --- a/server/tests/src/com/vaadin/tests/design/DesignFormatterTest.java +++ b/server/tests/src/com/vaadin/tests/design/DesignFormatterTest.java @@ -18,6 +18,7 @@ package com.vaadin.tests.design; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashSet; @@ -53,17 +54,127 @@ public class DesignFormatterTest { @Test public void testSupportedClasses() { - for (Class<?> type : new Class<?>[] { String.class, Boolean.class, - Integer.class, Float.class, Byte.class, Short.class, - Double.class, ShortcutAction.class, Date.class, - FileResource.class, ExternalResource.class, - ThemeResource.class, Resource.class, TimeZone.class }) { + for (Class<?> type : new Class<?>[] { boolean.class, char.class, + byte.class, short.class, int.class, long.class, float.class, + double.class, Boolean.class, Character.class, Byte.class, + Short.class, Integer.class, Long.class, Float.class, + Double.class, BigDecimal.class, String.class, + ShortcutAction.class, Date.class, FileResource.class, + ExternalResource.class, ThemeResource.class, Resource.class, + TimeZone.class }) { assertTrue("not supported " + type.getSimpleName(), formatter.canConvert(type)); } } @Test + public void testBoolean() { + assertEquals("true", formatter.format(true)); + assertEquals("false", formatter.format(false)); + + assertEquals(true, formatter.parse("true", boolean.class)); + assertEquals(true, formatter.parse("foobar", boolean.class)); + assertEquals(true, formatter.parse("", boolean.class)); + assertEquals(false, formatter.parse("false", boolean.class)); + + assertEquals(true, formatter.parse("true", Boolean.class)); + assertEquals(true, formatter.parse("foobar", Boolean.class)); + assertEquals(true, formatter.parse("", Boolean.class)); + assertEquals(false, formatter.parse("false", Boolean.class)); + } + + @Test + public void testIntegral() { + byte b = 123; + assertEquals("123", formatter.format(b)); + assertEquals(b, (byte) formatter.parse("123", byte.class)); + assertEquals((Byte) b, formatter.parse("123", Byte.class)); + + b = -123; + assertEquals("-123", formatter.format(b)); + assertEquals(b, (byte) formatter.parse("-123", byte.class)); + assertEquals((Byte) b, formatter.parse("-123", Byte.class)); + + short s = 12345; + assertEquals("12345", formatter.format(s)); + assertEquals(s, (short) formatter.parse("12345", short.class)); + assertEquals((Short) s, formatter.parse("12345", Short.class)); + + s = -12345; + assertEquals("-12345", formatter.format(s)); + assertEquals(s, (short) formatter.parse("-12345", short.class)); + assertEquals((Short) s, formatter.parse("-12345", Short.class)); + + int i = 123456789; + assertEquals("123456789", formatter.format(i)); + assertEquals(i, (int) formatter.parse("123456789", int.class)); + assertEquals((Integer) i, formatter.parse("123456789", Integer.class)); + + i = -123456789; + assertEquals("-123456789", formatter.format(i)); + assertEquals(i, (int) formatter.parse("-123456789", int.class)); + assertEquals((Integer) i, formatter.parse("-123456789", Integer.class)); + + long l = 123456789123456789L; + assertEquals("123456789123456789", formatter.format(l)); + assertEquals(l, + (long) formatter.parse("123456789123456789", long.class)); + assertEquals((Long) l, + formatter.parse("123456789123456789", Long.class)); + + l = -123456789123456789L; + assertEquals("-123456789123456789", formatter.format(l)); + assertEquals(l, + (long) formatter.parse("-123456789123456789", long.class)); + assertEquals((Long) l, + formatter.parse("-123456789123456789", Long.class)); + } + + @Test + public void testFloatingPoint() { + float f = 123.4567f; + assertEquals("123.457", formatter.format(f)); + assertEquals(f, formatter.parse("123.4567", float.class), 1e-4); + assertEquals(f, formatter.parse("123.4567", Float.class), 1e-4); + + double d = 123456789.123456789; + assertEquals("123456789.123", formatter.format(d)); + assertEquals(d, formatter.parse("123456789.123456789", double.class), + 1e-9); + assertEquals(d, formatter.parse("123456789.123456789", Double.class), + 1e-9); + + } + + @Test + public void testBigDecimal() { + BigDecimal bd = new BigDecimal("123456789123456789.123456789123456789"); + assertEquals("123456789123456789.123", formatter.format(bd)); + assertEquals(bd, formatter.parse( + "123456789123456789.123456789123456789", BigDecimal.class)); + } + + @Test + public void testChar() { + char c = '\uABCD'; + assertEquals("\uABCD", formatter.format(c)); + assertEquals(c, (char) formatter.parse("\uABCD", char.class)); + assertEquals((Character) c, formatter.parse("\uABCD", Character.class)); + + c = 'y'; + assertEquals(c, (char) formatter.parse("yes", char.class)); + } + + @Test + public void testString() { + + for (String s : new String[] { "", "foobar", "\uABCD", "驯鹿" }) { + assertEquals(s, formatter.format(s)); + assertEquals(s, formatter.parse(s, String.class)); + } + } + + @Test public void testDate() throws Exception { Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2012-02-17"); String formatted = formatter.format(date); diff --git a/server/tests/src/com/vaadin/tests/server/component/FieldDefaultValues.java b/server/tests/src/com/vaadin/tests/server/component/FieldDefaultValues.java new file mode 100644 index 0000000000..5c9993e6dd --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/FieldDefaultValues.java @@ -0,0 +1,84 @@ +/* + * 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.server.component; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.VaadinClasses; +import com.vaadin.ui.Field; +import com.vaadin.ui.PasswordField; +import com.vaadin.ui.ProgressBar; +import com.vaadin.ui.RichTextArea; +import com.vaadin.ui.Slider; +import com.vaadin.ui.TextArea; + +public class FieldDefaultValues { + + @Test + public void testFieldsHaveDefaultValueAfterClear() throws Exception { + for (Field<?> field : createFields()) { + Object originalValue = field.getValue(); + + // Some fields are not initialized to the "empty" value. #17089 + if (field instanceof PasswordField || field instanceof ProgressBar + || field instanceof RichTextArea + || field instanceof TextArea) { + originalValue = null; + } + + field.clear(); + + Object clearedValue = field.getValue(); + + Assert.assertEquals("Expected to get default value after clearing " + + field.getClass().getName(), originalValue, clearedValue); + } + } + + @Test + public void testFieldsAreEmptyAfterClear() throws Exception { + for (Field<?> field : createFields()) { + field.clear(); + + if (field instanceof Slider) { + Assert.assertFalse( + "Slider should not be empty even after being cleared", + field.isEmpty()); + + } else { + Assert.assertTrue(field.getClass().getName() + + " should be empty after being cleared", + field.isEmpty()); + } + } + } + + @SuppressWarnings("rawtypes") + private static List<Field<?>> createFields() throws InstantiationException, + IllegalAccessException { + List<Field<?>> fieldInstances = new ArrayList<Field<?>>(); + + for (Class<? extends Field> fieldType : VaadinClasses.getFields()) { + fieldInstances.add(fieldType.newInstance()); + } + return fieldInstances; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/TouchDevicesTooltip.java b/uitest/src/com/vaadin/tests/components/TouchDevicesTooltip.java deleted file mode 100644 index 1a3b4cdda5..0000000000 --- a/uitest/src/com/vaadin/tests/components/TouchDevicesTooltip.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.vaadin.tests.components; - -import com.vaadin.data.util.converter.StringToIntegerConverter; -import com.vaadin.data.validator.IntegerRangeValidator; -import com.vaadin.server.VaadinRequest; -import com.vaadin.ui.Label; -import com.vaadin.ui.TextField; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; - -public class TouchDevicesTooltip extends AbstractTestUI { - - @Override - protected void setup(VaadinRequest request) { - final Label errorLabel = new Label("No error"); - addComponent(errorLabel); - - TextField textField = new TextField("Value"); - textField.setConverter(new StringToIntegerConverter()); - textField.addValidator(new IntegerRangeValidator("incorrect value", 0, 100)); - textField.setImmediate(true); - textField.setValue("-5"); - addComponent(textField); - - TextField textField2 = new TextField("Value2"); - textField2.setConverter(new StringToIntegerConverter()); - textField2.addValidator(new IntegerRangeValidator("incorrect value2", 0, 100)); - textField2.setImmediate(true); - textField2.setValue("-5"); - addComponent(textField2); - } - - public static class Bean { - @NotNull - @Min(0) - private Integer value; - - public Integer getValue() { - return value; - } - - public void setValue(Integer value) { - this.value = value; - } - } - - @Override - protected Integer getTicketNumber() { - return 15353; - } - - @Override - public String getDescription() { - return "Displaying error message in slot for touch devices"; - } -} diff --git a/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldConnector.java b/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldConnector.java new file mode 100644 index 0000000000..5cdc8f1396 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldConnector.java @@ -0,0 +1,24 @@ +package com.vaadin.tests.components.datefield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.DateField; +import com.vaadin.ui.PopupDateField; + +public class PopupDateFieldConnector extends AbstractTestUI { + @Override + protected void setup(VaadinRequest request) { + addComponent(new PopupDateField()); + addComponent(new DateField()); + } + + @Override + protected Integer getTicketNumber() { + return 17090; + } + + @Override + protected String getTestDescription() { + return "PopupDateFieldElement should be accessible using TB4 PopupDateFieldElement."; + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldConnectorTest.java b/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldConnectorTest.java new file mode 100644 index 0000000000..5334327a83 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldConnectorTest.java @@ -0,0 +1,21 @@ +package com.vaadin.tests.components.datefield; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +import org.junit.Test; + +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.testbench.elements.PopupDateFieldElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class PopupDateFieldConnectorTest extends SingleBrowserTest { + + @Test + public void popupDateFieldElementIsLocated() { + openTestURL(); + + assertThat($(PopupDateFieldElement.class).all().size(), is(1)); + assertThat($(DateFieldElement.class).all().size(), is(2)); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/embedded/FlashIsVisibleTest.java b/uitest/src/com/vaadin/tests/components/embedded/FlashIsVisibleTest.java new file mode 100644 index 0000000000..64d70df88f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/embedded/FlashIsVisibleTest.java @@ -0,0 +1,32 @@ +/* + * 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.embedded; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class FlashIsVisibleTest extends + com.vaadin.tests.components.flash.FlashIsVisibleTest { + + @Override + @Test + public void testFlashIsCorrectlyDisplayed() throws Exception { + assertTrue("Test is using wrong url", + getTestUrl().contains(".embedded.")); + super.testFlashIsCorrectlyDisplayed(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridCellFocusOnResetSize.java b/uitest/src/com/vaadin/tests/components/grid/GridCellFocusOnResetSize.java new file mode 100644 index 0000000000..c0e3c9d683 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridCellFocusOnResetSize.java @@ -0,0 +1,34 @@ +/* + * 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.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.grid.GridCellFocusOnResetSizeWidget; +import com.vaadin.tests.widgetset.server.TestWidgetComponent; + +@Widgetset(TestingWidgetSet.NAME) +public class GridCellFocusOnResetSize extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + addComponent(new TestWidgetComponent( + GridCellFocusOnResetSizeWidget.class)); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridCellFocusOnResetSizeTest.java b/uitest/src/com/vaadin/tests/components/grid/GridCellFocusOnResetSizeTest.java new file mode 100644 index 0000000000..31ccb4eaf2 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridCellFocusOnResetSizeTest.java @@ -0,0 +1,57 @@ +/* + * 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 static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elementsbase.ServerClass; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridCellFocusOnResetSizeTest extends MultiBrowserTest { + + @ServerClass("com.vaadin.tests.widgetset.server.TestWidgetComponent") + public static class MyGridElement extends GridElement { + } + + @Test + public void testCellFocusOnSizeReset() throws IOException { + openTestURL(); + + GridElement grid = $(MyGridElement.class).first(); + int rowIndex = 9; + grid.getCell(rowIndex, 0).click(); + assertTrue("Row was not focused after click.", grid.getRow(rowIndex) + .isFocused()); + + // Clicking the button decreases size until it is down to 5 rows. + while (rowIndex > 4) { + findElement(By.tagName("button")).click(); + assertTrue("Row focus was not moved when size decreased", grid + .getRow(--rowIndex).isFocused()); + } + + // Next click increases size back to 10, this should not move focus. + findElement(By.tagName("button")).click(); + assertTrue("Row focus should not have moved when size increased", grid + .getRow(4).isFocused()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java index 0f04a1552e..f91f93c5d5 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java @@ -16,7 +16,6 @@ package com.vaadin.tests.components.grid.basicfeatures.server; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import com.vaadin.testbench.elements.NotificationElement; @@ -39,27 +38,6 @@ public class GridRowAddRemoveTest extends GridBasicFeaturesTest { } @Test - @Ignore("This test checks the parameters passed to Container. Has nothing to do with what's sent to client.") - public void removeRows_loadAllAtOnce() { - openTestURL(); - - selectMenuPath("Component", "Size", "HeightMode Row"); - selectMenuPath("Settings", "Clear log"); - selectMenuPath("Component", "Body rows", "Remove 18 first rows"); - - Assert.assertTrue( - "All newly required rows should be fetched in the same round trip.", - logContainsText("Requested items 37 - 55")); - - selectMenuPath("Settings", "Clear log"); - selectMenuPath("Component", "Body rows", "Remove 18 first rows"); - - Assert.assertTrue( - "All newly required rows should be fetched in the same round trip.", - logContainsText("Requested items 37 - 55")); - } - - @Test public void testAdd18Rows() { setDebug(true); openTestURL(); diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridScrollTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridScrollTest.java new file mode 100644 index 0000000000..9313b40770 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridScrollTest.java @@ -0,0 +1,57 @@ +/* + * 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.basicfeatures.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridScrollTest extends GridBasicFeaturesTest { + + @Test + public void testCorrectItemRequestsOnScroll() { + openTestURL(); + + assertTrue("Initial push from server not found", + getLogRow(1).equals("0. Requested items 0 - 40")); + // Client response varies a bit between browsers as different amount of + // rows is cached. + assertTrue("First row request from client not found", getLogRow(0) + .startsWith("1. Requested items 0 - ")); + + selectMenuPath("Component", "Size", "HeightMode Row"); + + selectMenuPath("Settings", "Clear log"); + $(GridElement.class).first().scrollToRow(40); + assertEquals("Log row did not contain expected item request", + "0. Requested items 0 - 86", getLogRow(0)); + assertEquals("There should be only one log row", " ", getLogRow(1)); + selectMenuPath("Settings", "Clear log"); + $(GridElement.class).first().scrollToRow(100); + assertEquals("Log row did not contain expected item request", + "0. Requested items 47 - 146", getLogRow(0)); + assertEquals("There should be only one log row", " ", getLogRow(1)); + selectMenuPath("Settings", "Clear log"); + $(GridElement.class).first().scrollToRow(300); + assertEquals("Log row did not contain expected item request", + "0. Requested items 247 - 346", getLogRow(0)); + assertEquals("There should be only one log row", " ", getLogRow(1)); + } +} diff --git a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java index 8f8e446ce3..d0134a4feb 100644 --- a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java +++ b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java @@ -25,8 +25,11 @@ import java.net.SocketException; import java.util.Enumeration; import java.util.Properties; +import org.openqa.selenium.remote.DesiredCapabilities; + import com.vaadin.testbench.annotations.BrowserFactory; import com.vaadin.testbench.annotations.RunOnHub; +import com.vaadin.testbench.parallel.Browser; /** * Provides values for parameters which depend on where the test is run. @@ -50,16 +53,43 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { private static final Properties properties = new Properties(); private static final File propertiesFile = new File("work", "eclipse-run-selected-test.properties"); + private static final String FIREFOX_PATH = "firefox.path"; + static { if (propertiesFile.exists()) { try { properties.load(new FileInputStream(propertiesFile)); + if (properties.containsKey(RUN_LOCALLY_PROPERTY)) { + System.setProperty("useLocalWebDriver", "true"); + DesiredCapabilities localBrowser = getRunLocallyCapabilities(); + System.setProperty( + "browsers.include", + localBrowser.getBrowserName() + + localBrowser.getVersion()); + } + if (properties.containsKey(FIREFOX_PATH)) { + System.setProperty(FIREFOX_PATH, + properties.getProperty(FIREFOX_PATH)); + } } catch (IOException e) { throw new RuntimeException(e); } } } + private static DesiredCapabilities getRunLocallyCapabilities() { + Browser localBrowser; + try { + localBrowser = Browser.valueOf(properties.getProperty( + RUN_LOCALLY_PROPERTY).toUpperCase()); + } catch (Exception e) { + System.err.println(e.getMessage()); + System.err.println("Falling back to FireFox"); + localBrowser = Browser.FIREFOX; + } + return localBrowser.getDesiredCapabilities(); + } + protected static String getProperty(String name) { String property = properties.getProperty(name); if (property == null) { diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridCellFocusOnResetSizeWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridCellFocusOnResetSizeWidget.java new file mode 100644 index 0000000000..b2893463a7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridCellFocusOnResetSizeWidget.java @@ -0,0 +1,114 @@ +/* + * 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.widgetset.client.grid; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.ui.Button; +import com.vaadin.client.data.DataChangeHandler; +import com.vaadin.client.data.DataSource; +import com.vaadin.client.renderers.HtmlRenderer; +import com.vaadin.client.widgets.Grid; +import com.vaadin.client.widgets.Grid.SelectionMode; + +public class GridCellFocusOnResetSizeWidget extends + PureGWTTestApplication<Grid<String[]>> { + + private Grid<String[]> grid; + + private final class MyDataSource implements DataSource<String[]> { + List<String[]> rows = new ArrayList<String[]>(); + int ROWS_MAX = 10; + int size = ROWS_MAX; + DataChangeHandler handler = null; + { + for (int i = 0; i < ROWS_MAX; ++i) { + rows.add(new String[] { "Foo " + i }); + } + } + + @Override + public void ensureAvailability(int firstRowIndex, int numberOfRows) { + handler.dataAvailable(firstRowIndex, numberOfRows); + } + + @Override + public int size() { + return size; + } + + @Override + public void setDataChangeHandler(DataChangeHandler dataChangeHandler) { + handler = dataChangeHandler; + } + + @Override + public RowHandle<String[]> getHandle(final String[] rowData) { + return null; + } + + @Override + public String[] getRow(int rowIndex) { + if (rowIndex < size && rowIndex >= 0) { + return rows.get(rowIndex); + } + return null; + } + + public void changeSize() { + size--; + if (size < ROWS_MAX / 2) { + size = ROWS_MAX; + } + handler.resetDataAndSize(size); + } + } + + private class Col extends Grid.Column<String, String[]> { + public Col(String header) { + super(header, new HtmlRenderer()); + } + + @Override + public String getValue(String[] row) { + int index = grid.getColumns().indexOf(this); + return "<span>" + String.valueOf(row[index]) + "</span>"; + } + } + + public GridCellFocusOnResetSizeWidget() { + super(new Grid<String[]>()); + grid = getTestedWidget(); + grid.setSelectionMode(SelectionMode.NONE); + grid.setWidth("300px"); + grid.addColumn(new Col("Foo")); + final MyDataSource dataSource = new MyDataSource(); + grid.setDataSource(dataSource); + Button widget = new Button("Change Container Size"); + widget.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + dataSource.changeSize(); + } + }); + addNorth(grid, 400); + addNorth(widget, 50); + } +} diff --git a/uitest/tb2/com/vaadin/tests/components/embedded/FlashIsVisible.html b/uitest/tb2/com/vaadin/tests/components/embedded/FlashIsVisible.html deleted file mode 100644 index ffa2ac11ec..0000000000 --- a/uitest/tb2/com/vaadin/tests/components/embedded/FlashIsVisible.html +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.embedded.FlashIsVisible</td> - <td></td> -</tr> -<!--Allow the flash plugin to load before taking the screenshot--> -<tr> - <td>pause</td> - <td>5000</td> - <td></td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>blue-circle</td> -</tr> - -</tbody></table> -</body> -</html> |