Browse Source

8.14 cherry-picks (#12418)

* Improve thread safety (#12395)

See: https://vaadin.com/forum/thread/17522264/concurrentmodificationexception-in-vaadin-shared-on-karaf-4-2-x

* Fix incompatible selenium version in test module. (#12397)

* Fixed a dependency version in a karaf test module. (#12399)

* Checkstyle tweaks to DateField widgets. (#12400)

- Added and updated JavaDocs.
- Updated comments.
- Updated to use non-deprecated method calls.
- Removed unnecessary warning suppressions.
- Suppressed warnings for unavoidable deprecation.

* fix: set Vaadin session attribute using lock in reinitializeSession (#12401)

* Cherry picked unit test from Flow

See https://github.com/vaadin/flow/pull/11538

* Fix missing import

* Cherry pick fix from Flow

* deprecate vaadin-snasphots repo (#12405)

* deprecate vaadin-snasphots repo

* Update chrome version to 93

* add more screenshots

* fix: Add MPR UI id request parameter (#12412)

* fix: Add MPR UI id request parameter

Related-to https://github.com/vaadin/multiplatform-runtime/issues/85

* test: Remove redundant non-empty param test

* test: Remove leftovers

* fix: Init window.mprUiId earlier than window.vaadin

* Add missing '='

* Update links shown by license checker (#12402)

vaadin.com/pro does no longer have the info

* fix: Add row limit to DataCommunicator row data requests (#12415)

* Add row limit to DataCommunicator row data requests

* Add missing constant

* Add unit test

* Add test for extending Grid

* Fixed test

Co-authored-by: Tatu Lund <tatu@vaadin.com>
Co-authored-by: Anna Koskinen <Ansku@users.noreply.github.com>
Co-authored-by: Zhe Sun <31067185+ZheSun88@users.noreply.github.com>
Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com>
tags/8.14.1
Olli Tietäväinen 2 years ago
parent
commit
ab775a3211
No account linked to committer's email address
21 changed files with 433 additions and 34 deletions
  1. 4
    4
      client-compiler/src/main/resources/com/vaadin/tools/CvalChecker.properties
  2. 96
    8
      client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java
  3. 31
    3
      client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java
  4. 39
    6
      client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java
  5. 2
    0
      client/src/main/java/com/vaadin/client/ui/VDateCalendarPanel.java
  6. 84
    1
      client/src/main/java/com/vaadin/client/ui/VDateField.java
  7. 4
    0
      client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java
  8. 24
    3
      client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java
  9. 4
    0
      client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java
  10. 16
    0
      client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java
  11. 16
    2
      client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java
  12. 15
    0
      server/src/main/java/com/vaadin/data/provider/DataCommunicator.java
  13. 14
    4
      server/src/main/java/com/vaadin/server/VaadinService.java
  14. 6
    0
      server/src/main/resources/VAADIN/vaadinBootstrap.js
  15. 8
    0
      server/src/test/java/com/vaadin/data/provider/DataCommunicatorTest.java
  16. 44
    0
      server/src/test/java/com/vaadin/server/VaadinServiceTest.java
  17. 19
    0
      server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java
  18. 1
    1
      test/pom.xml
  19. 1
    1
      test/servlet-containers/karaf/vaadin-karaf-bundle1/pom.xml
  20. 1
    0
      uitest/src/main/java/com/vaadin/tests/components/ui/UIInitBrowserDetails.java
  21. 4
    1
      uitest/src/test/java/com/vaadin/tests/components/ui/UIInitBrowserDetailsTest.java

+ 4
- 4
client-compiler/src/main/resources/com/vaadin/tools/CvalChecker.properties View File

expired={2} for {0} {1} has expired. Get a valid license at vaadin.com/pro
expired={2} for {0} {1} has expired. Get a valid license at vaadin.com/pro/licenses


none=License for {0} {1} not found. Go to vaadin.com/pro for more details.
none=License for {0} {1} not found. Go to https://vaadin.com/licensing-faq-and-troubleshooting for more details.


invalid=License for {0} {1} is not valid. Get a valid license from vaadin.com/pro
invalid=License for {0} {1} is not valid. Get a valid license from vaadin.com/pro/licenses


unreachable=License for {0} {1} has not been validated. Check your network connection. unreachable=License for {0} {1} has not been validated. Check your network connection.




valid= > Using a valid license for {0} {1}. valid= > Using a valid license for {0} {1}.


agpl=Using AGPL version of {0} {1}. Commercial licensing options available at vaadin.com/pro
agpl=Using AGPL version of {0} {1}. Commercial licensing options available at vaadin.com/pricing

+ 96
- 8
client/src/main/java/com/vaadin/client/ui/VAbstractCalendarPanel.java View File

* the resolution type which this field is based on (day, month, ...) * the resolution type which this field is based on (day, month, ...)
* @since 8.0 * @since 8.0
*/ */
@SuppressWarnings("deprecation")
public abstract class VAbstractCalendarPanel<R extends Enum<R>> public abstract class VAbstractCalendarPanel<R extends Enum<R>>
extends FocusableFlexTable implements KeyDownHandler, KeyPressHandler, extends FocusableFlexTable implements KeyDownHandler, KeyPressHandler,
MouseOutHandler, MouseDownHandler, MouseUpHandler, BlurHandler, MouseOutHandler, MouseDownHandler, MouseUpHandler, BlurHandler,
FocusHandler, SubPartAware { FocusHandler, SubPartAware {


/**
* Interface for updating date field value based on the current calendar
* panel data or canceling the update.
*
* @author Vaadin Ltd
*/
public interface SubmitListener { public interface SubmitListener {


/** /**
* {@code focused} value. * {@code focused} value.
*/ */
public interface FocusChangeListener { public interface FocusChangeListener {
/**
* Called when focused date has changed in the calendar panel.
*
* @param focusedDate
* the currently focused date in the panel
*/
void focusChanged(Date focusedDate); void focusChanged(Date focusedDate);
} }


* Represents a click handler for when a user selects a value by using the * Represents a click handler for when a user selects a value by using the
* mouse * mouse
*/ */
@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "deprecation" })
private ClickHandler dayClickHandler = event -> { private ClickHandler dayClickHandler = event -> {
if (!isEnabled() || isReadonly()) { if (!isEnabled() || isReadonly()) {
return; return;
private Map<String, String> dateStyles = new HashMap<String, String>(); private Map<String, String> dateStyles = new HashMap<String, String>();
private DateTimeFormat df = DateTimeFormat.getFormat("yyyy-MM-dd"); private DateTimeFormat df = DateTimeFormat.getFormat("yyyy-MM-dd");


/**
* Constructs a calendar panel widget for displaying and selecting a date.
*/
public VAbstractCalendarPanel() { public VAbstractCalendarPanel() {
getElement().setId(DOM.createUniqueId()); getElement().setId(DOM.createUniqueId());
setStyleName(VDateField.CLASSNAME + "-calendarpanel"); setStyleName(VDateField.CLASSNAME + "-calendarpanel");
addBlurHandler(this); addBlurHandler(this);
} }


/**
* Sets the parent date field widget.
*
* @param parent
* the parent widget
*/
public void setParentField(VDateField<R> parent) { public void setParentField(VDateField<R> parent) {
this.parent = parent; this.parent = parent;
} }
/** /**
* Updates year, month, day from focusedDate to value * Updates year, month, day from focusedDate to value
*/ */
@SuppressWarnings("deprecation")
private void selectFocused() { private void selectFocused() {
if (focusedDate != null if (focusedDate != null
&& isDateInsideRange(focusedDate, getResolution())) { && isDateInsideRange(focusedDate, getResolution())) {
} }
} }


/**
* @deprecated This method is not used by the framework code anymore.
* @return {@code false}
*/
@Deprecated
protected boolean onValueChange() { protected boolean onValueChange() {
return false; return false;
} }


/**
* Returns the current date resolution.
*
* @return the resolution
*/
public R getResolution() { public R getResolution() {
return resolution; return resolution;
} }


/**
* Sets the current date resolution.
*
* @param resolution
* the new resolution
*/
public void setResolution(R resolution) { public void setResolution(R resolution) {
this.resolution = resolution; this.resolution = resolution;
} }


updateAssistiveLabels(); updateAssistiveLabels();


@SuppressWarnings("deprecation")
final String monthName = needsMonth final String monthName = needsMonth
? getDateTimeService().getMonth(displayedMonth.getMonth()) ? getDateTimeService().getMonth(displayedMonth.getMonth())
: ""; : "";
@SuppressWarnings("deprecation")
final int year = displayedMonth.getYear() + 1900; final int year = displayedMonth.getYear() + 1900;


getFlexCellFormatter().setStyleName(0, 2, getFlexCellFormatter().setStyleName(0, 2,
} }
} }


@SuppressWarnings("deprecation")
private void updateControlButtonRangeStyles(boolean needsMonth) { private void updateControlButtonRangeStyles(boolean needsMonth) {


if (focusedDate == null) { if (focusedDate == null) {
return parent; return parent;
} }


/**
* Sets date time service for the widget.
*
* @param dateTimeService
* date time service
*/
public void setDateTimeService(DateTimeService dateTimeService) { public void setDateTimeService(DateTimeService dateTimeService) {
this.dateTimeService = dateTimeService; this.dateTimeService = dateTimeService;
} }
* selector or not. ISO 8601 defines that a week always starts with a Monday * selector or not. ISO 8601 defines that a week always starts with a Monday
* so the week numbers are only shown if this is the case. * so the week numbers are only shown if this is the case.
* *
* @return true if week number should be shown, false otherwise
* @return {@code true} if week number should be shown, {@code false}
* otherwise
*/ */
public boolean isShowISOWeekNumbers() { public boolean isShowISOWeekNumbers() {
return showISOWeekNumbers; return showISOWeekNumbers;
} }


/**
* Sets whether ISO 8601 week numbers should be shown in the value selector
* or not. ISO 8601 defines that a week always starts with a Monday so the
* week numbers are only shown if this is the case.
*
* @param showISOWeekNumbers
* {@code true} if week number should be shown, {@code false}
* otherwise
*/
public void setShowISOWeekNumbers(boolean showISOWeekNumbers) { public void setShowISOWeekNumbers(boolean showISOWeekNumbers) {
this.showISOWeekNumbers = showISOWeekNumbers; this.showISOWeekNumbers = showISOWeekNumbers;
if (initialRenderDone && isBelowMonth(resolution)) { if (initialRenderDone && isBelowMonth(resolution)) {
.compareTo(dateStrResolution) <= 0; .compareTo(dateStrResolution) <= 0;
} }


@SuppressWarnings("deprecation")
private String dateStrResolution(Date date, R minResolution) { private String dateStrResolution(Date date, R minResolution) {
String dateStrResolution = (1900 + date.getYear()) + ""; String dateStrResolution = (1900 + date.getYear()) + "";
while (dateStrResolution.length() < 4) { while (dateStrResolution.length() < 4) {
/** /**
* Builds the day and time selectors of the calendar. * Builds the day and time selectors of the calendar.
*/ */
@SuppressWarnings("deprecation")
private void buildCalendarBody() { private void buildCalendarBody() {


final int weekColumn = 0; final int weekColumn = 0;
* resolution of the calendar is changed and no date has been * resolution of the calendar is changed and no date has been
* selected. * selected.
*/ */
@SuppressWarnings("deprecation")
protected void doRenderCalendar(boolean updateDate) { protected void doRenderCalendar(boolean updateDate) {
super.setStylePrimaryName( super.setStylePrimaryName(
getDateField().getStylePrimaryName() + "-calendarpanel"); getDateField().getStylePrimaryName() + "-calendarpanel");
/** /**
* Moves the focus forward the given number of days. * Moves the focus forward the given number of days.
*/ */
@SuppressWarnings("deprecation")
private void focusNextDay(int days) { private void focusNextDay(int days) {
if (focusedDate == null) { if (focusedDate == null) {
return; return;
/** /**
* Selects the next month * Selects the next month
*/ */
@SuppressWarnings("deprecation")
private void focusNextMonth() { private void focusNextMonth() {


if (focusedDate == null) { if (focusedDate == null) {
} }


// Now also checking whether the day is inside the range or not. If not // Now also checking whether the day is inside the range or not. If not
// inside,
// correct it
// inside, correct it
if (!isDateInsideRange(requestedNextMonthDate, if (!isDateInsideRange(requestedNextMonthDate,
getResolution(this::isDay))) { getResolution(this::isDay))) {
requestedNextMonthDate = adjustDateToFitInsideRange( requestedNextMonthDate = adjustDateToFitInsideRange(
renderCalendar(); renderCalendar();
} }


@SuppressWarnings("deprecation")
private static void addOneMonth(Date date) { private static void addOneMonth(Date date) {
int currentMonth = date.getMonth(); int currentMonth = date.getMonth();
int requestedMonth = (currentMonth + 1) % 12; int requestedMonth = (currentMonth + 1) % 12;
} }
} }


@SuppressWarnings("deprecation")
private static void removeOneMonth(Date date) { private static void removeOneMonth(Date date) {
int currentMonth = date.getMonth(); int currentMonth = date.getMonth();


/** /**
* Selects the previous month * Selects the previous month
*/ */
@SuppressWarnings("deprecation")
private void focusPreviousMonth() { private void focusPreviousMonth() {


if (focusedDate == null) { if (focusedDate == null) {
/** /**
* Selects the previous year * Selects the previous year
*/ */
@SuppressWarnings("deprecation")
private void focusPreviousYear(int years) { private void focusPreviousYear(int years) {


if (focusedDate == null) { if (focusedDate == null) {
/** /**
* Selects the next year * Selects the next year
*/ */
@SuppressWarnings("deprecation")
private void focusNextYear(int years) { private void focusNextYear(int years) {


if (focusedDate == null) { if (focusedDate == null) {
* @return Return true if the key press was handled by the method, else * @return Return true if the key press was handled by the method, else
* return false. * return false.
*/ */
@SuppressWarnings("deprecation")
protected boolean handleNavigationDayMode(int keycode, boolean ctrl, protected boolean handleNavigationDayMode(int keycode, boolean ctrl,
boolean shift) { boolean shift) {


return date; return date;
} }


@SuppressWarnings("deprecation")
private Date parseRangeString(String dateStr) { private Date parseRangeString(String dateStr) {
if (dateStr == null || "".equals(dateStr)) { if (dateStr == null || "".equals(dateStr)) {
return null; return null;
* an additional action which will be executed in case * an additional action which will be executed in case
* rerendering is not required * rerendering is not required
*/ */
@SuppressWarnings("deprecation")
protected void doSetDate(Date currentDate, boolean needRerender, protected void doSetDate(Date currentDate, boolean needRerender,
Runnable focusAction) { Runnable focusAction) {
// Check that we are not re-rendering an already active date // Check that we are not re-rendering an already active date
dateThatFitsInsideRange.getMonth(), 1); dateThatFitsInsideRange.getMonth(), 1);
// value was adjusted. Set selected to null to not cause // value was adjusted. Set selected to null to not cause
// confusion, but this is only needed (and allowed) when we have // confusion, but this is only needed (and allowed) when we have
// a day
// resolution
// a day resolution
if (isDay(getResolution())) { if (isDay(getResolution())) {
value = null; value = null;
} }
private class Day extends InlineHTML { private class Day extends InlineHTML {
private final Date date; private final Date date;


@SuppressWarnings("deprecation")
Day(Date date) { Day(Date date) {
super("" + date.getDate()); super("" + date.getDate());
this.date = date; this.date = date;
} }
} }


/**
* Returns the current date value.
*
* @return current date value
*/
public Date getDate() { public Date getDate() {
return value; return value;
} }


private String rangeEnd; private String rangeEnd;


@SuppressWarnings("deprecation")
@Override @Override
public String getSubPartName( public String getSubPartName(
com.google.gwt.user.client.Element subElement) { com.google.gwt.user.client.Element subElement) {
return w.getElement().isOrHasChild(subElement); return w.getElement().isOrHasChild(subElement);
} }


@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "deprecation" })
@Override @Override
public com.google.gwt.user.client.Element getSubPartElement( public com.google.gwt.user.client.Element getSubPartElement(
String subPart) { String subPart) {
*/ */
public class FocusedDate extends Date { public class FocusedDate extends Date {


/**
* Constructs a date instance that keeps track of the currently selected
* date within the calendar panel and updates the related text field
* accordingly if there is one.
*
* @param year
* the year value
* @param month
* the month value between 0-11
* @param date
* the day of the month value between 1-31
* @see FocusedDate
*/
@SuppressWarnings("deprecation")
public FocusedDate(int year, int month, int date) { public FocusedDate(int year, int month, int date) {
super(year, month, date); super(year, month, date);
} }

+ 31
- 3
client/src/main/java/com/vaadin/client/ui/VAbstractDateFieldCalendar.java View File



/** /**
* A client side implementation for inline date field. * A client side implementation for inline date field.
*
* @param <PANEL>
* the calendar panel type this field uses
* @param <R>
* the resolution type which this field is based on (day, month, ...)
* @author Vaadin Ltd
*/ */
public abstract class VAbstractDateFieldCalendar<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>> public abstract class VAbstractDateFieldCalendar<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>>
extends VDateField<R> { extends VDateField<R> {
/** For internal use only. May be removed or replaced in the future. */ /** For internal use only. May be removed or replaced in the future. */
public final PANEL calendarPanel; public final PANEL calendarPanel;


/**
* Constructs a date selection widget with an inline date/time selector.
*
* @param panel
* the calendar panel instance that should be displayed
* @param resolution
* the resolution this widget should display (day, month, ...)
*/
public VAbstractDateFieldCalendar(PANEL panel, R resolution) { public VAbstractDateFieldCalendar(PANEL panel, R resolution) {
super(resolution); super(resolution);
calendarPanel = panel; calendarPanel = panel;


@Override @Override
public void onCancel() { public void onCancel() {
// TODO Auto-generated method stub

// NOP
} }
}); });
calendarPanel.setFocusOutListener(event -> { calendarPanel.setFocusOutListener(event -> {
}); });
} }


@SuppressWarnings("deprecation")
/**
* Update buffered values and send them (if any) to the server.
*/
public abstract void updateValueFromPanel(); public abstract void updateValueFromPanel();


/**
* Sets the tabulator index for the calendar panel element that represents
* the entire widget in the browser's focus cycle.
*
* @param tabIndex
* the new tabulator index
*/
public void setTabIndex(int tabIndex) { public void setTabIndex(int tabIndex) {
calendarPanel.getElement().setTabIndex(tabIndex); calendarPanel.getElement().setTabIndex(tabIndex);
} }


/**
* Returns the tabulator index of the calendar panel element that represents
* the entire widget in the browser's focus cycle.
*
* @return the tabulator index
*/
public int getTabIndex() { public int getTabIndex() {
return calendarPanel.getElement().getTabIndex(); return calendarPanel.getElement().getTabIndex();
} }

+ 39
- 6
client/src/main/java/com/vaadin/client/ui/VAbstractPopupCalendar.java View File

* then pass set it by calling the * then pass set it by calling the
* <code>setCalendarPanel(VAbstractCalendarPanel panel)</code> method. * <code>setCalendarPanel(VAbstractCalendarPanel panel)</code> method.
* *
* @param <PANEL>
* the calendar panel type this field uses
* @param <R>
* the resolution type which this field is based on (day, month, ...)
* @since 8.0 * @since 8.0
* @author Vaadin Ltd
*/ */
public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>> public abstract class VAbstractPopupCalendar<PANEL extends VAbstractCalendarPanel<R>, R extends Enum<R>>
extends VAbstractTextualDate<R> extends VAbstractTextualDate<R>
public PANEL calendar; public PANEL calendar;


/** For internal use only. May be removed or replaced in the future. */ /** For internal use only. May be removed or replaced in the future. */
@SuppressWarnings("deprecation")
public final VOverlay popup; public final VOverlay popup;


/** For internal use only. May be removed or replaced in the future. */ /** For internal use only. May be removed or replaced in the future. */


private static final String CALENDAR_TOGGLE_ID = "popupButton"; private static final String CALENDAR_TOGGLE_ID = "popupButton";


/**
* Constructs a date selection widget with a text field and a pop-up
* date/time selector.
*
* @param calendarPanel
* the calendar panel instance that should be displayed in the
* pop-up
* @param resolution
* the resolution this widget should display (day, month, ...)
*/
@SuppressWarnings("deprecation")
public VAbstractPopupCalendar(PANEL calendarPanel, R resolution) { public VAbstractPopupCalendar(PANEL calendarPanel, R resolution) {
super(resolution); super(resolution);




// FIXME: Problem is, that the element with the provided id does not // FIXME: Problem is, that the element with the provided id does not
// exist yet in html. This is the same problem as with the context menu. // exist yet in html. This is the same problem as with the context menu.
// Apply here the same fix (#11795)
// Apply here the same fix (#3901)
Roles.getTextboxRole().setAriaControlsProperty(text.getElement(), Roles.getTextboxRole().setAriaControlsProperty(text.getElement(),
Id.of(calendar.getElement())); Id.of(calendar.getElement()));
Roles.getButtonRole().setAriaControlsProperty( Roles.getButtonRole().setAriaControlsProperty(
popup.setWidget(wrapper); popup.setWidget(wrapper);
popup.addCloseHandler(this); popup.addCloseHandler(this);


DOM.setElementProperty(calendar.getElement(), "id",
"PID_VAADIN_POPUPCAL");
calendar.getElement().setPropertyString("id", "PID_VAADIN_POPUPCAL");


sinkEvents(Event.ONKEYDOWN); sinkEvents(Event.ONKEYDOWN);


/** /**
* Changes the current date, and updates the * Changes the current date, and updates the
* {@link VDateField#bufferedResolutions}, possibly * {@link VDateField#bufferedResolutions}, possibly
* {@link VDateField#sendBufferedValues()} to the server if needed
* {@link VDateField#sendBufferedValues()} to the server if needed.
* *
* @param newDate * @param newDate
* the new {@code Date} to update * the new {@code Date} to update
* Sets the state of the text field of this component. By default the text * Sets the state of the text field of this component. By default the text
* field is enabled. Disabling it causes only the button for date selection * field is enabled. Disabling it causes only the button for date selection
* to be active, thus preventing the user from entering invalid dates. See * to be active, thus preventing the user from entering invalid dates. See
* <a href="http://dev.vaadin.com/ticket/6790>#6790</a>.
* <a href="http://dev.vaadin.com/ticket/6790">#6790</a>.
* <p>
* If the text field is enabled, it represents this widget within the
* browser's tabulator focus cycle. When the text field is disabled, that
* role is instead given to the date selection button. If the entire
* component is disabled, the focus cycle skips this widget altogether.
* *
* @param textFieldEnabled * @param textFieldEnabled
* {@code true} if the text field should be enabled,
* {@code false} if disabled
*/ */
public void setTextFieldEnabled(boolean textFieldEnabled) { public void setTextFieldEnabled(boolean textFieldEnabled) {
this.textFieldEnabled = textFieldEnabled; this.textFieldEnabled = textFieldEnabled;
updateTextFieldEnabled(); updateTextFieldEnabled();
} }


/**
* Updates the text field's enabled status to correspond with the latest
* value set through {@link #setTextFieldEnabled(boolean)} and this
* component's general {@link #setEnabled(boolean)}.
*
* @see #setTextFieldEnabled(boolean)
*/
protected void updateTextFieldEnabled() { protected void updateTextFieldEnabled() {
boolean reallyEnabled = isEnabled() && isTextFieldEnabled(); boolean reallyEnabled = isEnabled() && isTextFieldEnabled();
// IE has a non input disabled themeing that can not be overridden so we // IE has a non input disabled themeing that can not be overridden so we
} }
} }


@SuppressWarnings("deprecation")
@Override @Override
public void bindAriaCaption( public void bindAriaCaption(
com.google.gwt.user.client.Element captionElement) { com.google.gwt.user.client.Element captionElement) {
* Get the key code that opens the calendar panel. By default it is the down * Get the key code that opens the calendar panel. By default it is the down
* key but you can override this to be whatever you like * key but you can override this to be whatever you like
* *
* @return
* @return the key code that opens the calendar panel
*/ */
protected int getOpenCalenderPanelKey() { protected int getOpenCalenderPanelKey() {
return KeyCodes.KEY_DOWN; return KeyCodes.KEY_DOWN;
} }
} }


@SuppressWarnings("deprecation")
@Override @Override
public com.google.gwt.user.client.Element getSubPartElement( public com.google.gwt.user.client.Element getSubPartElement(
String subPart) { String subPart) {
return super.getSubPartElement(subPart); return super.getSubPartElement(subPart);
} }


@SuppressWarnings("deprecation")
@Override @Override
public String getSubPartName( public String getSubPartName(
com.google.gwt.user.client.Element subElement) { com.google.gwt.user.client.Element subElement) {

+ 2
- 0
client/src/main/java/com/vaadin/client/ui/VDateCalendarPanel.java View File

import com.vaadin.shared.ui.datefield.DateResolution; import com.vaadin.shared.ui.datefield.DateResolution;


/** /**
* A calendar panel widget to show and select a date.
*
* @author Vaadin Ltd * @author Vaadin Ltd
* @since 8.0 * @since 8.0
*/ */

+ 84
- 1
client/src/main/java/com/vaadin/client/ui/VDateField.java View File

public abstract class VDateField<R extends Enum<R>> extends FlowPanel public abstract class VDateField<R extends Enum<R>> extends FlowPanel
implements Field, HasEnabled { implements Field, HasEnabled {


/** Default classname for this widget. */
public static final String CLASSNAME = "v-datefield"; public static final String CLASSNAME = "v-datefield";


/** For internal use only. May be removed or replaced in the future. */ /** For internal use only. May be removed or replaced in the future. */


private R currentResolution; private R currentResolution;


/** Currently used locale string, e.g. {@code en_US}. */
protected String currentLocale; protected String currentLocale;


/** Is the widget read-only or not. */
protected boolean readonly; protected boolean readonly;


/** Is the widget enabled or not. */
protected boolean enabled; protected boolean enabled;


/** /**
/** For internal use only. May be removed or replaced in the future. */ /** For internal use only. May be removed or replaced in the future. */
public DateTimeService dts; public DateTimeService dts;


/** Should ISO 8601 week numbers be shown in the date selector or not. */
protected boolean showISOWeekNumbers; protected boolean showISOWeekNumbers;


/**
* Constructs a widget for a date field.
*
* @param resolution
* the resolution for this widget (day, month, ...)
*/
public VDateField(R resolution) { public VDateField(R resolution) {
setStyleName(CLASSNAME); setStyleName(CLASSNAME);
dts = new DateTimeService(); dts = new DateTimeService();
currentResolution = resolution; currentResolution = resolution;
} }


/**
* Returns the current resolution.
*
* @return the resolution
*/
public R getCurrentResolution() { public R getCurrentResolution() {
return currentResolution; return currentResolution;
} }


/**
* Sets the resolution.
*
* @param currentResolution
* the new resolution
*/
public void setCurrentResolution(R currentResolution) { public void setCurrentResolution(R currentResolution) {
this.currentResolution = currentResolution; this.currentResolution = currentResolution;
} }


/**
* Returns the current locale String.
*
* @return the locale String
*/
public String getCurrentLocale() { public String getCurrentLocale() {
return currentLocale; return currentLocale;
} }


/**
* Sets the locale String.
*
* @param currentLocale
* the new locale String.
*/
public void setCurrentLocale(String currentLocale) { public void setCurrentLocale(String currentLocale) {
this.currentLocale = currentLocale; this.currentLocale = currentLocale;
} }


/**
* Returns the current date value.
*
* @return the date value
*/
public Date getCurrentDate() { public Date getCurrentDate() {
return date; return date;
} }


/**
* Sets the date value.
*
* @param date
* the new date value
*/
public void setCurrentDate(Date date) { public void setCurrentDate(Date date) {
this.date = date; this.date = date;
} }
* *
* @see #setCurrentDate(Map) * @see #setCurrentDate(Map)
* @param defaultValues * @param defaultValues
* a map from resolutions to date values
* @since 8.1.2 * @since 8.1.2
*/ */
public void setDefaultDate(Map<R, Integer> defaultValues) { public void setDefaultDate(Map<R, Integer> defaultValues) {
return defaultDate; return defaultDate;
} }


/**
* Returns whether this widget is read-only or not.
*
* @return {@code true} if read-only, {@code false} otherwise
*/
public boolean isReadonly() { public boolean isReadonly() {
return readonly; return readonly;
} }


/**
* Sets whether this widget should be read-only or not.
*
* @param readonly
* {@code true} if read-only, {@code false} otherwise
*/
public void setReadonly(boolean readonly) { public void setReadonly(boolean readonly) {
this.readonly = readonly; this.readonly = readonly;
} }
this.enabled = enabled; this.enabled = enabled;
} }


/**
* Returns the date time service for this widget.
*
* @return the date time service
*/
public DateTimeService getDateTimeService() { public DateTimeService getDateTimeService() {
return dts; return dts;
} }


/**
* Returns the connector id that corresponds with this widget.
*
* @return the connector id
* @deprecated This method is not used by the framework code anymore.
*/
@Deprecated
public String getId() { public String getId() {
return connector.getConnectorId(); return connector.getConnectorId();
} }


/**
* Returns the current application connection.
*
* @return the application connection
*/
public ApplicationConnection getClient() { public ApplicationConnection getClient() {
return client; return client;
} }
* selector or not. ISO 8601 defines that a week always starts with a Monday * selector or not. ISO 8601 defines that a week always starts with a Monday
* so the week numbers are only shown if this is the case. * so the week numbers are only shown if this is the case.
* *
* @return true if week number should be shown, false otherwise
* @return {@code true} if week number should be shown, {@code false}
* otherwise
*/ */
public boolean isShowISOWeekNumbers() { public boolean isShowISOWeekNumbers() {
return showISOWeekNumbers; return showISOWeekNumbers;
} }


/**
* Sets whether ISO 8601 week numbers should be shown in the date selector
* or not. ISO 8601 defines that a week always starts with a Monday so the
* week numbers are only shown if this is the case.
*
* @param showISOWeekNumbers
* {@code true} if week number should be shown, {@code false}
* otherwise
*/
public void setShowISOWeekNumbers(boolean showISOWeekNumbers) { public void setShowISOWeekNumbers(boolean showISOWeekNumbers) {
this.showISOWeekNumbers = showISOWeekNumbers; this.showISOWeekNumbers = showISOWeekNumbers;
} }

+ 4
- 0
client/src/main/java/com/vaadin/client/ui/VDateFieldCalendar.java View File

public class VDateFieldCalendar public class VDateFieldCalendar
extends VAbstractDateFieldCalendar<VDateCalendarPanel, DateResolution> { extends VAbstractDateFieldCalendar<VDateCalendarPanel, DateResolution> {


/**
* Constructs a widget for the InlineDateField component.
*/
public VDateFieldCalendar() { public VDateFieldCalendar() {
super(GWT.create(VDateCalendarPanel.class), YEAR); super(GWT.create(VDateCalendarPanel.class), YEAR);
} }


@Override @Override
@SuppressWarnings("deprecation")
public void updateBufferedValues() { public void updateBufferedValues() {
// If field is invisible at the beginning, client can still be null when // If field is invisible at the beginning, client can still be null when
// this function is called. // this function is called.

+ 24
- 3
client/src/main/java/com/vaadin/client/ui/VDateTimeCalendarPanel.java View File

import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
import com.vaadin.shared.ui.datefield.DateTimeResolution; import com.vaadin.shared.ui.datefield.DateTimeResolution;


/** /**
* A calendar panel widget to show and select a date and a time.
*
* @author Vaadin Ltd * @author Vaadin Ltd
* @since 8.0 * @since 8.0
*/ */
* Constructs the ListBoxes and updates their value * Constructs the ListBoxes and updates their value
* *
*/ */
@SuppressWarnings("deprecation")
private void buildTime() { private void buildTime() {
clear(); clear();


/** /**
* Updates the value to correspond to the values in value. * Updates the value to correspond to the values in value.
*/ */
@SuppressWarnings("deprecation")
public void updateTimes() { public void updateTimes() {
if (getDate() == null) { if (getDate() == null) {
setDate(new Date()); setDate(new Date());
* .event.dom.client.ChangeEvent) * .event.dom.client.ChangeEvent)
*/ */
@Override @Override
@SuppressWarnings("deprecation")
public void onChange(ChangeEvent event) { public void onChange(ChangeEvent event) {
/* /*
* Value from dropdowns gets always set for the value. Like year and * Value from dropdowns gets always set for the value. Like year and
*/ */
public interface TimeChangeListener { public interface TimeChangeListener {


/**
* Handle time change.
*
* @param hour
* the new hour value
* @param min
* the new minute value
* @param sec
* the new second value
* @param msec
* the new millisecond value
*/
void changed(int hour, int min, int sec, int msec); void changed(int hour, int min, int sec, int msec);
} }


* The time change listener is triggered when the user changes the time. * The time change listener is triggered when the user changes the time.
* *
* @param listener * @param listener
* the listener to use
*/ */
public void setTimeChangeListener(TimeChangeListener listener) { public void setTimeChangeListener(TimeChangeListener listener) {
timeChangeListener = listener; timeChangeListener = listener;
} }


@Override @Override
public String getSubPartName(Element subElement) {
@SuppressWarnings("deprecation")
public String getSubPartName(
com.google.gwt.user.client.Element subElement) {
if (time != null) { if (time != null) {
if (contains(time.hours, subElement)) { if (contains(time.hours, subElement)) {
return SUBPART_HOUR_SELECT; return SUBPART_HOUR_SELECT;
} }


@Override @Override
public Element getSubPartElement(String subPart) {
@SuppressWarnings("deprecation")
public com.google.gwt.user.client.Element getSubPartElement(
String subPart) {
if (SUBPART_HOUR_SELECT.equals(subPart)) { if (SUBPART_HOUR_SELECT.equals(subPart)) {
return time.hours.getElement(); return time.hours.getElement();
} }

+ 4
- 0
client/src/main/java/com/vaadin/client/ui/VDateTimeFieldCalendar.java View File

public class VDateTimeFieldCalendar extends public class VDateTimeFieldCalendar extends
VAbstractDateFieldCalendar<VDateTimeCalendarPanel, DateTimeResolution> { VAbstractDateFieldCalendar<VDateTimeCalendarPanel, DateTimeResolution> {


/**
* Constructs a widget for the InlineDateTimeField component.
*/
public VDateTimeFieldCalendar() { public VDateTimeFieldCalendar() {
super(GWT.create(VDateTimeCalendarPanel.class), MINUTE); super(GWT.create(VDateTimeCalendarPanel.class), MINUTE);
} }


@Override @Override
@SuppressWarnings("deprecation")
public void updateBufferedValues() { public void updateBufferedValues() {
// If field is invisible at the beginning, client can still be null when // If field is invisible at the beginning, client can still be null when
// this function is called. // this function is called.

+ 16
- 0
client/src/main/java/com/vaadin/client/ui/VPopupCalendar.java View File



import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.vaadin.shared.ui.datefield.DateResolution; import com.vaadin.shared.ui.datefield.DateResolution;
import com.vaadin.shared.ui.datefield.DateTimeResolution;


/** /**
* Represents a date selection component with a text field and a popup date * Represents a date selection component with a text field and a popup date
public class VPopupCalendar public class VPopupCalendar
extends VAbstractPopupCalendar<VDateCalendarPanel, DateResolution> { extends VAbstractPopupCalendar<VDateCalendarPanel, DateResolution> {


/**
* Constructs a date selection component with a text field and a pop-up date
* selector. Uses a {@link VDateCalendarPanel} as the pop-up content.
* Default resolution is {@link DateTimeResolution#YEAR}.
*/
public VPopupCalendar() { public VPopupCalendar() {
super(GWT.create(VDateCalendarPanel.class), YEAR); super(GWT.create(VDateCalendarPanel.class), YEAR);
} }
super.setCurrentResolution(resolution == null ? YEAR : resolution); super.setCurrentResolution(resolution == null ? YEAR : resolution);
} }


/**
* Creates a date based on the provided date values map. Any values of a
* more precise resolution than day are ignored.
*
* @param dateValues
* a map with date values to convert into a date
* @return the date based on the dateValues map
*/
@SuppressWarnings("deprecation")
public static Date makeDate(Map<DateResolution, Integer> dateValues) { public static Date makeDate(Map<DateResolution, Integer> dateValues) {
if (dateValues.get(YEAR) == null) { if (dateValues.get(YEAR) == null) {
return null; return null;
} }


@Override @Override
@SuppressWarnings("deprecation")
protected void updateBufferedResolutions() { protected void updateBufferedResolutions() {
super.updateBufferedResolutions(); super.updateBufferedResolutions();
Date currentDate = getDate(); Date currentDate = getDate();

+ 16
- 2
client/src/main/java/com/vaadin/client/ui/VPopupTimeCalendar.java View File

import com.vaadin.shared.ui.datefield.DateTimeResolution; import com.vaadin.shared.ui.datefield.DateTimeResolution;


/** /**
* Represents a date-time selection component with a text field and a popup date
* selector.
* Represents a date-time selection component with a text field and a pop-up
* date-and-time selector.
* *
* @author Vaadin Ltd * @author Vaadin Ltd
* *
public class VPopupTimeCalendar extends public class VPopupTimeCalendar extends
VAbstractPopupCalendar<VDateTimeCalendarPanel, DateTimeResolution> { VAbstractPopupCalendar<VDateTimeCalendarPanel, DateTimeResolution> {


/**
* Constructs a date-time selection component with a text field and a pop-up
* date-and-time selector. Uses a {@link VDateTimeCalendarPanel} as the
* pop-up content. Default resolution is {@link DateTimeResolution#MINUTE}.
*/
public VPopupTimeCalendar() { public VPopupTimeCalendar() {
super(GWT.create(VDateTimeCalendarPanel.class), MINUTE); super(GWT.create(VDateTimeCalendarPanel.class), MINUTE);
} }
super.setCurrentResolution(resolution == null ? MINUTE : resolution); super.setCurrentResolution(resolution == null ? MINUTE : resolution);
} }


/**
* Creates a date based on the provided date values map.
*
* @param dateValues
* a map with date values to convert into a date
* @return the date based on the dateValues map
*/
@SuppressWarnings("deprecation")
public static Date makeDate(Map<DateTimeResolution, Integer> dateValues) { public static Date makeDate(Map<DateTimeResolution, Integer> dateValues) {
if (dateValues.get(YEAR) == null) { if (dateValues.get(YEAR) == null) {
return null; return null;
} }


@Override @Override
@SuppressWarnings("deprecation")
protected void updateBufferedResolutions() { protected void updateBufferedResolutions() {
super.updateBufferedResolutions(); super.updateBufferedResolutions();
Date currentDate = getDate(); Date currentDate = getDate();

+ 15
- 0
server/src/main/java/com/vaadin/data/provider/DataCommunicator.java View File

public class DataCommunicator<T> extends AbstractExtension { public class DataCommunicator<T> extends AbstractExtension {


private Registration dataProviderUpdateRegistration; private Registration dataProviderUpdateRegistration;
private static final int MAXIMUM_ALLOWED_ROWS = 500;


/** /**
* Simple implementation of collection data provider communication. All data * Simple implementation of collection data provider communication. All data
*/ */
protected void onRequestRows(int firstRowIndex, int numberOfRows, protected void onRequestRows(int firstRowIndex, int numberOfRows,
int firstCachedRowIndex, int cacheSize) { int firstCachedRowIndex, int cacheSize) {
if (numberOfRows > getMaximumAllowedRows()) {
throw new IllegalStateException(
"Client tried fetch more rows than allowed. This is denied to prevent denial of service.");
}
setPushRows(Range.withLength(firstRowIndex, numberOfRows)); setPushRows(Range.withLength(firstRowIndex, numberOfRows));
markAsDirty(); markAsDirty();
} }


/**
* Set the maximum allowed rows to be fetched in one query.
*
* @return Maximum allowed rows for one query.
* @since 8.14.1
*/
protected int getMaximumAllowedRows() {
return MAXIMUM_ALLOWED_ROWS;
}

/** /**
* Triggered when rows have been dropped from the client side cache. * Triggered when rows have been dropped from the client side cache.
* *

+ 14
- 4
server/src/main/java/com/vaadin/server/VaadinService.java View File

if (value instanceof VaadinSession) { if (value instanceof VaadinSession) {
// set flag to avoid cleanup // set flag to avoid cleanup
VaadinSession serviceSession = (VaadinSession) value; VaadinSession serviceSession = (VaadinSession) value;
serviceSession.setAttribute(PRESERVE_UNBOUND_SESSION_ATTRIBUTE,
Boolean.TRUE);
serviceSession.lock();
try {
serviceSession.setAttribute(
PRESERVE_UNBOUND_SESSION_ATTRIBUTE, Boolean.TRUE);
} finally {
serviceSession.unlock();
}
} }
attrs.put(name, value); attrs.put(name, value);
} }
serviceSession.getLockInstance()); serviceSession.getLockInstance());


service.storeSession(serviceSession, newSession); service.storeSession(serviceSession, newSession);
serviceSession.setAttribute(PRESERVE_UNBOUND_SESSION_ATTRIBUTE,
null);
serviceSession.lock();
try {
serviceSession.setAttribute(
PRESERVE_UNBOUND_SESSION_ATTRIBUTE, null);
} finally {
serviceSession.unlock();
}
} }
} }



+ 6
- 0
server/src/main/resources/VAADIN/vaadinBootstrap.js View File

params += '&v-wn=' + encodeURIComponent(window.name); params += '&v-wn=' + encodeURIComponent(window.name);
} }


// This parameter is used in multiplatform-runtime as a key for
// storing the MPR UI content in the session
if (window.mprUiId) {
params += '&v-mui=' + encodeURIComponent(window.mprUiId);
}

// Detect touch device support // Detect touch device support
var supportsTouch = false; var supportsTouch = false;
try { try {

+ 8
- 0
server/src/test/java/com/vaadin/data/provider/DataCommunicatorTest.java View File

assertTrue("DataCommunicator should be marked as dirty", assertTrue("DataCommunicator should be marked as dirty",
ui.getConnectorTracker().isDirty(communicator)); ui.getConnectorTracker().isDirty(communicator));
} }


@Test(expected = IllegalStateException.class)
public void requestTooMuchRowsFail() {
TestDataCommunicator communicator = new TestDataCommunicator();
communicator.onRequestRows(0, communicator.getMaximumAllowedRows() + 10,
0, 0);
}
} }

+ 44
- 0
server/src/test/java/com/vaadin/server/VaadinServiceTest.java View File

import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingEvent;


import java.util.Collections;

import org.easymock.EasyMock; import org.easymock.EasyMock;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito;


import com.vaadin.shared.Registration; import com.vaadin.shared.Registration;
import com.vaadin.util.CurrentInstance; import com.vaadin.util.CurrentInstance;
assertEquals(1, listener.callCount); assertEquals(1, listener.callCount);
assertEquals(1, listener2.callCount); assertEquals(1, listener2.callCount);
} }

@Test
public void reinitializeSession_setVaadinSessionAttriuteWithLock() {
VaadinRequest request = Mockito.mock(VaadinRequest.class);

VaadinSession vaadinSession = Mockito.mock(VaadinSession.class);
VaadinSession newVaadinSession = Mockito.mock(VaadinSession.class);

WrappedSession session = mockSession(request, vaadinSession, "foo");

Mockito.doAnswer(invocation -> {
mockSession(request, newVaadinSession, "bar");
return null;
}).when(session).invalidate();

VaadinService.reinitializeSession(request);

Mockito.verify(vaadinSession, Mockito.times(2)).lock();
Mockito.verify(vaadinSession).setAttribute(
VaadinService.PRESERVE_UNBOUND_SESSION_ATTRIBUTE, Boolean.TRUE);
Mockito.verify(vaadinSession).setAttribute(
VaadinService.PRESERVE_UNBOUND_SESSION_ATTRIBUTE, null);
Mockito.verify(vaadinSession, Mockito.times(2)).unlock();
}

private WrappedSession mockSession(VaadinRequest request,
VaadinSession vaadinSession, String attributeName) {
WrappedSession session = Mockito.mock(WrappedSession.class);
Mockito.when(request.getWrappedSession()).thenReturn(session);

Mockito.when(session.getAttributeNames())
.thenReturn(Collections.singleton(attributeName));

Mockito.when(session.getAttribute(attributeName))
.thenReturn(vaadinSession);

VaadinService service = Mockito.mock(VaadinService.class);

Mockito.when(vaadinSession.getService()).thenReturn(service);
return session;
}
} }

+ 19
- 0
server/src/test/java/com/vaadin/tests/server/component/grid/GridTest.java View File

column.isSortableByUser()); column.isSortableByUser());
} }


@Test
public void extendGridCustomDataCommunicator() {
Grid<String> grid = new MyGrid<>();
}

public class MyDataCommunicator<T> extends DataCommunicator<T> {
@Override
protected int getMaximumAllowedRows() {
return 600;
}
}

public class MyGrid<T> extends Grid<T> {

public MyGrid() {
super(new MyDataCommunicator());
}

}
} }

+ 1
- 1
test/pom.xml View File

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring.boot.version>1.5.9.RELEASE</spring.boot.version> <spring.boot.version>1.5.9.RELEASE</spring.boot.version>
<selenium.version>3.14.0</selenium.version>
<selenium.version>3.12.0</selenium.version>


<!-- Don't care about coding style for tests. --> <!-- Don't care about coding style for tests. -->
<sonar.skip>true</sonar.skip> <sonar.skip>true</sonar.skip>

+ 1
- 1
test/servlet-containers/karaf/vaadin-karaf-bundle1/pom.xml View File

<dependency> <dependency>
<groupId>com.vaadin</groupId> <groupId>com.vaadin</groupId>
<artifactId>vaadin-osgi-integration</artifactId> <artifactId>vaadin-osgi-integration</artifactId>
<version>8.1.0.beta1</version>
<version>${vaadin.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>

+ 1
- 0
uitest/src/main/java/com/vaadin/tests/components/ui/UIInitBrowserDetails.java View File

addDetail("dst saving", "v-dstd", wb.getDSTSavings()); addDetail("dst saving", "v-dstd", wb.getDSTSavings());
addDetail("dst in effect", "v-dston", wb.isDSTInEffect()); addDetail("dst in effect", "v-dston", wb.isDSTInEffect());
addDetail("current date", "v-curdate", wb.getCurrentDate()); addDetail("current date", "v-curdate", wb.getCurrentDate());
addDetail("mpr ui id", "v-mui", "");
} }


private void addDetail(String name, String param, Object value) { private void addDetail(String name, String param, Object value) {

+ 4
- 1
uitest/src/test/java/com/vaadin/tests/components/ui/UIInitBrowserDetailsTest.java View File

public class UIInitBrowserDetailsTest extends MultiBrowserTest { public class UIInitBrowserDetailsTest extends MultiBrowserTest {


@Test @Test
public void testBrowserDetails() throws Exception {
public void testBrowserDetails() {
openTestURL(); openTestURL();
/* location */ /* location */
compareRequestAndBrowserValue("v-loc", "location", "null"); compareRequestAndBrowserValue("v-loc", "location", "null");
compareRequestAndBrowserValue("v-sw", "screen width", "-1"); compareRequestAndBrowserValue("v-sw", "screen width", "-1");
/* screen height */ /* screen height */
compareRequestAndBrowserValue("v-sh", "screen height", "-1"); compareRequestAndBrowserValue("v-sh", "screen height", "-1");
/* mpr ui id */
compareRequestAndBrowserValue("v-mui", "mpr ui id",
"any-non-empty-value");
/* timezone offset */ /* timezone offset */
assertTextNotNull("timezone offset"); assertTextNotNull("timezone offset");
/* raw timezone offset */ /* raw timezone offset */

Loading…
Cancel
Save