summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2014-09-03 11:48:47 +0300
committerTeemu Suo-Anttila <teemusa@vaadin.com>2014-09-03 15:33:01 +0300
commit927e424acc1e43a12bdbbcd971302d00717af540 (patch)
treea91f0486fb646f6d1de9a4d590e25100347cc7ec
parent600d5b436d7ca33840b1b697082d140a5040bdf3 (diff)
parentf6282cbe0386d03b57a65450bc163b20bfecfb70 (diff)
downloadvaadin-framework-927e424acc1e43a12bdbbcd971302d00717af540.tar.gz
vaadin-framework-927e424acc1e43a12bdbbcd971302d00717af540.zip
Merge remote-tracking branch 'origin/master' into grid
This merge needs Grid to use elemental.json instead of org.json Change-Id: Ib3c387c7e282b2502f266bafbdaad8727f5dc6ef
-rw-r--r--.classpath2
-rw-r--r--WebContent/VAADIN/themes/valo/_valo.scss6
-rw-r--r--WebContent/VAADIN/themes/valo/components/_accordion.scss69
-rw-r--r--WebContent/VAADIN/themes/valo/components/_all.scss22
-rw-r--r--WebContent/VAADIN/themes/valo/components/_button.scss132
-rw-r--r--WebContent/VAADIN/themes/valo/components/_calendar.scss45
-rw-r--r--WebContent/VAADIN/themes/valo/components/_checkbox.scss24
-rw-r--r--WebContent/VAADIN/themes/valo/components/_colorpicker.scss19
-rw-r--r--WebContent/VAADIN/themes/valo/components/_combobox.scss208
-rw-r--r--WebContent/VAADIN/themes/valo/components/_csslayout.scss26
-rw-r--r--WebContent/VAADIN/themes/valo/components/_datefield.scss156
-rw-r--r--WebContent/VAADIN/themes/valo/components/_dragwrapper.scss14
-rw-r--r--WebContent/VAADIN/themes/valo/components/_formlayout.scss163
-rw-r--r--WebContent/VAADIN/themes/valo/components/_label.scss132
-rw-r--r--WebContent/VAADIN/themes/valo/components/_menubar.scss2
-rw-r--r--WebContent/VAADIN/themes/valo/components/_nativeselect.scss2
-rw-r--r--WebContent/VAADIN/themes/valo/components/_notification.scss41
-rw-r--r--WebContent/VAADIN/themes/valo/components/_orderedlayout.scss2
-rw-r--r--WebContent/VAADIN/themes/valo/components/_panel.scss2
-rw-r--r--WebContent/VAADIN/themes/valo/components/_popupview.scss4
-rw-r--r--WebContent/VAADIN/themes/valo/components/_tabsheet.scss155
-rw-r--r--WebContent/VAADIN/themes/valo/components/_textarea.scss37
-rw-r--r--WebContent/VAADIN/themes/valo/components/_textfield.scss126
-rw-r--r--WebContent/VAADIN/themes/valo/components/_valo-menu.scss17
-rw-r--r--WebContent/VAADIN/themes/valo/components/_window.scss10
-rw-r--r--WebContent/VAADIN/themes/valo/shared/_contextmenu.scss6
-rw-r--r--WebContent/VAADIN/themes/valo/shared/_global.scss58
-rw-r--r--WebContent/VAADIN/themes/valo/shared/_loading-indicator.scss39
-rw-r--r--WebContent/VAADIN/themes/valo/shared/_overlay.scss188
-rw-r--r--WebContent/VAADIN/themes/valo/shared/_tooltip.scss75
-rw-r--r--WebContent/VAADIN/themes/valo/shared/_variables.scss579
-rw-r--r--WebContent/VAADIN/themes/valo/util/_anim.scss113
-rw-r--r--WebContent/VAADIN/themes/valo/util/_bevel-and-shadow.scss144
-rw-r--r--WebContent/VAADIN/themes/valo/util/_blend-modes.scss1
-rw-r--r--WebContent/VAADIN/themes/valo/util/_color.scss115
-rw-r--r--WebContent/VAADIN/themes/valo/util/_css3.scss17
-rw-r--r--WebContent/VAADIN/themes/valo/util/_gradient.scss32
-rw-r--r--WebContent/VAADIN/themes/valo/util/_lists.scss83
-rw-r--r--WebContent/VAADIN/themes/valo/util/_util.scss58
-rw-r--r--WebContent/license.html8
-rw-r--r--build.properties2
-rwxr-xr-xbuild/ide.xml10
-rw-r--r--buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java37
-rw-r--r--client-compiler/src/com/vaadin/tools/CvalChecker.java43
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java190
-rw-r--r--client/src/com/vaadin/client/componentlocator/ComponentLocator.java27
-rw-r--r--client/src/com/vaadin/client/componentlocator/VaadinFinderLocatorStrategy.java31
-rw-r--r--client/src/com/vaadin/client/debug/internal/SelectorPath.java4
-rw-r--r--client/src/com/vaadin/client/ui/VFilterSelect.java2
-rw-r--r--client/src/com/vaadin/client/ui/VGridLayout.java6
-rw-r--r--client/src/com/vaadin/client/ui/VPopupView.java55
-rw-r--r--client/src/com/vaadin/client/ui/VScrollTable.java337
-rw-r--r--client/src/com/vaadin/client/ui/VSlider.java4
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/DateCell.java30
-rw-r--r--client/src/com/vaadin/client/ui/ui/UIConnector.java4
-rw-r--r--eclipse/Development Mode (vaadin).launch29
-rw-r--r--eclipse/Super Development Mode (vaadin).launch24
-rw-r--r--gwt-files.xml12
-rw-r--r--gwt/ivy.xml2
-rw-r--r--push/build.xml2
-rw-r--r--push/ivy.xml2
-rw-r--r--server/src/com/vaadin/data/RpcDataProviderExtension.java83
-rw-r--r--server/src/com/vaadin/server/AbstractClientConnector.java6
-rw-r--r--server/src/com/vaadin/server/BootstrapHandler.java67
-rw-r--r--server/src/com/vaadin/server/ClientConnector.java7
-rw-r--r--server/src/com/vaadin/server/ClientMethodInvocation.java15
-rw-r--r--server/src/com/vaadin/server/Constants.java2
-rw-r--r--server/src/com/vaadin/server/DragAndDropService.java6
-rw-r--r--server/src/com/vaadin/server/EncodeResult.java18
-rw-r--r--server/src/com/vaadin/server/JavaScriptCallbackHelper.java15
-rw-r--r--server/src/com/vaadin/server/JsonCodec.java307
-rw-r--r--server/src/com/vaadin/server/LegacyCommunicationManager.java15
-rw-r--r--server/src/com/vaadin/server/VaadinService.java30
-rw-r--r--server/src/com/vaadin/server/VaadinServlet.java16
-rw-r--r--server/src/com/vaadin/server/communication/ClientRpcWriter.java33
-rw-r--r--server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java20
-rw-r--r--server/src/com/vaadin/server/communication/ConnectorTypeWriter.java14
-rw-r--r--server/src/com/vaadin/server/communication/DateSerializer.java10
-rw-r--r--server/src/com/vaadin/server/communication/JSONSerializer.java14
-rw-r--r--server/src/com/vaadin/server/communication/PortletBootstrapHandler.java12
-rw-r--r--server/src/com/vaadin/server/communication/PushHandler.java4
-rw-r--r--server/src/com/vaadin/server/communication/ServerRpcHandler.java77
-rw-r--r--server/src/com/vaadin/server/communication/SharedStateWriter.java18
-rw-r--r--server/src/com/vaadin/server/communication/UIInitHandler.java18
-rw-r--r--server/src/com/vaadin/server/communication/UidlRequestHandler.java8
-rw-r--r--server/src/com/vaadin/server/communication/UidlWriter.java24
-rw-r--r--server/src/com/vaadin/ui/Button.java10
-rw-r--r--server/src/com/vaadin/ui/CheckBox.java10
-rw-r--r--server/src/com/vaadin/ui/ConnectorTracker.java33
-rw-r--r--server/src/com/vaadin/ui/JavaScript.java12
-rw-r--r--server/src/com/vaadin/ui/JavaScriptFunction.java10
-rw-r--r--server/src/com/vaadin/ui/Slider.java10
-rw-r--r--server/src/com/vaadin/ui/TabSheet.java55
-rw-r--r--server/src/com/vaadin/ui/components/grid/Grid.java29
-rw-r--r--server/src/com/vaadin/ui/components/grid/Renderer.java10
-rw-r--r--server/src/com/vaadin/ui/components/grid/renderers/DateRenderer.java9
-rw-r--r--server/src/com/vaadin/ui/components/grid/renderers/HtmlRenderer.java7
-rw-r--r--server/src/com/vaadin/ui/components/grid/renderers/NumberRenderer.java9
-rw-r--r--server/src/com/vaadin/ui/components/grid/renderers/TextRenderer.java7
-rw-r--r--server/src/com/vaadin/ui/themes/ValoTheme.java2
-rw-r--r--server/tests/src/com/vaadin/server/JSONSerializerTest.java32
-rw-r--r--server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java4
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestClientMethodSerialization.java19
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/grid/RendererTest.java25
-rw-r--r--shared/ivy.xml2
-rw-r--r--shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java3
-rw-r--r--uitest/src/com/vaadin/tests/components/LayoutAttachListenerInfo.java1
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarNotifications.html41
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarNotifications.java116
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarNotificationsTest.java82
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarNotificationsTestIE.java91
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarRescheduleEvent.java105
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarRescheduleEventTest.java82
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java23
-rw-r--r--uitest/src/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopen.java79
-rw-r--r--uitest/src/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopenTest.java80
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/IntArrayRenderer.java17
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/RowAwareRenderer.java9
-rw-r--r--uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacing.java91
-rw-r--r--uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacingTest.java104
-rw-r--r--uitest/src/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java10
-rw-r--r--uitest/src/com/vaadin/tests/components/popupview/PopupViewShortcutActionHandler.java79
-rw-r--r--uitest/src/com/vaadin/tests/components/popupview/PopupViewShortcutActionHandlerTest.java79
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableMatchesMouseDownMouseUpElement.java76
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableMatchesMouseDownMouseUpElementTest.java147
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/tabsheet/NewSelectionAfterTabRemove.java61
-rw-r--r--uitest/src/com/vaadin/tests/components/tabsheet/NewSelectionAfterTabRemoveTest.java121
-rw-r--r--uitest/src/com/vaadin/tests/extensions/JavascriptManagerTest.java15
-rw-r--r--uitest/src/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java6
-rw-r--r--uitest/src/com/vaadin/tests/layouts/TestLayoutClickListeners.html239
-rw-r--r--uitest/src/com/vaadin/tests/layouts/TestLayoutClickListeners.java45
-rw-r--r--uitest/src/com/vaadin/tests/layouts/TestLayoutClickListenersTest.java200
-rw-r--r--uitest/src/com/vaadin/tests/minitutorials/v7a3/Flot.java10
-rw-r--r--uitest/src/com/vaadin/tests/minitutorials/v7a3/JSAPIUI.java12
-rw-r--r--uitest/src/com/vaadin/tests/push/TrackMessageSizeUI.java5
-rw-r--r--uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java5
-rw-r--r--uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java12
-rw-r--r--uitest/src/com/vaadin/tests/tb3/DndActionsTest.java50
-rw-r--r--uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java1
-rw-r--r--uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java3
141 files changed, 5159 insertions, 1867 deletions
diff --git a/.classpath b/.classpath
index 62c06df6c8..847fe8f769 100644
--- a/.classpath
+++ b/.classpath
@@ -24,6 +24,6 @@
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="con" path="org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;ivyXmlPath=buildhelpers%2Fivy.xml&amp;confs=ide&amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;loadSettingsOnDemand=false&amp;propertyFiles=build.properties"/>
- <classpathentry kind="con" path="org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;ivyXmlPath=gwt%2Fivy.xml&amp;confs=ide&amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;loadSettingsOnDemand=false&amp;propertyFiles=%24%7Bworkspace_loc%3Avaadin%2Fbuild.properties%7D"/>
+ <classpathentry exported="true" kind="con" path="org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;ivyXmlPath=gwt%2Fivy.xml&amp;confs=ide&amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;loadSettingsOnDemand=false&amp;propertyFiles=%24%7Bworkspace_loc%3Avaadin%2Fbuild.properties%7D"/>
<classpathentry kind="output" path="build/classes"/>
</classpath>
diff --git a/WebContent/VAADIN/themes/valo/_valo.scss b/WebContent/VAADIN/themes/valo/_valo.scss
index f7d0534da1..8a2da5b789 100644
--- a/WebContent/VAADIN/themes/valo/_valo.scss
+++ b/WebContent/VAADIN/themes/valo/_valo.scss
@@ -48,7 +48,11 @@
@include valo-global;
-// The main theme mixin
+/**
+ * The main Valo theme mixin, which outputs all the selectors and properties to produce
+ * the variation specified by global variables. Should not be included multiple times
+ * per compilation.
+ */
@mixin valo {
@include valo-common;
@include valo-components;
diff --git a/WebContent/VAADIN/themes/valo/components/_accordion.scss b/WebContent/VAADIN/themes/valo/components/_accordion.scss
index e5457a2331..91ce4efe33 100644
--- a/WebContent/VAADIN/themes/valo/components/_accordion.scss
+++ b/WebContent/VAADIN/themes/valo/components/_accordion.scss
@@ -1,3 +1,10 @@
+/**
+ * Outputs the selectors and properties for the Accordion component.
+ *
+ * @param {string} $primary-stylename (v-accordion) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ * @group accordion
+ */
@mixin valo-accordion ($primary-stylename: v-accordion, $include-additional-styles: contains($v-included-additional-styles, accordion)) {
.#{$primary-stylename} {
@include valo-accordion-style;
@@ -22,7 +29,9 @@
border-radius: 0;
@include box-shadow(none);
- > .#{$primary-stylename}-item {
+ > .#{$primary-stylename}-item,
+ > .#{$primary-stylename}-item > div > .v-caption,
+ > .#{$primary-stylename}-item > .#{$primary-stylename}-item-content {
border-radius: 0;
}
}
@@ -31,7 +40,10 @@
}
-
+/**
+ * Outputs the styles for the Accordion component root element.
+ * @group accordion
+ */
@mixin valo-accordion-style {
@include valo-panel-style;
$grad-style: valo-gradient-style($v-gradient);
@@ -41,50 +53,64 @@
}
+/**
+ * Outputs the styles for an individual Accordion item root element.
+ * @group accordion
+ */
@mixin valo-accordion-item-style {
+ $_br: $v-border-radius - first-number($v-border);
position: relative;
- overflow: hidden;
@if $v-border-radius > 0 {
- $_br: $v-border-radius - first-number($v-border);
-
&:first-child {
- border-radius: $_br $_br 0 0;
-
- .v-caption {
- border-radius: inherit;
- }
+ border-top-left-radius: $_br;
+ border-top-right-radius: $_br;
}
&:last-child {
- border-radius: 0 0 $_br $_br;
+ border-bottom-left-radius: $_br;
+ border-bottom-right-radius: $_br;
- .v-caption {
- border-radius: 0;
+ [class*="item-content"] {
+ border-radius: inherit;
}
}
}
- &:last-child:not([class*="item-open"]) .v-caption {
+ &[class*="item-open"]:last-child > div > .v-caption {
+ border-radius: 0;
+ }
+
+ &:not([class*="item-open"]):last-child > div > .v-caption {
border-bottom: none;
+ margin-bottom: 0;
}
&[class*="item-open"] + [class*="item"] {
- border-top: valo-border($color: $v-panel-background-color, $strength: 0.7);
+ border-top: valo-border($border: $v-panel-border, $color: $v-panel-background-color, $strength: 0.7);
}
}
-
+/**
+ * Outputs the styles for an individual Accordion item's caption element.
+ *
+ * @param {color} $background-color (null) - the background color of the caption. Other styles (such as font and border colors, gradients and bevels) adapt to the background color automatically.
+ * @group accordion
+ */
@mixin valo-accordion-item-caption-style ($background-color: null) {
- .v-caption {
+ border-radius: inherit;
+
+ > .v-caption {
@include valo-panel-caption-style($background-color: $background-color or $v-background-color);
display: block;
@if $background-color == null {
background: transparent;
}
border-bottom-color: first-color(valo-border($color: $v-panel-background-color));
+ border-radius: inherit;
cursor: pointer;
+ position: relative;
&:hover:before,
&:active:before {
@@ -94,6 +120,7 @@
right: 0;
bottom: 0;
left: 0;
+ border-radius: inherit;
}
@if $v-hover-styles-enabled {
@@ -110,11 +137,11 @@
}
+/**
+ * Outputs the styles for an individual Accordion item's content element.
+ * @group accordion
+ */
@mixin valo-accordion-item-content-style {
- position: absolute;
- width: 100%;
- bottom: 0;
- right: 0;
@include box-shadow(valo-bevel-and-shadow($shadow: join(inset, $v-shadow), $shadow-opacity: $v-shadow-opacity/2));
background-color: $v-panel-background-color;
@include box-sizing(border-box);
diff --git a/WebContent/VAADIN/themes/valo/components/_all.scss b/WebContent/VAADIN/themes/valo/components/_all.scss
index b41a2f3308..0efc363a82 100644
--- a/WebContent/VAADIN/themes/valo/components/_all.scss
+++ b/WebContent/VAADIN/themes/valo/components/_all.scss
@@ -42,13 +42,33 @@
@import "valo-menu";
+/**
+ * Outputs all the selectors and properties for all individual components to produce
+ * the variation specified by global variables.
+ *
+ * This mixin can be called multiple times for a theme, if you for instance wish to
+ * generate alternative color versions of the components.
+ *
+ * @example scss
+ * .my-theme {
+ * // The default color variation
+ * @include valo;
+ *
+ * .sidebar {
+ * // For the sidebar context, we generate a darker variant of all components
+ * $v-background-color: #696969;
+ * background-color: $v-background-color;
+ * @include valo-components;
+ * }
+ * }
+ */
@mixin valo-components {
@if v-is-included(absolutelayout) {
@include valo-absolutelayout;
}
- @if v-is-included(orderedlayout) {
+ @if v-is-included(orderedlayout) or v-is-included(verticallayout) or v-is-included(horizontallayout) {
@include valo-orderedlayout;
}
diff --git a/WebContent/VAADIN/themes/valo/components/_button.scss b/WebContent/VAADIN/themes/valo/components/_button.scss
index 42953ea610..eb57e20d2a 100644
--- a/WebContent/VAADIN/themes/valo/components/_button.scss
+++ b/WebContent/VAADIN/themes/valo/components/_button.scss
@@ -1,3 +1,11 @@
+/**
+ * Outputs the selectors and properties for the Button component.
+ *
+ * @param {string} $primary-stylename (v-button) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group button
+ */
@mixin valo-button ($primary-stylename: v-button, $include-additional-styles: contains($v-included-additional-styles, button)) {
.#{$primary-stylename} {
@include valo-button-static-style;
@@ -97,9 +105,14 @@
}
-
-
-
+/**
+ * Outputs the static styles (i.e. styles which don't differ between button variants) for a button.
+ *
+ * @param {list} $states (normal hover focus active disabled) - The button states for which to output corresponding static styles
+ * @param {bool} $vertical-centering (true) - Should the output contain a vertical centering guide
+ *
+ * @group button
+ */
@mixin valo-button-static-style ($states: (normal, hover, focus, active, disabled), $vertical-centering: true) {
@if contains($states, normal) {
position: relative;
@@ -148,14 +161,30 @@
}
-
-
-
+/**
+ * Outputs the styles for a button variant.
+ *
+ * @param {size} $unit-size ($v-unit-size) - The sizing of the button, which corresponds its height
+ * @param {size | list} $padding (null) - The padding of the button. Computed from other parameters by default.
+ * @param {color} $font-color (null) - The font color of the button. Computed from the $background-color by default.
+ * @param {number} $font-weight ($v-font-weight + 100) - The font weight of the button
+ * @param {size} $font-size (null) - The font size of the button. Inherited from the parent by default.
+ * @param {string} $cursor (null) - The mouse cursor of the button
+ * @param {color} $background-color ($v-background-color) - The background color of the button
+ * @param {list} $border ($v-border) - The border of the button
+ * @param {size} $border-radius ($v-border-radius) - The border-radius of the button
+ * @param {list} $gradient ($v-gradient) - Valo specific gradient value. See the documentation for $v-gradient.
+ * @param {list} $bevel ($v-bevel) - Box-shadow value according to $v-bevel documentation
+ * @param {list} $shadow ($v-shadow) - Box-shadow value according to $v-shadow documentation
+ * @param {list} $states (normal hover focus active disabled) - The button states for which to output corresponding styles
+ *
+ * @group button
+ */
@mixin valo-button-style (
$unit-size : $v-unit-size,
- $padding : null, // Computed by default
+ $padding : null,
- $font-color : null, // Computed by default
+ $font-color : null,
$font-weight : $v-font-weight + 100,
$font-size : null, // Inherited by default
$cursor : null,
@@ -207,7 +236,7 @@
}
@if $bevel and type-of($_font-color) == color and type-of($background-color) == color {
- text-shadow: valo-text-shadow($_font-color, $background-color, $bevel);
+ text-shadow: valo-text-shadow($_font-color, $background-color);
}
@if $bevel == none and $shadow == none {
@@ -237,8 +266,14 @@
}
-
-
+/**
+ * Outputs the hover state styles for a button. The styles are by default targeted
+ * for a pseudo element which is shown on top of the normal state button.
+ *
+ * @group button
+ *
+ * @param {color} $background-color ($v-background-color) - The background color of the normal state button
+ */
@mixin valo-button-hover-style ($background-color: $v-background-color) {
$bg: darken($background-color, 25%);
@if is-dark-color($background-color) {
@@ -248,8 +283,16 @@
}
-
-@mixin valo-button-focus-style ($background-color: $v-background-color, $border-fallback: inherit, $include-box-shadow: true) {
+/**
+ * Outputs the focus state styles for a button. The styles are by default targeted
+ * for a pseudo element which is shown on top of the normal state button.
+ *
+ * @group button
+ *
+ * @param {color} $background-color ($v-background-color) - The background color of the normal state button
+ * @param {list} $border-fallback (inherit) - If the luminance of $v-focus-color is less than the $background-color, the focus color is also used for the border color. If not, then $border-fallback is used for the focus element's border value.
+ */
+@mixin valo-button-focus-style ($background-color: $v-background-color, $border-fallback: inherit) {
$focus-color: $v-focus-color;
@if color-luminance($focus-color) + 50 < color-luminance($background-color) {
@@ -258,22 +301,31 @@
border: $border-fallback or valo-border($color: $background-color);
}
- @include valo-focus-style($include-box-shadow: $include-box-shadow);
+ @include valo-focus-style;
}
-
+/**
+ * Outputs the active state (pressed/down) styles for a button. The styles are by default targeted
+ * for a pseudo element which is shown on top of the normal state button.
+ *
+ * @group button
+ *
+ * @param {color} $background-color ($v-background-color) - The background color of the normal state button
+ */
@mixin valo-button-active-style ($background-color: $v-background-color) {
$bg: scale-color($background-color, $lightness: -50%, $saturation: saturation($background-color));
background-color: rgba($bg, .2);
}
-
-
-
+/**
+ * Outputs styles to allow vertical centering of the icon and the caption, independent of the
+ * height of the button.
+ *
+ * @group button
+ */
@mixin valo-button-vertical-centering {
- // Vertical centering of icon and caption, independent of the height of the button
@include valo-vertical-align-guide($to-align: div, $pseudo-element: before);
// WebKit handles line-heights and vertical-alignments somewhat differently, so we need to adjust
@@ -293,8 +345,14 @@
}
-
-
+/**
+ * Output styles for a borderless button. Expects that the targeted element
+ * already has both valo-button-static-style and valo-button-style included.
+ *
+ * @param {color} $font-color (inherit) - The font color of the borderless button
+ *
+ * @group button
+ */
@mixin valo-button-borderless-style ($font-color: inherit) {
border: none;
@include box-shadow(none);
@@ -321,7 +379,15 @@
}
-@mixin valo-button-quiet-style ($primary-stylename: v-button) {
+/**
+ * Output styles for a "quiet" button (a button whose outline is only shown
+ * once the user hovers over the button caption). Expects that the targeted
+ * element already has both valo-button-static-style and valo-button-style
+ * included.
+ *
+ * @group button
+ */
+@mixin valo-button-quiet-style {
visibility: hidden;
&:focus,
@@ -329,19 +395,24 @@
visibility: visible;
}
- .#{$primary-stylename}-wrap {
+ [class*="wrap"] {
visibility: visible;
}
- .#{$primary-stylename}-caption {
+ [class*="caption"] {
// For IE8
display: inline-block;
}
}
-@mixin valo-button-icon-align-right-style ($primary-stylename: v-button) {
- .#{$primary-stylename}-wrap {
+/**
+ * Output styles to align a button's icon on the right side of its caption.
+ *
+ * @group button
+ */
+@mixin valo-button-icon-align-right-style {
+ [class*="wrap"] {
display: inline-block;
}
@@ -357,12 +428,17 @@
}
-@mixin valo-button-icon-align-top-style ($primary-stylename: v-button) {
+/**
+ * Output styles to align a button's icon on top of its caption.
+ *
+ * @group button
+ */
+@mixin valo-button-icon-align-top-style {
height: auto;
padding-top: ceil($v-unit-size/9);
padding-bottom: ceil($v-unit-size/9);
- .#{$primary-stylename}-wrap {
+ [class*="wrap"] {
display: inline-block;
}
diff --git a/WebContent/VAADIN/themes/valo/components/_calendar.scss b/WebContent/VAADIN/themes/valo/components/_calendar.scss
index 753291eea9..bf1dc1c3dc 100644
--- a/WebContent/VAADIN/themes/valo/components/_calendar.scss
+++ b/WebContent/VAADIN/themes/valo/components/_calendar.scss
@@ -1,6 +1,27 @@
+/**
+ * A list of colors for custom event colors. Can be an empty list of you don't
+ * need any custom event colors.
+ *
+ * @example javascript
+ * // Java code
+ * // 'event' is an instance of EditableCalendarEvent
+ * event.setStyleName("color1"); // 1st color in the list
+ * event.setStyleName("color2"); // 2nd color in the list
+ * // etc.
+ *
+ * @group calendar
+ */
$v-calendar-event-colors: #00ace0, #2d9f19, #d18100, #ce3812, #2d55cd !default;
+/**
+ * Outputs the global selectors and properties for the Calendar component - styles which are
+ * considered mandatory for the component to work properly.
+ *
+ * @param {string} $primary-stylename (v-calendar) - the primary style name for the selectors
+ *
+ * @group calendar
+ */
@mixin valo-calendar-global ($primary-stylename: v-calendar) {
.#{$primary-stylename}-month-day-scrollable {
overflow-y: scroll;
@@ -103,12 +124,13 @@ $v-calendar-event-colors: #00ace0, #2d9f19, #d18100, #ce3812, #2d55cd !default;
}
-
-
-
-
-
-
+/**
+ * Outputs the selectors and properties for the Calendar component.
+ *
+ * @param {string} $primary-stylename (v-calendar) - the primary style name for the selectors
+ *
+ * @group calendar
+ */
@mixin valo-calendar ($primary-stylename: v-calendar) {
@@ -525,12 +547,23 @@ $v-calendar-event-colors: #00ace0, #2d9f19, #d18100, #ce3812, #2d55cd !default;
}
+/**
+ * Outputs the styles for the previous button.
+ *
+ * @group calendar
+ */
@mixin valo-calendar-prev-style {
&:before {
@include valo-tabsheet-scroller-prev-icon-style;
}
}
+
+/**
+ * Outputs the styles for the next button.
+ *
+ * @group calendar
+ */
@mixin valo-calendar-next-style {
&:before {
@include valo-tabsheet-scroller-next-icon-style;
diff --git a/WebContent/VAADIN/themes/valo/components/_checkbox.scss b/WebContent/VAADIN/themes/valo/components/_checkbox.scss
index 9fe360c6ed..7ad08ad74d 100644
--- a/WebContent/VAADIN/themes/valo/components/_checkbox.scss
+++ b/WebContent/VAADIN/themes/valo/components/_checkbox.scss
@@ -1,3 +1,11 @@
+/**
+ * Outputs the selectors and properties for the CheckBox component.
+ *
+ * @param {string} $primary-stylename (v-checkbox) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group checkbox
+ */
@mixin valo-checkbox ($primary-stylename: v-checkbox, $include-additional-styles: contains($v-included-additional-styles, checkbox)) {
.#{$primary-stylename} {
@@ -20,12 +28,26 @@
}
+/**
+ * Outputs the font icon to indicate the checked state.
+ *
+ * @group checkbox
+ */
@mixin valo-checkbox-icon-style {
content: "\f00c";
font-family: FontAwesome;
}
+/**
+ * Outputs the styles for a checkbox variant.
+ *
+ * @param {color} $background-color ($v-background-color) - The background color of the checkbox
+ * @param {size} $unit-size ($v-unit-size) - The sizing of the checkbox. The width and height of the checkbox will be the unit-size divided by 2.
+ * @param {color} $selection-color ($v-selection-color) - The color of the checked state icon
+ *
+ * @group checkbox
+ */
@mixin valo-checkbox-style ($background-color: $v-background-color, $unit-size: $v-unit-size, $selection-color: $v-selection-color) {
// So that we can use the same 'unit-size' for all component sizes
@@ -57,7 +79,7 @@
margin: 0;
&:focus ~ label:before {
- @include valo-button-focus-style($background-color: $background-color, $border-fallback: null, $include-box-shadow: false);
+ @include valo-button-focus-style($background-color: $background-color, $border-fallback: null);
@include box-shadow(valo-bevel-and-shadow($background-color: $background-color, $bevel: $v-bevel, $shadow: $v-shadow, $gradient: $v-gradient, $include-focus: true));
}
diff --git a/WebContent/VAADIN/themes/valo/components/_colorpicker.scss b/WebContent/VAADIN/themes/valo/components/_colorpicker.scss
index 4460aafb21..b859904e59 100644
--- a/WebContent/VAADIN/themes/valo/components/_colorpicker.scss
+++ b/WebContent/VAADIN/themes/valo/components/_colorpicker.scss
@@ -1,3 +1,11 @@
+/**
+ * Outputs the global selectors and properties for the ColorPicker component - styles which are
+ * considered mandatory for the component to work properly.
+ *
+ * @param {string} $primary-stylename (v-colorpicker) - the primary style name for the selectors
+ *
+ * @group colorpicker
+ */
@mixin valo-colorpicker-global ($primary-stylename: v-colorpicker) {
$valo-colorpicker-pathPrefix: null;
@if $v-relative-paths == false {
@@ -73,10 +81,13 @@
}
-
-
-
-
+/**
+ * Outputs the selectors and properties for the ColorPicker component.
+ *
+ * @param {string} $primary-stylename (v-colorpicker) - the primary style name for the selectors
+ *
+ * @group colorpicker
+ */
@mixin valo-colorpicker ($primary-stylename: v-colorpicker) {
.#{$primary-stylename}-popup.v-window {
diff --git a/WebContent/VAADIN/themes/valo/components/_combobox.scss b/WebContent/VAADIN/themes/valo/components/_combobox.scss
index 93cb5393ee..0b756126ff 100644
--- a/WebContent/VAADIN/themes/valo/components/_combobox.scss
+++ b/WebContent/VAADIN/themes/valo/components/_combobox.scss
@@ -1,9 +1,17 @@
+/**
+ * Outputs the selectors and properties for the ComboBox component.
+ *
+ * @param {string} $primary-stylename (v-filterselect) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group combobox
+ */
@mixin valo-combobox ($primary-stylename: v-filterselect, $include-additional-styles: contains($v-included-additional-styles, combobox)) {
.#{$primary-stylename} {
position: relative;
width: $v-default-field-width;
- @include valo-combobox-style($primary-stylename: $primary-stylename);
+ @include valo-combobox-style;
white-space: nowrap;
.v-icon {
@@ -24,39 +32,11 @@
}
.#{$primary-stylename}-suggestpopup {
- @include valo-combobox-popup-style($primary-stylename: $primary-stylename);
+ @include valo-combobox-popup-style;
}
.#{$primary-stylename}-no-input {
- cursor: pointer;
- text-shadow: valo-text-shadow();
-
- @if $v-border-radius != $v-textfield-border-radius {
- border-radius: $v-border-radius;
- }
-
- .#{$primary-stylename}-input {
- @include user-select(none);
- @include valo-gradient;
- cursor: inherit;
- @include box-shadow(valo-bevel-and-shadow($bevel: $v-bevel, $shadow: $v-shadow, $gradient: $v-gradient));
- @include valo-border-with-gradient($border: $v-border, $color: $v-background-color, $gradient: $v-gradient);
- text-shadow: inherit;
- text-overflow: ellipsis;
- border-radius: inherit;
-
- &:focus {
- @include valo-textfield-focus-style($bevel: $v-bevel, $shadow: $v-shadow, $gradient: $v-gradient, $background-color: $v-background-color);
- }
- }
-
- .#{$primary-stylename}-button {
- border-left: none !important;
- }
-
- &:hover .#{$primary-stylename}-button:before {
- color: inherit;
- }
+ @include valo-combobox-no-input-style;
}
@@ -110,16 +90,29 @@
}
-
-
-
-
+/**
+ * Outputs the styles for a combobox variant.
+ *
+ * @param {size} $unit-size ($v-unit-size) - The sizing of the combobox, which corresponds its height
+ * @param {color} $font-color (null) - The font color of the combobox. Computed from the $background-color by default.
+ * @param {number} $font-weight (max(400, $v-font-weight)) - The font weight of the combobox
+ * @param {size} $font-size (null) - The font size of the combobox. Inherited from the parent by default.
+ * @param {color} $background-color ($v-textfield-background-color) - The background color of the combobox
+ * @param {list} $border ($v-textfield-border) - The border of the combobox
+ * @param {size} $border-radius ($v-textfield-border-radius) - The border-radius of the combobox
+ * @param {list} $gradient (none) - Valo specific gradient value. See the documentation for $v-gradient.
+ * @param {list} $bevel ($v-textfield-bevel) - Box-shadow value according to $v-bevel documentation
+ * @param {list} $shadow ($v-textfield-shadow) - Box-shadow value according to $v-shadow documentation
+ * @param {list} $states (normal focus disabled) - The combobox states for which to output corresponding styles
+ *
+ * @group combobox
+ */
@mixin valo-combobox-style (
$unit-size: $v-unit-size,
- $font-color: null, // Computed by default
+ $font-color: null,
$font-weight: max(400, $v-font-weight),
- $font-size: null, // Inherited by default
+ $font-size: null,
$background-color: $v-textfield-background-color,
$border: $v-textfield-border,
@@ -129,14 +122,13 @@
$bevel: $v-textfield-bevel,
$shadow: $v-textfield-shadow,
- $primary-stylename: v-filterselect,
$states: normal focus disabled
) {
height: $unit-size;
border-radius: $border-radius;
- .#{$primary-stylename}-input {
+ [class*="input"] {
@include valo-combobox-input-style(
$unit-size: $unit-size,
$gradient: $gradient,
@@ -151,7 +143,7 @@
$states: $states);
}
- .v-icon + .#{$primary-stylename}-input {
+ .v-icon + [class*="input"] {
padding-left: $unit-size;
}
@@ -171,17 +163,17 @@
padding-top: .12em;
}
- &.#{$primary-stylename}-prompt > .#{$primary-stylename}-input {
+ &[class*="prompt"] > [class*="input"] {
@include valo-textfield-prompt-style($background-color);
}
- .#{$primary-stylename}-button {
- @include valo-combobox-button-style($unit-size: $unit-size, $bevel: $bevel, $background-color: $background-color);
+ [class$="button"] {
+ @include valo-combobox-button-style($unit-size: $unit-size, $bevel: $bevel, $background-color: $background-color, $border-radius: $border-radius, $border: $border);
}
&.v-disabled {
@include opacity($v-textfield-disabled-opacity);
- & .#{$primary-stylename}-button {
+ & [class$="button"] {
cursor: default;
pointer-events: none;
&:active:after {
@@ -191,11 +183,11 @@
}
&.v-readonly {
- .#{$primary-stylename}-input {
+ [class*="input"] {
@include valo-textfield-readonly-style;
}
- .#{$primary-stylename}-button {
+ [class$="button"] {
cursor: default;
pointer-events: none;
&:active:after {
@@ -206,18 +198,34 @@
}
-
-
+/**
+ * Outputs the styles for a combobox variant input element.
+ *
+ * @param {size} $unit-size ($v-unit-size) - The sizing of the input (affects the padding only, width and height are 100%)
+ * @param {size | list} $padding (null) - The padding of the input. Computed from other parameters by default.
+ * @param {color} $font-color (null) - The font color of the input. Computed from the $background-color by default.
+ * @param {number} $font-weight (null) - The font weight of the input. Inherited from the parent by default.
+ * @param {size} $font-size (null) - The font size of the combobox. Inherited from the parent by default.
+ * @param {color} $background-color ($v-textfield-background-color) - The background color of the input
+ * @param {list} $border ($v-textfield-border) - The border of the input
+ * @param {size} $border-radius ($v-textfield-border-radius) - The border-radius of the input
+ * @param {list} $gradient (none) - Valo specific gradient value. See the documentation for $v-gradient.
+ * @param {list} $bevel ($v-textfield-bevel) - Box-shadow value according to $v-bevel documentation
+ * @param {list} $shadow ($v-textfield-shadow) - Box-shadow value according to $v-shadow documentation
+ * @param {list} $states (normal focus disabled) - The combobox states for which to output corresponding styles
+ *
+ * @group combobox
+ */
@mixin valo-combobox-input-style (
$unit-size: $v-unit-size,
- $padding: null, // Computed by default
+ $padding: null,
- $font-color: null, // Computed by default
- $font-weight: null, // Inherited by default
- $font-size: null, // Inherited by default
+ $font-color: null,
+ $font-weight: null,
+ $font-size: null,
$background-color: $v-textfield-background-color,
- $border: $v-border,
+ $border: $v-textfield-border,
$border-radius: $v-textfield-border-radius,
$gradient: none,
@@ -246,13 +254,19 @@
}
-
-
-
-
-
-@mixin valo-combobox-button-style ($unit-size: $v-unit-size, $bevel: $v-bevel, $background-color: $v-textfield-background-color) {
- $border-width: first-number($v-textfield-border);
+/**
+ * Outputs the styles for a combobox variant button element.
+ *
+ * @param {size} $unit-size ($v-unit-size) - The sizing of the button, which corresponds its width.
+ * @param {list} $bevel ($v-textfield-bevel) - Box-shadow value according to $v-bevel documentation
+ * @param {color} $background-color ($v-textfield-background-color) - The background color of the input, which affects the font color of the button
+ * @param {size} $border-radius ($v-textfield-border-radius) - The border-radius of the input, which affects the border-radius of the button
+ * @param {list} $border ($v-textfield-border) - The border of the input, which affects the border of the button
+ *
+ * @group combobox
+ */
+@mixin valo-combobox-button-style ($unit-size: $v-unit-size, $bevel: $v-bevel, $background-color: $v-textfield-background-color, $border-radius: $v-border-radius, $border: $v-textfield-border) {
+ $border-width: first-number($v-textfield-border) or 0;
@include valo-tappable;
position: absolute;
top: $border-width;
@@ -310,16 +324,23 @@
}
-
+/**
+ * Outputs the font icon styles for the combobox drop down button.
+ *
+ * @group combobox
+ */
@mixin valo-combobox-button-icon-style {
font-family: FontAwesome;
content: "\f078";
}
-
-
-@mixin valo-combobox-popup-style ($primary-stylename: v-filterselect) {
+/**
+ * Outputs the styles for a combobox popup.
+ *
+ * @group combobox
+ */
+@mixin valo-combobox-popup-style {
@if $v-animations-enabled {
@if $v-overlay-animate-in {
@@ -331,11 +352,15 @@
// closing when the user selects an item
}
- .#{$primary-stylename}-suggestmenu {
+ [class$="suggestmenu"] {
@include valo-selection-overlay-style($animate-in: false, $animate-out: false);
- box-sizing: border-box;
+ @include box-sizing(border-box);
position: relative;
z-index: 1;
+
+ &[style*="height"] {
+ @include box-sizing(content-box);
+ }
}
margin-top: ceil($v-unit-size/8) !important;
@@ -355,7 +380,7 @@
@include valo-selection-item-selected-style;
}
- .#{$primary-stylename}-status {
+ [class$="status"] {
position: absolute;
right: $v-border-radius;
$bg: scale-color($v-background-color, $lightness: -15%);
@@ -371,7 +396,7 @@
pointer-events: none;
@if $v-animations-enabled {
- @include animation(valo-anim-slide-in-down 200ms 80ms backwards);
+ @include animation(valo-animate-in-slide-down 200ms 80ms backwards);
}
> * {
@@ -396,9 +421,24 @@
color: valo-font-color($v-background-color);
+ &:after {
+ // Extend click target when hovering over (popup width might change between pages)
+ content: "";
+ position: absolute;
+ display: block;
+ border-radius: 50%;
+ }
+
&:hover {
@include opacity(1);
background: rgba($v-background-color, .5);
+
+ &:after {
+ top: -10px;
+ bottom: -10px;
+ left: -20px;
+ right: -20px;
+ }
}
span {
@@ -434,3 +474,35 @@
display: none;
}
}
+
+@mixin valo-combobox-no-input-style {
+ cursor: pointer;
+ text-shadow: valo-text-shadow();
+
+ @if $v-border-radius != $v-textfield-border-radius {
+ border-radius: $v-border-radius;
+ }
+
+ [class*="input"] {
+ @include user-select(none);
+ @include valo-gradient;
+ cursor: inherit;
+ @include box-shadow(valo-bevel-and-shadow($bevel: $v-bevel, $shadow: $v-shadow, $gradient: $v-gradient));
+ @include valo-border-with-gradient($border: $v-border, $color: $v-background-color, $gradient: $v-gradient);
+ text-shadow: inherit;
+ text-overflow: ellipsis;
+ border-radius: inherit;
+
+ &:focus {
+ @include valo-textfield-focus-style($bevel: $v-bevel, $shadow: $v-shadow, $gradient: $v-gradient, $background-color: $v-background-color);
+ }
+ }
+
+ [class$="button"] {
+ border-left: none !important;
+ }
+
+ &:hover [class$="button"]:before {
+ color: inherit;
+ }
+}
diff --git a/WebContent/VAADIN/themes/valo/components/_csslayout.scss b/WebContent/VAADIN/themes/valo/components/_csslayout.scss
index b0fa4362e7..3525bcad5a 100644
--- a/WebContent/VAADIN/themes/valo/components/_csslayout.scss
+++ b/WebContent/VAADIN/themes/valo/components/_csslayout.scss
@@ -1,6 +1,20 @@
+/**
+ * The amount of spacing between different widgets in a component group.
+ * If null, a computed value is used ($v-border size * -1, or 1px if $v-border size is 0)
+ *
+ * @group csslayout
+ */
$v-component-group-spacing: null !default;
+/**
+ * Outputs the additional styles for the CssLayout component. Does not produce any other output.
+ *
+ * @param {string} $primary-stylename (v-csslayout) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group csslayout
+ */
@mixin valo-csslayout ($primary-stylename: v-csslayout, $include-additional-styles: contains($v-included-additional-styles, csslayout)){
@if $include-additional-styles {
.#{$primary-stylename}-well {
@@ -20,6 +34,18 @@ $v-component-group-spacing: null !default;
}
+/**
+ * Outputs the styles for a horizontal component group. The target component is
+ * expected to be a CssLayout, which is a single DIV element with child components
+ * directly inside.
+ *
+ * @group csslayout
+ *
+ * @example scss
+ * .my-csslayout {
+ * @include valo-component-group;
+ * }
+ */
@mixin valo-component-group {
white-space: nowrap;
position: relative;
diff --git a/WebContent/VAADIN/themes/valo/components/_datefield.scss b/WebContent/VAADIN/themes/valo/components/_datefield.scss
index 81c7fa0e5e..b1d5dcce5b 100644
--- a/WebContent/VAADIN/themes/valo/components/_datefield.scss
+++ b/WebContent/VAADIN/themes/valo/components/_datefield.scss
@@ -1,9 +1,17 @@
+/**
+ * Outputs the selectors and properties for the DateField component.
+ *
+ * @param {string} $primary-stylename (v-datefield) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group datefield
+ */
@mixin valo-datefield ($primary-stylename: v-datefield, $include-additional-styles: contains($v-included-additional-styles, datefield)) {
.#{$primary-stylename} {
position: relative;
width: $v-default-field-width;
- @include valo-datefield-style($primary-stylename: $primary-stylename);
+ @include valo-datefield-style;
}
.#{$primary-stylename}-error {
@@ -89,6 +97,13 @@
}
+/**
+ * Outputs the selectors and properties for the InlineDateField component.
+ *
+ * @param {string} $primary-stylename (v-inline-datefield) - the primary style name for the selectors
+ *
+ * @group datefield
+ */
@mixin valo-inline-datefield ($primary-stylename: v-inline-datefield) {
@include valo-datefield-calendarpanel-style(#{$primary-stylename}-calendarpanel);
@@ -100,9 +115,19 @@
}
-
-
-
+/**
+ * Outputs the styles for a date field variant.
+ *
+ * @param {list} $bevel ($v-textfield-bevel) - Box-shadow value according to $v-bevel documentation
+ * @param {list} $shadow ($v-textfield-shadow) - Box-shadow value according to $v-shadow documentation
+ * @param {size} $unit-size ($v-unit-size) - The sizing of the datefield, which corresponds its height
+ * @param {list} $border ($v-textfield-border) - The border of the datefield
+ * @param {size} $border-radius ($v-textfield-border-radius) - The border-radius of the datefield
+ * @param {color} $background-color ($v-textfield-background-color) - The background color of the datefield
+ * @param {list} $states (normal focus disabled) - The datefield states for which to output corresponding styles
+ *
+ * @group datefield
+ */
@mixin valo-datefield-style (
$bevel : $v-textfield-bevel,
$shadow : $v-textfield-shadow,
@@ -110,14 +135,13 @@
$border : $v-textfield-border,
$border-radius : $v-textfield-border-radius,
$background-color : $v-textfield-background-color,
- $primary-stylename : v-datefield,
$states : normal focus disabled
) {
height: $unit-size;
border-radius: $border-radius;
- .#{$primary-stylename}-textfield {
+ [class*="textfield"] {
@include box-sizing(border-box);
@include valo-textfield-style($bevel: $bevel, $shadow: $shadow, $unit-size: $unit-size, $border: $border, $border-radius: $border-radius, $background-color: $background-color, $states: $states) ;
padding-left: $unit-size * 1.2;
@@ -126,18 +150,18 @@
border-radius: inherit;
}
- &.#{$primary-stylename}-prompt > .#{$primary-stylename}-textfield {
+ &[class*="prompt"] > [class*="textfield"] {
@include valo-textfield-prompt-style($background-color);
}
- .#{$primary-stylename}-button {
+ [class$="button"] {
@include valo-datefield-button-style($unit-size: $unit-size, $bevel: $bevel, $background-color: $background-color, $border-radius: $border-radius, $border: $border);
}
&.v-disabled {
@include opacity($v-disabled-opacity);
- .#{$primary-stylename}-button {
+ [class$="button"] {
cursor: default;
pointer-events: none;
&:active:after {
@@ -147,11 +171,11 @@
}
&.v-readonly {
- .#{$primary-stylename}-textfield {
+ [class*="textfield"] {
@include valo-textfield-readonly-style;
}
- .#{$primary-stylename}-button {
+ [class$="button"] {
cursor: default;
pointer-events: none;
&:active:after {
@@ -162,10 +186,19 @@
}
-
-
+/**
+ * Outputs the styles for a date field variant button element.
+ *
+ * @param {size} $unit-size ($v-unit-size) - The sizing of the button, which corresponds its width.
+ * @param {list} $bevel ($v-textfield-bevel) - Box-shadow value according to $v-bevel documentation
+ * @param {color} $background-color ($v-textfield-background-color) - The background color of the input, which affects the font color of the button
+ * @param {size} $border-radius ($v-textfield-border-radius) - The border-radius of the input, which affects the border-radius of the button
+ * @param {list} $border ($v-textfield-border) - The border of the input, which affects the border of the button
+ *
+ * @group datefield
+ */
@mixin valo-datefield-button-style ($unit-size: $v-unit-size, $bevel: $v-bevel, $background-color: $v-textfield-background-color, $border-radius: $v-border-radius, $border: $v-textfield-border) {
- $border-width: first-number($border) or first-number($v-textfield-border);
+ $border-width: first-number($border) or 0;
@include valo-tappable;
-webkit-appearance: none;
background: transparent;
@@ -223,16 +256,22 @@
}
-
-
+/**
+ * Outputs the font icon styles for the date field drop down button.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-button-icon-style {
font-family: FontAwesome;
content: "\f073";
}
-
-
+/**
+ * Outputs the styles for a date field popup.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-popup-style {
@include valo-overlay-style;
@@ -241,8 +280,9 @@
width: auto;
table {
- border-collapse: collapse;
+ border-collapse: collapse;
border-spacing: 0;
+ margin: 0 auto;
}
td {
@@ -253,6 +293,13 @@
}
+/**
+ * Outputs the styles for calendar panel (i.e. month view).
+ *
+ * @param {string} $primary-stylename (v-datefield-calendarpanel) - the primary style name for the selectors
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-style ($primary-stylename: v-datefield-calendarpanel) {
.#{$primary-stylename} {
font-size: $v-font-size;
@@ -360,7 +407,7 @@
}
td.#{$primary-stylename}-month {
- width: round($v-unit-size * 3.5);
+ width: round($v-unit-size * 4);
@include valo-datefield-calendarpanel-month-style;
}
@@ -409,8 +456,11 @@
}
-
-
+/**
+ * Outputs the styles for an individual day element in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-day-style {
@include box-sizing(border-box);
width: round($v-unit-size * 0.8);
@@ -429,29 +479,60 @@
}
}
+
+/**
+ * Outputs the hover state styles for an individual day element in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-day-hover-style {
color: $v-selection-color;
}
+
+/**
+ * Outputs the styles for an individual day element, which are not part of the current month, in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-day-offmonth-style {
color: mix(valo-font-color($v-background-color), $v-background-color);
background: transparent;
}
+
+/**
+ * Outputs the styles for todays day element in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-day-today-style {
color: valo-font-color($v-background-color, 0.9);
font-weight: max(600, $v-font-weight + 100);
border-color: valo-font-color($v-background-color, 0.3);
}
+
+/**
+ * Outputs the styles for the selected day element in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-day-selected-style {
color: valo-font-color($v-selection-color);
@include valo-gradient($v-selection-color);
border: none;
+ font-weight: max(600, $v-font-weight + 100);
}
+
+/**
+ * Outputs the focus state styles for an individual day element in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-day-focused-style {
- @include valo-focus-style($include-box-shadow: true);
+ @include valo-focus-style;
position: relative; // Show above other cells
.v-ie8 & {
@@ -460,26 +541,55 @@
}
+/**
+ * Outputs the font icon styles for the next month button in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-nextmonth-icon-style {
font-family: FontAwesome;
content: "\f105";
}
+
+/**
+ * Outputs the font icon styles for the previous month button in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-prevmonth-icon-style {
font-family: FontAwesome;
content: "\f104";
}
+
+/**
+ * Outputs the font icon styles for the next year button in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-nextyear-icon-style {
font-family: FontAwesome;
content: "\f101";
}
+
+/**
+ * Outputs the font icon styles for the previous year button in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-prevyear-icon-style {
font-family: FontAwesome;
content: "\f100";
}
+
+/**
+ * Outputs the styles for the current month and year title element in a calendar panel.
+ *
+ * @group datefield
+ */
@mixin valo-datefield-calendarpanel-month-style {
color: $v-selection-color;
}
diff --git a/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss b/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss
index 1eaf078661..6e4859b82c 100644
--- a/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss
+++ b/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss
@@ -1,3 +1,10 @@
+/**
+ * Outputs the styles and selectors for the DragAndDropWrapper component.
+ *
+ * @param {string} $primary-stylename (v-ddwrapper) - the primary style name for the selectors
+ *
+ * @group drag-n-drop
+ */
@mixin valo-dragwrapper ($primary-stylename: v-ddwrapper) {
[draggable=true] {
@@ -103,8 +110,11 @@
}
-
-
+/**
+ * Outputs the styles for a drop target when the drag is on top of it.
+ *
+ * @group drag-n-drop
+ */
@mixin valo-ddwrapper-box-hint-style {
border-width: 2px;
border-radius: $v-border-radius;
diff --git a/WebContent/VAADIN/themes/valo/components/_formlayout.scss b/WebContent/VAADIN/themes/valo/components/_formlayout.scss
index fc065cec3d..7a9e81b30a 100644
--- a/WebContent/VAADIN/themes/valo/components/_formlayout.scss
+++ b/WebContent/VAADIN/themes/valo/components/_formlayout.scss
@@ -1,7 +1,15 @@
+/**
+ * Outputs the selectors and properties for the FormLayout component.
+ *
+ * @param {string} $primary-stylename (v-formlayout) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group formlayout
+ */
@mixin valo-formlayout ($primary-stylename: v-formlayout, $include-additional-styles: contains($v-included-additional-styles, formlayout)) {
@include valo-formlayout-spacing;
- @include valo-formlayout-margins;
+ @include valo-formlayout-margin;
.#{$primary-stylename} > table {
border-spacing: 0;
@@ -53,91 +61,114 @@
@if $include-additional-styles {
.#{$primary-stylename}.light {
- @include valo-formlayout-light-style($primary-stylename);
+ @include valo-formlayout-light-style;
}
}
}
-@mixin valo-formlayout-margins ($primary-stylename: v-formlayout, $all: null, $top: $v-layout-margin-top, $right: $v-layout-margin-right, $bottom: $v-layout-margin-bottom, $left: $v-layout-margin-left) {
- @if $all != null {
- $top: $all;
- $right: $all;
- $bottom: $all;
- $left: $all;
- }
-
- .#{$primary-stylename}-margin-top > tbody > .#{$primary-stylename}-firstrow {
- > .#{$primary-stylename}-captioncell,
- > .#{$primary-stylename}-contentcell,
- > .#{$primary-stylename}-errorcell {
- padding-top: $top;
- }
- }
-
- .#{$primary-stylename}-margin-bottom > tbody > .#{$primary-stylename}-lastrow {
- > .#{$primary-stylename}-captioncell,
- > .#{$primary-stylename}-contentcell,
- > .#{$primary-stylename}-errorcell {
- padding-bottom: $bottom;
- }
- }
-
- .#{$primary-stylename}-margin-left > tbody > .#{$primary-stylename}-row > .#{$primary-stylename}-captioncell {
+/**
+ * Outputs the styles for form layout margin.
+ *
+ * @param {list} $margin ($v-layout-margin-top $v-layout-margin-right $v-layout-margin-bottom $v-layout-margin-left) - The margin for the form layout (any valid CSS margin value)
+ *
+ * @group formlayout
+ */
+@mixin valo-formlayout-margin ($margin: $v-layout-margin-top $v-layout-margin-right $v-layout-margin-bottom $v-layout-margin-left) {
+ $top: 0;
+ $right: 0;
+ $bottom: 0;
+ $left: 0;
+
+ @if length($margin) == 1 {
+ $top: $margin;
+ $right: $margin;
+ $bottom: $margin;
+ $left: $margin;
+ } @else if length($margin) == 2 {
+ $top: nth($margin, 1);
+ $right: nth($margin, 2);
+ $bottom: nth($margin, 1);
+ $left: nth($margin, 2);
+ } @else if length($margin) == 3 {
+ $top: nth($margin, 1);
+ $right: nth($margin, 2);
+ $bottom: nth($margin, 3);
+ $left: nth($margin, 2);
+ } @else if length($margin) == 4 {
+ $top: nth($margin, 1);
+ $right: nth($margin, 2);
+ $bottom: nth($margin, 3);
+ $left: nth($margin, 4);
+ }
+
+ [class*="margin-top"] > tbody > [class*="firstrow"] > td {
+ padding-top: $top;
+ }
+
+ [class*="margin-bottom"] > tbody > [class*="lastrow"] > td {
+ padding-bottom: $bottom;
+ }
+
+ [class*="margin-left"] > tbody > [class*="row"] > [class*="captioncell"] {
padding-left: $left;
}
- .#{$primary-stylename}-margin-right > tbody > .#{$primary-stylename}-row > .#{$primary-stylename}-contentcell {
+ [class*="margin-right"] > tbody > [class*="row"] > [class*="contentcell"] {
padding-right: $right;
}
}
-@mixin valo-formlayout-spacing ($primary-stylename: v-formlayout, $vertical: $v-layout-spacing-vertical) {
- .#{$primary-stylename}-spacing > tbody > .#{$primary-stylename}-row {
- > .#{$primary-stylename}-captioncell,
- > .#{$primary-stylename}-contentcell,
- > .#{$primary-stylename}-errorcell {
- padding-top: $vertical;
- }
+/**
+ * Outputs the styles for form layout spacing.
+ *
+ * @param {size} $vertical ($v-layout-spacing-vertical) - The vertical spacing between the rows in the form layout
+ *
+ * @group formlayout
+ */
+@mixin valo-formlayout-spacing ($vertical: $v-layout-spacing-vertical) {
+ [class*="spacing"] > tbody > [class*="row"] > td {
+ padding-top: $vertical;
}
-}
-
-
+ [class*="spacing"] > tbody > [class*="firstrow"] > td {
+ padding-top: 0;
+ }
+}
-@mixin valo-formlayout-light-style ($primary-stylename: v-formlayout, $row-height: $v-unit-size) {
+/**
+ * Outputs the styles for a light style form layout. This mixin expects the target to have the normal styles of a form layout applied.
+ *
+ * @param {size} $row-height ($v-unit-size) - The height of an individual form layout row
+ *
+ * @group formlayout
+ */
+@mixin valo-formlayout-light-style ($row-height: $v-unit-size) {
> table {
padding: 0;
}
- > table > tbody > .#{$primary-stylename}-row {
- > .#{$primary-stylename}-captioncell,
- > .#{$primary-stylename}-contentcell,
- > .#{$primary-stylename}-errorcell {
- padding-top: 0;
- height: $row-height; // Effectively min-height
- }
- }
-
- > table > tbody > .#{$primary-stylename}-row td {
+ > table > tbody > [class*="row"] > td {
+ padding-top: 0;
+ height: $row-height; // Effectively min-height
border-bottom: valo-border($color: $v-app-background-color, $strength: 0.3);
}
- > table > tbody > .#{$primary-stylename}-lastrow td {
+ > table > tbody > [class*="lastrow"] > td {
border-bottom: none;
}
- > table > tbody > .#{$primary-stylename}-row > .#{$primary-stylename}-captioncell {
+ > table > tbody > [class*="row"] > [class*="captioncell"] {
color: valo-font-color($v-background-color, .5);
text-align: right;
padding-left: ceil($v-unit-size/3);
line-height: $row-height;
}
- .#{$primary-stylename}-contentcell {
+ > table > tbody > [class*="row"] > [class*="contentcell"] {
> .v-textfield,
> .v-textarea,
> .v-filterselect,
@@ -156,6 +187,10 @@
background: transparent;
border: none;
color: inherit;
+
+ &:focus {
+ box-shadow: none;
+ }
}
> .v-textfield-prompt,
@@ -169,6 +204,17 @@
> .v-richtextarea {
height: auto;
}
+
+ > .v-label-h2,
+ > .v-label-h3,
+ > .v-label-h4 {
+ border-bottom: none;
+ }
+
+ > .v-label-h3,
+ > .v-label-h4 {
+ margin-top: 0;
+ }
}
.v-richtextarea {
@@ -192,17 +238,4 @@
.v-checkbox {
margin-left: ceil($v-unit-size/6);
}
-
- > table > tbody > .#{$primary-stylename}-row > .#{$primary-stylename}-contentcell {
- > .v-label-h2,
- > .v-label-h3,
- > .v-label-h4 {
- border-bottom: none;
- }
-
- > .v-label-h3,
- > .v-label-h4 {
- margin-top: 0;
- }
- }
}
diff --git a/WebContent/VAADIN/themes/valo/components/_label.scss b/WebContent/VAADIN/themes/valo/components/_label.scss
index 7f4fef58d9..b59d3e0e21 100644
--- a/WebContent/VAADIN/themes/valo/components/_label.scss
+++ b/WebContent/VAADIN/themes/valo/components/_label.scss
@@ -1,24 +1,110 @@
-$v-font-weight--header: $v-font-weight - 100 !default;
-$v-line-height--header: 1.1 !default;
-$v-font-family--header: null !default;
-$v-font-color--colored: $v-selection-color !default;
-
-$v-font-size--h1: 2.4em !default;
-$v-font-size--h2: 1.6em !default;
-$v-font-size--h3: 1.2em !default;
-$v-font-size--large: 1.2em !default;
-$v-font-size--small: 0.87em !default;
-
-$v-font-family--h1: $v-font-family--header !default;
-$v-font-family--h2: $v-font-family--header !default;
-$v-font-family--h3: $v-font-family--header !default;
-
-$v-letter-spacing--h1: -0.03em !default;
-$v-letter-spacing--h2: -0.02em !default;
-$v-letter-spacing--h3: 0 !default;
-$v-letter-spacing--h4: 0 !default;
-
-
+/**
+ * The font weight for headers.
+ *
+ * @group label
+ */
+$v-font-weight--header: $v-font-weight - 100 !default;
+
+/**
+ * The line height for headers.
+ *
+ * @group label
+ */
+$v-line-height--header: 1.1 !default;
+
+/**
+ * The font family for headers.
+ *
+ * @group label
+ */
+$v-font-family--header: null !default;
+
+/**
+ * The font color for colored style labels.
+ *
+ * @group label
+ */
+$v-font-color--colored: $v-selection-color !default;
+
+/**
+ * The font size for 1st level headers.
+ *
+ * @group label
+ */
+$v-font-size--h1: 2.4em !default;
+
+/**
+ * The font size for 2nd level headers.
+ *
+ * @group label
+ */
+$v-font-size--h2: 1.6em !default;
+
+/**
+ * The font size for 3rd level headers.
+ *
+ * @group label
+ */
+$v-font-size--h3: 1.2em !default;
+
+/**
+ * The font family for 1st level headers.
+ *
+ * @group label
+ */
+$v-font-family--h1: $v-font-family--header !default;
+
+/**
+ * The font family for 2nd level headers.
+ *
+ * @group label
+ */
+$v-font-family--h2: $v-font-family--header !default;
+
+/**
+ * The font family for 3rd level headers.
+ *
+ * @group label
+ */
+$v-font-family--h3: $v-font-family--header !default;
+
+/**
+ * The letter spacing for 1st level headers.
+ *
+ * @group label
+ */
+$v-letter-spacing--h1: -0.03em !default;
+
+/**
+ * The letter spacing for 2nd level headers.
+ *
+ * @group label
+ */
+$v-letter-spacing--h2: -0.02em !default;
+
+/**
+ * The letter spacing for 3rd level headers.
+ *
+ * @group label
+ */
+$v-letter-spacing--h3: 0 !default;
+
+/**
+ * The letter spacing for 4th level headers.
+ *
+ * @group label
+ */
+$v-letter-spacing--h4: 0 !default;
+
+
+/**
+ * Outputs the selectors and styles for the Label component.
+ *
+ * @param {string} $primary-stylename (v-label) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group label
+ */
@mixin valo-label ($primary-stylename: v-label, $include-additional-styles: contains($v-included-additional-styles, label)) {
.#{$primary-stylename} {
@@ -34,7 +120,7 @@ $v-letter-spacing--h4: 0 !default;
h3, .#{$primary-stylename}-h3 {
line-height: $v-line-height--header;
font-weight: $v-font-weight--header;
- color: valo-header-color($v-app-background-color);
+ color: valo-font-color($v-app-background-color, 0.92);
}
h1, .#{$primary-stylename}-h1 {
@@ -65,7 +151,7 @@ $v-letter-spacing--h4: 0 !default;
line-height: $v-line-height--header;
font-weight: $v-font-weight + 200;
font-size: $v-font-size--small;
- color: valo-header-color($v-app-background-color, $contrast: 0.12);
+ color: valo-font-color($v-app-background-color, 0.74);
text-transform: uppercase;
letter-spacing: $v-letter-spacing--h4;
margin-top: 2.4em;
diff --git a/WebContent/VAADIN/themes/valo/components/_menubar.scss b/WebContent/VAADIN/themes/valo/components/_menubar.scss
index 7368579d43..fee5b87e84 100644
--- a/WebContent/VAADIN/themes/valo/components/_menubar.scss
+++ b/WebContent/VAADIN/themes/valo/components/_menubar.scss
@@ -283,6 +283,7 @@
border-radius: 0;
padding: first-number($v-border);
@include box-shadow(none);
+ text-shadow: none;
background: transparent;
color: inherit;
@@ -296,7 +297,6 @@
margin-right: max(1px, first-number($v-border));
border-radius: $v-border-radius;
color: $v-selection-color;
- text-shadow: valo-text-shadow($font-color: $v-selection-color, $offset: -1px);
padding: 0 round($v-unit-size/3);
@if $v-animations-enabled {
diff --git a/WebContent/VAADIN/themes/valo/components/_nativeselect.scss b/WebContent/VAADIN/themes/valo/components/_nativeselect.scss
index 1b7469ed2b..3f24d9293f 100644
--- a/WebContent/VAADIN/themes/valo/components/_nativeselect.scss
+++ b/WebContent/VAADIN/themes/valo/components/_nativeselect.scss
@@ -27,6 +27,6 @@
&:focus {
outline: none;
- @include valo-focus-style($include-box-shadow: true);
+ @include valo-focus-style;
}
}
diff --git a/WebContent/VAADIN/themes/valo/components/_notification.scss b/WebContent/VAADIN/themes/valo/components/_notification.scss
index 3cfa446f7d..ff5e2da8d6 100644
--- a/WebContent/VAADIN/themes/valo/components/_notification.scss
+++ b/WebContent/VAADIN/themes/valo/components/_notification.scss
@@ -33,23 +33,23 @@ $v-notification-title-color: $v-focus-color !default;
@if $v-animations-enabled {
.#{$primary-stylename}-animate-in {
- @include animation(valo-placeholder-animate-in 100ms, valo-anim-fade-in 100ms);
+ @include animation(valo-animate-in-fade 180ms);
- &.v-position-left {
- @include animation(valo-placeholder-animate-in 200ms, valo-anim-slide-in-right 200ms);
+ &.v-position-top {
+ @include animation(valo-animate-in-slide-down 400ms);
}
- &.v-position-right {
- @include animation(valo-placeholder-animate-in 200ms, valo-anim-slide-in-left 200ms);
+ &.v-position-bottom {
+ @include animation(valo-animate-in-slide-up 400ms);
}
}
.#{$primary-stylename}-animate-out {
- @include animation(valo-placeholder-animate-out 150ms, valo-anim-fade-out 150ms);
+ @include animation(valo-animate-out-fade 150ms);
- &.v-position-left,
- &.v-position-right {
- @include animation(valo-placeholder-animate-out 120ms, valo-anim-drop-fade-out 120ms);
+ &.v-position-top,
+ &.v-position-bottom {
+ @include animation(valo-animate-out-slide-down-fade 200ms);
}
}
}
@@ -216,11 +216,12 @@ $v-notification-title-color: $v-focus-color !default;
height: round($v-unit-size/1.5);
line-height: round($v-unit-size/1.5) - 1px;
cursor: pointer;
- color: #000;
+ $color: if(is-dark-color($v-overlay-background-color), #fff, #000);
+ color: $color;
@include opacity(.5);
text-align: center;
- border: first-number($v-border) solid #000;
- border-color: rgba(0,0,0,.3);
+ border: first-number($v-border) solid $color;
+ border-color: rgba($color, .3);
border-radius: 50%;
@include transition(opacity 200ms);
}
@@ -230,8 +231,10 @@ $v-notification-title-color: $v-focus-color !default;
}
&:active:after {
- background-color: #000;
- color: #fff;
+ $color: if(is-dark-color($v-overlay-background-color), #000, #fff);
+ $bg: if(is-dark-color($v-overlay-background-color), #fff, #000);
+ background-color: $bg;
+ color: $color;
@include opacity(.3);
@include transition(none 200ms);
}
@@ -242,7 +245,7 @@ $v-notification-title-color: $v-focus-color !default;
@mixin valo-notification-style {
- background: valo-overlay-background-color();
+ background: $v-overlay-background-color;
@include box-shadow(0px 5px 15px 0px rgba(0,0,0,0.15));
padding: round($v-unit-size/2) round($v-unit-size/1.7);
@@ -274,11 +277,11 @@ $v-notification-title-color: $v-focus-color !default;
@if $v-animations-enabled {
&[class*="animate-in"] {
- @include animation(valo-placeholder-animate-in 200ms, valo-anim-slide-in-down 200ms);
+ @include animation(valo-animate-in-slide-down 300ms);
}
&[class*="animate-out"] {
- @include animation(valo-placeholder-animate-out 200ms, valo-anim-slide-out-up 200ms);
+ @include animation(valo-animate-out-slide-up 200ms);
}
}
}
@@ -288,11 +291,11 @@ $v-notification-title-color: $v-focus-color !default;
@if $v-animations-enabled {
&[class*="animate-in"] {
- @include animation(valo-placeholder-animate-in 200ms, valo-anim-slide-in-up 200ms);
+ @include animation(valo-animate-in-slide-up 300ms);
}
&[class*="animate-out"] {
- @include animation(valo-placeholder-animate-out 200ms, valo-anim-slide-out-down 200ms);
+ @include animation(valo-animate-out-slide-down 200ms);
}
}
}
diff --git a/WebContent/VAADIN/themes/valo/components/_orderedlayout.scss b/WebContent/VAADIN/themes/valo/components/_orderedlayout.scss
index dbe2490826..ae1347d0e3 100644
--- a/WebContent/VAADIN/themes/valo/components/_orderedlayout.scss
+++ b/WebContent/VAADIN/themes/valo/components/_orderedlayout.scss
@@ -140,7 +140,7 @@
-@mixin valo-orderedlayout ($include-additional-styles: contains($v-included-additional-styles, orderedlayout)) {
+@mixin valo-orderedlayout ($include-additional-styles: contains($v-included-additional-styles, orderedlayout) or contains($v-included-additional-styles, verticallayout) or contains($v-included-additional-styles, horizontallayout)) {
.v-margin-top {
padding-top: $v-layout-margin-top;
diff --git a/WebContent/VAADIN/themes/valo/components/_panel.scss b/WebContent/VAADIN/themes/valo/components/_panel.scss
index 07e21cccbf..8a7cd72c7c 100644
--- a/WebContent/VAADIN/themes/valo/components/_panel.scss
+++ b/WebContent/VAADIN/themes/valo/components/_panel.scss
@@ -97,7 +97,7 @@ $v-panel-border: $v-border !default;
font-weight: $v-caption-font-weight;
font-size: $v-caption-font-size;
@include box-shadow(valo-bevel-and-shadow($background-color: $bg, $bevel: $bevel, $shadow: $shadow, $gradient: $gradient));
- text-shadow: valo-text-shadow(valo-font-color($bg), $bg, $v-bevel);
+ text-shadow: valo-text-shadow(valo-font-color($bg), $bg);
}
diff --git a/WebContent/VAADIN/themes/valo/components/_popupview.scss b/WebContent/VAADIN/themes/valo/components/_popupview.scss
index 794a6997de..12e294e8cc 100644
--- a/WebContent/VAADIN/themes/valo/components/_popupview.scss
+++ b/WebContent/VAADIN/themes/valo/components/_popupview.scss
@@ -8,9 +8,9 @@
.#{$primary-stylename} {
@include valo-link-style;
}
-
+
.#{$primary-stylename}-popup {
- @include valo-overlay-style($animate-in: v-popupview-animate-in 120ms, $animate-out: (valo-placeholder-animate-out 120ms, valo-anim-fade-out 120ms));
+ @include valo-overlay-style($animate-in: v-popupview-animate-in 120ms, $animate-out: (valo-animate-out-fade 120ms));
.popupContent {
@include valo-panel-adjust-content-margins;
diff --git a/WebContent/VAADIN/themes/valo/components/_tabsheet.scss b/WebContent/VAADIN/themes/valo/components/_tabsheet.scss
index ccd70c4328..7dafbe4624 100644
--- a/WebContent/VAADIN/themes/valo/components/_tabsheet.scss
+++ b/WebContent/VAADIN/themes/valo/components/_tabsheet.scss
@@ -1,8 +1,19 @@
+/**
+ * Should the tabsheet content changes be animated.
+ *
+ * @group tabsheet
+ */
$v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
-
-
+/**
+ * Outputs the global selectors and properties for the TabSheet component - styles which are
+ * considered mandatory for the component to work properly.
+ *
+ * @param {string} $primary-stylename (v-tabsheet) - the primary style name for the selectors
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-global ($primary-stylename: v-tabsheet) {
.#{$primary-stylename}-hidetabs > .#{$primary-stylename}-tabcontainer,
.#{$primary-stylename}-spacertd,
@@ -48,9 +59,14 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
-
-
-
+/**
+ * Outputs the selectors and properties for the TabSheet component.
+ *
+ * @param {string} $primary-stylename (v-tabsheet) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet ($primary-stylename: v-tabsheet, $include-additional-styles: contains($v-included-additional-styles, tabsheet)) {
.#{$primary-stylename} {
&:not(.v-has-width) {
@@ -77,7 +93,7 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
@if $v-tabsheet-content-animation-enabled {
.#{$primary-stylename}-tabsheetpanel > .v-scrollable > .v-widget {
- @include valo-anim-fade-in(300ms);
+ @include valo-animate-in-fade(300ms);
}
$spinner-size: round($v-unit-size/2);
@@ -85,37 +101,17 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
.#{$primary-stylename}-deco {
@include valo-spinner($size: $spinner-size);
- height: 0 !important;
- border-style: none;
- display: block;
+ display: none;
position: absolute;
- z-index: -1;
+ z-index: 1;
bottom: 50%;
margin-bottom: round($v-unit-size/-2) - $spinner-size/2;
left: 50%;
margin-left: $spinner-size/-2;
- opacity: 0;
-
- .v-ie8 & {
- min-height: 0;
- }
}
.#{$primary-stylename}-loading .#{$primary-stylename}-deco {
- @include transition(opacity 200ms 200ms);
- opacity: 1;
- z-index: 1;
- height: $spinner-size !important;
- border-style: solid;
-
- .v-ie8 &,
- .v-ie9 & {
- border-style: none;
- }
-
- .v-ie8 & {
- min-height: 30px;
- }
+ display: block;
}
}
@@ -159,6 +155,11 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
+/**
+ * Outputs the styles for the tabcontainer element of a tabsheet.
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-tabcontainer-style ($primary-stylename: v-tabsheet) {
position: relative;
@include box-sizing(border-box);
@@ -168,7 +169,7 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
position: absolute;
height: 0;
// iOS panics with background color, creating black line artifacts
- border-top: max(1px, first-number($v-border)) solid first-color(valo-border($strength: 0.5));
+ border-top: max(1px, first-number($v-border)) solid first-color(valo-border($color: $v-app-background-color, $strength: 0.5));
bottom: 0;
left: 0;
right: 0;
@@ -180,6 +181,11 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
+/**
+ * Outputs the styles for the tabitemcell element of a tabsheet.
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-tabitemcell-style ($primary-stylename: v-tabsheet) {
vertical-align: bottom;
@@ -269,6 +275,11 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
+/**
+ * Outputs the styles for the tab scroller element of a tabsheet.
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-scroller-style ($primary-stylename: v-tabsheet) {
$border-color: first-color(valo-border($strength: 0.5));
@@ -352,24 +363,38 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
+/**
+ * Outputs the font icon styles for the previous button element of a tabsheet scroller.
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-scroller-prev-icon-style {
font-family: FontAwesome;
content: "\f053";
}
+/**
+ * Outputs the font icon styles for the next button element of a tabsheet scroller.
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-scroller-next-icon-style {
font-family: FontAwesome;
content: "\f054";
}
-
-
-
-
-
-
+/**
+ * Outputs the styles for the framed tabsheet style.
+ *
+ * @param {string} $primary-stylename (v-tabsheet) - The primary style name for the selectors
+ * @param {bool} $frame-inactive-tabs (true) - Should inactive tabs be framed as well (the active tab is always framed with this style)
+ * @param {bool} $outer-frame (true) - Should the frame contain the whole tabsheet (i.e. tabbar and tab content). If false, works like a "borderless" style.
+ * @param {size} $tab-spacing ($v-unit-size/10) - The spacing between tabs
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-framed-style ($primary-stylename: v-tabsheet, $frame-inactive-tabs: true, $outer-frame: true, $tab-spacing: round($v-unit-size/10)) {
> .#{$primary-stylename}-tabcontainer {
.v-caption {
@@ -387,7 +412,7 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
&:hover {
background-color: darken($v-app-background-color, 3%);
- border-bottom-color: first-color(valo-border($strength: 0.5));
+ border-bottom-color: first-color(valo-border($color: $v-app-background-color, $strength: 0.5));
}
}
@@ -398,13 +423,13 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
@if $frame-inactive-tabs {
.#{$primary-stylename}-tabitem .v-caption {
- border-color: first-color(valo-border($strength: 0.5));
+ border-color: first-color(valo-border($color: $v-app-background-color, $strength: 0.5));
}
}
.#{$primary-stylename}-tabitem-selected .v-caption {
background: $v-panel-background-color;
- border-color: first-color(valo-border($strength: 0.5));
+ border-color: first-color(valo-border($color: $v-app-background-color, $strength: 0.5));
border-bottom: none;
padding-bottom: first-number($v-border);
}
@@ -429,7 +454,7 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
@if $outer-frame {
- border: valo-border($strength: 0.5);
+ border: valo-border($color: $v-app-background-color, $strength: 0.5);
border-top: none;
}
}
@@ -437,7 +462,7 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
&.padded-tabbar {
> .#{$primary-stylename}-tabcontainer {
@if $outer-frame {
- border: valo-border($strength: 0.5);
+ border: valo-border($color: $v-app-background-color, $strength: 0.5);
border-bottom: none;
}
@@ -452,19 +477,29 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
-
-
-
-
-
-
-
+/**
+ * Outputs the styles for a tabsheet where the tabs are aligned to the position specified by the parameter in the tabbar.
+ *
+ * @param {string} $primary-stylename (v-tabsheet) - The primary style name for the selectors
+ * @param {string} $align (center) - The alignment of the tabs inside the tabbar. Possible values: left, right, center.
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-align-tabs-style ($primary-stylename: v-tabsheet, $align: center) {
> .#{$primary-stylename}-tabcontainer {
text-align: $align;
}
}
+
+/**
+ * Outputs the styles for a tabsheet where all tabs in the tabbar have equal width and span the entire width of the tabbar.
+ *
+ * @param {string} $primary-stylename (v-tabsheet) - The primary style name for the selectors
+ * @param {bool} $flex (false) - Should the size of the tabs be proportional to their content, i.e. should the available space in the tabbar be distributed to the tabs in relation to their content sizes.
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-equal-width-tabs-style ($primary-stylename: v-tabsheet, $flex: false) {
> .#{$primary-stylename}-tabcontainer {
table,
@@ -491,6 +526,14 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
}
+
+/**
+ * Outputs the styles for a tabsheet where the icons of individual tabs are on top of the tab captions.
+ *
+ * @param {string} $primary-stylename (v-tabsheet) - The primary style name for the selectors
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-icons-on-top-style ($primary-stylename: v-tabsheet) {
> div > .#{$primary-stylename}-tabs {
.v-caption {
@@ -514,6 +557,14 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
+/**
+ * Outputs the styles for a tabsheet where only the selected tab has the close button visible.
+ * Note that the other tabs can still be closed programmatically.
+ *
+ * @param {string} $primary-stylename (v-tabsheet) - The primary style name for the selectors
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-only-selected-closable-style ($primary-stylename: v-tabsheet) {
> .#{$primary-stylename}-tabcontainer .#{$primary-stylename}-caption-close {
visibility: hidden;
@@ -525,6 +576,14 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default;
}
+/**
+ * Outputs the styles for a tabsheet where the tabbar has increased padding to separate the tabs
+ * inside it from their surrounding container.
+ *
+ * @param {string} $primary-stylename (v-tabsheet) - The primary style name for the selectors
+ *
+ * @group tabsheet
+ */
@mixin valo-tabsheet-padded-tabbar-style ($primary-stylename: v-tabsheet) {
> .#{$primary-stylename}-tabcontainer .#{$primary-stylename}-tabs {
padding: 0 round($v-unit-size/4);
diff --git a/WebContent/VAADIN/themes/valo/components/_textarea.scss b/WebContent/VAADIN/themes/valo/components/_textarea.scss
index 5e524bfb9e..ffd5ba855a 100644
--- a/WebContent/VAADIN/themes/valo/components/_textarea.scss
+++ b/WebContent/VAADIN/themes/valo/components/_textarea.scss
@@ -1,3 +1,11 @@
+/**
+ * Outputs the selectors and properties for the TextArea component.
+ *
+ * @param {string} $primary-stylename (v-textarea) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group textarea
+ */
@mixin valo-textarea ($primary-stylename: v-textarea, $include-additional-styles: contains($v-included-additional-styles, textarea)) {
.#{$primary-stylename} {
@@ -51,13 +59,30 @@
}
+/**
+ * Outputs the styles for a text area variant.
+ *
+ * @param {size} $unit-size ($v-unit-size) - The sizing of the text area, which corresponds its height
+ * @param {size | list} $padding (null) - The padding of the text area. Computed from other parameters by default.
+ * @param {color} $font-color (null) - The font color of the text area. Computed from the $background-color by default.
+ * @param {number} $font-weight (max(400, $v-font-weight)) - The font weight of the text area
+ * @param {size} $font-size (null) - The font size of the text area. Inherited from the parent by default.
+ * @param {color} $background-color ($v-textfield-background-color) - The background color of the text area
+ * @param {list} $border ($v-textfield-border) - The border of the text area
+ * @param {size} $border-radius ($v-textfield-border-radius) - The border-radius of the text area
+ * @param {list} $bevel ($v-textfield-bevel) - Box-shadow value according to $v-bevel documentation
+ * @param {list} $shadow ($v-textfield-shadow) - Box-shadow value according to $v-shadow documentation
+ * @param {list} $states (normal focus disabled) - The text area states for which to output corresponding styles
+ *
+ * @group textfield
+ */
@mixin valo-textarea-style (
$unit-size : $v-unit-size,
- $padding : round($v-unit-size/6), // Computed by default
+ $padding : round($v-unit-size/6),
- $font-color : null, // Computed by default
- $font-weight : max(400, $v-font-weight), // Inherited by default
- $font-size : null, // Inherited by default
+ $font-color : null,
+ $font-weight : max(400, $v-font-weight),
+ $font-size : null,
$background-color : $v-textfield-background-color,
$border : $v-textfield-border,
@@ -71,8 +96,8 @@
@include valo-textfield-style($unit-size: $unit-size, $padding: $padding,
$font-color: $font-color,
- $font-weight: $font-weight, // Inherited by default
- $font-size: $font-size, // Inherited by default
+ $font-weight: $font-weight,
+ $font-size: $font-size,
$background-color: $background-color,
$border: $border,
diff --git a/WebContent/VAADIN/themes/valo/components/_textfield.scss b/WebContent/VAADIN/themes/valo/components/_textfield.scss
index c194bd715f..f4ca3538bd 100644
--- a/WebContent/VAADIN/themes/valo/components/_textfield.scss
+++ b/WebContent/VAADIN/themes/valo/components/_textfield.scss
@@ -1,14 +1,60 @@
+/**
+ * The background color for text fields.
+ * @group textfield
+ */
$v-textfield-background-color: if(is-dark-color($v-app-background-color), darken($v-app-background-color, 4%), lighten($v-app-background-color, 8%)) !default;
+
+/**
+ * The background color for read-only text fields.
+ * @group textfield
+ */
$v-textfield-background-color--readonly: darkest-color($v-app-background-color, darken($v-textfield-background-color, 2%));
+
+/**
+ * The bevel style for text fields. See the documentation for $v-bevel.
+ * @group textfield
+ */
$v-textfield-bevel: inset 0 1px 0 v-shade !default;
+
+/**
+ * The shadow style for text fields. See the documentation for $v-shadow.
+ * @group textfield
+ */
$v-textfield-shadow: 0 1px 0 (v-tint 2) !default;
+
+/**
+ * The font-weight for text fields.
+ * @group textfield
+ */
$v-textfield-font-weight: 400 !default;
+
+/**
+ * The border style for text fields. See the documentation for $v-border.
+ * @group textfield
+ */
$v-textfield-border: $v-border !default;
+
+/**
+ * The border-radius for text fields. See the documentation for $v-border-radius;
+ * @group textfield
+ */
$v-textfield-border-radius: $v-border-radius !default;
-$v-textfield-disabled-opacity: $v-disabled-opacity !default;
+/**
+ * The opacity for disabled text fields.
+ * @group textfield
+ */
+$v-textfield-disabled-opacity: $v-disabled-opacity !default;
+/**
+ * Outputs the selectors and properties for the TextField component.
+ *
+ * @param {string} $primary-stylename (v-textfield) - the primary style name for the selectors
+ * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component
+ *
+ * @group textfield
+ */
@mixin valo-textfield ($primary-stylename: v-textfield, $include-additional-styles: contains($v-included-additional-styles, textfield)) {
.#{$primary-stylename} {
@@ -73,14 +119,30 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default;
}
-
+/**
+ * Outputs the styles for a text field variant.
+ *
+ * @param {size} $unit-size ($v-unit-size) - The sizing of the text field, which corresponds its height
+ * @param {size | list} $padding (null) - The padding of the text field. Computed from other parameters by default.
+ * @param {color} $font-color (null) - The font color of the text field. Computed from the $background-color by default.
+ * @param {number} $font-weight (max(400, $v-font-weight)) - The font weight of the text field
+ * @param {size} $font-size (null) - The font size of the text field. Inherited from the parent by default.
+ * @param {color} $background-color ($v-textfield-background-color) - The background color of the text field
+ * @param {list} $border ($v-textfield-border) - The border of the text field
+ * @param {size} $border-radius ($v-textfield-border-radius) - The border-radius of the text field
+ * @param {list} $bevel ($v-textfield-bevel) - Box-shadow value according to $v-bevel documentation
+ * @param {list} $shadow ($v-textfield-shadow) - Box-shadow value according to $v-shadow documentation
+ * @param {list} $states (normal focus disabled) - The text field states for which to output corresponding styles
+ *
+ * @group textfield
+ */
@mixin valo-textfield-style (
$unit-size : $v-unit-size,
- $padding : null, // Computed by default
+ $padding : null,
- $font-color : null, // Computed by default
+ $font-color : null,
$font-weight : max(400, $v-font-weight),
- $font-size : null, // Inherited by default
+ $font-size : null,
$background-color : $v-textfield-background-color,
$border : $v-textfield-border,
@@ -163,6 +225,13 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default;
}
+/**
+ * Outputs the styles for a text field input prompt.
+ *
+ * @param {color} $background-color ($v-textfield-background-color) - The background color of the text field
+ *
+ * @group textfield
+ */
@mixin valo-textfield-prompt-style ($background-color: $v-textfield-background-color) {
@if $background-color == transparent {
color: inherit;
@@ -179,6 +248,16 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default;
}
+/**
+ * Outputs the styles for a text field focus state.
+ *
+ * @param {list} $bevel ($v-textfield-bevel) - Box-shadow value according to $v-bevel documentation
+ * @param {list} $shadow ($v-textfield-shadow) - Box-shadow value according to $v-shadow documentation
+ * @param {color} $background-color ($v-textfield-background-color) - The background color of the text field
+ * @param {list} $gradient (null) - Valo specific gradient value. See the documentation for $v-gradient.
+ *
+ * @group textfield
+ */
@mixin valo-textfield-focus-style ($bevel: $v-textfield-bevel, $shadow: $v-textfield-shadow, $background-color: $v-textfield-background-color, $gradient: null) {
outline: none;
@if $v-animations-enabled {
@@ -197,6 +276,11 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default;
}
+/**
+ * Outputs the styles for a read-only text field.
+ *
+ * @group textfield
+ */
@mixin valo-textfield-readonly-style {
background: $v-textfield-background-color--readonly;
color: valo-font-color($v-textfield-background-color--readonly);
@@ -208,7 +292,13 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default;
}
-
+/**
+ * Outputs the styles for a borderless style text field.
+ *
+ * @param {color} $background-color (transparent) - The background color of the text field
+ *
+ * @group textfield
+ */
@mixin valo-textfield-borderless-style ($background-color: transparent) {
border: none;
border-radius: 0;
@@ -231,8 +321,11 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default;
}
-
-
+/**
+ * Outputs the styles for a text field error state.
+ *
+ * @group textfield
+ */
@mixin valo-textfield-error-style {
border-color: $v-error-indicator-color !important;
$bg: scale-color($v-error-indicator-color, $lightness: 98%);
@@ -241,11 +334,18 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default;
}
-
-
-
-
-
+/**
+ * Outputs the selectors and styles for an inline-icon style for a text field. Included indipendently (i.e. not enclosed with a parent text field selector).
+ *
+ * @param {string} $primary-stylename (v-textfield) - The primary style name for the selectors
+ * @param {string | list} $stylenames (inline-icon) - The additional style names which will define the inline-icon style
+ * @param {string} $input-selector (null) - Additional selector for a nested input element which should be targeted
+ * @param {size} $unit-size ($v-unit-size) - The unit size which the resulting style will support
+ * @param {size} $font-size ($v-font-size) - The font size which the resulting style will support (needed for font icons)
+ * @param {size} $image-icon-size (16px) - The image icon height which the resulting style will support (needed to center the icon vertically inside the text field)
+ *
+ * @group text field
+ */
@mixin valo-textfield-inline-icon($primary-stylename: v-textfield, $stylenames: inline-icon, $input-selector: null, $unit-size: $v-unit-size, $font-size: $v-font-size, $image-icon-size: 16px) {
$slot-selector: "";
$caption-selector: "";
diff --git a/WebContent/VAADIN/themes/valo/components/_valo-menu.scss b/WebContent/VAADIN/themes/valo/components/_valo-menu.scss
index 9a9e597888..59d3ddca4b 100644
--- a/WebContent/VAADIN/themes/valo/components/_valo-menu.scss
+++ b/WebContent/VAADIN/themes/valo/components/_valo-menu.scss
@@ -75,6 +75,7 @@ $valo-menu-background-color: scale-color($v-app-background-color, $lightness: if
@include valo-menubar-borderless-style;
margin: round($v-unit-size/2) round($v-unit-size/5);
display: block;
+ overflow: hidden;
text-align: center;
height: auto;
color: inherit;
@@ -83,6 +84,7 @@ $valo-menu-background-color: scale-color($v-app-background-color, $lightness: if
color: inherit;
white-space: normal;
line-height: 1.4;
+ margin: 0;
img.v-icon {
width: round($v-unit-size * 1.5);
@@ -93,6 +95,13 @@ $valo-menu-background-color: scale-color($v-app-background-color, $lightness: if
margin: 0 auto .3em;
border: valo-border();
}
+
+ &:after {
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ }
}
.v-menubar-menuitem-selected {
@@ -150,6 +159,10 @@ $valo-menu-background-color: scale-color($v-app-background-color, $lightness: if
border-right: none;
}
+ .valo-menu-part {
+ overflow: visible;
+ }
+
.valo-menu-toggle {
display: inline-block;
}
@@ -271,7 +284,7 @@ $valo-menu-background-color: scale-color($v-app-background-color, $lightness: if
padding: 0 round($v-unit-size) 0 round($v-unit-size/2);
cursor: pointer;
position: relative;
- text-shadow: valo-text-shadow($font-color: $font-color, $background-color: $bg, $offset: -2px);
+ text-shadow: valo-text-shadow($font-color: $font-color, $background-color: $bg, $offset: 2px);
@include transition(background-color 300ms, color 60ms);
$diff: color-luminance($bg) - color-luminance($v-selection-color);
@@ -297,7 +310,7 @@ $valo-menu-background-color: scale-color($v-app-background-color, $lightness: if
color: $active-color;
}
}
-
+
&.selected {
background: if(is-dark-color($bg), darken($bg, 3%), lighten($bg, 5%));
diff --git a/WebContent/VAADIN/themes/valo/components/_window.scss b/WebContent/VAADIN/themes/valo/components/_window.scss
index cdd2298499..574c14b3b6 100644
--- a/WebContent/VAADIN/themes/valo/components/_window.scss
+++ b/WebContent/VAADIN/themes/valo/components/_window.scss
@@ -1,8 +1,8 @@
$v-window-background-color: $v-panel-background-color !default;
$v-window-border-radius: $v-border-radius !default;
$v-window-shadow: 0 2px 10px (v-shade 2), 0 16px 80px -6px (v-shade 3), last($v-overlay-shadow) !default;
-$v-window-animate-in: valo-placeholder-animate-in 140ms, valo-anim-fade-in 140ms !default;
-$v-window-animate-out: valo-placeholder-animate-out 100ms, valo-anim-scale-down-fade-out 100ms !default;
+$v-window-animate-in: valo-animate-in-fade 140ms !default;
+$v-window-animate-out: valo-animate-out-scale-down-fade 100ms !default;
$v-window-modality-curtain-background-color: #222 !default;
@@ -12,7 +12,7 @@ $v-window-modality-curtain-background-color: #222 !default;
100% { opacity: 1; }
}
- @include keyframes(valo-anim-scale-down-fade-out) {
+ @include keyframes(valo-animate-out-scale-down-fade) {
100% {
@include transform(scale(0.8));
opacity: 0;
@@ -59,7 +59,7 @@ $v-window-modality-curtain-background-color: #222 !default;
left: 0;
@include radial-gradient(circle at 50% 50%, $v-window-modality-curtain-background-color, darken($v-window-modality-curtain-background-color, valo-gradient-opacity()), $fallback: $v-window-modality-curtain-background-color);
@include opacity(max(0.2, 0.8 - valo-gradient-opacity()/100%));
- @include valo-anim-fade-in($duration: 400ms, $delay: 100ms);
+ @include valo-animate-in-fade($duration: 400ms, $delay: 100ms);
.v-op12 & {
// Opera 12 has a shitbreak with the fade-in (flickers)
@@ -205,7 +205,7 @@ $v-window-modality-curtain-background-color: #222 !default;
@include valo-panel-adjust-content-margins;
> .v-formlayout {
- @include valo-formlayout-margins($all: round($v-unit-size/3));
+ @include valo-formlayout-margin(round($v-unit-size/3));
}
position: relative;
diff --git a/WebContent/VAADIN/themes/valo/shared/_contextmenu.scss b/WebContent/VAADIN/themes/valo/shared/_contextmenu.scss
index 4b737416c2..7fd182b6cd 100644
--- a/WebContent/VAADIN/themes/valo/shared/_contextmenu.scss
+++ b/WebContent/VAADIN/themes/valo/shared/_contextmenu.scss
@@ -1,3 +1,9 @@
+/**
+ * Outputs the context menu selectors and styles, which is used by Table and Tree for instance.
+ *
+ * @requires {mixin} valo-selection-item-style
+ * @requires {mixin} valo-selection-item-selected-style
+ */
@mixin valo-contextmenu {
.v-contextmenu {
diff --git a/WebContent/VAADIN/themes/valo/shared/_global.scss b/WebContent/VAADIN/themes/valo/shared/_global.scss
index 5c010c128d..049518af73 100644
--- a/WebContent/VAADIN/themes/valo/shared/_global.scss
+++ b/WebContent/VAADIN/themes/valo/shared/_global.scss
@@ -4,9 +4,22 @@
@import "tooltip";
-// Include global styles only once
+/*
+ * A flag which is set to true when the global styles have been included in the compilation.
+ * Used to only include them once, if Valo is imported multiple times during the compilation
+ * (multiple theme support).
+ *
+ * @access private
+ * @type bool
+ */
$valo-global-included: false !default;
+/*
+ * Global Valo related styles, containing styles which are necessary for the application
+ * and widgets to work correctly.
+ *
+ * @access private
+ */
@mixin valo-global {
@if $valo-global-included == false {
@@ -173,14 +186,16 @@ $valo-global-included: false !default;
}
-
$valo-shared-pathPrefix: null;
@if $v-relative-paths == false {
$valo-shared-pathPrefix: "../valo/shared/";
}
-
+/**
+ * Styles for the application root element. Outputs font, font color, background color and default
+ * cursor styles.
+ */
@mixin valo-app-style {
font: $v-font-weight #{$v-font-size}/#{$v-line-height} $v-font-family;
color: $v-font-color;
@@ -195,7 +210,13 @@ $valo-shared-pathPrefix: null;
}
}
-
+/**
+ * Common application styles, such as loading indicators, tooltip and context menu styles,
+ * caption and icon defaults, basic HTML element resets.
+ * Should only be included once (done automatically when including the main valo mixin).
+ *
+ * @requires {mixin} valo-app-style
+ */
@mixin valo-common {
//@if & != null {
@@ -351,7 +372,9 @@ $valo-shared-pathPrefix: null;
-
+/**
+ * Generic component caption styles (captions which are generated by layouts).
+ */
@mixin valo-caption-style {
font-size: $v-caption-font-size;
font-weight: $v-caption-font-weight;
@@ -362,7 +385,11 @@ $valo-shared-pathPrefix: null;
}
-
+/**
+ * Error indicator styles. The error indicator is by default a font character which you can style freely.
+ *
+ * @requires {mixin} valo-error-indicator-icon-style by default
+ */
@mixin valo-error-indicator-style {
color: $v-error-indicator-color;
font-weight: 600;
@@ -374,18 +401,23 @@ $valo-shared-pathPrefix: null;
}
}
+/**
+ * The error indicator icon style. Should be a font character or a font icon.
+ */
@mixin valo-error-indicator-icon-style {
content: "!";
}
-
-// Make the BODY element scrollable instead of the .v-ui element. Scrolling the BODY works better on touch screens.
-// NOTE: breaks percentage sized overlay elements
-// @mixin valo-natural-page-scrolling
-// @usage
-// // Call without any parent selector somewhere in your theme
-// =valo-natural-page-scrolling;
+/**
+ * Make the BODY element scrollable instead of the .v-ui element. Scrolling the BODY usually
+ * works better on touch devices. You loose the ability to control the scroll position from
+ * the server side when using this.
+ *
+ * @example scss
+ * // Include without any parent selector
+ * @include valo-natural-page-scrolling;
+ */
@mixin valo-natural-page-scrolling {
html {
diff --git a/WebContent/VAADIN/themes/valo/shared/_loading-indicator.scss b/WebContent/VAADIN/themes/valo/shared/_loading-indicator.scss
index 56aab30d2b..645e188b09 100644
--- a/WebContent/VAADIN/themes/valo/shared/_loading-indicator.scss
+++ b/WebContent/VAADIN/themes/valo/shared/_loading-indicator.scss
@@ -1,5 +1,3 @@
-// TODO make fallbacks for IE 8 & 9
-
@-webkit-keyframes v-rotate-360 {
to {-webkit-transform: rotate(360deg);}
}
@@ -13,9 +11,16 @@
to {transform: rotate(360deg);}
}
-
-@mixin valo-spinner ($size: 24px, $thickness: 2px, $color: null, $speed: 500ms) {
- $color: $color or $v-focus-color;
+/**
+ * Creates a spinner to be used as a loading indicator. On browsers which do not
+ * support CSS animations, an animated GIF image is used as a fallback.
+ *
+ * @param {size} $size (24px) - the diameter of the spinner, in pixels. Should be divisible by 2, increased by 1px if not
+ * @param {size} $thickness (2px) - the thickness or width of the border of the spinner
+ * @param {color} $color ($v-focus-color) - the color of the border of the spinner
+ * @param {time} $speed (500ms) - the speed of the spinning animation
+ */
+@mixin valo-spinner ($size: 24px, $thickness: 2px, $color: $v-focus-color, $speed: 500ms) {
// Make size divisible by 2, so that the rotation won't jiggle
$size: round($size) + round($size) % 2;
height: $size !important;
@@ -59,9 +64,25 @@
-
+/**
+ * The color of the main loading indicator bar.
+ * @type color
+ */
$v-loading-indicator-color: $v-focus-color !default;
+
+/**
+ * The height of the main loading indicator bar.
+ *
+ * @type size
+ */
$v-loading-indicator-bar-height: ceil($v-unit-size/10) !default;
+
+/**
+ * The height of the main loading indicator bar when the request to the server
+ * is taking longer than usual and the user is notified that they should wait.
+ *
+ * @type size
+ */
$v-loading-indicator-bar-height--wait: ceil($v-unit-size/6) !default;
@@ -89,7 +110,11 @@ $v-loading-indicator-bar-height--wait: ceil($v-unit-size/6) !default;
}
-
+/*
+ * Outputs the necessary styles to create the main loading indicator bar.
+ *
+ * @access private
+ */
@mixin valo-loading-bar {
.v-loading-indicator {
diff --git a/WebContent/VAADIN/themes/valo/shared/_overlay.scss b/WebContent/VAADIN/themes/valo/shared/_overlay.scss
index dc54672cb6..926b00f529 100644
--- a/WebContent/VAADIN/themes/valo/shared/_overlay.scss
+++ b/WebContent/VAADIN/themes/valo/shared/_overlay.scss
@@ -1,40 +1,160 @@
-@function valo-overlay-background-color ($context: $v-background-color) {
- @if is-dark-color($context) {
- @return darken($context, 3%);
- }
- @return lighten($context, 2%);
-}
-
-
-$v-overlay-background-color: valo-overlay-background-color() !default;
+/**
+ * The background color for overlay elements.
+ *
+ * @type color
+ * @group overlay
+ */
+$v-overlay-background-color: if(is-dark-color($v-background-color), darken($v-background-color, 3%), lighten($v-background-color, 2%)) !default;
+
+/**
+ * The corner radius for overlay elements.
+ *
+ * @type size (px)
+ * @group overlay
+ */
$v-overlay-border-radius: $v-border-radius !default;
+
+/**
+ * The border width for overlay elements.
+ *
+ * @type size (px)
+ * @group overlay
+ */
$v-overlay-border-width: first-number($v-border) !default;
+/**
+ * The animation which is used when overlay elements are made visible.
+ *
+ * @type list
+ * @group overlay
+ */
$v-overlay-animate-in: valo-overlay-animate-in 120ms !default;
-$v-overlay-animate-out: valo-placeholder-animate-out 120ms, valo-anim-fade-out 120ms !default;
+/**
+ * The animation which is used when overlay elements are removed.
+ *
+ * @type list
+ * @group overlay
+ */
+$v-overlay-animate-out: valo-animate-out-fade 120ms !default;
+
+/**
+ * The padding on each size of overlay elements.
+ *
+ * @type size
+ * @group overlay
+ */
$v-overlay-padding: round($v-unit-size/9) !default;
+
+/**
+ * The padding on the top and bottom edges of overlay elements.
+ *
+ * @type size
+ * @group overlay
+ */
$v-overlay-padding-vertical: $v-overlay-padding !default;
+
+/**
+ * The padding on the left and right edges of overlay elements.
+ *
+ * @type size
+ * @group overlay
+ */
$v-overlay-padding-horizontal: $v-overlay-padding !default;
+/**
+ * The shadow used for overlay elements.
+ *
+ * @type list
+ * @group overlay
+ */
$v-overlay-shadow: 0 4px 10px 0 (v-shade 2), 0 3px 5px 0 v-shade, 0 0 0 $v-overlay-border-width (v-shade (2.5 - color-luminance($v-background-color)/255 + $v-bevel-depth/100%)) !default;
+/**
+ * The background color for selection overlays, i.e. overlays which present a
+ * list of options for the user to choose from, such as context menus and drop down
+ * menus.
+ *
+ * @type color
+ * @group overlay
+ */
$v-selection-overlay-background-color: $v-overlay-background-color !default;
+
+/**
+ * The padding on each size of selection overlay elements.
+ *
+ * @type size
+ * @group overlay
+ */
$v-selection-overlay-padding: $v-overlay-padding !default;
+
+/**
+ * The padding on the top and bottom edges of selection overlay elements.
+ *
+ * @type size
+ * @group overlay
+ */
$v-selection-overlay-padding-vertical: $v-selection-overlay-padding !default;
+
+/**
+ * The padding on the left and right edges of selection overlay elements.
+ *
+ * @type size
+ * @group overlay
+ */
$v-selection-overlay-padding-horizontal: $v-selection-overlay-padding !default;
+/**
+ * The corner radius for selection overlay elements.
+ *
+ * @type size (px)
+ * @group overlay
+ */
$v-selection-item-border-radius: $v-border-radius - 1px !default;
+
+/**
+ * The height of individual selection overlay list items.
+ *
+ * @type size (px)
+ * @group overlay
+ */
$v-selection-item-height: ceil($v-unit-size/1.4) !default;
+
+/**
+ * The horizontal padding for individual selection overlay list items.
+ *
+ * @type size
+ * @group overlay
+ */
$v-selection-item-padding-horizontal: ceil($v-unit-size/4) !default;
+
+/**
+ * The font weight for individual selection overlay list items.
+ *
+ * @type number | identifier
+ * @group overlay
+ */
$v-selection-item-font-weight: max(400, $v-font-weight);
-$v-selection-item-selection-color: $v-selection-color !default;
+/**
+ * The font color for individual selection overlay list items.
+ *
+ * @type color
+ * @group overlay
+ */
+$v-selection-item-selection-color: $v-selection-color !default;
+/*
+ * Simulates CSS box-shadow using the extraneous shadow elements in the DOM.
+ *
+ * @access private
+ * @deprecated The .v-shadow element is deprecated since 7.3.0
+ * @group overlay
+ */
@mixin valo-ie8-shadow($shadow, $element: top) {
.#{$element} {
$shadow-offset-x: nth($shadow, 1);
@@ -97,7 +217,16 @@ $v-selection-item-selection-color: $v-selection-color !default;
-
+/**
+ * Outputs styles for overlay elements
+ *
+ * @group overlay
+ *
+ * @param {color} $background-color ($v-overlay-background-color) - the background color for the overlay
+ * @param {list} $shadow ($v-overlay-shadow) - the shadow for the overlay
+ * @param {list} $animate-in ($v-overlay-animate-in) - the animation used when the overlay is made visible
+ * @param {list} $animate-out ($v-overlay-animate-out) - the animation used when the overlay is removed
+ */
@mixin valo-overlay-style (
$background-color: $v-overlay-background-color,
$shadow: $v-overlay-shadow,
@@ -135,7 +264,15 @@ $v-selection-item-selection-color: $v-selection-color !default;
-
+/**
+ * Outputs styles for selection overlay elements.
+ *
+ * @group overlay
+ *
+ * @param {color} $background-color ($v-selection-overlay-background-color) - the background color for the overlay
+ * @param {list} $animate-in ($v-overlay-animate-in) - the animation used when the selection overlay is made visible
+ * @param {list} $animate-out ($v-overlay-animate-out) - the animation used when the selection overlay is removed
+ */
@mixin valo-selection-overlay-style ($background-color: $v-selection-overlay-background-color, $animate-in: $v-overlay-animate-in, $animate-out: $v-overlay-animate-out) {
@include valo-overlay-style($background-color: $background-color, $animate-in: $animate-in, $animate-out: $animate-out);
padding: $v-selection-overlay-padding-vertical $v-selection-overlay-padding-horizontal;
@@ -143,7 +280,11 @@ $v-selection-item-selection-color: $v-selection-color !default;
-
+/**
+ * Outputs the styles for selection item elements (i.e. individual items in context menus and drop down menus).
+ *
+ * @group overlay
+ */
@mixin valo-selection-item-style {
cursor: pointer;
line-height: $v-selection-item-height;
@@ -178,7 +319,11 @@ $v-selection-item-selection-color: $v-selection-color !default;
-
+/**
+ * Outputs the styles for selected selection item elements.
+ *
+ * @group overlay
+ */
@mixin valo-selection-item-selected-style {
@include valo-gradient($v-selection-item-selection-color);
$font-color: valo-font-color($v-selection-item-selection-color, 0.9);
@@ -192,13 +337,24 @@ $v-selection-item-selection-color: $v-selection-color !default;
-
+/**
+ * Outputs the selectors and styles for generic dragging ghost elements.
+ *
+ * @group drag-n-drop
+ */
@mixin valo-drag-element {
.v-drag-element {
@include valo-drag-element-style;
}
}
+/**
+ * Outputs the styles for generic dragging ghost elements.
+ *
+ * @group drag-n-drop
+ *
+ * @param {color} $background-color ($v-app-background-color) - the background color for the ghost element
+ */
@mixin valo-drag-element-style ($background-color: $v-app-background-color) {
background: $background-color;
color: valo-font-color($background-color);
diff --git a/WebContent/VAADIN/themes/valo/shared/_tooltip.scss b/WebContent/VAADIN/themes/valo/shared/_tooltip.scss
index 7b7b83ff33..3c9c914499 100644
--- a/WebContent/VAADIN/themes/valo/shared/_tooltip.scss
+++ b/WebContent/VAADIN/themes/valo/shared/_tooltip.scss
@@ -1,16 +1,81 @@
-// @category Tooltip
-
+/**
+ * The backgound color for tooltips.
+ *
+ * @type color
+ * @group tooltip
+ */
$v-tooltip-background-color: rgba(if(is-dark-color($v-background-color), scale-color($v-background-color, $lightness: 80%), scale-color($v-background-color, $lightness: -80%)), .9) !default;
+
+/**
+ * The font color for tooltips.
+ *
+ * @type color
+ * @group tooltip
+ */
$v-tooltip-font-color: valo-font-color(opacify($v-tooltip-background-color, 1), 1) !default;
+
+/**
+ * The font size for tooltips.
+ *
+ * @type size
+ * @group tooltip
+ */
$v-tooltip-font-size: max(12px, round($v-font-size * 0.86)) !default;
+
+/**
+ * The CSS box shadow for tooltips.
+ *
+ * @type list
+ * @group tooltip
+ */
$v-tooltip-box-shadow: 0 2px 12px rgba(#000, .2) !default;
+
+/**
+ * The vertical padding for tooltips.
+ *
+ * @type size
+ * @group tooltip
+ */
$v-tooltip-padding-vertical: round($v-unit-size/8) !default;
+
+/**
+ * The horizontal padding for tooltips.
+ *
+ * @type size
+ * @group tooltip
+ */
$v-tooltip-padding-horizontal: round($v-unit-size/4) !default;
+
+/**
+ * The backgound color for error tooltips.
+ *
+ * @type color
+ * @group tooltip
+ */
$v-tooltip-error-message-background-color: #fff !default;
+
+/**
+ * The font color for error tooltips.
+ *
+ * @type color
+ * @group tooltip
+ */
$v-tooltip-error-message-font-color: $v-error-indicator-color !default;
+
+/**
+ * The corner radius for tooltips.
+ *
+ * @type size
+ * @group tooltip
+ */
$v-tooltip-border-radius: $v-border-radius - 1px !default;
+/**
+ * Outputs the selectors and styles for tooltip elements.
+ *
+ * @group tooltip
+ */
@mixin valo-tooltip {
.v-tooltip {
@include valo-tooltip-style;
@@ -54,7 +119,11 @@ $v-tooltip-border-radius: $v-border-radius - 1px !default;
}
}
-
+/**
+ * Outputs the main styles for tooltip elements.
+ *
+ * @group tooltip
+ */
@mixin valo-tooltip-style {
background-color: opacify($v-tooltip-background-color, 1); // For IE8
background-color: $v-tooltip-background-color;
diff --git a/WebContent/VAADIN/themes/valo/shared/_variables.scss b/WebContent/VAADIN/themes/valo/shared/_variables.scss
index 7dd3827298..4634a71fea 100644
--- a/WebContent/VAADIN/themes/valo/shared/_variables.scss
+++ b/WebContent/VAADIN/themes/valo/shared/_variables.scss
@@ -1,88 +1,459 @@
// Color functions are used to calculate default font color
@import "../util/color";
-
-
-// A static text that is shown while the application JavaScript is loaded and started
-$v-app-loading-text : "" !default;
-
-
-// Base line height used for all widgets
-$v-line-height : 1.55 !default;
-
-
-$v-background-color : hsl(210, 0%, 98%) !default;
-$v-app-background-color : $v-background-color !default;
-
-$v-font-size : 16px !default; // Should be specified in pixels
-$v-font-weight : 300 !default; // Must be specified as a numeric value (i.e. not 'normal' or 'bold')
-$v-font-color : valo-font-color($v-app-background-color) !default;
-$v-font-family : "Open Sans", sans-serif !default;
-
-$v-caption-font-size : round($v-font-size * 0.9) !default; // Should be a pixel value
-$v-caption-font-weight : max(400, $v-font-weight) !default;
-
-$v-unit-size : round(2.3 * $v-font-size) !default; // Must be specified in pixels (suitable range 18-50)
-
-$v-layout-margin-top : round($v-unit-size) !default;
-$v-layout-margin-right : round($v-unit-size) !default;
-$v-layout-margin-bottom : round($v-unit-size) !default;
-$v-layout-margin-left : round($v-unit-size) !default;
-
-$v-layout-spacing-vertical : round($v-unit-size/3) !default;
-$v-layout-spacing-horizontal : round($v-unit-size/3) !default;
-
-$v-border : 1px solid (v-shade 0.7) !default; // Size must be specified in pixels
-$v-border-radius : 4px !default; // Must be specified in pixels
-
-$v-gradient : v-linear 8% !default;
-
-$v-bevel : inset 0 1px 0 v-tint, inset 0 -1px 0 v-shade !default;
-$v-bevel-depth : 30% !default;
-
-$v-shadow : 0 2px 3px v-shade !default;
-$v-shadow-opacity : 5% !default;
-
-$v-focus-color : valo-focus-color() !default;
-$v-focus-style : 0 0 0 2px rgba($v-focus-color, .5) !default;
-
-$v-animations-enabled : true !default;
-$v-hover-styles-enabled : true !default;
-
-$v-disabled-opacity : 0.5 !default;
-
-$v-selection-color : $v-focus-color !default;
-
-$v-default-field-width : $v-unit-size * 5 !default;
-
-$v-error-indicator-color : #ed473b !default;
-$v-required-field-indicator-color : $v-error-indicator-color !default;
-$v-friendly-color : #2c9720 !default;
-
-
-$v-scaling-factor--tiny : 0.75 !default;
-$v-scaling-factor--small : 0.85 !default;
-$v-scaling-factor--large : 1.2 !default;
-$v-scaling-factor--huge : 1.6 !default;
-
-$v-unit-size--tiny : round($v-unit-size * $v-scaling-factor--tiny) !default;
-$v-unit-size--small : round($v-unit-size * $v-scaling-factor--small) !default;
-$v-unit-size--large : round($v-unit-size * $v-scaling-factor--large) !default;
-$v-unit-size--huge : round($v-unit-size * $v-scaling-factor--huge) !default;
-
-$v-font-size--tiny : ceil($v-font-size * $v-scaling-factor--tiny) !default;
-$v-font-size--small : ceil($v-font-size * $v-scaling-factor--small) !default;
-$v-font-size--large : ceil($v-font-size * $v-scaling-factor--large) !default;
-$v-font-size--huge : ceil($v-font-size * $v-scaling-factor--huge) !default;
-
-
-
-// List of components to include in the theme compilation. The list can be modified to make
-// the compiled theme smaller by removing unused components from the list.
-//
-// @usage
-// // Remove the Calendar component styles from the output
-// $v-included-components: remove($v-included-components, calendar);
+/**
+ * A static text that is shown under the loading spinned while the client-side
+ * engine is being loaded and started. The text must be given in quotes. The
+ * text can not be localized currently.
+ *
+ * @type string, quoted
+ */
+$v-app-loading-text: "" !default;
+
+/**
+ * Base line height for all widgets. It must be given a unitless number.
+ *
+ * @group typography
+ * @type number
+ */
+$v-line-height: 1.55 !default;
+
+/**
+ * Base font size for the theme. The font size defines the overall sizing of
+ * UI components by default. Must be specified in pixels.
+ *
+ * @group typography
+ * @type size (px)
+ */
+$v-font-size: 16px !default;
+
+/**
+ * Base font weight for plain text.
+ * Must be specified as a numeric value: 100, 200, 300 (light), 400 (regular),
+ * 500, 600, 700 (bold), 800 or 900.
+ *
+ * @group typography
+ * @type number
+ */
+$v-font-weight: 300 !default;
+
+/**
+ * Base font family for the theme. Can be any valid CSS font stack.
+ *
+ * @group typography
+ * @type list
+ */
+$v-font-family: "Open Sans", sans-serif !default;
+
+/**
+ * Font size for generic component captions. Can be any valid CSS font-size. A
+ * round pixel value is recommended.
+ *
+ * @group typography
+ * @type number
+ */
+$v-caption-font-size: round($v-font-size * 0.9) !default;
+
+/**
+ * Font weight for generic component captions. Can be any valid CSS font-weight.
+ *
+ * @group typography
+ * @type number | identifier
+ */
+$v-caption-font-weight: max(400, $v-font-weight) !default;
+
+/**
+ * Border specification for the components that have a border. The border width
+ * must be specified in pixels. For the border color, you can specify any CSS color
+ * or one of the v-tint, v-shade, and v-tone keywords.
+ *
+ * @group style
+ * @type list
+ */
+$v-border: 1px solid (v-shade 0.7) !default;
+
+/**
+ * Corner radius for components that have a border. The measure must be specified as a
+ * single pixel value (i.e. not as a list of values for each corner).
+ *
+ * @group style
+ * @type size (px)
+ */
+$v-border-radius: 4px !default;
+
+/**
+ * Color gradient style for components that have a gradient. The gradient style may use
+ * the following keywords: v-linear and v-linear-reverse. The opacity must be given
+ * as percentage between 0% and 100%.
+ *
+ * #### Gradient styles
+ *
+ * - __v-linear__ - The start of the gradient is a lighter shade of the base color and the end is a darker shade of the base color. A basic linear gradient.
+ * - __v-linear-reverse__ - Same as v-linear, but the color stops are reversed (darker at the start and lighter at the end)
+ *
+ * @group style
+ * @type list
+ */
+$v-gradient: v-linear 8% !default;
+
+/**
+ * Inset shadow style to define how some components are "raised" from the background.
+ * The value follows the syntax of CSS box-shadow, and should be a list of insets.
+ * For the bevel color, you can specify any CSS color or one of the v-tint, v-shade,
+ * and v-tone keywords.
+ *
+ * @group style
+ * @type list
+ */
+$v-bevel: inset 0 1px 0 v-tint, inset 0 -1px 0 v-shade !default;
+
+/**
+ * Specifies the "depth" of the bevel shadow, as applied to one of the color keywords for
+ * the bevel style. The actual amount of tint, shade, or tone is computed from the depth.
+ *
+ * @group style
+ * @type number (pct)
+ */
+$v-bevel-depth: 30% !default;
+
+/**
+ * Default shadow style for all components. As with $v-bevel, the value follows the syntax
+ * of CSS box-shadow, but without the inset. For the shadow color, you can specify any CSS
+ * color or one of the v-tint or v-shade keywords.
+ *
+ * @group style
+ * @type list
+ */
+$v-shadow: 0 2px 3px v-shade !default;
+
+/**
+ * Specifies the opacity of the shadow, as applied to one of the color keywords for the
+ * shadow style. The actual amount of tint or shade is computed from the depth.
+ *
+ * @group style
+ * @type number (pct)
+ */
+$v-shadow-opacity: 5% !default;
+
+/**
+ * The background color is the main control parameter for the Valo theme and
+ * it is used for computing all other colors in the theme. If the color is dark
+ * (has low luminance), * light foreground colors that give high contrast
+ * with the background are automatically used.
+ *
+ * Can be any valid CSS color.
+ *
+ * @group color
+ * @type color
+ */
+$v-background-color: hsl(210, 0%, 98%) !default;
+
+/**
+ * Background color of the UI's root element. You can specify the color in
+ * any way allowed in CSS. Used as the base for other default colors, such
+ * as panel and window content areas.
+ *
+ * Can be any valid CSS color.
+ *
+ * @group color
+ * @type color
+ */
+$v-app-background-color: $v-background-color !default;
+
+/**
+ * Base font color for the theme. Can be any valid CSS color.
+ *
+ * @group color
+ * @type color
+ */
+$v-font-color: valo-font-color($v-app-background-color) !default;
+
+/**
+ * Color for the field focus indicator. The valo-focus-color() function computes a
+ * high-contrast color from the context, which is usually the background color. The color
+ * can be any CSS color.
+ *
+ * @group color
+ * @type color
+ */
+$v-focus-color: valo-focus-color() !default;
+
+/**
+ * Box-shadow specification for the field focus indicator. The space-separated values
+ * are the horizontal shadow position in pixels, vertical shadow position in pixels,
+ * blur distance in pixels, spread distance in pixels, and the color. The color can be
+ * any CSS color. You can only specify the color, in which case defaults for the position
+ * are used. rgba() or hsla() can be used to enable transparency.
+ *
+ * @group style
+ * @type list | color
+ */
+$v-focus-style: 0 0 0 2px rgba($v-focus-color, .5) !default;
+
+/**
+ * Opacity of disabled components, from 0 to 1. Not all components have reduced opacity when disabled, such as Labels.
+ *
+ * @group style
+ * @type number
+ */
+$v-disabled-opacity: 0.5 !default;
+
+/**
+ * Color for indicating selection in selection components.
+ *
+ * @group color
+ * @type color
+ */
+$v-selection-color: $v-focus-color !default;
+
+/**
+ * Color of the component error indicator and other error indications, such as the
+ * error style notification.
+ *
+ * @group color
+ * @type color
+ */
+$v-error-indicator-color: #ed473b !default;
+
+/**
+ * Color of the required indicator in field components.
+ *
+ * @group color
+ * @type color
+ */
+$v-required-field-indicator-color: $v-error-indicator-color !default;
+
+/**
+ * Color used for success states and to indicate safe actions (i.e. actions that
+ * will not cause any data loss).
+ *
+ * @group color
+ * @type color
+ */
+$v-friendly-color: #2c9720 !default;
+
+/**
+ * Color specifications for $v-border, $v-bevel, and $v-shadow may use, in addition to CSS colors, the following keywords:
+ *
+ * - __v-tint__ - Lighter than the background color
+ * - __v-shade__ - Darker than the background color
+ * - __v-tone__ - Adaptive color specification: darker on light background and lighter on dark background. Not usable in $v-shadow.
+ *
+ *
+ * These keywords can be further adjusted by combining them with a strength multiplier, specified in parenthesis.
+ *
+ * Examples:
+ *
+ * (v-tint 2)
+ * (v-shade 0.6)
+ * (v-tone 1.1)
+ *
+ * @group color
+ */
+$v-color-keywords: v-tint, v-shade, v-tone;
+
+/**
+ * This is the base size for various layout measures. It is directly used in some
+ * measures, such as button height and layout margins, while other measures are
+ * derived from it. The value must be specified in pixels, with a suitable range
+ * of 18-50.
+ *
+ * @group layout
+ * @type size (px)
+ */
+$v-unit-size: round(2.3 * $v-font-size) !default;
+
+/**
+ * Scaling factor for tiny sizes. Must be a unitless number.
+ *
+ * @group layout
+ * @type number
+ */
+$v-scaling-factor--tiny: 0.75 !default;
+
+/**
+ * Scaling factor for small sizes. Must be a unitless number.
+ *
+ * @group layout
+ * @type number
+ */
+$v-scaling-factor--small: 0.85 !default;
+
+/**
+ * Scaling factor for large sizes. Must be a unitless number.
+ *
+ * @group layout
+ * @type number
+ */
+$v-scaling-factor--large: 1.2 !default;
+
+/**
+ * Scaling factor for huge sizes. Must be a unitless number.
+ *
+ * @group layout
+ * @type number
+ */
+$v-scaling-factor--huge: 1.6 !default;
+
+/**
+ * Unit size for tiny components. Must be a pixel value.
+ *
+ * @group layout
+ * @type size (px)
+ */
+$v-unit-size--tiny: round($v-unit-size * $v-scaling-factor--tiny) !default;
+
+/**
+ * Unit size for small components. Must be a pixel value.
+ *
+ * @group layout
+ * @type size (px)
+ */
+$v-unit-size--small: round($v-unit-size * $v-scaling-factor--small) !default;
+
+/**
+ * Unit size for large components. Must be a pixel value.
+ *
+ * @group layout
+ * @type size (px)
+ */
+$v-unit-size--large: round($v-unit-size * $v-scaling-factor--large) !default;
+
+/**
+ * Unit size for huge components. Must be a pixel value.
+ *
+ * @group layout
+ * @type size (px)
+ */
+$v-unit-size--huge: round($v-unit-size * $v-scaling-factor--huge) !default;
+
+/**
+ * The top margin size for all built-in layout components, when the margin is
+ * enabled with setMargin(). Can be any valid CSS size.
+ *
+ * @group layout
+ * @type size
+ */
+$v-layout-margin-top: round($v-unit-size) !default;
+
+/**
+ * The right margin size for all built-in layout components, when the margin is
+ * enabled with setMargin(). Can be any valid CSS size.
+ *
+ * @group layout
+ * @type size
+ */
+$v-layout-margin-right: round($v-unit-size) !default;
+
+/**
+ * The bottom margin size for all built-in layout components, when the margin is
+ * enabled with setMargin(). Can be any valid CSS size.
+ *
+ * @group layout
+ * @type size
+ */
+$v-layout-margin-bottom: round($v-unit-size) !default;
+
+/**
+ * The left margin size for all built-in layout components, when the margin is
+ * enabled with setMargin(). Can be any valid CSS size.
+ *
+ * @group layout
+ * @type size
+ */
+$v-layout-margin-left: round($v-unit-size) !default;
+
+/**
+ * Amount of vertical space when spacing is enabled for a layout with setSpacing().
+ * Can be any valid CSS size.
+ *
+ * @group layout
+ * @type size
+ */
+$v-layout-spacing-vertical: round($v-unit-size/3) !default;
+
+/**
+ * Amount of horizontal space when spacing is enabled for a layout with setSpacing().
+ * Can be any valid CSS size.
+ *
+ * @group layout
+ * @type size
+ */
+$v-layout-spacing-horizontal: round($v-unit-size/3) !default;
+
+/**
+ * Tiny font size.
+ *
+ * @group typography
+ * @type size (px)
+ */
+$v-font-size--tiny: ceil($v-font-size * $v-scaling-factor--tiny) !default;
+
+/**
+ * Small font size.
+ *
+ * @group typography
+ * @type size (px)
+ */
+$v-font-size--small: ceil($v-font-size * $v-scaling-factor--small) !default;
+
+/**
+ * Large font size.
+ *
+ * @group typography
+ * @type size (px)
+ */
+$v-font-size--large: ceil($v-font-size * $v-scaling-factor--large) !default;
+
+/**
+ * Huge font size.
+ *
+ * @group typography
+ * @type size (px)
+ */
+$v-font-size--huge: ceil($v-font-size * $v-scaling-factor--huge) !default;
+
+/**
+ * Default width of certain field components, unless overridden with setWidth().
+ *
+ * @group layout
+ * @type size (px)
+ */
+$v-default-field-width: $v-unit-size * 5 !default;
+
+/**
+ * Specifies whether various CSS animations are used. Not all animations are disabled when
+ * set to false, such as the default loading indicator animations.
+ *
+ * @group optimization
+ * @type bool
+ */
+$v-animations-enabled: true !default;
+
+/**
+ * Specifies whether various :hover styles are used for indicating that mouse pointer
+ * hovers over an element.
+ *
+ * @group optimization
+ * @type bool
+ */
+$v-hover-styles-enabled: true !default;
+
+/**
+ * List of components to include in the theme compilation. The list can be modified to make
+ * the compiled theme smaller by removing unused components from the list.
+ *
+ * @group optimization
+ * @type list
+ *
+ * @example scss
+ * // Remove the Calendar component styles from the output (must be declared after importing Valo)
+ * $v-included-components: remove($v-included-components, calendar);
+ *
+ * @example scss
+ * // Only include the Label, Button and Vertical and Horizontal layouts in the compilation
+ * $v-included-components: label, button, orderedlayout;
+ */
$v-included-components:
absolutelayout,
accordion,
@@ -125,23 +496,43 @@ $v-included-components:
window,
valo-menu !default;
-
+/**
+ * List of components whose additional styles should be included in the compilation.
+ *
+ * @group optimization
+ * @type list
+ */
$v-included-additional-styles: $v-included-components !default;
-
-// Checks if a given component is included in the compilation. Used by the collection mixins that
-// include all components, like valo-components and valo-components.
-// @param $component-name {String} the name of the component to check
-// @param $is-included {list} (Optional) the list of components which is checked
-// @return {Boolean} true if the component is included in the compilation, false if not
+/**
+ * Checks if a given component is included in the compilation. Used by the collection mixins that
+ * include all components (i.e. valo-components).
+ *
+ * @requires $v-included-components
+ *
+ * @example scss
+ * @if v-is-included(button) {
+ * // The Button component is included in the compilation
+ * }
+ *
+ * @param {string} $component-name - the name of the component to check
+ * @param {list} $is-included ($v-included-components) - the list of components which is checked
+ *
+ * @return {bool} true if the component is included in the compilation, false if not
+ *
+ * @group optimization
+ */
@function v-is-included ($component-name, $is-included: $v-included-components) {
@return contains($is-included, $component-name);
}
-
-// A flag to note whether relative URL paths are relative to the currently parsed SCSS file or to the compilation root file.
-// The Vaadin compiler parses URL paths differently than the regular Sass compiler (i.e. Vaadin modifies relative url paths).
-// This boolean is used to flag which compiler is used, so that paths are correct for different resources.
-// false == Ruby, true == Vaadin
+/**
+ * A flag to note whether relative URL paths are relative to the currently parsed SCSS file or to the compilation root file.
+ * The Vaadin compiler parses URL paths differently than the regular Sass compiler (i.e. Vaadin modifies relative url paths).
+ * This boolean is used to flag which compiler is used, so that paths are correct for different resources.
+ * false == Ruby, true == Vaadin
+ *
+ * @type bool
+ */
$v-relative-paths: true !default;
diff --git a/WebContent/VAADIN/themes/valo/util/_anim.scss b/WebContent/VAADIN/themes/valo/util/_anim.scss
index 430a6e4722..0cb738d832 100644
--- a/WebContent/VAADIN/themes/valo/util/_anim.scss
+++ b/WebContent/VAADIN/themes/valo/util/_anim.scss
@@ -1,73 +1,62 @@
-@if $v-animations-enabled {
+$valo-anim-keyframes-included: false !default;
- // 'Placeholder' animation names to trigger VOverlay animation-in and animation-out
- @include keyframes(valo-placeholder-animate-in) {
- 0% {
- visibility: visible;
- }
- }
+@if $v-animations-enabled and $valo-anim-keyframes-included == false{
- @include keyframes(valo-placeholder-animate-out) {
- 100% {
- visibility: visible;
- }
- }
-
- @include keyframes(valo-anim-fade-in) {
+ @include keyframes(valo-animate-in-fade) {
0% {
opacity: 0;
}
}
- @include keyframes(valo-anim-fade-out) {
+ @include keyframes(valo-animate-out-fade) {
100% {
opacity: 0;
}
}
- @include keyframes(valo-anim-slide-in-down) {
+ @include keyframes(valo-animate-in-slide-down) {
0% {
@include transform( translateY(-100%) );
}
}
- @include keyframes(valo-anim-slide-in-up) {
+ @include keyframes(valo-animate-in-slide-up) {
0% {
@include transform( translateY(100%) );
}
}
- @include keyframes(valo-anim-slide-in-left) {
+ @include keyframes(valo-animate-in-slide-left) {
0% {
@include transform( translateX(100%) );
}
}
- @include keyframes(valo-anim-slide-in-right) {
+ @include keyframes(valo-animate-in-slide-right) {
0% {
@include transform( translateX(-100%) );
}
}
- @include keyframes(valo-anim-slide-out-down) {
+ @include keyframes(valo-animate-out-slide-down) {
100% {
@include transform( translateY(100%) );
}
}
- @include keyframes(valo-anim-slide-out-up) {
+ @include keyframes(valo-animate-out-slide-up) {
100% {
@include transform( translateY(-100%) );
}
}
- @include keyframes(valo-anim-slide-out-left) {
+ @include keyframes(valo-animate-out-slide-left) {
100% {
@include transform( translateX(-100%) );
}
}
- @include keyframes(valo-anim-slide-out-right) {
+ @include keyframes(valo-animate-out-slide-right) {
100% {
@include transform( translateX(100%) );
}
@@ -80,36 +69,84 @@
}
}
- @include keyframes(valo-anim-drop-fade-out) {
+ @include keyframes(valo-animate-out-slide-down-fade) {
100% {
opacity: 0;
@include transform(translatey(30%));
}
}
-
+
+ $valo-anim-keyframes-included: true;
}
-
-@mixin valo-anim-fade-in ($duration: 120ms, $delay: null){
- @include animation(valo-anim-fade-in $duration $delay);
+/**
+ * Add animate-in-fade animation to the targeted elements.
+ *
+ * @group animation
+ *
+ * @param {time} $duration (180ms) - the duration of the fade
+ * @param {time} $delay (null) - the delay of the fade
+ */
+@mixin valo-animate-in-fade ($duration: 180ms, $delay: null){
+ @include animation(valo-animate-in-fade $duration $delay);
}
-@mixin valo-anim-fade-out ($duration: 120ms, $delay: null){
- @include animation(valo-anim-fade-out $duration $delay);
+/**
+ * Add animate-out-fade animation to the targeted elements.
+ *
+ * @group animation
+ *
+ * @param {time} $duration (180ms) - the duration of the fade
+ * @param {time} $delay (null) - the delay of the fade
+ */
+@mixin valo-animate-out-fade ($duration: 180ms, $delay: null){
+ @include animation(valo-animate-out-fade $duration $delay);
}
-@mixin valo-anim-slide-down ($duration: 260ms, $delay: null){
- @include animation(valo-anim-slide-down $duration $delay);
+/**
+ * Add animate-in-slide-down animation to the targeted elements.
+ *
+ * @group animation
+ *
+ * @param {time} $duration (400ms) - the duration of the slide
+ * @param {time} $delay (null) - the delay of the slide
+ */
+@mixin valo-animate-in-slide-down ($duration: 400ms, $delay: null){
+ @include animation(valo-animate-in-slide-down $duration $delay);
}
-@mixin valo-anim-slide-up ($duration: 260ms, $delay: null){
- @include animation(valo-anim-slide-up $duration $delay);
+/**
+ * Add animate-in-slide-up animation to the targeted elements.
+ *
+ * @group animation
+ *
+ * @param {time} $duration (400ms) - the duration of the slide
+ * @param {time} $delay (null) - the delay of the slide
+ */
+@mixin valo-animate-in-slide-up ($duration: 400ms, $delay: null){
+ @include animation(valo-animate-in-slide-up $duration $delay);
}
-@mixin valo-anim-slide-left ($duration: 260ms, $delay: null){
- @include animation(valo-anim-slide-left $duration $delay);
+/**
+ * Add animate-in-slide-left animation to the targeted elements.
+ *
+ * @group animation
+ *
+ * @param {time} $duration (400ms) - the duration of the slide
+ * @param {time} $delay (null) - the delay of the slide
+ */
+@mixin valo-animate-in-slide-left ($duration: 400ms, $delay: null){
+ @include animation(valo-animate-in-slide-left $duration $delay);
}
-@mixin valo-anim-slide-right ($duration: 260ms, $delay: null){
- @include animation(valo-anim-slide-right $duration $delay);
+/**
+ * Add animate-in-slide-right animation to the targeted elements.
+ *
+ * @group animation
+ *
+ * @param {time} $duration (400ms) - the duration of the slide
+ * @param {time} $delay (null) - the delay of the slide
+ */
+@mixin valo-animate-in-slide-right ($duration: 400ms, $delay: null){
+ @include animation(valo-animate-in-slide-right $duration $delay);
}
diff --git a/WebContent/VAADIN/themes/valo/util/_bevel-and-shadow.scss b/WebContent/VAADIN/themes/valo/util/_bevel-and-shadow.scss
index bf5b9b78bd..346a50c9de 100644
--- a/WebContent/VAADIN/themes/valo/util/_bevel-and-shadow.scss
+++ b/WebContent/VAADIN/themes/valo/util/_bevel-and-shadow.scss
@@ -1,3 +1,15 @@
+/**
+ * Computes a CSS border property value for the given base color.
+ *
+ * @group style
+ *
+ * @param {list} $border ($v-border) - CSS border value which can contain any of the color keywords
+ * @param {color} $color ($v-background-color) - the base color to which the color keywords are applied to
+ * @param {color} $context (null) - context/surrounding color where the border is expected to appear. The color of the final border is the darker of the two parameters passed to this function.
+ * @param {number} $strength (1) - adjustment for the border contrast
+ *
+ * @return {list} The input $border value with any color keyword replaced with the corresponding actual color
+ */
@function valo-border($border: $v-border, $color: $v-background-color, $context: null, $strength: 1) {
@if type-of($border) != list {
@return $border;
@@ -18,8 +30,8 @@
$adjust-type: first-string($part);
$adjust-amount: first-number($part);
- $tint: blend-screen(white($v-bevel-depth/100%*$adjust-amount*$strength), $color);
- $shade: blend-linearburn(black($v-bevel-depth/100%*$adjust-amount*$strength), $color);
+ $tint: blend-screen(rgba(#fff, $v-bevel-depth/100%*$adjust-amount*$strength), $color);
+ $shade: blend-linearburn(rgba(#000, $v-bevel-depth/100%*$adjust-amount*$strength), $color);
@if $adjust-type == v-tone {
@if is-dark-color($color) {
@@ -42,22 +54,46 @@
}
-@mixin valo-border-with-gradient($border: $v-border, $color: $v-background-color, $gradient: $v-gradient) {
- border: valo-border($border, $color);
-
- // Adjust border-colors for gradient
+/**
+ * Similar to the valo-border function, but adjusts the top and bottom border colors to suit an element with a gradient background-color.
+ *
+ * @group style
+ *
+ * @param {list} $border ($v-border) - CSS border value which can contain any of the color keywords
+ * @param {color} $color ($v-background-color) - the base color to which the color keywords are applied to
+ * @param {color} $context (null) - context/surrounding color where the border is expected to appear. The color of the final border is the darker of the two parameters passed to this function.
+ * @param {number} $strength (1) - adjustment for the border contrast
+ * @param {list} $gradient ($v-gradient) - Valo specific gradient value. See the documentation for $v-gradient.
+ */
+@mixin valo-border-with-gradient($border: $v-border, $color: $v-background-color, $context: null, $strength: 1, $gradient: $v-gradient) {
+ border: valo-border($border, $color, $context, $strength);
+
+ // Adjust border colors for gradient
@if $gradient {
$color-stops: valo-gradient-color-stops($color, $gradient);
$top: first(first($color-stops));
$bottom: first(last($color-stops));
- border-top-color: first-color(valo-border($border, $top));
- border-bottom-color: first-color(valo-border($border, $bottom));
+ border-top-color: first-color(valo-border($border, $top, $context, $strength));
+ border-bottom-color: first-color(valo-border($border, $bottom, $context, $strength));
}
}
-
-
+/**
+ * Computes a CSS box-shadow value according to the specified style parameters.
+ *
+ * @group style
+ *
+ * @param {list} $bevel (null) - box-shadow value according to $v-bevel documentation
+ * @param {number} $bevel-depth ($v-bevel-depth) - percentage defining the depth/amount of the bevel effect. Affects the color keywords specified in the $bevel parameter.
+ * @param {list} $shadow (null) - box-shadow value according to $v-shadow documentation
+ * @param {number} $shadow-opacity ($v-shadow-opacity) - percentage defining the opacity/amount of the shadow effect. Affects the color keywords specified in the $shadow parameter.
+ * @param {color} $background-color ($v-background-color) - the base color to which the color keywords are applied to
+ * @param {list} $gradient (null) - Valo specific gradient value. See the documentation for $v-gradient. Affects the color keywords specified in the $bevel parameter.
+ * @param {bool} $include-focus (false) - should the box-shadow value include $v-focus-style as well (only added if $v-focus-style is a)
+ *
+ * @return {list} CSS box-shadow value, combined from $bevel and $shadow with all occurences of v-tint, v-shade and v-tone color keywords replaced with the corresponding actual color
+ */
@function valo-bevel-and-shadow ($bevel: null, $bevel-depth: $v-bevel-depth, $shadow: null, $shadow-opacity: $v-shadow-opacity, $background-color: $v-background-color, $gradient: null, $include-focus: false) {
$box-shadow: null;
@@ -117,9 +153,18 @@
}
-
-@function valo-replace-tones($list, $tint-color, $gradient: null, $shade-color: null) {
- $shade-color: $shade-color or $tint-color;
+/**
+ * Replaces color keywords in the given list.
+ *
+ * @group style
+ *
+ * @param {list} $list - any CSS list with possible color keywords
+ * @param {color} $color - The color to which color keywords are applied to
+ * @param {list} $gradient (null) - Valo specific gradient value. See the documentation for $v-gradient. Affects the replacement colors to accommodate the gradient.
+ *
+ * @return {list} The input $list parameter with all occurences of v-tint, v-shade and v-tone color keywords replaced with the corresponding actual color
+ */
+@function valo-replace-tones($list, $color, $gradient: null) {
$ret: ();
@each $part in $list {
@@ -130,11 +175,11 @@
$adjust-type: first-string($part);
$adjust-amount: first-number($part);
- $top-color: $tint-color;
- $bottom-color: $shade-color;
+ $top-color: $color;
+ $bottom-color: $color;
@if $gradient {
- $color-stops: valo-gradient-color-stops($tint-color, $gradient);
+ $color-stops: valo-gradient-color-stops($color, $gradient);
$top-color: first(first($color-stops));
$bottom-color: first(last($color-stops));
}
@@ -142,20 +187,20 @@
$tint: blend-lighten(adjust-color($top-color, $lightness: $v-bevel-depth/4*$adjust-amount, $saturation: -$v-bevel-depth/2), scale-color($top-color, $lightness: $v-bevel-depth/4*$adjust-amount));
$shade: blend-darken(rgba(scale-color($bottom-color, $lightness: max(-30%, -$v-bevel-depth/3*$adjust-amount), $saturation: -$v-bevel-depth/2), $v-bevel-depth/100%), $bottom-color);
- $color: null;
+ $new-color: null;
@if $adjust-type == v-tone {
- @if is-dark-color($tint-color) {
- $color: $tint;
+ @if is-dark-color($color) {
+ $new-color: $tint;
} @else {
- $color: $shade;
+ $new-color: $shade;
}
} @else if $adjust-type == v-tint {
- $color: $tint;
+ $new-color: $tint;
} @else if $adjust-type == v-shade {
- $color: $shade;
+ $new-color: $shade;
}
- $ret: join($ret, $color);
+ $ret: join($ret, $new-color);
} @else {
$ret: join($ret, $part);
@@ -166,6 +211,15 @@
}
+/**
+ * Replace color keywords in the given box-shadow parameter.
+ *
+ * @group style
+ *
+ * @param {list} $shadow - CSS box-shadow value, or any other CSS list which might contain either the v-tint or the v-shade color keywords.
+ *
+ * @return {list} the input $shadow parameter with all occurences of v-tint and v-shade color keywords replaced with the corresponding actual color
+ */
@function valo-replace-shadow ($shadow) {
$ret: ();
@each $part in $shadow {
@@ -196,36 +250,24 @@
}
-@function valo-text-shadow($font-color: $v-font-color, $background-color: $v-background-color, $bevel: $v-bevel, $offset: 1px) {
- @if type-of($bevel) != list or $v-bevel-depth == 0 {
- @return null;
- }
-
- $needle: null;
+/**
+ * Return a CSS text-shadow property value according to the specified style parameters.
+ *
+ * @group style
+ *
+ * @param {color} $font-color ($v-font-color) - the color of the text to which the text-shadow is added
+ * @param {color} $background-color ($v-background-color) - the color of the background where the text is to which the text-shadow is added
+ * @param {size} $offset (-1px) - the size of the text shadow vertical offset
+ * @param {number (pct)} $opacity ($v-shadow-opacity) - the percentage amount of shadow which is applied
+ */
+@function valo-text-shadow($font-color: $v-font-color, $background-color: $v-background-color, $offset: -1px, $opacity: $v-shadow-opacity) {
+ $color: null;
@if color-luminance($font-color) < color-luminance($background-color) {
- // Text darker than bg, light shadow. Look for tint
- $needle: v-tint;
+ $color: rgba(#fff, $opacity / 100%);
+ $offset: $offset * -1;
} @else {
- // Text lighter than bg, dark shadow. Look for shade
- $needle: v-shade;
- }
-
- // Use the first match from the bevel list
- @while list-of-lists($bevel) {
- $bevel: first($bevel);
- }
-
- // Remove possible 'inset'
- $bevel: remove($bevel, inset);
-
- $color: $background-color;
- @each $b in $bevel {
- $strength: 1;
- @if type-of($b) == list {
- $strength: first-number($b);
- }
- $color: if($needle==v-tint, rgba(#fff, $v-shadow-opacity/100%*$strength), rgba(#000, $v-shadow-opacity/100%*$strength));
+ $color: rgba(#000, $opacity / 100%);
}
- @return 0 if($needle==v-tint, $offset, $offset*-1) 0 $color;
+ @return 0 $offset 0 $color;
}
diff --git a/WebContent/VAADIN/themes/valo/util/_blend-modes.scss b/WebContent/VAADIN/themes/valo/util/_blend-modes.scss
index 3da575660d..40d4defbdb 100644
--- a/WebContent/VAADIN/themes/valo/util/_blend-modes.scss
+++ b/WebContent/VAADIN/themes/valo/util/_blend-modes.scss
@@ -1,6 +1,5 @@
// From https://github.com/heygrady/scss-blend-modes
// MIT license
-// Remember to add a license notice to Vaadin
//--------------------------------
// Normal
diff --git a/WebContent/VAADIN/themes/valo/util/_color.scss b/WebContent/VAADIN/themes/valo/util/_color.scss
index 0c80d2f0d0..37612fd48d 100644
--- a/WebContent/VAADIN/themes/valo/util/_color.scss
+++ b/WebContent/VAADIN/themes/valo/util/_color.scss
@@ -1,37 +1,48 @@
// "Photoshop" blend modes
@import "blend-modes";
-// Returns the luminance of a color (0-255)
-// (perceived brightness, rather than absolute mathematical lightness value)
-//
-// "The luminance calculation is a weighted average of the color channels that approximates
-// how humans perceive brightness, while lightness is just an average of the largest and
-// smallest channels without regard to perception."
-//
-// Source for equation: http://en.wikipedia.org/wiki/Luminance_(relative)
+/**
+ * Returns the luminance of a color (0-255), i.e. the perceived brightness, rather than
+ * the absolute mathematical lightness value.
+ *
+ * "The luminance calculation is a weighted average of the color channels that approximates
+ * how humans perceive brightness, while lightness is just an average of the largest and
+ * smallest channels without regard to perception."
+ *
+ * Source: http://en.wikipedia.org/wiki/Luminance_(relative)
+ *
+ * @group color
+ *
+ * @param {color} $color - the color whose luminance value to get
+ *
+ * @return {number} the luminance value of the color, in the range of 0-255
+ *
+ */
@function color-luminance ($color) {
@return 0.2126 * red($color) + 0.7152 * green($color) + 0.0722 * blue($color);
}
-// Arbitrary luminance threshold after which colors should be adjusted either darker or lighter
+/**
+ * Luminance value after which colors will be considered light (i.e. not dark).
+ *
+ * @group color
+ */
$v-luminance-threshold: 150 !default;
-
-@function black($opacity: 1) {
- @return transparentize(#000, 1 - $opacity);
-}
-
-@function white($opacity: 1) {
- @return transparentize(#fff, 1 - $opacity);
-}
-
-
-
-@function is-dark-color($bg-color) {
- $luminance: color-luminance($bg-color);
- @if $luminance < $v-luminance-threshold or (saturation($bg-color) > 80% and ($luminance < $v-luminance-threshold + 20)) {
+/**
+ * Checks whether the color is considered dark or light, according to it's luminance and saturation.
+ *
+ * @group color
+ *
+ * @param {color} $color - the color to check
+ *
+ * @return {bool} true if the color is considered dark, false if considered light
+ */
+@function is-dark-color($color) {
+ $luminance: color-luminance($color);
+ @if $luminance < $v-luminance-threshold or (saturation($color) > 80% and ($luminance < $v-luminance-threshold + 20)) {
@return true;
} @else {
@return false;
@@ -39,6 +50,15 @@ $v-luminance-threshold: 150 !default;
}
+/**
+ * Get the darkest color (by luminance) from a list of colors.
+ *
+ * @group color
+ *
+ * @param {list} $colors - a list of CSS colors
+ *
+ * @return {color} darkest color (by luminance) from a list of colors
+ */
@function darkest-color($colors...) {
$darkest: first($colors);
@each $color in $colors {
@@ -49,31 +69,38 @@ $v-luminance-threshold: 150 !default;
@return $darkest;
}
-// Returns a text color with enough contrast for the given background color
-@function valo-font-color ($bg-color, $contrast: 0.8) {
- @if $bg-color {
+
+/**
+ * Returns a font color with enough contrast for the given background color.
+ *
+ * @group color
+ *
+ * @param {color} $bg-color - the background color for which to compute a suitable font color
+ * @param {number} $contrast (0.8) - the contrast of the font color compared to the background color
+ *
+ * @return {color} a suitable font color for the given background color
+ */
+@function valo-font-color ($bg-color, $contrast: 0.72) {
+ @if type-of($bg-color) == color {
@if is-dark-color($bg-color) {
@return scale-color($bg-color, $lightness: min(100%, 100% * $contrast), $saturation: max(-100%, -50% * $contrast));
} @else {
- @return scale-color($bg-color, $lightness: max(-100%, -100% * $contrast * 0.9), $saturation: max(-100%, -50% * $contrast));
+ @return scale-color($bg-color, $lightness: max(-100%, -100% * $contrast), $saturation: max(-100%, -50% * $contrast));
}
}
@return null;
}
-@function valo-header-color ($bg-color, $contrast: 1) {
- $font-color: valo-font-color($bg-color);
- @if is-dark-color($bg-color) {
- @return lighten($font-color, 30% * $contrast);
- } @else {
- @return darken($font-color, 20% * $contrast);
- }
-}
-
-
-
-
+/**
+ * Returns a suitable focus color for the given background color.
+ *
+ * @group color
+ *
+ * @param {color} $context ($v-app-background-color) - the background color for which to compute a suitable focus color
+ *
+ * @return {color} a suitable focus color for the given background color
+ */
@function valo-focus-color ($context: $v-app-background-color) {
$color: $context;
@if is-dark-color($context) {
@@ -85,9 +112,13 @@ $v-luminance-threshold: 150 !default;
}
-
-@mixin valo-focus-style($include-box-shadow: false) {
- @if $include-box-shadow and type-of($v-focus-style) == list {
+/**
+ * Output the default focus styles (border-color and box-shadow).
+ *
+ * @group style
+ */
+@mixin valo-focus-style {
+ @if type-of($v-focus-style) == list {
@include box-shadow($v-focus-style);
} @else if type-of($v-focus-style) == color {
border-color: $v-focus-style;
diff --git a/WebContent/VAADIN/themes/valo/util/_css3.scss b/WebContent/VAADIN/themes/valo/util/_css3.scss
index b1215d735f..dc2dc781a7 100644
--- a/WebContent/VAADIN/themes/valo/util/_css3.scss
+++ b/WebContent/VAADIN/themes/valo/util/_css3.scss
@@ -1,3 +1,11 @@
+/**
+ * Cross-browser opacity.
+ *
+ * @param {number} $value - opacity value from 0 to 1
+ * @param {bool} $important (false) - should the property value be declared with !important
+ *
+ * @group util
+ */
@mixin opacity ($value, $important: false) {
$importantValue: null;
@if $important {
@@ -14,7 +22,14 @@
}
}
-// -webkit-box-shadow still needed for Android 2.3 and 3.0, as well as iOS 5
+/**
+ * Cross-browser box-shadow.
+ * -webkit-box-shadow is still needed for Android 2.3 and 3.0, as well as iOS 5
+ *
+ * @param {list} $shadows - Any valid CSS box-shadow value
+ *
+ * @group util
+ */
@mixin box-shadow ($shadows...) {
@include prefixer(box-shadow, $shadows, webkit spec);
}
diff --git a/WebContent/VAADIN/themes/valo/util/_gradient.scss b/WebContent/VAADIN/themes/valo/util/_gradient.scss
index df159ad611..99490046ba 100644
--- a/WebContent/VAADIN/themes/valo/util/_gradient.scss
+++ b/WebContent/VAADIN/themes/valo/util/_gradient.scss
@@ -1,3 +1,13 @@
+/**
+ * Outputs cross-browser Valo-specific linear gradient background-image declarations.
+ *
+ * @group style
+ *
+ * @param {color} $color ($v-background-color) - The base color for the gradient color stops
+ * @param {list} $gradient ($v-gradient) - Valo-specific gradient value. See the documentation for $v-gradient.
+ * @param {color} $fallback (null) - A fallback color for browser which do not support linear gradients (IE8 and IE9 in particular). If null, the base $color is used instead.
+ * @param {string} $direction (to bottom) - the direction of the linear gradient. The color stops are by default so that a lighter shade is at the start and a darker shade is at the end.
+ */
@mixin valo-gradient($color: $v-background-color, $gradient: $v-gradient, $fallback: null, $direction: to bottom) {
@if $color {
@if $gradient {
@@ -9,6 +19,14 @@
}
}
+/**
+ * Returns a valid CSS, Valo-specific, color stop list to be used in a linear gradient.
+ *
+ * @group style
+ *
+ * @param {color} $color - the base color for the color stops
+ * @param {list} $gradient ($v-gradient) - Valo-specific gradient value. See the documentation for $v-gradient.
+ */
@function valo-gradient-color-stops($color, $gradient: $v-gradient) {
$style: valo-gradient-style($gradient);
$opacity: valo-gradient-opacity($gradient);
@@ -31,6 +49,13 @@
}
+/**
+ * Returns the style part of a Valo-specific gradient value.
+ *
+ * @param {list} $gradient ($v-gradient) - Valo-specific gradient value. See the documentation for $v-gradient.
+ *
+ * @return {string} One of the possible style values for $v-gradient
+ */
@function valo-gradient-style($gradient: $v-gradient) {
@if type-of($gradient) != list {
@return none;
@@ -38,6 +63,13 @@
@return first-string($gradient);
}
+/**
+ * Returns the opacity part of a Valo-specific gradient value.
+ *
+ * @param {list} $gradient ($v-gradient) - Valo-specific gradient value. See the documentation for $v-gradient.
+ *
+ * @return {number} A percentage value from 0% to 100%
+ */
@function valo-gradient-opacity($gradient: $v-gradient) {
@if type-of($gradient) != list {
@return 0%;
diff --git a/WebContent/VAADIN/themes/valo/util/_lists.scss b/WebContent/VAADIN/themes/valo/util/_lists.scss
index 54471b1380..f82c4f0fe3 100644
--- a/WebContent/VAADIN/themes/valo/util/_lists.scss
+++ b/WebContent/VAADIN/themes/valo/util/_lists.scss
@@ -1,15 +1,26 @@
-@function contains($list, $var, $recursive: false) {
+/**
+ * Checks if a list contains a certain value.
+ *
+ * @param {list} $list - the list to check
+ * @param {value} $var - the value to search for
+ * @param {bool} $recursive (false) - should any contained lists be checked for the value
+ *
+ * @return {bool} true if the value is found from the list, false otherwise
+ *
+ * @group lists
+ */
+@function contains($list, $value, $recursive: false) {
@if $recursive == false {
- @return (false != index($list, $var));
+ @return (false != index($list, $value));
}
$ret: false;
@each $item in $list {
@if type-of($item) == list and $recursive {
- @if contains($item, $var, true) {
+ @if contains($item, $value, true) {
@return true;
}
- } @else if $item == $var {
+ } @else if $item == $value {
@return true;
}
}
@@ -18,6 +29,15 @@
}
+/**
+ * Check whether a list contains nested lists.
+ *
+ * @param {list} $list - the list to check
+ *
+ * @return {bool} true of the list contains other nested lists, false otherwise
+ *
+ * @group lists
+ */
@function list-of-lists($list) {
@each $part in $list {
@if type-of($part) != list {
@@ -28,26 +48,72 @@
}
+/**
+ * Get the first color value from a list.
+ *
+ * @param {list} $list - a list which should contain a color value
+ *
+ * @return {color} The first color encountered in the list
+ *
+ * @group lists
+ */
@function first-color($list) {
@return first-of-type($list, color);
}
+/**
+ * Get the first number value from a list.
+ *
+ * @param {list} $list - a list which should contain a number value
+ *
+ * @return {number} The first number encountered in the list
+ *
+ * @group lists
+ */
@function first-number($list) {
@return first-of-type($list, number);
}
+/**
+ * Get the first string value from a list.
+ *
+ * @param {list} $list - a list which should contain a string value
+ *
+ * @return {string} The first string encountered in the list
+ *
+ * @group lists
+ */
@function first-string($list) {
@return first-of-type($list, string);
}
+/**
+ * Get the first contained list from the list passed as the parameter.
+ *
+ * @param {list} $list - a list which should contain a nested list
+ *
+ * @return {list} The first list encountered in the list passed as the parameter
+ *
+ * @group lists
+ */
@function first-list($list) {
@return first-of-type($list, list);
}
+/**
+ * Get the first value of a certain type from a list.
+ *
+ * @param {list} $list - a list which should contain a value of the certain type
+ * @param {string} $type - the type of value to search for
+ *
+ * @return {value} The first item of the certain type encountered in the list
+ *
+ * @group lists
+ */
@function first-of-type($list, $type) {
@each $item in $list {
@if type-of($item) == $type {
@@ -63,6 +129,15 @@
}
+/**
+ * Flatten nested lists to one list, while maintaining the original list separators.
+ *
+ * @param {list} $list - the list to flatten
+ *
+ * @return {list} the same list with all nested lists flattened
+ *
+ * @group lists
+ */
@function flatten-list($list) {
$ret: ();
@each $item in $list {
diff --git a/WebContent/VAADIN/themes/valo/util/_util.scss b/WebContent/VAADIN/themes/valo/util/_util.scss
index 1f983c0dad..585504600d 100644
--- a/WebContent/VAADIN/themes/valo/util/_util.scss
+++ b/WebContent/VAADIN/themes/valo/util/_util.scss
@@ -1,4 +1,12 @@
-// Align element vertically inside
+/**
+ * Ouput selectors and properties to vertically center elements inside their parent.
+ *
+ * @param {string} $to-align (()) - The selector to match the elements which you wish to align vertically. The targeted elements should be inline or inline-block elements.
+ * @param {string} $align (middle) - The vertical-align value, e.g. top, middle, bottom
+ * @param {string} $pseudo-element (after) - Which pseudo element to use for the vertical align guide
+ *
+ * @group util
+ */
@mixin valo-vertical-align-guide ($to-align: (), $align: middle, $pseudo-element: after) {
&:#{$pseudo-element} {
content: "";
@@ -18,7 +26,11 @@
}
-
+/**
+ * Indicate that an element is clickable/tappable
+ *
+ * @group util
+ */
@mixin valo-tappable {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-touch-callout: none;
@@ -26,13 +38,53 @@
}
-
+/**
+ * Output Vaadin Responsive extension specific width-range declaration.
+ *
+ * @param {size} $min (0) - The lower bound for the width-range
+ * @param {size} $max (null) - The upper bound for the width-range
+ *
+ * @group util
+ *
+ * @example scss
+ * .v-ui {
+ * font-size: 18px;
+ *
+ * // Make the font-size smaller for 481px-768px wide UIs
+ * @include width-range(481px, 768px) {
+ * font-size: 16px;
+ * }
+ *
+ * // Make it even smaller for UIs narrower than 480px
+ * @include width-range($max: 480px) {
+ * font-size: 14px;
+ * }
+ * }
+ */
@mixin width-range($min: 0, $max: null) {
&[width-range~="#{$min}-#{$max}"] {
@content;
}
}
+/**
+ * Output Vaadin Responsive extension specific height-range declaration.
+ *
+ * @param {size} $min (0) - The lower bound for the height-range
+ * @param {size} $max (null) - The upper bound for the height-range
+ *
+ * @group util
+ *
+ * @example scss
+ * .v-csslayout {
+ * color: red;
+ *
+ * // Make the text color blue when the layout height is between 100px-300px
+ * @include height-range(100px, 300px) {
+ * color: blue;
+ * }
+ * }
+ */
@mixin height-range($min: 0, $max: null) {
&[height-range~="#{$min}-#{$max}"] {
@content;
diff --git a/WebContent/license.html b/WebContent/license.html
index f714e4d64d..0ce22da99c 100644
--- a/WebContent/license.html
+++ b/WebContent/license.html
@@ -160,6 +160,14 @@
<td title="Custom web font">Lora</td>
<td><a href="licenses/OFL.txt">SIL OFL 1.1</a></td>
</tr>
+ <tr>
+ <td><a href="https://github.com/heygrady/scss-blend-modes">SCSS Blend Modes</a></td>
+ <td><a href="licenses/the-mit-license.txt">The MIT License</a></td>
+ </tr>
+ <tr>
+ <td><a href="https://github.com/Team-Sass/Sass-list-functions">Sass list functions</a></td>
+ <td><a href="licenses/the-mit-license.txt">The MIT License</a></td>
+ </tr>
<!-- The extracted vaadin-sass-compiler -->
<tr>
<td>Vaadin Sass Compiler</td>
diff --git a/build.properties b/build.properties
index 0a25dab4b9..a9ad640e53 100644
--- a/build.properties
+++ b/build.properties
@@ -5,6 +5,6 @@ vaadin.vendor=Vaadin Ltd
vaadin.url=http://vaadin.com
vaadin.java.version=1.6
vaadin.version=0.0.0.unversioned-development-build
-vaadin.sass.version=0.9.9
+vaadin.sass.version=0.9.10
gwt.version=2.6.0.vaadin5
commons-io.version=2.4
diff --git a/build/ide.xml b/build/ide.xml
index 1e586acc19..fff4ba911d 100755
--- a/build/ide.xml
+++ b/build/ide.xml
@@ -128,13 +128,17 @@
<target name="compile-widgetset" depends="resolve">
<property name="module" value="${widgetset}" />
<property name="module.output.dir" location="WebContent/VAADIN/widgetsets" />
+ <property name="logLevel" value="TRACE" />
<property name="style" value="PRETTY" />
<property name="localWorkers" value="2" />
+ <!-- Whether assertions should be compiled into the widgetset.
+ Either "-ea" to enable or "" to disable. -->
+ <property name="assertions" value="-ea" />
<property name="extraParams" value="" />
<mkdir dir="${module.output.dir}" />
- <echo>Compiling ${module} to ${module.output.dir} with parameters -logLevel TRACE -style ${style} -localWorkers ${localWorkers} -strict ${extraParams}</echo>
+ <echo>Compiling ${module} to ${module.output.dir} with parameters -logLevel ${logLevel} -style ${style} -localWorkers ${localWorkers} ${assertions} -strict ${extraParams}</echo>
<!--<ivy:resolve log="download-only" inline="true" organisation="javax.validation" module="validation-api"
revision="1.0.0.GA"/> -->
@@ -144,14 +148,14 @@
<arg value="-workDir" />
<arg value="${work.dir}" />
<arg value="-logLevel" />
- <arg value="TRACE" />
+ <arg value="${logLevel}" />
<arg value="-war" />
<arg value="${module.output.dir}" />
<arg value="-style" />
<arg value="${style}" />
-
<arg value="-localWorkers" />
<arg value="${localWorkers}" />
+ <arg line="${assertions}" />
<arg value="-strict" />
<arg line="${extraParams}" />
<arg value="${module}" />
diff --git a/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java b/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java
index dc2a676ab8..5bb010a1d2 100644
--- a/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java
+++ b/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java
@@ -20,6 +20,7 @@ import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
+import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.IOUtils;
@@ -33,12 +34,26 @@ public class FetchReleaseNotesTickets {
+ "</tr>"; //
public static void main(String[] args) throws IOException {
- String versions = System.getProperty("vaadin.version");
- if (versions == null || versions.equals("")) {
+ String versionsProperty = System.getProperty("vaadin.version");
+ if (versionsProperty == null || versionsProperty.equals("")) {
usage();
}
String milestone = "";
- for (String version : versions.split(" ")) {
+
+ List<String> versions = new ArrayList<String>();
+ for (String version : versionsProperty.split(" ")) {
+ if (version.endsWith(".0") || version.matches(".*\\.rc\\d+")) {
+ // Find all prerelease versions for final or rc
+
+ // Strip potential rc prefix
+ version = version.replaceAll("\\.rc\\d+$", "");
+ versions.addAll(findPrereleaseVersions(version));
+ } else {
+ versions.add(version);
+ }
+ }
+
+ for (String version : versions) {
if (!milestone.equals("")) {
milestone += "&amp;";
}
@@ -48,6 +63,22 @@ public class FetchReleaseNotesTickets {
printMilestone(milestone);
}
+ private static List<String> findPrereleaseVersions(String baseVersion) {
+ List<String> versions = new ArrayList<String>();
+
+ for (int i = 0; i < 50; i++) {
+ versions.add(baseVersion + ".alpha" + i);
+ }
+ for (int i = 0; i < 10; i++) {
+ versions.add(baseVersion + ".beta" + i);
+ }
+ for (int i = 0; i < 10; i++) {
+ versions.add(baseVersion + ".rc" + i);
+ }
+
+ return versions;
+ }
+
private static void printMilestone(String milestone)
throws MalformedURLException, IOException {
diff --git a/client-compiler/src/com/vaadin/tools/CvalChecker.java b/client-compiler/src/com/vaadin/tools/CvalChecker.java
index e426c5c4e6..c48aa7d9db 100644
--- a/client-compiler/src/com/vaadin/tools/CvalChecker.java
+++ b/client-compiler/src/com/vaadin/tools/CvalChecker.java
@@ -31,9 +31,10 @@ import java.util.Locale;
import java.util.ResourceBundle;
import java.util.prefs.Preferences;
+import elemental.json.JsonException;
+import elemental.json.JsonObject;
+import elemental.json.impl.JsonUtil;
import org.apache.commons.io.IOUtils;
-import org.json.JSONException;
-import org.json.JSONObject;
/**
* This class is able to validate the vaadin CVAL license.
@@ -58,9 +59,9 @@ public final class CvalChecker {
public static class CvalInfo {
public static class Product {
- private JSONObject o;
+ private JsonObject o;
- public Product(JSONObject o) {
+ public Product(JsonObject o) {
this.o = o;
}
@@ -74,40 +75,32 @@ public final class CvalChecker {
}
@SuppressWarnings("unchecked")
- private static <T> T get(JSONObject o, String k, Class<T> clz) {
+ private static <T> T get(JsonObject o, String k, Class<T> clz) {
Object ret = null;
try {
if (clz == String.class) {
ret = o.getString(k);
- } else if (clz == JSONObject.class) {
- ret = o.getJSONObject(k);
+ } else if (clz == JsonObject.class) {
+ ret = o.getObject(k);
} else if (clz == Integer.class) {
- ret = o.getInt(k);
+ ret = Integer.valueOf((int) o.getNumber(k));
} else if (clz == Date.class) {
- ret = new Date(o.getLong(k));
+ ret = new Date((long) o.getNumber(k));
} else if (clz == Boolean.class) {
ret = o.getBoolean(k);
}
- } catch (JSONException e) {
+ } catch (JsonException e) {
}
return (T) ret;
}
- private static <T> T put(JSONObject o, String k, Object v) {
- try {
- o.put(k, v);
- } catch (JSONException e) {
- }
- return null;
- }
-
- private JSONObject o;
+ private JsonObject o;
private Product product;
- public CvalInfo(JSONObject o) {
+ public CvalInfo(JsonObject o) {
this.o = o;
- product = new Product(get(o, "product", JSONObject.class));
+ product = new Product(get(o, "product", JsonObject.class));
}
public Boolean getExpired() {
@@ -139,11 +132,11 @@ public final class CvalChecker {
}
public void setExpiredEpoch(Date expiredEpoch) {
- put(o, "expiredEpoch", expiredEpoch.getTime());
+ o.put("expiredEpoch", expiredEpoch.getTime());
}
public void setMessage(String msg) {
- put(o, "message", msg);
+ o.put("message", msg);
}
@Override
@@ -327,9 +320,9 @@ public final class CvalChecker {
return null;
}
try {
- JSONObject o = new JSONObject(json);
+ JsonObject o = JsonUtil.parse(json);
return new CvalInfo(o);
- } catch (JSONException e) {
+ } catch (JsonException e) {
return null;
}
}
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index 90aa0a14d6..3e3ad033a7 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -110,14 +110,14 @@ import com.vaadin.shared.ui.ui.UIState.PushConfigurationState;
* This is the client side communication "engine", managing client-server
* communication with its server side counterpart
* com.vaadin.server.VaadinService.
- *
+ *
* Client-side connectors receive updates from the corresponding server-side
* connector (typically component) as state updates or RPC calls. The connector
* has the possibility to communicate back with its server side counter part
* through RPC calls.
- *
+ *
* TODO document better
- *
+ *
* Entry point classes (widgetsets) define <code>onModuleLoad()</code>.
*/
public class ApplicationConnection implements HasHandlers {
@@ -149,12 +149,12 @@ public class ApplicationConnection implements HasHandlers {
* A string that, if found in a non-JSON response to a UIDL request, will
* cause the browser to refresh the page. If followed by a colon, optional
* whitespace, and a URI, causes the browser to synchronously load the URI.
- *
+ *
* <p>
* This allows, for instance, a servlet filter to redirect the application
* to a custom login page when the session expires. For example:
* </p>
- *
+ *
* <pre>
* if (sessionExpired) {
* response.setHeader(&quot;Content-Type&quot;, &quot;text/html&quot;);
@@ -345,7 +345,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Event triggered when a XHR request has finished with the status code of
* the response.
- *
+ *
* Useful for handlers observing network failures like online/off-line
* monitors.
*/
@@ -401,12 +401,12 @@ public class ApplicationConnection implements HasHandlers {
/**
* Event triggered when a application is stopped by calling
* {@link ApplicationConnection#setApplicationRunning(false)}.
- *
+ *
* To listen for the event add a {@link ApplicationStoppedHandler} by
* invoking
* {@link ApplicationConnection#addHandler(ApplicationConnection.ApplicationStoppedEvent.Type, ApplicationStoppedHandler)}
* to the {@link ApplicationConnection}
- *
+ *
* @since 7.1.8
* @author Vaadin Ltd
*/
@@ -433,7 +433,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Called when a communication error has occurred. Returning
* <code>true</code> from this method suppresses error handling.
- *
+ *
* @param details
* A string describing the error.
* @param statusCode
@@ -448,7 +448,7 @@ public class ApplicationConnection implements HasHandlers {
* A listener for listening to application stopped events. The listener can
* be added to a {@link ApplicationConnection} by invoking
* {@link ApplicationConnection#addHandler(ApplicationStoppedEvent.Type, ApplicationStoppedHandler)}
- *
+ *
* @since 7.1.8
* @author Vaadin Ltd
*/
@@ -458,7 +458,7 @@ public class ApplicationConnection implements HasHandlers {
* Triggered when the {@link ApplicationConnection} marks a previously
* running application as stopped by invoking
* {@link ApplicationConnection#setApplicationRunning(false)}
- *
+ *
* @param event
* the event triggered by the {@link ApplicationConnection}
*/
@@ -569,7 +569,7 @@ public class ApplicationConnection implements HasHandlers {
* called once this application has started (first response received) or
* failed to start. This ensures that the applications are started in order,
* to avoid session-id problems.
- *
+ *
*/
public void start() {
String jsonText = configuration.getUIDL();
@@ -646,7 +646,7 @@ public class ApplicationConnection implements HasHandlers {
return componentLocator.@com.vaadin.client.componentlocator.ComponentLocator::getElementsByPathStartingAt(Ljava/lang/String;Lcom/google/gwt/dom/client/Element;)(id, element);
});
client.getPathForElement = $entry(function(element) {
- return componentLocator.@com.vaadin.client.componentlocator.ComponentLocator::getPathForElement(Lcom/google/gwt/dom/client/Element;)(element);
+ return componentLocator.@com.vaadin.client.componentlocator.ComponentLocator::getLegacyPathForElement(Lcom/google/gwt/dom/client/Element;)(element);
});
client.initializing = false;
@@ -679,7 +679,7 @@ public class ApplicationConnection implements HasHandlers {
* <li><code>vaadin.postRequestHooks</code> is a map of functions which gets
* called after each XHR made by vaadin application. Note, that it is
* attaching js functions responsibility to create the variable like this:
- *
+ *
* <code><pre>
* if(!vaadin.postRequestHooks) {vaadin.postRequestHooks = new Object();}
* postRequestHooks.myHook = function(appId) {
@@ -690,7 +690,7 @@ public class ApplicationConnection implements HasHandlers {
* </pre></code> First parameter passed to these functions is the identifier
* of Vaadin application that made the request.
* </ul>
- *
+ *
* TODO make this multi-app aware
*/
private native void initializeClientHooks()
@@ -721,7 +721,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Runs possibly registered client side post request hooks. This is expected
* to be run after each uidl request made by Vaadin application.
- *
+ *
* @param appId
*/
private static native void runPostRequestHooks(String appId)
@@ -741,7 +741,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* If on Liferay and logged in, ask the client side session management
* JavaScript to extend the session duration.
- *
+ *
* Otherwise, Liferay client side JavaScript will explicitly expire the
* session even though the server side considers the session to be active.
* See ticket #8305 for more information.
@@ -760,7 +760,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Indicates whether or not there are currently active UIDL requests. Used
* internally to sequence requests properly, seldom needed in Widgets.
- *
+ *
* @return true if there are active requests
*/
public boolean hasActiveRequest() {
@@ -780,7 +780,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Requests an analyze of layouts, to find inconsistencies. Exclusively used
* for debugging during development.
- *
+ *
* @deprecated as of 7.1. Replaced by {@link UIConnector#analyzeLayouts()}
*/
@Deprecated
@@ -792,7 +792,7 @@ public class ApplicationConnection implements HasHandlers {
* Sends a request to the server to print details to console that will help
* the developer to locate the corresponding server-side connector in the
* source code.
- *
+ *
* @param serverConnector
* @deprecated as of 7.1. Replaced by
* {@link UIConnector#showServerDebugInfo(ServerConnector)}
@@ -804,7 +804,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Makes an UIDL request to the server.
- *
+ *
* @param reqInvocations
* Data containing RPC invocations and all related information.
* @param extraParams
@@ -844,7 +844,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Sends an asynchronous or synchronous UIDL request to the server using the
* given URI.
- *
+ *
* @param uri
* The URI to use for the request. May includes GET parameters
* @param payload
@@ -982,7 +982,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Handles received UIDL JSON text, parsing it, and passing it on to the
* appropriate handlers, while logging timing information.
- *
+ *
* @param jsonText
* @param statusCode
*/
@@ -1010,7 +1010,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Sends an asynchronous UIDL request to the server using the given URI.
- *
+ *
* @param uri
* The URI to use for the request. May includes GET parameters
* @param payload
@@ -1135,17 +1135,17 @@ public class ApplicationConnection implements HasHandlers {
}
} else {
cssLoaded = true;
- handleReceivedJSONMessage(new Date(), jsonText, json);
if (cssWaits >= MAX_CSS_WAITS) {
- VConsole.error("CSS files may have not loaded properly.");
+ getLogger().severe("CSS files may have not loaded properly.");
}
+ handleReceivedJSONMessage(new Date(), jsonText, json);
}
}
/**
* Checks whether or not the CSS is loaded. By default checks the size of
* the loading indicator element.
- *
+ *
* @return
*/
protected boolean isCSSLoaded() {
@@ -1155,12 +1155,12 @@ public class ApplicationConnection implements HasHandlers {
/**
* Shows the communication error notification.
- *
+ *
* @param details
* Optional details for debugging.
* @param statusCode
* The status code returned for the request
- *
+ *
*/
protected void showCommunicationError(String details, int statusCode) {
VConsole.error("Communication error: " + details);
@@ -1169,7 +1169,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Shows the authentication error notification.
- *
+ *
* @param details
* Optional details for debugging.
*/
@@ -1180,7 +1180,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Shows the session expiration notification.
- *
+ *
* @param details
* Optional details for debugging.
*/
@@ -1191,7 +1191,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Shows an error notification.
- *
+ *
* @param details
* Optional details for debugging.
* @param message
@@ -1204,7 +1204,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Shows the error notification.
- *
+ *
* @param details
* Optional details for debugging.
*/
@@ -1292,7 +1292,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* This method is called after applying uidl change set to application.
- *
+ *
* It will clean current and queued variable change sets. And send next
* change set if it exists.
*/
@@ -1311,7 +1311,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Cleans given queue of variable changes of such changes that came from
* components that do not exist anymore.
- *
+ *
* @param variableBurst
*/
private void cleanVariableBurst(
@@ -1360,7 +1360,7 @@ public class ApplicationConnection implements HasHandlers {
* <p>
* Used by the native "client.isActive" function.
* </p>
- *
+ *
* @return true if deferred commands are (potentially) being executed, false
* otherwise
*/
@@ -1375,7 +1375,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Returns the loading indicator used by this ApplicationConnection
- *
+ *
* @return The loading indicator for this ApplicationConnection
*/
public VLoadingIndicator getLoadingIndicator() {
@@ -1384,7 +1384,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Determines whether or not the loading indicator is showing.
- *
+ *
* @return true if the loading indicator is visible
* @deprecated As of 7.1. Use {@link #getLoadingIndicator()} and
* {@link VLoadingIndicator#isVisible()}.isVisible() instead.
@@ -1418,7 +1418,7 @@ public class ApplicationConnection implements HasHandlers {
* server is received.
* <p>
* The initial id when no request has yet been processed is -1.
- *
+ *
* @return and id identifying the response
*/
public int getLastResponseId() {
@@ -1843,13 +1843,13 @@ public class ApplicationConnection implements HasHandlers {
/**
* Sends the state change events created while updating the state
* information.
- *
+ *
* This must be called after hierarchy change listeners have been
* called. At least caption updates for the parent are strange if
* fired from state change listeners and thus calls the parent
* BEFORE the parent is aware of the child (through a
* ConnectorHierarchyChangedEvent)
- *
+ *
* @param pendingStateChangeEvents
* The events to send
*/
@@ -2164,7 +2164,7 @@ public class ApplicationConnection implements HasHandlers {
* Updates the connector hierarchy and returns a list of events that
* should be fired after update of the hierarchy and the state is
* done.
- *
+ *
* @param json
* The JSON containing the hierarchy information
* @return A collection of events that should be fired when update
@@ -2561,9 +2561,9 @@ public class ApplicationConnection implements HasHandlers {
/**
* Adds an explicit RPC method invocation to the send queue.
- *
+ *
* @since 7.0
- *
+ *
* @param invocation
* RPC method invocation
* @param delayed
@@ -2603,7 +2603,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Removes any pending invocation of the given method from the queue
- *
+ *
* @param invocation
* The invocation to remove
*/
@@ -2621,12 +2621,12 @@ public class ApplicationConnection implements HasHandlers {
/**
* This method sends currently queued variable changes to server. It is
* called when immediate variable update must happen.
- *
+ *
* To ensure correct order for variable changes (due servers multithreading
* or network), we always wait for active request to be handler before
* sending a new one. If there is an active request, we will put varible
* "burst" to queue that will be purged after current request is handled.
- *
+ *
*/
public void sendPendingVariableChanges() {
if (!deferedSendPending) {
@@ -2667,11 +2667,11 @@ public class ApplicationConnection implements HasHandlers {
/**
* Build the variable burst and send it to server.
- *
+ *
* When sync is forced, we also force sending of all pending variable-bursts
* at the same time. This is ok as we can assume that DOM will never be
* updated after this.
- *
+ *
* @param pendingInvocations
* List of RPC method invocations to send
*/
@@ -2758,7 +2758,7 @@ public class ApplicationConnection implements HasHandlers {
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update.
* </p>
- *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2780,7 +2780,7 @@ public class ApplicationConnection implements HasHandlers {
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update.
* </p>
- *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2803,7 +2803,7 @@ public class ApplicationConnection implements HasHandlers {
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update.
* </p>
- *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2826,7 +2826,7 @@ public class ApplicationConnection implements HasHandlers {
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update.
* </p>
- *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2849,7 +2849,7 @@ public class ApplicationConnection implements HasHandlers {
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update.
* </p>
- *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2872,7 +2872,7 @@ public class ApplicationConnection implements HasHandlers {
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update.
* </p>
- *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2895,7 +2895,7 @@ public class ApplicationConnection implements HasHandlers {
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update.
* </p>
- *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2918,7 +2918,7 @@ public class ApplicationConnection implements HasHandlers {
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update.
* </p>
- *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2935,13 +2935,13 @@ public class ApplicationConnection implements HasHandlers {
/**
* Sends a new value for the given paintables given variable to the server.
- *
+ *
* The update is actually queued to be sent at a suitable time. If immediate
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update.
- *
+ *
* A null array is sent as an empty array.
- *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2958,14 +2958,14 @@ public class ApplicationConnection implements HasHandlers {
/**
* Sends a new value for the given paintables given variable to the server.
- *
+ *
* The update is actually queued to be sent at a suitable time. If immediate
* is true, the update is sent as soon as possible. If immediate is false,
* the update will be sent along with the next immediate update. </p>
- *
+ *
* A null array is sent as an empty array.
- *
- *
+ *
+ *
* @param paintableId
* the id of the paintable that owns the variable
* @param variableName
@@ -2982,7 +2982,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Does absolutely nothing. Replaced by {@link LayoutManager}.
- *
+ *
* @param container
* @deprecated As of 7.0, serves no purpose
*/
@@ -3004,7 +3004,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Returns false
- *
+ *
* @param paintable
* @return false, always
* @deprecated As of 7.0, serves no purpose
@@ -3016,7 +3016,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Returns false
- *
+ *
* @param paintable
* @return false, always
* @deprecated As of 7.0, serves no purpose
@@ -3037,16 +3037,16 @@ public class ApplicationConnection implements HasHandlers {
/**
* Get either an existing ComponentConnector or create a new
* ComponentConnector with the given type and id.
- *
+ *
* If a ComponentConnector with the given id already exists, returns it.
* Otherwise creates and registers a new ComponentConnector of the given
* type.
- *
+ *
* @param connectorId
* Id of the paintable
* @param connectorType
* Type of the connector, as passed from the server side
- *
+ *
* @return Either an existing ComponentConnector or a new ComponentConnector
* of the given type
*/
@@ -3059,15 +3059,15 @@ public class ApplicationConnection implements HasHandlers {
/**
* Creates a new ServerConnector with the given type and id.
- *
+ *
* Creates and registers a new ServerConnector of the given type. Should
* never be called with the connector id of an existing connector.
- *
+ *
* @param connectorId
* Id of the new connector
* @param connectorType
* Type of the connector, as passed from the server side
- *
+ *
* @return A new ServerConnector of the given type
*/
private ServerConnector createAndRegisterConnector(String connectorId,
@@ -3087,7 +3087,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Gets a recource that has been pre-loaded via UIDL, such as custom
* layouts.
- *
+ *
* @param name
* identifier of the resource to get
* @return the resource
@@ -3098,7 +3098,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Singleton method to get instance of app's context menu.
- *
+ *
* @return VContextMenu object
*/
public VContextMenu getContextMenu() {
@@ -3113,7 +3113,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Gets an {@link Icon} instance corresponding to a URI.
- *
+ *
* @since 7.2
* @param uri
* @return Icon object
@@ -3135,7 +3135,7 @@ public class ApplicationConnection implements HasHandlers {
* Translates custom protocols in UIDL URI's to be recognizable by browser.
* All uri's from UIDL should be routed via this method before giving them
* to browser due URI's in UIDL may contain custom protocols like theme://.
- *
+ *
* @param uidlUri
* Vaadin URI from uidl
* @return translated URI ready for browser
@@ -3207,7 +3207,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Gets the URI for the current theme. Can be used to reference theme
* resources.
- *
+ *
* @return URI to the current theme
*/
public String getThemeUri() {
@@ -3218,7 +3218,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Listens for Notification hide event, and redirects. Used for system
* messages, such as session expired.
- *
+ *
*/
private class NotificationRedirect implements VNotification.EventListener {
String url;
@@ -3247,7 +3247,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Gets the token (aka double submit cookie) that the server uses to protect
* against Cross Site Request Forgery attacks.
- *
+ *
* @return the CSRF token string
*/
public String getCsrfToken() {
@@ -3257,7 +3257,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Use to notify that the given component's caption has changed; layouts may
* have to be recalculated.
- *
+ *
* @param component
* the Paintable whose caption has changed
* @deprecated As of 7.0.2, has not had any effect for a long time
@@ -3269,7 +3269,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Gets the main view
- *
+ *
* @return the main view
*/
public UIConnector getUIConnector() {
@@ -3278,7 +3278,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Gets the {@link ApplicationConfiguration} for the current application.
- *
+ *
* @see ApplicationConfiguration
* @return the configuration for this application
*/
@@ -3291,7 +3291,7 @@ public class ApplicationConnection implements HasHandlers {
* list of events which has server side listeners is updated automatically
* before the component is updated so the value is correct if called from
* updatedFromUIDL.
- *
+ *
* @param paintable
* The connector to register event listeners for
* @param eventIdentifier
@@ -3311,7 +3311,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Adds the get parameters to the uri and returns the new uri that contains
* the parameters.
- *
+ *
* @param uri
* The uri to which the parameters should be added.
* @param extraParams
@@ -3364,7 +3364,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Get VTooltip instance related to application connection
- *
+ *
* @return VTooltip instance
*/
public VTooltip getVTooltip() {
@@ -3376,7 +3376,7 @@ public class ApplicationConnection implements HasHandlers {
* this method is now handled by the state change event handler in
* AbstractComponentConnector. The only function this method has is to
* return true if the UIDL is a "cached" update.
- *
+ *
* @param component
* @param uidl
* @param manageCaption
@@ -3427,7 +3427,7 @@ public class ApplicationConnection implements HasHandlers {
* Schedules a heartbeat request to occur after the configured heartbeat
* interval elapses if the interval is a positive number. Otherwise, does
* nothing.
- *
+ *
* @deprecated as of 7.2, use {@link Heartbeat#schedule()} instead
*/
@Deprecated
@@ -3441,7 +3441,7 @@ public class ApplicationConnection implements HasHandlers {
* Heartbeat requests are used to inform the server that the client-side is
* still alive. If the client page is closed or the connection lost, the
* server will eventually close the inactive UI.
- *
+ *
* @deprecated as of 7.2, use {@link Heartbeat#send()} instead
*/
@Deprecated
@@ -3465,7 +3465,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* This method can be used to postpone rendering of a response for a short
* period of time (e.g. to avoid the rendering process during animation).
- *
+ *
* @param lock
*/
public void suspendReponseHandling(Object lock) {
@@ -3474,7 +3474,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Resumes the rendering process once all locks have been removed.
- *
+ *
* @param lock
*/
public void resumeResponseHandling(Object lock) {
@@ -3519,7 +3519,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Sets the delegate that is called whenever a communication error occurrs.
- *
+ *
* @param delegate
* the delegate.
*/
@@ -3562,7 +3562,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Gets the active connector for focused element in browser.
- *
+ *
* @return Connector for focused element or null.
*/
private ComponentConnector getActiveConnector() {
@@ -3576,7 +3576,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Sets the status for the push connection.
- *
+ *
* @param enabled
* <code>true</code> to enable the push connection;
* <code>false</code> to disable the push connection.
@@ -3626,7 +3626,7 @@ public class ApplicationConnection implements HasHandlers {
/**
* Returns a human readable string representation of the method used to
* communicate with the server.
- *
+ *
* @since 7.1
* @return A string representation of the current transport type
*/
diff --git a/client/src/com/vaadin/client/componentlocator/ComponentLocator.java b/client/src/com/vaadin/client/componentlocator/ComponentLocator.java
index c1ddc02aae..52c7b57d1d 100644
--- a/client/src/com/vaadin/client/componentlocator/ComponentLocator.java
+++ b/client/src/com/vaadin/client/componentlocator/ComponentLocator.java
@@ -36,6 +36,7 @@ import com.vaadin.client.ApplicationConnection;
public class ComponentLocator {
private final List<LocatorStrategy> locatorStrategies;
+ private final LocatorStrategy legacyLocatorStrategy;
/**
* Reference to ApplicationConnection instance.
@@ -51,8 +52,9 @@ public class ComponentLocator {
*/
public ComponentLocator(ApplicationConnection client) {
this.client = client;
+ legacyLocatorStrategy = new LegacyLocatorStrategy(client);
locatorStrategies = Arrays.asList(new VaadinFinderLocatorStrategy(
- client), new LegacyLocatorStrategy(client));
+ client), legacyLocatorStrategy);
}
/**
@@ -106,7 +108,28 @@ public class ComponentLocator {
* String locator could not be created.
*/
public String getPathForElement(Element targetElement) {
- return getPathForElement(DOM.asOld(targetElement));
+ if (targetElement != null) {
+ return getPathForElement(DOM.asOld(targetElement));
+ }
+ return null;
+ }
+
+ /**
+ * Returns a String locator which uniquely identifies the target element.
+ * The returned locator is in a legacy format that is suitable for Vaadin
+ * TestBench Recorder. For non-legacy format, use
+ * {@link #getPathForElement(com.google.gwt.user.client.Element)} instead.
+ *
+ *
+ * @since
+ * @param targetElement
+ * The element to generate a path for.
+ * @return A String locator that identifies the target element or null if a
+ * String locator could not be created.
+ */
+ public String getLegacyPathForElement(Element targetElement) {
+ return legacyLocatorStrategy
+ .getPathForElement(DOM.asOld(targetElement));
}
/**
diff --git a/client/src/com/vaadin/client/componentlocator/VaadinFinderLocatorStrategy.java b/client/src/com/vaadin/client/componentlocator/VaadinFinderLocatorStrategy.java
index 6075d1bf48..9ed071c38f 100644
--- a/client/src/com/vaadin/client/componentlocator/VaadinFinderLocatorStrategy.java
+++ b/client/src/com/vaadin/client/componentlocator/VaadinFinderLocatorStrategy.java
@@ -20,6 +20,7 @@ import java.util.Arrays;
import java.util.List;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConnection;
@@ -72,8 +73,24 @@ public class VaadinFinderLocatorStrategy implements LocatorStrategy {
*/
@Override
public String getPathForElement(Element targetElement) {
- if (targetElement == null) {
- return "";
+ Element oldTarget = targetElement;
+ Widget targetWidget = Util.findPaintable(client, targetElement)
+ .getWidget();
+ targetElement = targetWidget.getElement();
+
+ // Find SubPart name if needed.
+ String subPart = null;
+ boolean hasSubParts = targetWidget instanceof SubPartAware;
+ if (oldTarget != targetElement) {
+ if (hasSubParts) {
+ subPart = ((SubPartAware) targetWidget).getSubPartName(DOM
+ .asOld(oldTarget));
+ }
+
+ if (!hasSubParts || subPart == null) {
+ // Couldn't find SubPart name for element.
+ return null;
+ }
}
List<ConnectorPath> hierarchy = getConnectorHierarchyForElement(targetElement);
@@ -102,7 +119,7 @@ public class VaadinFinderLocatorStrategy implements LocatorStrategy {
return null;
}
- return getBestSelector(generateQueries(path), targetElement);
+ return getBestSelector(generateQueries(path), targetElement, subPart);
}
/**
@@ -114,9 +131,12 @@ public class VaadinFinderLocatorStrategy implements LocatorStrategy {
* List of selectors
* @param target
* Target element
+ * @param subPart
+ * sub part selector string for actual target
* @return Best selector string formatted with a post filter
*/
- private String getBestSelector(List<String> selectors, Element target) {
+ private String getBestSelector(List<String> selectors, Element target,
+ String subPart) {
// The last selector gives us smallest list index for target element.
String bestSelector = selectors.get(selectors.size() - 1);
int min = getElementsByPath(bestSelector).indexOf(target);
@@ -141,7 +161,8 @@ public class VaadinFinderLocatorStrategy implements LocatorStrategy {
}
}
- return "(" + bestSelector + ")[" + min + "]";
+ return "(" + bestSelector + (subPart != null ? "#" + subPart : "")
+ + ")[" + min + "]";
}
diff --git a/client/src/com/vaadin/client/debug/internal/SelectorPath.java b/client/src/com/vaadin/client/debug/internal/SelectorPath.java
index 5627bf0250..3f21e46a96 100644
--- a/client/src/com/vaadin/client/debug/internal/SelectorPath.java
+++ b/client/src/com/vaadin/client/debug/internal/SelectorPath.java
@@ -82,6 +82,10 @@ public class SelectorPath {
.extractPostFilterPredicates(path);
if (postFilters.size() > 0) {
tmpPath = tmpPath.substring(1, tmpPath.lastIndexOf(')'));
+ if (tmpPath.contains("#")) {
+ // FIXME: SubParts should be handled.
+ tmpPath = tmpPath.split("#")[0];
+ }
}
// Generate an ElementQuery
diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java
index b323812c8c..356e7291c4 100644
--- a/client/src/com/vaadin/client/ui/VFilterSelect.java
+++ b/client/src/com/vaadin/client/ui/VFilterSelect.java
@@ -250,6 +250,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
addCloseHandler(this);
Roles.getListRole().set(getElement());
+
+ setPreviewingAllNativeEvents(true);
}
/**
diff --git a/client/src/com/vaadin/client/ui/VGridLayout.java b/client/src/com/vaadin/client/ui/VGridLayout.java
index 4929b02c9a..90ae944322 100644
--- a/client/src/com/vaadin/client/ui/VGridLayout.java
+++ b/client/src/com/vaadin/client/ui/VGridLayout.java
@@ -360,7 +360,8 @@ public class VGridLayout extends ComplexPanel {
cell.layoutVertically(y, reservedMargin);
}
- if (rowHasComponentsOrRowSpan(row) || rowHeights[row] > 0) {
+ if (!hideEmptyRowsAndColumns || rowHasComponentsOrRowSpan(row)
+ || rowHeights[row] > 0) {
y += rowHeights[row] + verticalSpacing;
}
}
@@ -398,7 +399,8 @@ public class VGridLayout extends ComplexPanel {
cell.layoutHorizontally(x, reservedMargin);
}
}
- if (colHasComponentsOrColSpan(i) || columnWidths[i] > 0) {
+ if (!hideEmptyRowsAndColumns || colHasComponentsOrColSpan(i)
+ || columnWidths[i] > 0) {
x += columnWidths[i] + horizontalSpacing;
}
}
diff --git a/client/src/com/vaadin/client/ui/VPopupView.java b/client/src/com/vaadin/client/ui/VPopupView.java
index 931945e546..1a59501d38 100644
--- a/client/src/com/vaadin/client/ui/VPopupView.java
+++ b/client/src/com/vaadin/client/ui/VPopupView.java
@@ -20,6 +20,8 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -40,6 +42,7 @@ import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.ComponentConnector;
+import com.vaadin.client.DeferredWorker;
import com.vaadin.client.Util;
import com.vaadin.client.VCaptionWrapper;
import com.vaadin.client.VConsole;
@@ -48,7 +51,8 @@ import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
import com.vaadin.client.ui.popupview.VisibilityChangeEvent;
import com.vaadin.client.ui.popupview.VisibilityChangeHandler;
-public class VPopupView extends HTML implements Iterable<Widget> {
+public class VPopupView extends HTML implements Iterable<Widget>,
+ DeferredWorker {
public static final String CLASSNAME = "v-popupview";
@@ -73,6 +77,8 @@ public class VPopupView extends HTML implements Iterable<Widget> {
public final CustomPopup popup;
private final Label loading = new Label();
+ private boolean popupShowInProgress;
+
/**
* loading constructor
*/
@@ -280,19 +286,33 @@ public class VPopupView extends HTML implements Iterable<Widget> {
@Override
public void show() {
+ popupShowInProgress = true;
// Find the shortcut action handler that should handle keyboard
// events from the popup. The events do not propagate automatically
// because the popup is directly attached to the RootPanel.
- Widget widget = VPopupView.this;
- while (shortcutActionHandler == null && widget != null) {
- if (widget instanceof ShortcutActionHandlerOwner) {
- shortcutActionHandler = ((ShortcutActionHandlerOwner) widget)
- .getShortcutActionHandler();
- }
- widget = widget.getParent();
- }
super.show();
+
+ /*
+ * Shortcut actions could be set (and currently in 7.2 they ARE SET
+ * via old style "updateFromUIDL" method, see f.e. UIConnector)
+ * AFTER method show() has been invoked (which is called as a
+ * reaction on change in component hierarchy). As a result there
+ * could be no shortcutActionHandler set yet. So let's postpone
+ * search of shortcutActionHandler.
+ */
+ Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+ @Override
+ public void execute() {
+ try {
+ if (shortcutActionHandler == null) {
+ shortcutActionHandler = findShortcutActionHandler();
+ }
+ } finally {
+ popupShowInProgress = false;
+ }
+ }
+ });
}
/**
@@ -378,6 +398,18 @@ public class VPopupView extends HTML implements Iterable<Widget> {
positionOrSizeUpdated();
}
+ private ShortcutActionHandler findShortcutActionHandler() {
+ Widget widget = VPopupView.this;
+ ShortcutActionHandler handler = null;
+ while (handler == null && widget != null) {
+ if (widget instanceof ShortcutActionHandlerOwner) {
+ handler = ((ShortcutActionHandlerOwner) widget)
+ .getShortcutActionHandler();
+ }
+ widget = widget.getParent();
+ }
+ return handler;
+ }
}// class CustomPopup
public HandlerRegistration addVisibilityChangeHandler(
@@ -391,4 +423,9 @@ public class VPopupView extends HTML implements Iterable<Widget> {
return Collections.singleton((Widget) popup).iterator();
}
+ @Override
+ public boolean isWorkPending() {
+ return popupShowInProgress;
+ }
+
}// class VPopupView
diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java
index cb90823a7f..2e3c110d43 100644
--- a/client/src/com/vaadin/client/ui/VScrollTable.java
+++ b/client/src/com/vaadin/client/ui/VScrollTable.java
@@ -25,6 +25,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
@@ -66,6 +68,8 @@ import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
@@ -129,7 +133,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
/**
* Simple interface for parts of the table capable of owning a context menu.
- *
+ *
* @since 7.2
* @author Vaadin Ltd
*/
@@ -139,7 +143,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
/**
* Handles showing context menu on "long press" from a touch screen.
- *
+ *
* @since 7.2
* @author Vaadin Ltd
*/
@@ -155,7 +159,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
/**
* Initializes a handler for a certain context menu owner.
- *
+ *
* @param target
* the owner of the context menu
*/
@@ -176,7 +180,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
/**
* A function to handle touch context events in a table.
- *
+ *
* @param event
* browser event to handle
*/
@@ -230,7 +234,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* Calculates how many pixels away the user's finger has traveled. This
* reduces the chance of small non-intentional movements from canceling
* the long press detection.
- *
+ *
* @param event
* the Event for which to check the move distance
* @return true if this is considered an intentional move by the user
@@ -522,11 +526,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
/**
* For internal use only. May be removed or replaced in the future.
- *
+ *
* Overwrites onBrowserEvent function on FocusableScrollPanel to give event
* access to touchContextProvider. Has to be public to give TableConnector
* access to the scrollBodyPanel field.
- *
+ *
* @since 7.2
* @author Vaadin Ltd
*/
@@ -763,6 +767,51 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private HandlerRegistration addCloseHandler;
+ /**
+ * Changes to manage mouseDown and mouseUp
+ */
+ /**
+ * The element where the last mouse down event was registered.
+ */
+ private Element lastMouseDownTarget;
+
+ /**
+ * Set to true by {@link #mouseUpPreviewHandler} if it gets a mouseup at the
+ * same element as {@link #lastMouseDownTarget}.
+ */
+ private boolean mouseUpPreviewMatched = false;
+
+ private HandlerRegistration mouseUpEventPreviewRegistration;
+
+ /**
+ * Previews events after a mousedown to detect where the following mouseup
+ * hits.
+ */
+ private final NativePreviewHandler mouseUpPreviewHandler = new NativePreviewHandler() {
+
+ @Override
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
+ if (event.getTypeInt() == Event.ONMOUSEUP) {
+ mouseUpEventPreviewRegistration.removeHandler();
+
+ // Event's reported target not always correct if event
+ // capture is in use
+ Element elementUnderMouse = Util.getElementUnderMouse(event
+ .getNativeEvent());
+ if (lastMouseDownTarget != null
+ && lastMouseDownTarget.isOrHasChild(elementUnderMouse)) {
+ mouseUpPreviewMatched = true;
+ } else {
+ getLogger().log(
+ Level.FINEST,
+ "Ignoring mouseup from " + elementUnderMouse
+ + " when mousedown was on "
+ + lastMouseDownTarget);
+ }
+ }
+ }
+ };
+
public VScrollTable() {
setMultiSelectMode(MULTISELECT_MODE_DEFAULT);
@@ -847,7 +896,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
/**
* Handles a context menu event on table body.
- *
+ *
* @param left
* left position of the context menu
* @param top
@@ -1253,19 +1302,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
selected = true;
keyboardSelectionOverRowFetchInProgress = true;
}
- if (selected) {
-
- if (focusedRow == null
- || !selectedRowKeys.contains(focusedRow
- .getKey())) {
- /*
- * The focus is no longer on a selected row. Move
- * focus to the selected row. (#10522)
- */
-
- setRowFocus(row);
- }
+ if (selected && selectedKeys.size() == 1) {
+ /*
+ * If a single item is selected, move focus to the
+ * selected row. (#10522)
+ */
+ setRowFocus(row);
}
+
if (selected != row.isSelected()) {
row.toggleSelection();
@@ -5922,114 +5966,134 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
break;
case Event.ONMOUSEUP:
- if (targetCellOrRowFound) {
- /*
- * Queue here, send at the same time as the
- * corresponding value change event - see #7127
- */
- boolean clickEventSent = handleClickEvent(event,
- targetTdOrTr, false);
-
- if (event.getButton() == Event.BUTTON_LEFT
- && isSelectable()) {
-
- // Ctrl+Shift click
- if ((event.getCtrlKey() || event.getMetaKey())
- && event.getShiftKey()
- && isMultiSelectModeDefault()) {
- toggleShiftSelection(false);
- setRowFocus(this);
-
- // Ctrl click
- } else if ((event.getCtrlKey() || event
- .getMetaKey())
- && isMultiSelectModeDefault()) {
- boolean wasSelected = isSelected();
- toggleSelection();
- setRowFocus(this);
- /*
- * next possible range select must start on
- * this row
- */
- selectionRangeStart = this;
- if (wasSelected) {
- removeRowFromUnsentSelectionRanges(this);
- }
+ /*
+ * Only fire a click if the mouseup hits the same
+ * element as the corresponding mousedown. This is first
+ * checked in the event preview but we can't fire the
+ * event there as the event might get canceled before it
+ * gets here.
+ */
+ if (mouseUpPreviewMatched
+ && lastMouseDownTarget != null
+ && lastMouseDownTarget == getElementTdOrTr(Util
+ .getElementUnderMouse(event))) {
+ // "Click" with left, right or middle button
+
+ if (targetCellOrRowFound) {
+ /*
+ * Queue here, send at the same time as the
+ * corresponding value change event - see #7127
+ */
+ boolean clickEventSent = handleClickEvent(
+ event, targetTdOrTr, false);
+
+ if (event.getButton() == Event.BUTTON_LEFT
+ && isSelectable()) {
+
+ // Ctrl+Shift click
+ if ((event.getCtrlKey() || event
+ .getMetaKey())
+ && event.getShiftKey()
+ && isMultiSelectModeDefault()) {
+ toggleShiftSelection(false);
+ setRowFocus(this);
+
+ // Ctrl click
+ } else if ((event.getCtrlKey() || event
+ .getMetaKey())
+ && isMultiSelectModeDefault()) {
+ boolean wasSelected = isSelected();
+ toggleSelection();
+ setRowFocus(this);
+ /*
+ * next possible range select must start
+ * on this row
+ */
+ selectionRangeStart = this;
+ if (wasSelected) {
+ removeRowFromUnsentSelectionRanges(this);
+ }
- } else if ((event.getCtrlKey() || event
- .getMetaKey()) && isSingleSelectMode()) {
- // Ctrl (or meta) click (Single selection)
- if (!isSelected()
- || (isSelected() && nullSelectionAllowed)) {
+ } else if ((event.getCtrlKey() || event
+ .getMetaKey())
+ && isSingleSelectMode()) {
+ // Ctrl (or meta) click (Single
+ // selection)
+ if (!isSelected()
+ || (isSelected() && nullSelectionAllowed)) {
- if (!isSelected()) {
- deselectAll();
+ if (!isSelected()) {
+ deselectAll();
+ }
+
+ toggleSelection();
+ setRowFocus(this);
}
- toggleSelection();
+ } else if (event.getShiftKey()
+ && isMultiSelectModeDefault()) {
+ // Shift click
+ toggleShiftSelection(true);
+
+ } else {
+ // click
+ boolean currentlyJustThisRowSelected = selectedRowKeys
+ .size() == 1
+ && selectedRowKeys
+ .contains(getKey());
+
+ if (!currentlyJustThisRowSelected) {
+ if (isSingleSelectMode()
+ || isMultiSelectModeDefault()) {
+ /*
+ * For default multi select mode
+ * (ctrl/shift) and for single
+ * select mode we need to clear
+ * the previous selection before
+ * selecting a new one when the
+ * user clicks on a row. Only in
+ * multiselect/simple mode the
+ * old selection should remain
+ * after a normal click.
+ */
+ deselectAll();
+ }
+ toggleSelection();
+ } else if ((isSingleSelectMode() || isMultiSelectModeSimple())
+ && nullSelectionAllowed) {
+ toggleSelection();
+ }/*
+ * else NOP to avoid excessive server
+ * visits (selection is removed with
+ * CTRL/META click)
+ */
+
+ selectionRangeStart = this;
setRowFocus(this);
}
- } else if (event.getShiftKey()
- && isMultiSelectModeDefault()) {
- // Shift click
- toggleShiftSelection(true);
-
- } else {
- // click
- boolean currentlyJustThisRowSelected = selectedRowKeys
- .size() == 1
- && selectedRowKeys
- .contains(getKey());
-
- if (!currentlyJustThisRowSelected) {
- if (isSingleSelectMode()
- || isMultiSelectModeDefault()) {
- /*
- * For default multi select mode
- * (ctrl/shift) and for single
- * select mode we need to clear the
- * previous selection before
- * selecting a new one when the user
- * clicks on a row. Only in
- * multiselect/simple mode the old
- * selection should remain after a
- * normal click.
- */
- deselectAll();
- }
- toggleSelection();
- } else if ((isSingleSelectMode() || isMultiSelectModeSimple())
- && nullSelectionAllowed) {
- toggleSelection();
- }/*
- * else NOP to avoid excessive server
- * visits (selection is removed with
- * CTRL/META click)
- */
-
- selectionRangeStart = this;
- setRowFocus(this);
+ // Remove IE text selection hack
+ if (BrowserInfo.get().isIE()) {
+ ((Element) event.getEventTarget()
+ .cast()).setPropertyJSO(
+ "onselectstart", null);
+ }
+ // Queue value change
+ sendSelectedRows(false);
}
-
- // Remove IE text selection hack
- if (BrowserInfo.get().isIE()) {
- ((Element) event.getEventTarget().cast())
- .setPropertyJSO("onselectstart",
- null);
+ /*
+ * Send queued click and value change events if
+ * any If a click event is sent, send value
+ * change with it regardless of the immediate
+ * flag, see #7127
+ */
+ if (immediate || clickEventSent) {
+ client.sendPendingVariableChanges();
}
- // Queue value change
- sendSelectedRows(false);
- }
- /*
- * Send queued click and value change events if any
- * If a click event is sent, send value change with
- * it regardless of the immediate flag, see #7127
- */
- if (immediate || clickEventSent) {
- client.sendPendingVariableChanges();
}
}
+ mouseUpPreviewMatched = false;
+ lastMouseDownTarget = null;
break;
case Event.ONTOUCHEND:
case Event.ONTOUCHCANCEL:
@@ -6135,6 +6199,17 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
break;
case Event.ONMOUSEDOWN:
+ /*
+ * When getting a mousedown event, we must detect where
+ * the corresponding mouseup event if it's on a
+ * different part of the page.
+ */
+ lastMouseDownTarget = getElementTdOrTr(Util
+ .getElementUnderMouse(event));
+ mouseUpPreviewMatched = false;
+ mouseUpEventPreviewRegistration = Event
+ .addNativePreviewHandler(mouseUpPreviewHandler);
+
if (targetCellOrRowFound) {
setRowFocus(this);
ensureFocus();
@@ -6269,7 +6344,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
*/
private Element getEventTargetTdOrTr(Event event) {
final Element eventTarget = event.getEventTarget().cast();
- Widget widget = Util.findWidget(eventTarget, null);
+ return getElementTdOrTr(eventTarget);
+ }
+
+ private Element getElementTdOrTr(Element element) {
+
+ Widget widget = Util.findWidget(element, null);
if (widget != this) {
/*
@@ -6289,7 +6369,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return null;
}
}
- return getTdOrTr(eventTarget);
+ return getTdOrTr(element);
}
@Override
@@ -7435,7 +7515,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
if (row != null) {
-
// Apply focus style to new selection
row.addStyleName(getStylePrimaryName() + "-focus");
@@ -7449,14 +7528,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// Set new focused row
focusedRow = row;
- /*
- * Don't scroll to the focused row when in multiselect mode.
- * (#13341)
- */
-
- if (isSingleSelectMode()) {
- ensureRowIsVisible(row);
- }
+ ensureRowIsVisible(row);
return true;
}
@@ -7476,6 +7548,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// get odd scrolling here.
return;
}
+ /*
+ * FIXME The next line doesn't always do what expected, because if the
+ * row is not in the DOM it won't scroll to it.
+ */
Util.scrollIntoViewVertically(row.getElement());
}
@@ -7930,7 +8006,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
public void lazyRevertFocusToRow(final VScrollTableRow currentlyFocusedRow) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {
-
@Override
public void execute() {
if (currentlyFocusedRow != null) {
@@ -8133,4 +8208,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
public boolean isWorkPending() {
return lazyAdjustColumnWidths.isRunning();
}
+
+ private static Logger getLogger() {
+ return Logger.getLogger(VScrollTable.class.getName());
+ }
}
diff --git a/client/src/com/vaadin/client/ui/VSlider.java b/client/src/com/vaadin/client/ui/VSlider.java
index 86e5ef129d..a6ff8fabb4 100644
--- a/client/src/com/vaadin/client/ui/VSlider.java
+++ b/client/src/com/vaadin/client/ui/VSlider.java
@@ -35,7 +35,6 @@ import com.google.gwt.user.client.ui.HasValue;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.Util;
-import com.vaadin.client.VConsole;
import com.vaadin.shared.ui.slider.SliderOrientation;
public class VSlider extends SimpleFocusablePanel implements Field,
@@ -329,13 +328,11 @@ public class VSlider extends SimpleFocusablePanel implements Field,
DOM.eventPreventDefault(event); // prevent selecting text
DOM.eventCancelBubble(event, true);
event.stopPropagation();
- VConsole.log("Slider move start");
}
break;
case Event.ONMOUSEMOVE:
case Event.ONTOUCHMOVE:
if (dragging) {
- VConsole.log("Slider move");
setValueByEvent(event, false);
updateFeedbackPosition();
event.stopPropagation();
@@ -345,7 +342,6 @@ public class VSlider extends SimpleFocusablePanel implements Field,
feedbackPopup.hide();
case Event.ONMOUSEUP:
// feedbackPopup.hide();
- VConsole.log("Slider move end");
dragging = false;
handle.setClassName(getStylePrimaryName() + "-handle");
DOM.releaseCapture(getElement());
diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/DateCell.java b/client/src/com/vaadin/client/ui/calendar/schedule/DateCell.java
index ffa5f78071..bef03707ba 100644
--- a/client/src/com/vaadin/client/ui/calendar/schedule/DateCell.java
+++ b/client/src/com/vaadin/client/ui/calendar/schedule/DateCell.java
@@ -18,7 +18,6 @@ package com.vaadin.client.ui.calendar.schedule;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -203,6 +202,8 @@ public class DateCell extends FocusableComplexPanel implements
width = getOffsetWidth()
- Util.measureHorizontalBorder(getElement());
+ // Update moveWidth for any DateCellDayEvent child
+ updateEventCellsWidth();
recalculateEventWidths();
} else {
removeStyleDependentName("Hsized");
@@ -221,6 +222,8 @@ public class DateCell extends FocusableComplexPanel implements
// recalc heights&size for events. all other height sizes come
// from css
startingSlotHeight = slotElements[0].getOffsetHeight();
+ // Update slotHeight for each DateCellDayEvent child
+ updateEventCellsHeight();
recalculateEventPositions();
if (isToday()) {
@@ -327,14 +330,7 @@ public class DateCell extends FocusableComplexPanel implements
.setHeight(slotElementHeights[i], Unit.PX);
}
- Iterator<Widget> it = iterator();
- while (it.hasNext()) {
- Widget child = it.next();
- if (child instanceof DateCellDayEvent) {
- ((DateCellDayEvent) child).setSlotHeightInPX(getSlotHeight());
- }
-
- }
+ updateEventCellsHeight();
}
public int getSlotHeight() {
@@ -829,4 +825,20 @@ public class DateCell extends FocusableComplexPanel implements
.contextMenu(event, DateCell.this);
}
}
+
+ private void updateEventCellsWidth() {
+ for (Widget widget : getChildren()) {
+ if (widget instanceof DateCellDayEvent) {
+ ((DateCellDayEvent) widget).setMoveWidth(width);
+ }
+ }
+ }
+
+ private void updateEventCellsHeight() {
+ for (Widget widget : getChildren()) {
+ if (widget instanceof DateCellDayEvent) {
+ ((DateCellDayEvent) widget).setSlotHeightInPX(getSlotHeight());
+ }
+ }
+ }
}
diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java
index c88fd23eca..d6f14bf158 100644
--- a/client/src/com/vaadin/client/ui/ui/UIConnector.java
+++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java
@@ -494,7 +494,11 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
// the user
root.getElement().setInnerHTML("");
+ // Activate the initial theme by only adding the class name. Not calling
+ // activateTheme here as it will also cause a full layout and updates to
+ // the overlay container which has not yet been created at this point
activeTheme = applicationConnection.getConfiguration().getThemeName();
+ root.addStyleName(activeTheme);
root.add(getWidget());
diff --git a/eclipse/Development Mode (vaadin).launch b/eclipse/Development Mode (vaadin).launch
index 8c828eca96..2b8ff23ce8 100644
--- a/eclipse/Development Mode (vaadin).launch
+++ b/eclipse/Development Mode (vaadin).launch
@@ -2,27 +2,22 @@
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<stringAttribute key="bad_container_name" value="\eclipse"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/gwt-dev/core/src/com/google/gwt/dev/DevMode.java"/>
+<listEntry value="/vaadin"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
+<listEntry value="4"/>
</listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;vaadin&quot; type=&quot;1&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/client/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/uitest/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/apache/tapestry-util-text-4.0.2.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/junit/junit-4.8.2.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/tomcat/servlet-api-2.5.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA-sources.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=client%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=server%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=shared%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=client-compiler%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=gwt%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=uitest%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/client/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/uitest/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;vaadin&quot; type=&quot;1&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=client%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=shared%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=uitest%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=%24%7Bworkspace_loc%3Avaadin%2Fbuild.properties%7D&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=push%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=gwt%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=%24%7Bworkspace_loc%3Avaadin%2Fbuild.properties%7D&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
diff --git a/eclipse/Super Development Mode (vaadin).launch b/eclipse/Super Development Mode (vaadin).launch
index 147ec2ae13..ed243cba82 100644
--- a/eclipse/Super Development Mode (vaadin).launch
+++ b/eclipse/Super Development Mode (vaadin).launch
@@ -9,21 +9,15 @@
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;vaadin&quot; type=&quot;1&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/client/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/uitest/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/apache/tapestry-util-text-4.0.2.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/junit/junit-4.8.2.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/tomcat/servlet-api-2.5.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;GWT_TOOLS/lib/javax/validation/validation-api-1.0.0.GA-sources.jar&quot; path=&quot;3&quot; type=&quot;3&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=client%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=server%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=shared%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=client-compiler%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=gwt%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=uitest%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/client/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/vaadin/uitest/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;vaadin&quot; type=&quot;1&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=client%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=shared%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=uitest%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=%24%7Bworkspace_loc%3Avaadin%2Fbuild.properties%7D&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=push%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=gwt%2Fivy.xml&amp;amp;confs=ide&amp;amp;ivySettingsPath=%24%7Bworkspace_loc%3Avaadin%2Fivysettings.xml%7D&amp;amp;loadSettingsOnDemand=false&amp;amp;propertyFiles=%24%7Bworkspace_loc%3Avaadin%2Fbuild.properties%7D&quot; javaProject=&quot;vaadin&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
</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"/>
diff --git a/gwt-files.xml b/gwt-files.xml
index 4a8486ab55..c0ef583177 100644
--- a/gwt-files.xml
+++ b/gwt-files.xml
@@ -182,6 +182,13 @@
<include name="com/google/gwt/user/client/rpc/IsSerializable.*" />
</fileset>
+ <!-- GWT Elemental -->
+ <fileset dir="${gwt.elemental.jar.files}">
+ <include name="elemental/util/Array*" />
+ <include name="elemental/util/Can*" />
+ <include name="elemental/util/Map*" />
+ <include name="elemental/json/**" />
+ </fileset>
</union>
<union id="server.gwt.includes">
@@ -189,5 +196,10 @@
<!-- Server files from gwt-user -->
<include name="com/google/gwt/*/server/**" />
</fileset>
+ <!-- GWT Elemental -->
+ <fileset dir="${gwt.elemental.jar.files}">
+ <exclude name="META-INF/**" />
+ <exclude name="super/**" />
+ </fileset>
</union>
</project>
diff --git a/gwt/ivy.xml b/gwt/ivy.xml
index 52d8acea92..d34b7ccfcc 100644
--- a/gwt/ivy.xml
+++ b/gwt/ivy.xml
@@ -25,6 +25,6 @@
<dependency org="com.vaadin.external.gwt" name="gwt-dev" rev="${gwt.version}" conf="gwt-dev,ide->default" />
<dependency org="com.vaadin.external.gwt" name="gwt-user" rev="${gwt.version}" conf="gwt-user,ide->default" />
<dependency org="com.vaadin.external.gwt" name="gwt-codeserver" rev="${gwt.version}" conf="gwt-codeserver,ide->default" />
- <dependency org="com.vaadin.external.gwt" name="gwt-elemental" rev="${gwt.version}" conf="gwt-elemental->default" />
+ <dependency org="com.vaadin.external.gwt" name="gwt-elemental" rev="${gwt.version}" conf="gwt-elemental,ide->default" />
</dependencies>
</ivy-module>
diff --git a/push/build.xml b/push/build.xml
index dee5820efb..fb80cc7cbf 100644
--- a/push/build.xml
+++ b/push/build.xml
@@ -16,7 +16,7 @@
<property name="vaadinPush.debug.js" location="${result.dir}/js/VAADIN/vaadinPush.debug.js" />
<!-- Keep the version number in sync with ivy.xml, server/src/com/vaadin/server/Constants.java -->
- <property name="atmosphere.runtime.version" value="2.1.2.vaadin3" />
+ <property name="atmosphere.runtime.version" value="2.1.2.vaadin4" />
<property name="jquery.js" location="lib/jquery/jquery-1.11.0.js" />
<path id="classpath.compile.custom" />
diff --git a/push/ivy.xml b/push/ivy.xml
index d3b4944353..b6bd1b06f7 100644
--- a/push/ivy.xml
+++ b/push/ivy.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ivy-module [
<!-- Keep the version number in sync with build.xml -->
- <!ENTITY atmosphere.runtime.version "2.1.2.vaadin3">
+ <!ENTITY atmosphere.runtime.version "2.1.2.vaadin4">
<!ENTITY atmosphere.js.version "2.1.5.vaadin4">
]>
diff --git a/server/src/com/vaadin/data/RpcDataProviderExtension.java b/server/src/com/vaadin/data/RpcDataProviderExtension.java
index 3185300897..f0a9ca39fd 100644
--- a/server/src/com/vaadin/data/RpcDataProviderExtension.java
+++ b/server/src/com/vaadin/data/RpcDataProviderExtension.java
@@ -19,7 +19,6 @@ package com.vaadin.data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -27,10 +26,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.google.gwt.thirdparty.guava.common.collect.BiMap;
import com.google.gwt.thirdparty.guava.common.collect.HashBiMap;
import com.vaadin.data.Container.Indexed;
@@ -56,6 +51,11 @@ import com.vaadin.ui.components.grid.Renderer;
import com.vaadin.ui.components.grid.selection.SelectionChangeEvent;
import com.vaadin.ui.components.grid.selection.SelectionChangeListener;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonObject;
+import elemental.json.JsonValue;
+
/**
* Provides Vaadin server-side container data source to a
* {@link com.vaadin.client.ui.grid.GridConnector}. This is currently
@@ -704,43 +704,36 @@ public class RpcDataProviderExtension extends AbstractExtension {
private void pushRows(int firstRow, List<?> itemIds) {
Collection<?> propertyIds = container.getContainerPropertyIds();
- JSONArray rows = new JSONArray();
- for (Object itemId : itemIds) {
- rows.put(getRowData(propertyIds, itemId));
+ JsonArray rows = Json.createArray();
+ for (int i = 0; i < itemIds.size(); ++i) {
+ rows.set(i, getRowData(propertyIds, itemIds.get(i)));
}
- String jsonString = rows.toString();
- getRpcProxy(DataProviderRpc.class).setRowData(firstRow, jsonString);
+ getRpcProxy(DataProviderRpc.class).setRowData(firstRow, rows.toJson());
}
- private JSONObject getRowData(Collection<?> propertyIds, Object itemId) {
+ private JsonValue getRowData(Collection<?> propertyIds, Object itemId) {
Item item = container.getItem(itemId);
- String[] row = new String[propertyIds.size()];
- JSONArray rowData = new JSONArray();
+ JsonArray rowData = Json.createArray();
Grid grid = getGrid();
- try {
- for (Object propertyId : propertyIds) {
- GridColumn column = grid.getColumn(propertyId);
- Object propertyValue = item.getItemProperty(propertyId)
- .getValue();
- Object encodedValue = encodeValue(propertyValue,
- column.getRenderer(), column.getConverter(),
- grid.getLocale());
+ int i = 0;
+ for (Object propertyId : propertyIds) {
+ GridColumn column = grid.getColumn(propertyId);
- rowData.put(encodedValue);
- }
+ Object propertyValue = item.getItemProperty(propertyId).getValue();
+ JsonValue encodedValue = encodeValue(propertyValue,
+ column.getRenderer(), column.getConverter(),
+ grid.getLocale());
- final JSONObject rowObject = new JSONObject();
- rowObject.put(GridState.JSONKEY_DATA, rowData);
- rowObject.put(GridState.JSONKEY_ROWKEY, keyMapper.getKey(itemId));
- return rowObject;
- } catch (final JSONException e) {
- throw new RuntimeException("Grid was unable to serialize "
- + "data for row (this should've been caught "
- + "eariler by other Grid logic)", e);
+ rowData.set(i++, encodedValue);
}
+
+ final JsonObject rowObject = Json.createObject();
+ rowObject.put(GridState.JSONKEY_DATA, rowData);
+ rowObject.put(GridState.JSONKEY_ROWKEY, keyMapper.getKey(itemId));
+ return rowObject;
}
@Override
@@ -809,10 +802,10 @@ public class RpcDataProviderExtension extends AbstractExtension {
* roundtrip.
*/
Object itemId = container.getIdByIndex(index);
- JSONObject row = getRowData(container.getContainerPropertyIds(), itemId);
- JSONArray rowArray = new JSONArray(Collections.singleton(row));
- String jsonString = rowArray.toString();
- getRpcProxy(DataProviderRpc.class).setRowData(index, jsonString);
+ JsonValue row = getRowData(container.getContainerPropertyIds(), itemId);
+ JsonArray rowArray = Json.createArray();
+ rowArray.set(0, row);
+ getRpcProxy(DataProviderRpc.class).setRowData(index, rowArray.toJson());
}
@Override
@@ -888,7 +881,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
* the locale to use in conversion
* @return an encoded value ready to be sent to the client
*/
- public static <T> Object encodeValue(Object modelValue,
+ public static <T> JsonValue encodeValue(Object modelValue,
Renderer<T> renderer, Converter<?, ?> converter, Locale locale) {
Class<T> presentationType = renderer.getPresentationType();
T presentationValue;
@@ -913,24 +906,8 @@ public class RpcDataProviderExtension extends AbstractExtension {
safeConverter.getPresentationType(), locale);
}
- Object encodedValue = renderer.encode(presentationValue);
+ JsonValue encodedValue = renderer.encode(presentationValue);
- /*
- * because this is a relatively heavy operation, we'll hide this behind
- * an assert so that the check will be removed in production mode
- */
- assert jsonSupports(encodedValue) : "org.json.JSONObject does not know how to serialize objects of type "
- + encodedValue.getClass().getName();
return encodedValue;
}
-
- private static boolean jsonSupports(Object encodedValue) {
- JSONObject jsonObject = new JSONObject();
- try {
- jsonObject.accumulate("test", encodedValue);
- } catch (JSONException e) {
- return false;
- }
- return true;
- }
}
diff --git a/server/src/com/vaadin/server/AbstractClientConnector.java b/server/src/com/vaadin/server/AbstractClientConnector.java
index 03300b20e2..19796af48d 100644
--- a/server/src/com/vaadin/server/AbstractClientConnector.java
+++ b/server/src/com/vaadin/server/AbstractClientConnector.java
@@ -32,9 +32,6 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.logging.Logger;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.event.EventRouter;
import com.vaadin.event.MethodEventSource;
import com.vaadin.shared.communication.ClientRpc;
@@ -46,6 +43,7 @@ import com.vaadin.ui.Component.Event;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.LegacyComponent;
import com.vaadin.ui.UI;
+import elemental.json.JsonObject;
/**
* An abstract base class for ClientConnector implementations. This class
@@ -243,7 +241,7 @@ public abstract class AbstractClientConnector implements ClientConnector,
}
@Override
- public JSONObject encodeState() throws JSONException {
+ public JsonObject encodeState() {
return LegacyCommunicationManager.encodeState(this, getState(false));
}
diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java
index 73bafcca25..0605d6a2b8 100644
--- a/server/src/com/vaadin/server/BootstrapHandler.java
+++ b/server/src/com/vaadin/server/BootstrapHandler.java
@@ -30,8 +30,6 @@ import java.util.Set;
import javax.servlet.http.HttpServletResponse;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.jsoup.nodes.DataNode;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.DocumentType;
@@ -44,6 +42,11 @@ import com.vaadin.shared.Version;
import com.vaadin.shared.communication.PushMode;
import com.vaadin.ui.UI;
+import elemental.json.Json;
+import elemental.json.JsonException;
+import elemental.json.JsonObject;
+import elemental.json.impl.JsonUtil;
+
/**
*
* @author Vaadin Ltd
@@ -191,7 +194,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
String html = getBootstrapHtml(context);
writeBootstrapPage(response, html);
- } catch (JSONException e) {
+ } catch (JsonException e) {
writeError(response, e);
}
@@ -340,10 +343,8 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
* @param context
*
* @throws IOException
- * @throws JSONException
*/
- private void setupMainDiv(BootstrapContext context) throws IOException,
- JSONException {
+ private void setupMainDiv(BootstrapContext context) throws IOException {
String style = getMainDivStyle(context);
/*- Add classnames;
@@ -375,14 +376,6 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
String vaadinLocation = vaadinService.getStaticFileLocation(request)
+ "/VAADIN/";
- fragmentNodes
- .add(new Element(Tag.valueOf("iframe"), "")
- .attr("tabIndex", "-1")
- .attr("id", "__gwt_historyFrame")
- .attr("style",
- "position:absolute;width:0;height:0;border:0;overflow:hidden")
- .attr("src", "javascript:false"));
-
if (context.getPushMode().isEnabled()) {
// Load client-side dependencies for push support
String pushJS = vaadinLocation;
@@ -407,8 +400,8 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
StringBuilder builder = new StringBuilder();
builder.append("//<![CDATA[\n");
builder.append("if (!window.vaadin) alert("
- + JSONObject.quote("Failed to load the bootstrap javascript: "
- + bootstrapLocation) + ");\n");
+ + JsonUtil.quote("Failed to load the bootstrap javascript: "
+ + bootstrapLocation) + ");\n");
appendMainScriptTagContents(context, builder);
@@ -420,8 +413,8 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
}
protected void appendMainScriptTagContents(BootstrapContext context,
- StringBuilder builder) throws JSONException, IOException {
- JSONObject appConfig = getApplicationParameters(context);
+ StringBuilder builder) throws IOException {
+ JsonObject appConfig = getApplicationParameters(context);
boolean isDebug = !context.getSession().getConfiguration()
.isProductionMode();
@@ -446,21 +439,21 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
}
private static void appendJsonObject(StringBuilder builder,
- JSONObject jsonObject, boolean isDebug) throws JSONException {
+ JsonObject jsonObject, boolean isDebug) {
if (isDebug) {
- builder.append(jsonObject.toString(4));
+ builder.append(JsonUtil.stringify(jsonObject, 4));
} else {
- builder.append(jsonObject.toString());
+ builder.append(JsonUtil.stringify(jsonObject));
}
}
- protected JSONObject getApplicationParameters(BootstrapContext context)
- throws JSONException, PaintException {
+ protected JsonObject getApplicationParameters(BootstrapContext context)
+ throws PaintException {
VaadinRequest request = context.getRequest();
VaadinSession session = context.getSession();
VaadinService vaadinService = request.getService();
- JSONObject appConfig = new JSONObject();
+ JsonObject appConfig = Json.createObject();
String themeName = context.getThemeName();
if (themeName != null) {
@@ -473,7 +466,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
appConfig.put("extraParams", "&" + IGNORE_RESTART_PARAM + "=1");
}
- JSONObject versionInfo = new JSONObject();
+ JsonObject versionInfo = Json.createObject();
versionInfo.put("vaadinVersion", Version.getFullVersion());
appConfig.put("versionInfo", versionInfo);
@@ -487,30 +480,42 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
request);
if (systemMessages != null) {
// Write the CommunicationError -message to client
- JSONObject comErrMsg = new JSONObject();
+ JsonObject comErrMsg = Json.createObject();
comErrMsg.put("caption",
systemMessages.getCommunicationErrorCaption());
comErrMsg.put("message",
systemMessages.getCommunicationErrorMessage());
- comErrMsg.put("url", systemMessages.getCommunicationErrorURL());
+ if (systemMessages.getCommunicationErrorURL() == null) {
+ comErrMsg.put("url", Json.createNull());
+ } else {
+ comErrMsg.put("url", systemMessages.getCommunicationErrorURL());
+ }
appConfig.put("comErrMsg", comErrMsg);
- JSONObject authErrMsg = new JSONObject();
+ JsonObject authErrMsg = Json.createObject();
authErrMsg.put("caption",
systemMessages.getAuthenticationErrorCaption());
authErrMsg.put("message",
systemMessages.getAuthenticationErrorMessage());
- authErrMsg.put("url", systemMessages.getAuthenticationErrorURL());
+ if (systemMessages.getAuthenticationErrorURL() == null) {
+ authErrMsg.put("url", Json.createNull());
+ } else {
+ authErrMsg.put("url", systemMessages.getAuthenticationErrorURL());
+ }
appConfig.put("authErrMsg", authErrMsg);
- JSONObject sessExpMsg = new JSONObject();
+ JsonObject sessExpMsg = Json.createObject();
sessExpMsg
.put("caption", systemMessages.getSessionExpiredCaption());
sessExpMsg
.put("message", systemMessages.getSessionExpiredMessage());
- sessExpMsg.put("url", systemMessages.getSessionExpiredURL());
+ if (systemMessages.getSessionExpiredURL() == null) {
+ sessExpMsg.put("url", Json.createNull());
+ } else {
+ sessExpMsg.put("url", systemMessages.getSessionExpiredURL());
+ }
appConfig.put("sessExpMsg", sessExpMsg);
}
diff --git a/server/src/com/vaadin/server/ClientConnector.java b/server/src/com/vaadin/server/ClientConnector.java
index e61ba50a3a..50ce2754cb 100644
--- a/server/src/com/vaadin/server/ClientConnector.java
+++ b/server/src/com/vaadin/server/ClientConnector.java
@@ -20,15 +20,13 @@ import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.event.ConnectorEvent;
import com.vaadin.event.ConnectorEventListener;
import com.vaadin.shared.Connector;
import com.vaadin.shared.communication.SharedState;
import com.vaadin.ui.UI;
import com.vaadin.util.ReflectTools;
+import elemental.json.JsonObject;
/**
* Interface implemented by all connectors that are capable of communicating
@@ -279,10 +277,9 @@ public interface ClientConnector extends Connector {
* .
*
* @return a JSON object with the encoded connector state
- * @throws JSONException
* if the state can not be encoded
*/
- public JSONObject encodeState() throws JSONException;
+ public JsonObject encodeState() ;
/**
* Handle a request directed to this connector. This can be used by
diff --git a/server/src/com/vaadin/server/ClientMethodInvocation.java b/server/src/com/vaadin/server/ClientMethodInvocation.java
index e51138d7bf..97caa7614a 100644
--- a/server/src/com/vaadin/server/ClientMethodInvocation.java
+++ b/server/src/com/vaadin/server/ClientMethodInvocation.java
@@ -23,8 +23,9 @@ import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
-import org.json.JSONArray;
-import org.json.JSONException;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+import elemental.json.impl.JsonUtil;
/**
* Internal class for keeping track of pending server to client method
@@ -107,8 +108,8 @@ public class ClientMethodInvocation implements Serializable,
Type type = parameterTypes[i];
if (type instanceof Class<?>) {
Class<?> clazz = (Class<?>) type;
- if (JSONArray.class.isAssignableFrom(clazz)) {
- parameters[i] = ((JSONArray) parameters[i]).toString();
+ if (JsonArray.class.isAssignableFrom(clazz)) {
+ parameters[i] = JsonUtil.stringify((JsonArray) parameters[i]);
}
}
}
@@ -124,10 +125,10 @@ public class ClientMethodInvocation implements Serializable,
Type type = parameterTypes[i];
if (type instanceof Class<?>) {
Class<?> clazz = (Class<?>) type;
- if (JSONArray.class.isAssignableFrom(clazz)) {
+ if (JsonArray.class.isAssignableFrom(clazz)) {
try {
- parameters[i] = new JSONArray(((String) parameters[i]));
- } catch (JSONException e) {
+ parameters[i] = JsonUtil.<JsonArray>parse((String) parameters[i]);
+ } catch (JsonException e) {
throw new IOException(e);
}
}
diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java
index 08b5b70f50..aa1e02a96e 100644
--- a/server/src/com/vaadin/server/Constants.java
+++ b/server/src/com/vaadin/server/Constants.java
@@ -67,7 +67,7 @@ public interface Constants {
// Keep the version number in sync with push/build.xml and other locations
// listed in that file
- static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.1.2.vaadin3";
+ static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.1.2.vaadin4";
static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n"
+ "=================================================================\n"
diff --git a/server/src/com/vaadin/server/DragAndDropService.java b/server/src/com/vaadin/server/DragAndDropService.java
index 087a670b5b..c21f27de97 100644
--- a/server/src/com/vaadin/server/DragAndDropService.java
+++ b/server/src/com/vaadin/server/DragAndDropService.java
@@ -24,9 +24,6 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.event.Transferable;
import com.vaadin.event.TransferableImpl;
import com.vaadin.event.dd.DragAndDropEvent;
@@ -41,6 +38,7 @@ import com.vaadin.shared.communication.SharedState;
import com.vaadin.shared.ui.dd.DragEventType;
import com.vaadin.ui.Component;
import com.vaadin.ui.UI;
+import elemental.json.JsonObject;
public class DragAndDropService implements VariableOwner, ClientConnector {
@@ -352,7 +350,7 @@ public class DragAndDropService implements VariableOwner, ClientConnector {
}
@Override
- public JSONObject encodeState() throws JSONException {
+ public JsonObject encodeState() {
// TODO Auto-generated method stub
return null;
}
diff --git a/server/src/com/vaadin/server/EncodeResult.java b/server/src/com/vaadin/server/EncodeResult.java
index 55a97aa829..bf4fd48438 100644
--- a/server/src/com/vaadin/server/EncodeResult.java
+++ b/server/src/com/vaadin/server/EncodeResult.java
@@ -18,29 +18,31 @@ package com.vaadin.server;
import java.io.Serializable;
+import elemental.json.JsonValue;
+
public class EncodeResult implements Serializable {
- private final Object encodedValue;
- private final Object diff;
+ private final JsonValue encodedValue;
+ private final JsonValue diff;
- public EncodeResult(Object encodedValue) {
+ public EncodeResult(JsonValue encodedValue) {
this(encodedValue, null);
}
- public EncodeResult(Object encodedValue, Object diff) {
+ public EncodeResult(JsonValue encodedValue, JsonValue diff) {
this.encodedValue = encodedValue;
this.diff = diff;
}
- public Object getEncodedValue() {
+ public JsonValue getEncodedValue() {
return encodedValue;
}
- public Object getDiff() {
+ public JsonValue getDiff() {
return diff;
}
- public Object getDiffOrValue() {
- Object diff = getDiff();
+ public JsonValue getDiffOrValue() {
+ JsonValue diff = getDiff();
if (diff != null) {
return diff;
} else {
diff --git a/server/src/com/vaadin/server/JavaScriptCallbackHelper.java b/server/src/com/vaadin/server/JavaScriptCallbackHelper.java
index 53fb1f838b..2552db6d13 100644
--- a/server/src/com/vaadin/server/JavaScriptCallbackHelper.java
+++ b/server/src/com/vaadin/server/JavaScriptCallbackHelper.java
@@ -18,21 +18,20 @@ package com.vaadin.server;
import java.io.Serializable;
import java.lang.reflect.Method;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.shared.JavaScriptConnectorState;
import com.vaadin.ui.AbstractJavaScriptComponent;
import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc;
import com.vaadin.ui.JavaScriptFunction;
import com.vaadin.util.ReflectTools;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+
/**
* Internal helper class used to implement functionality common to
* {@link AbstractJavaScriptComponent} and {@link AbstractJavaScriptExtension}.
@@ -47,7 +46,7 @@ import com.vaadin.util.ReflectTools;
public class JavaScriptCallbackHelper implements Serializable {
private static final Method CALL_METHOD = ReflectTools.findMethod(
- JavaScriptCallbackRpc.class, "call", String.class, JSONArray.class);
+ JavaScriptCallbackRpc.class, "call", String.class, JsonArray.class);
private AbstractClientConnector connector;
private Map<String, JavaScriptFunction> callbacks = new HashMap<String, JavaScriptFunction>();
@@ -75,11 +74,11 @@ public class JavaScriptCallbackHelper implements Serializable {
if (javascriptCallbackRpc == null) {
javascriptCallbackRpc = new JavaScriptCallbackRpc() {
@Override
- public void call(String name, JSONArray arguments) {
+ public void call(String name, JsonArray arguments) {
JavaScriptFunction callback = callbacks.get(name);
try {
callback.call(arguments);
- } catch (JSONException e) {
+ } catch (JsonException e) {
throw new IllegalArgumentException(e);
}
}
@@ -95,7 +94,7 @@ public class JavaScriptCallbackHelper implements Serializable {
+ name
+ " on the client because a callback with the same name is registered on the server.");
}
- JSONArray args = new JSONArray(Arrays.asList(arguments));
+ JsonArray args = (JsonArray) JsonCodec.encode(arguments, null, Object[].class, null).getEncodedValue();
connector.addMethodInvocationToQueue(
JavaScriptCallbackRpc.class.getName(), CALL_METHOD,
new Object[] { name, args });
diff --git a/server/src/com/vaadin/server/JsonCodec.java b/server/src/com/vaadin/server/JsonCodec.java
index 34b05f73bf..1e9438453a 100644
--- a/server/src/com/vaadin/server/JsonCodec.java
+++ b/server/src/com/vaadin/server/JsonCodec.java
@@ -28,12 +28,10 @@ import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -41,10 +39,6 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.communication.DateSerializer;
import com.vaadin.server.communication.JSONSerializer;
import com.vaadin.shared.Connector;
@@ -53,6 +47,16 @@ import com.vaadin.shared.communication.UidlValue;
import com.vaadin.ui.Component;
import com.vaadin.ui.ConnectorTracker;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+import elemental.json.JsonNull;
+import elemental.json.JsonObject;
+import elemental.json.JsonString;
+import elemental.json.JsonType;
+import elemental.json.JsonValue;
+import elemental.json.impl.JreJsonArray;
+
/**
* Decoder for converting RPC parameters and other values from JSON in transfer
* between the client and the server and vice versa.
@@ -62,21 +66,32 @@ import com.vaadin.ui.ConnectorTracker;
public class JsonCodec implements Serializable {
/* Immutable Encode Result representing null */
- private static final EncodeResult ENCODE_RESULT_NULL = new EncodeResult(
- JSONObject.NULL);
+ private static final EncodeResult ENCODE_RESULT_NULL = new EncodeResult(Json.createNull());
/* Immutable empty JSONArray */
- private static final JSONArray EMPTY_JSON_ARRAY = new JSONArray() {
+ private static final JsonArray EMPTY_JSON_ARRAY = new JreJsonArray(Json.instance()) {
@Override
- public JSONArray put(Object value) {
+ public void set(int index, JsonValue value) {
throw new UnsupportedOperationException(
- "Immutable empty JSONArray.");
+ "Immutable empty JsonArray.");
}
@Override
- public JSONArray put(int index, Object value) {
+ public void set(int index, String string) {
throw new UnsupportedOperationException(
- "Immutable empty JSONArray.");
+ "Immutable empty JsonArray.");
+ }
+
+ @Override
+ public void set(int index, double number) {
+ throw new UnsupportedOperationException(
+ "Immutable empty JsonArray.");
+ }
+
+ @Override
+ public void set(int index, boolean bool) {
+ throw new UnsupportedOperationException(
+ "Immutable empty JsonArray.");
}
};
@@ -266,8 +281,7 @@ public class JsonCodec implements Serializable {
}
public static Object decodeInternalOrCustomType(Type targetType,
- Object value, ConnectorTracker connectorTracker)
- throws JSONException {
+ JsonValue value, ConnectorTracker connectorTracker) {
if (isInternalType(targetType)) {
return decodeInternalType(targetType, false, value,
connectorTracker);
@@ -276,50 +290,49 @@ public class JsonCodec implements Serializable {
}
}
- public static Object decodeCustomType(Type targetType, Object value,
- ConnectorTracker connectorTracker) throws JSONException {
+ public static Object decodeCustomType(Type targetType, JsonValue value,
+ ConnectorTracker connectorTracker) {
if (isInternalType(targetType)) {
- throw new JSONException("decodeCustomType cannot be used for "
+ throw new JsonException("decodeCustomType cannot be used for "
+ targetType + ", which is an internal type");
}
// Try to decode object using fields
- if (value == JSONObject.NULL) {
+ if (value.getType() == JsonType.NULL) {
return null;
} else if (targetType == byte.class || targetType == Byte.class) {
- return Byte.valueOf(String.valueOf(value));
+ return Byte.valueOf((byte) value.asNumber());
} else if (targetType == char.class || targetType == Character.class) {
- return Character.valueOf(String.valueOf(value).charAt(0));
+ return Character.valueOf(value.asString().charAt(0));
} else if (targetType instanceof Class<?>
&& ((Class<?>) targetType).isArray()) {
// Legacy Object[] and String[] handled elsewhere, this takes care
// of generic arrays
Class<?> componentType = ((Class<?>) targetType).getComponentType();
- return decodeArray(componentType, (JSONArray) value,
+ return decodeArray(componentType, (JsonArray) value,
connectorTracker);
} else if (targetType instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) targetType)
.getGenericComponentType();
- return decodeArray(componentType, (JSONArray) value,
+ return decodeArray(componentType, (JsonArray) value,
connectorTracker);
- } else if (targetType == JSONObject.class
- || targetType == JSONArray.class) {
+ } else if (JsonValue.class.isAssignableFrom(getClassForType(targetType))) {
return value;
} else if (Enum.class.isAssignableFrom(getClassForType(targetType))) {
Class<?> classForType = getClassForType(targetType);
return decodeEnum(classForType.asSubclass(Enum.class),
- (String) value);
+ (JsonString) value);
} else if (customSerializers.containsKey(getClassForType(targetType))) {
return customSerializers.get(getClassForType(targetType))
.deserialize(targetType, value, connectorTracker);
} else {
- return decodeObject(targetType, (JSONObject) value,
+ return decodeObject(targetType, (JsonObject) value,
connectorTracker);
}
}
- private static Object decodeArray(Type componentType, JSONArray value,
- ConnectorTracker connectorTracker) throws JSONException {
+ private static Object decodeArray(Type componentType, JsonArray value,
+ ConnectorTracker connectorTracker) {
Class<?> componentClass = getClassForType(componentType);
Object array = Array.newInstance(componentClass, value.length());
for (int i = 0; i < value.length(); i++) {
@@ -352,37 +365,36 @@ public class JsonCodec implements Serializable {
* true if generics should be enforce, false to only allow
* internal types in collections
* @return
- * @throws JSONException
*/
public static Object decodeInternalType(Type targetType,
- boolean restrictToInternalTypes, Object encodedJsonValue,
- ConnectorTracker connectorTracker) throws JSONException {
+ boolean restrictToInternalTypes, JsonValue encodedJsonValue,
+ ConnectorTracker connectorTracker) {
if (!isInternalType(targetType)) {
- throw new JSONException("Type " + targetType
+ throw new JsonException("Type " + targetType
+ " is not a supported internal type.");
}
String transportType = getInternalTransportType(targetType);
- if (encodedJsonValue == JSONObject.NULL) {
+ if (encodedJsonValue.getType() == JsonType.NULL) {
return null;
} else if (targetType == Void.class) {
- throw new JSONException(
+ throw new JsonException(
"Something other than null was encoded for a null type");
}
// UidlValue
if (targetType == UidlValue.class) {
- return decodeUidlValue((JSONArray) encodedJsonValue,
+ return decodeUidlValue((JsonArray) encodedJsonValue,
connectorTracker);
}
// Collections
if (JsonConstants.VTYPE_LIST.equals(transportType)) {
return decodeList(targetType, restrictToInternalTypes,
- (JSONArray) encodedJsonValue, connectorTracker);
+ (JsonArray) encodedJsonValue, connectorTracker);
} else if (JsonConstants.VTYPE_SET.equals(transportType)) {
return decodeSet(targetType, restrictToInternalTypes,
- (JSONArray) encodedJsonValue, connectorTracker);
+ (JsonArray) encodedJsonValue, connectorTracker);
} else if (JsonConstants.VTYPE_MAP.equals(transportType)) {
return decodeMap(targetType, restrictToInternalTypes,
encodedJsonValue, connectorTracker);
@@ -391,42 +403,40 @@ public class JsonCodec implements Serializable {
// Arrays
if (JsonConstants.VTYPE_ARRAY.equals(transportType)) {
- return decodeObjectArray(targetType, (JSONArray) encodedJsonValue,
+ return decodeObjectArray(targetType, (JsonArray) encodedJsonValue,
connectorTracker);
} else if (JsonConstants.VTYPE_STRINGARRAY.equals(transportType)) {
- return decodeStringArray((JSONArray) encodedJsonValue);
+ return decodeStringArray((JsonArray) encodedJsonValue);
}
// Special Vaadin types
- String stringValue = String.valueOf(encodedJsonValue);
-
if (JsonConstants.VTYPE_CONNECTOR.equals(transportType)) {
- return connectorTracker.getConnector(stringValue);
+ return connectorTracker.getConnector(encodedJsonValue.asString());
}
// Legacy types
if (JsonConstants.VTYPE_STRING.equals(transportType)) {
- return stringValue;
+ return encodedJsonValue.asString();
} else if (JsonConstants.VTYPE_INTEGER.equals(transportType)) {
- return Integer.valueOf(stringValue);
+ return (int) encodedJsonValue.asNumber();
} else if (JsonConstants.VTYPE_LONG.equals(transportType)) {
- return Long.valueOf(stringValue);
+ return (long) encodedJsonValue.asNumber();
} else if (JsonConstants.VTYPE_FLOAT.equals(transportType)) {
- return Float.valueOf(stringValue);
+ return (float) encodedJsonValue.asNumber();
} else if (JsonConstants.VTYPE_DOUBLE.equals(transportType)) {
- return Double.valueOf(stringValue);
+ return encodedJsonValue.asNumber();
} else if (JsonConstants.VTYPE_BOOLEAN.equals(transportType)) {
- return Boolean.valueOf(stringValue);
+ return encodedJsonValue.asBoolean();
}
- throw new JSONException("Unknown type " + transportType);
+ throw new JsonException("Unknown type " + transportType);
}
- private static UidlValue decodeUidlValue(JSONArray encodedJsonValue,
- ConnectorTracker connectorTracker) throws JSONException {
+ private static UidlValue decodeUidlValue(JsonArray encodedJsonValue,
+ ConnectorTracker connectorTracker) {
String type = encodedJsonValue.getString(0);
Object decodedValue = decodeInternalType(getType(type), true,
@@ -435,13 +445,13 @@ public class JsonCodec implements Serializable {
}
private static Map<Object, Object> decodeMap(Type targetType,
- boolean restrictToInternalTypes, Object jsonMap,
- ConnectorTracker connectorTracker) throws JSONException {
- if (jsonMap instanceof JSONArray) {
+ boolean restrictToInternalTypes, JsonValue jsonMap,
+ ConnectorTracker connectorTracker) {
+ if (jsonMap.getType() == JsonType.ARRAY) {
// Client-side has no declared type information to determine
// encoding method for empty maps, so these are handled separately.
// See #8906.
- JSONArray jsonArray = (JSONArray) jsonMap;
+ JsonArray jsonArray = (JsonArray) jsonMap;
if (jsonArray.length() == 0) {
return new HashMap<Object, Object>();
}
@@ -453,27 +463,27 @@ public class JsonCodec implements Serializable {
Type valueType = ((ParameterizedType) targetType)
.getActualTypeArguments()[1];
if (keyType == String.class) {
- return decodeStringMap(valueType, (JSONObject) jsonMap,
+ return decodeStringMap(valueType, (JsonObject) jsonMap,
connectorTracker);
} else if (keyType == Connector.class) {
- return decodeConnectorMap(valueType, (JSONObject) jsonMap,
+ return decodeConnectorMap(valueType, (JsonObject) jsonMap,
connectorTracker);
} else {
- return decodeObjectMap(keyType, valueType, (JSONArray) jsonMap,
+ return decodeObjectMap(keyType, valueType, (JsonArray) jsonMap,
connectorTracker);
}
} else {
- return decodeStringMap(UidlValue.class, (JSONObject) jsonMap,
+ return decodeStringMap(UidlValue.class, (JsonObject) jsonMap,
connectorTracker);
}
}
private static Map<Object, Object> decodeObjectMap(Type keyType,
- Type valueType, JSONArray jsonMap, ConnectorTracker connectorTracker)
- throws JSONException {
+ Type valueType, JsonArray jsonMap, ConnectorTracker connectorTracker)
+ {
- JSONArray keys = jsonMap.getJSONArray(0);
- JSONArray values = jsonMap.getJSONArray(1);
+ JsonArray keys = jsonMap.getArray(0);
+ JsonArray values = jsonMap.getArray(1);
assert (keys.length() == values.length());
@@ -491,12 +501,10 @@ public class JsonCodec implements Serializable {
}
private static Map<Object, Object> decodeConnectorMap(Type valueType,
- JSONObject jsonMap, ConnectorTracker connectorTracker)
- throws JSONException {
+ JsonObject jsonMap, ConnectorTracker connectorTracker) {
Map<Object, Object> map = new HashMap<Object, Object>();
- for (Iterator<?> iter = jsonMap.keys(); iter.hasNext();) {
- String key = (String) iter.next();
+ for (String key : jsonMap.keys()) {
Object value = decodeInternalOrCustomType(valueType,
jsonMap.get(key), connectorTracker);
if (valueType == UidlValue.class) {
@@ -509,12 +517,10 @@ public class JsonCodec implements Serializable {
}
private static Map<Object, Object> decodeStringMap(Type valueType,
- JSONObject jsonMap, ConnectorTracker connectorTracker)
- throws JSONException {
+ JsonObject jsonMap, ConnectorTracker connectorTracker) {
Map<Object, Object> map = new HashMap<Object, Object>();
- for (Iterator<?> iter = jsonMap.keys(); iter.hasNext();) {
- String key = (String) iter.next();
+ for (String key : jsonMap.keys()) {
Object value = decodeInternalOrCustomType(valueType,
jsonMap.get(key), connectorTracker);
if (valueType == UidlValue.class) {
@@ -535,11 +541,10 @@ public class JsonCodec implements Serializable {
* @param encodedValueAndType
* @param application
* @return
- * @throws JSONException
*/
private static Object decodeParametrizedType(Type targetType,
- boolean restrictToInternalTypes, int typeIndex, Object value,
- ConnectorTracker connectorTracker) throws JSONException {
+ boolean restrictToInternalTypes, int typeIndex, JsonValue value,
+ ConnectorTracker connectorTracker) {
if (!restrictToInternalTypes && targetType instanceof ParameterizedType) {
Type childType = ((ParameterizedType) targetType)
.getActualTypeArguments()[typeIndex];
@@ -555,12 +560,11 @@ public class JsonCodec implements Serializable {
}
}
- private static Object decodeEnum(Class<? extends Enum> cls, String value) {
- return Enum.valueOf(cls, value);
+ private static Object decodeEnum(Class<? extends Enum> cls, JsonString value) {
+ return Enum.valueOf(cls, value.getString());
}
- private static String[] decodeStringArray(JSONArray jsonArray)
- throws JSONException {
+ private static String[] decodeStringArray(JsonArray jsonArray) {
int length = jsonArray.length();
List<String> tokens = new ArrayList<String>(length);
for (int i = 0; i < length; ++i) {
@@ -570,21 +574,20 @@ public class JsonCodec implements Serializable {
}
private static Object[] decodeObjectArray(Type targetType,
- JSONArray jsonArray, ConnectorTracker connectorTracker)
- throws JSONException {
+ JsonArray jsonArray, ConnectorTracker connectorTracker) {
List<Object> list = decodeList(List.class, true, jsonArray,
connectorTracker);
return list.toArray(new Object[list.size()]);
}
private static List<Object> decodeList(Type targetType,
- boolean restrictToInternalTypes, JSONArray jsonArray,
- ConnectorTracker connectorTracker) throws JSONException {
+ boolean restrictToInternalTypes, JsonArray jsonArray,
+ ConnectorTracker connectorTracker) {
int arrayLength = jsonArray.length();
List<Object> list = new ArrayList<Object>(arrayLength);
for (int i = 0; i < arrayLength; ++i) {
// each entry always has two elements: type and value
- Object encodedValue = jsonArray.get(i);
+ JsonValue encodedValue = jsonArray.get(i);
Object decodedChild = decodeParametrizedType(targetType,
restrictToInternalTypes, 0, encodedValue, connectorTracker);
list.add(decodedChild);
@@ -593,8 +596,8 @@ public class JsonCodec implements Serializable {
}
private static Set<Object> decodeSet(Type targetType,
- boolean restrictToInternalTypes, JSONArray jsonArray,
- ConnectorTracker connectorTracker) throws JSONException {
+ boolean restrictToInternalTypes, JsonArray jsonArray,
+ ConnectorTracker connectorTracker) {
HashSet<Object> set = new HashSet<Object>();
set.addAll(decodeList(targetType, restrictToInternalTypes, jsonArray,
connectorTracker));
@@ -602,8 +605,7 @@ public class JsonCodec implements Serializable {
}
private static Object decodeObject(Type targetType,
- JSONObject serializedObject, ConnectorTracker connectorTracker)
- throws JSONException {
+ JsonObject serializedObject, ConnectorTracker connectorTracker) {
Class<?> targetClass = getClassForType(targetType);
@@ -612,7 +614,7 @@ public class JsonCodec implements Serializable {
for (BeanProperty property : getProperties(targetClass)) {
String fieldName = property.getName();
- Object encodedFieldValue = serializedObject.get(fieldName);
+ JsonValue encodedFieldValue = serializedObject.get(fieldName);
Type fieldType = property.getType();
Object decodedFieldValue = decodeInternalOrCustomType(
fieldType, encodedFieldValue, connectorTracker);
@@ -622,13 +624,12 @@ public class JsonCodec implements Serializable {
return decodedObject;
} catch (Exception e) {
- throw new JSONException(e.getMessage());
+ throw new RuntimeException(e);
}
}
- public static EncodeResult encode(Object value, Object diffState,
- Type valueType, ConnectorTracker connectorTracker)
- throws JSONException {
+ public static EncodeResult encode(Object value, JsonValue diffState,
+ Type valueType, ConnectorTracker connectorTracker) {
if (null == value) {
return ENCODE_RESULT_NULL;
@@ -636,13 +637,19 @@ public class JsonCodec implements Serializable {
// Storing a single reference and only returning the EncodeResult at the
// end the method is much shorter in bytecode which allows inlining
- Object toReturn;
+ JsonValue toReturn;
- if (value instanceof String || value instanceof Boolean
- || value instanceof Number || value instanceof Character
- || value instanceof JSONArray || value instanceof JSONObject) {
+ if (value instanceof JsonValue) {
// all JSON compatible types are returned as is.
- toReturn = value;
+ toReturn = (JsonValue) value;
+ } else if (value instanceof String) {
+ toReturn = Json.create((String) value);
+ } else if (value instanceof Boolean) {
+ toReturn = Json.create((Boolean) value);
+ } else if (value instanceof Number) {
+ toReturn = Json.create(((Number) value).doubleValue());
+ } else if (value instanceof Character) {
+ toReturn = Json.create(Character.toString((Character) value));
} else if (value instanceof String[]) {
toReturn = toJsonArray((String[]) value);
} else if (value instanceof Collection) {
@@ -658,9 +665,9 @@ public class JsonCodec implements Serializable {
return ENCODE_RESULT_NULL;
}
// Connectors are simply serialized as ID.
- toReturn = ((Connector) value).getConnectorId();
+ toReturn = Json.create(((Connector) value).getConnectorId());
} else if (value instanceof Enum) {
- toReturn = ((Enum<?>) value).name();
+ toReturn = Json.create(((Enum<?>) value).name());
} else if (customSerializers.containsKey(value.getClass())) {
toReturn = serializeJson(value, connectorTracker);
} else if (valueType instanceof GenericArrayType) {
@@ -677,10 +684,10 @@ public class JsonCodec implements Serializable {
// needs to return it directly rather than assigning it to
// toReturn.
return encodeObject(value, (Class<?>) valueType,
- (JSONObject) diffState, connectorTracker);
+ (JsonObject) diffState, connectorTracker);
}
} else {
- throw new JSONException("Can not encode type " + valueType);
+ throw new JsonException("Can not encode type " + valueType);
}
return new EncodeResult(toReturn);
}
@@ -706,10 +713,9 @@ public class JsonCodec implements Serializable {
* Loops through the fields of value and encodes them.
*/
private static EncodeResult encodeObject(Object value, Class<?> valueType,
- JSONObject referenceValue, ConnectorTracker connectorTracker)
- throws JSONException {
- JSONObject encoded = new JSONObject();
- JSONObject diff = new JSONObject();
+ JsonObject referenceValue, ConnectorTracker connectorTracker) {
+ JsonObject encoded = Json.createObject();
+ JsonObject diff = Json.createObject();
try {
for (BeanProperty property : getProperties(valueType)) {
@@ -719,7 +725,7 @@ public class JsonCodec implements Serializable {
Type fieldType = property.getType();
Object fieldValue = property.getValue(value);
- if (encoded.has(fieldName)) {
+ if (encoded.hasKey(fieldName)) {
throw new RuntimeException(
"Can't encode "
+ valueType.getName()
@@ -728,10 +734,10 @@ public class JsonCodec implements Serializable {
+ ". This can happen if there are getters and setters for a public field (the framework can't know which to ignore) or if there are properties with only casing distinguishing between the names (e.g. getFoo() and getFOO())");
}
- Object fieldReference;
+ JsonValue fieldReference;
if (referenceValue != null) {
fieldReference = referenceValue.get(fieldName);
- if (JSONObject.NULL.equals(fieldReference)) {
+ if (fieldReference instanceof JsonNull) {
fieldReference = null;
}
} else {
@@ -748,7 +754,7 @@ public class JsonCodec implements Serializable {
}
} catch (Exception e) {
// TODO: Should exceptions be handled in a different way?
- throw new JSONException(e.getMessage());
+ throw new RuntimeException(e);
}
return new EncodeResult(encoded, diff);
}
@@ -760,8 +766,8 @@ public class JsonCodec implements Serializable {
* @param referenceValue
* @return
*/
- private static boolean jsonEquals(Object fieldValue, Object referenceValue) {
- if (fieldValue == JSONObject.NULL) {
+ private static boolean jsonEquals(JsonValue fieldValue, JsonValue referenceValue) {
+ if (fieldValue instanceof JsonNull) {
fieldValue = null;
}
@@ -769,41 +775,33 @@ public class JsonCodec implements Serializable {
return true;
} else if (fieldValue == null || referenceValue == null) {
return false;
- } else if (fieldValue instanceof Integer
- && referenceValue instanceof Integer) {
- return ((Integer) fieldValue).equals(referenceValue);
- } else if (fieldValue instanceof Boolean
- && referenceValue instanceof Boolean) {
- return ((Boolean) fieldValue).equals(referenceValue);
} else {
- return fieldValue.toString().equals(referenceValue.toString());
+ return fieldValue.jsEquals(referenceValue);
}
}
- private static JSONArray encodeArrayContents(Type componentType,
- Object array, ConnectorTracker connectorTracker)
- throws JSONException {
- JSONArray jsonArray = new JSONArray();
+ private static JsonArray encodeArrayContents(Type componentType,
+ Object array, ConnectorTracker connectorTracker) {
+ JsonArray jsonArray = Json.createArray();
for (int i = 0; i < Array.getLength(array); i++) {
EncodeResult encodeResult = encode(Array.get(array, i), null,
componentType, connectorTracker);
- jsonArray.put(encodeResult.getEncodedValue());
+ jsonArray.set(i, encodeResult.getEncodedValue());
}
return jsonArray;
}
- private static JSONArray encodeCollection(Type targetType,
- Collection<?> collection, ConnectorTracker connectorTracker)
- throws JSONException {
- JSONArray jsonArray = new JSONArray();
+ private static JsonArray encodeCollection(Type targetType,
+ Collection<?> collection, ConnectorTracker connectorTracker) {
+ JsonArray jsonArray = Json.createArray();
for (Object o : collection) {
- jsonArray.put(encodeChild(targetType, 0, o, connectorTracker));
+ jsonArray.set(jsonArray.length(), encodeChild(targetType, 0, o, connectorTracker));
}
return jsonArray;
}
- private static Object encodeChild(Type targetType, int typeIndex, Object o,
- ConnectorTracker connectorTracker) throws JSONException {
+ private static JsonValue encodeChild(Type targetType, int typeIndex, Object o,
+ ConnectorTracker connectorTracker) {
if (targetType instanceof ParameterizedType) {
Type childType = ((ParameterizedType) targetType)
.getActualTypeArguments()[typeIndex];
@@ -812,19 +810,19 @@ public class JsonCodec implements Serializable {
connectorTracker);
return encodeResult.getEncodedValue();
} else {
- throw new JSONException("Collection is missing generics");
+ throw new JsonException("Collection is missing generics");
}
}
- private static Object encodeMap(Type mapType, Map<?, ?> map,
- ConnectorTracker connectorTracker) throws JSONException {
+ private static JsonValue encodeMap(Type mapType, Map<?, ?> map,
+ ConnectorTracker connectorTracker) {
Type keyType, valueType;
if (mapType instanceof ParameterizedType) {
keyType = ((ParameterizedType) mapType).getActualTypeArguments()[0];
valueType = ((ParameterizedType) mapType).getActualTypeArguments()[1];
} else {
- throw new JSONException("Map is missing generics");
+ throw new JsonException("Map is missing generics");
}
if (map.isEmpty()) {
@@ -842,11 +840,10 @@ public class JsonCodec implements Serializable {
}
}
- private static JSONArray encodeObjectMap(Type keyType, Type valueType,
- Map<?, ?> map, ConnectorTracker connectorTracker)
- throws JSONException {
- JSONArray keys = new JSONArray();
- JSONArray values = new JSONArray();
+ private static JsonArray encodeObjectMap(Type keyType, Type valueType,
+ Map<?, ?> map, ConnectorTracker connectorTracker) {
+ JsonArray keys = Json.createArray();
+ JsonArray values = Json.createArray();
for (Entry<?, ?> entry : map.entrySet()) {
EncodeResult encodedKey = encode(entry.getKey(), null, keyType,
@@ -854,19 +851,23 @@ public class JsonCodec implements Serializable {
EncodeResult encodedValue = encode(entry.getValue(), null,
valueType, connectorTracker);
- keys.put(encodedKey.getEncodedValue());
- values.put(encodedValue.getEncodedValue());
+ keys.set(keys.length(), encodedKey.getEncodedValue());
+ values.set(values.length(), encodedValue.getEncodedValue());
}
- return new JSONArray(Arrays.asList(keys, values));
+ JsonArray jsonMap = Json.createArray();
+ jsonMap.set(0, keys);
+ jsonMap.set(1, values);
+
+ return jsonMap;
}
/*
* Encodes a connector map. Invisible connectors are skipped.
*/
- private static JSONObject encodeConnectorMap(Type valueType, Map<?, ?> map,
- ConnectorTracker connectorTracker) throws JSONException {
- JSONObject jsonMap = new JSONObject();
+ private static JsonObject encodeConnectorMap(Type valueType, Map<?, ?> map,
+ ConnectorTracker connectorTracker) {
+ JsonObject jsonMap = Json.createObject();
for (Entry<?, ?> entry : map.entrySet()) {
ClientConnector key = (ClientConnector) entry.getKey();
@@ -881,9 +882,9 @@ public class JsonCodec implements Serializable {
return jsonMap;
}
- private static JSONObject encodeStringMap(Type valueType, Map<?, ?> map,
- ConnectorTracker connectorTracker) throws JSONException {
- JSONObject jsonMap = new JSONObject();
+ private static JsonObject encodeStringMap(Type valueType, Map<?, ?> map,
+ ConnectorTracker connectorTracker) {
+ JsonObject jsonMap = Json.createObject();
for (Entry<?, ?> entry : map.entrySet()) {
String key = (String) entry.getKey();
@@ -904,16 +905,16 @@ public class JsonCodec implements Serializable {
return typeToTransportType.get(getClassForType(valueType));
}
- private static Object serializeJson(Object value,
+ private static JsonValue serializeJson(Object value,
ConnectorTracker connectorTracker) {
JSONSerializer serializer = customSerializers.get(value.getClass());
return serializer.serialize(value, connectorTracker);
}
- private static JSONArray toJsonArray(String[] array) {
- JSONArray jsonArray = new JSONArray();
+ private static JsonArray toJsonArray(String[] array) {
+ JsonArray jsonArray = Json.createArray();
for (int i = 0; i < array.length; ++i) {
- jsonArray.put(array[i]);
+ jsonArray.set(i, array[i]);
}
return jsonArray;
}
diff --git a/server/src/com/vaadin/server/LegacyCommunicationManager.java b/server/src/com/vaadin/server/LegacyCommunicationManager.java
index 0dda5661bd..e1beb1153c 100644
--- a/server/src/com/vaadin/server/LegacyCommunicationManager.java
+++ b/server/src/com/vaadin/server/LegacyCommunicationManager.java
@@ -27,9 +27,6 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.ClientConnector.ConnectorErrorEvent;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.JavaScriptConnectorState;
@@ -40,6 +37,9 @@ import com.vaadin.ui.HasComponents;
import com.vaadin.ui.SelectiveRenderer;
import com.vaadin.ui.UI;
+import elemental.json.JsonObject;
+import elemental.json.JsonValue;
+
/**
* This is a common base class for the server-side implementations of the
* communication system between the client code (compiled with GWT into
@@ -85,12 +85,11 @@ public class LegacyCommunicationManager implements Serializable {
* @deprecated As of 7.1. See #11411.
*/
@Deprecated
- public static JSONObject encodeState(ClientConnector connector,
- SharedState state) throws JSONException {
+ public static JsonObject encodeState(ClientConnector connector, SharedState state) {
UI uI = connector.getUI();
ConnectorTracker connectorTracker = uI.getConnectorTracker();
Class<? extends SharedState> stateType = connector.getStateType();
- Object diffState = connectorTracker.getDiffState(connector);
+ JsonValue diffState = connectorTracker.getDiffState(connector);
boolean supportsDiffState = !JavaScriptConnectorState.class
.isAssignableFrom(stateType);
if (diffState == null && supportsDiffState) {
@@ -113,9 +112,9 @@ public class LegacyCommunicationManager implements Serializable {
stateType, uI.getConnectorTracker());
if (supportsDiffState) {
connectorTracker.setDiffState(connector,
- (JSONObject) encodeResult.getEncodedValue());
+ (JsonObject) encodeResult.getEncodedValue());
}
- return (JSONObject) encodeResult.getDiff();
+ return (JsonObject) encodeResult.getDiff();
}
/**
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index 8d44ff74ed..8fd6da8dee 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -48,9 +48,6 @@ import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.event.EventRouter;
import com.vaadin.server.VaadinSession.FutureAccess;
@@ -67,6 +64,11 @@ import com.vaadin.ui.UI;
import com.vaadin.util.CurrentInstance;
import com.vaadin.util.ReflectTools;
+import elemental.json.Json;
+import elemental.json.JsonException;
+import elemental.json.JsonObject;
+import elemental.json.impl.JsonUtil;
+
/**
* Provide deployment specific settings that are required outside terminal
* specific code.
@@ -1574,22 +1576,26 @@ public abstract class VaadinService implements Serializable {
message += "<br/><br/>" + details;
}
- JSONObject appError = new JSONObject();
+ JsonObject appError = Json.createObject();
appError.put("caption", caption);
appError.put("message", message);
- appError.put("url", url);
+ if (url == null) {
+ appError.put("url", Json.createNull());
+ } else {
+ appError.put("url", url);
+ }
- JSONObject meta = new JSONObject();
+ JsonObject meta = Json.createObject();
meta.put("appError", appError);
- JSONObject json = new JSONObject();
- json.put("changes", new JSONObject());
- json.put("resources", new JSONObject());
- json.put("locales", new JSONObject());
+ JsonObject json = Json.createObject();
+ json.put("changes", Json.createObject());
+ json.put("resources", Json.createObject());
+ json.put("locales", Json.createObject());
json.put("meta", meta);
json.put(ApplicationConstants.SERVER_SYNC_ID, -1);
- returnString = json.toString();
- } catch (JSONException e) {
+ returnString = JsonUtil.stringify(json);
+ } catch (JsonException e) {
getLogger().log(Level.WARNING,
"Error creating critical notification JSON message", e);
}
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index 09b8a22a46..4656f9a672 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/com/vaadin/server/VaadinServlet.java
@@ -77,10 +77,20 @@ public class VaadinServlet extends HttpServlet implements Constants {
long newest = 0;
for (String uri : sourceUris) {
File file = new File(uri);
- if (!file.exists()) {
- return -1;
- } else {
+ if (file.exists()) {
newest = Math.max(newest, file.lastModified());
+ } else if (!uri.startsWith("VAADIN/")) {
+ /*
+ * Ignore missing files starting with VAADIN/ since those
+ * are fetched from the classpath, report problem and abort
+ * for other files.
+ */
+ getLogger()
+ .log(Level.WARNING,
+ "Could not resolve timestamp for {0}, Scss on the fly caching will be disabled",
+ uri);
+ // -1 means this cache entry will never be valid
+ return -1;
}
}
diff --git a/server/src/com/vaadin/server/communication/ClientRpcWriter.java b/server/src/com/vaadin/server/communication/ClientRpcWriter.java
index 1090fdbab9..6631f6176d 100644
--- a/server/src/com/vaadin/server/communication/ClientRpcWriter.java
+++ b/server/src/com/vaadin/server/communication/ClientRpcWriter.java
@@ -24,9 +24,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.server.ClientConnector;
import com.vaadin.server.ClientMethodInvocation;
import com.vaadin.server.EncodeResult;
@@ -35,6 +32,12 @@ import com.vaadin.server.PaintException;
import com.vaadin.shared.communication.ClientRpc;
import com.vaadin.ui.UI;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+import elemental.json.JsonValue;
+import elemental.json.impl.JsonUtil;
+
/**
* Serializes {@link ClientRpc client RPC} invocations to JSON.
*
@@ -59,18 +62,18 @@ public class ClientRpcWriter implements Serializable {
Collection<ClientMethodInvocation> pendingInvocations = collectPendingRpcCalls(ui
.getConnectorTracker().getDirtyVisibleConnectors());
- JSONArray rpcCalls = new JSONArray();
+ JsonArray rpcCalls = Json.createArray();
for (ClientMethodInvocation invocation : pendingInvocations) {
// add invocation to rpcCalls
try {
- JSONArray invocationJson = new JSONArray();
- invocationJson.put(invocation.getConnector().getConnectorId());
- invocationJson.put(invocation.getInterfaceName());
- invocationJson.put(invocation.getMethodName());
- JSONArray paramJson = new JSONArray();
+ JsonArray invocationJson = Json.createArray();
+ invocationJson.set(0, invocation.getConnector().getConnectorId());
+ invocationJson.set(1, invocation.getInterfaceName());
+ invocationJson.set(2, invocation.getMethodName());
+ JsonArray paramJson = Json.createArray();
for (int i = 0; i < invocation.getParameterTypes().length; ++i) {
Type parameterType = invocation.getParameterTypes()[i];
- Object referenceParameter = null;
+ JsonValue referenceParameter = null;
// TODO Use default values for RPC parameter types
// if (!JsonCodec.isInternalType(parameterType)) {
// try {
@@ -84,11 +87,11 @@ public class ClientRpcWriter implements Serializable {
EncodeResult encodeResult = JsonCodec.encode(
invocation.getParameters()[i], referenceParameter,
parameterType, ui.getConnectorTracker());
- paramJson.put(encodeResult.getEncodedValue());
+ paramJson.set(i, encodeResult.getEncodedValue());
}
- invocationJson.put(paramJson);
- rpcCalls.put(invocationJson);
- } catch (JSONException e) {
+ invocationJson.set(3, paramJson);
+ rpcCalls.set(rpcCalls.length(), invocationJson);
+ } catch (JsonException e) {
throw new PaintException(
"Failed to serialize RPC method call parameters for connector "
+ invocation.getConnector().getConnectorId()
@@ -97,7 +100,7 @@ public class ClientRpcWriter implements Serializable {
+ e.getMessage(), e);
}
}
- writer.write(rpcCalls.toString());
+ writer.write(JsonUtil.stringify(rpcCalls));
}
/**
diff --git a/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java b/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java
index 653048b930..1c1a220b5d 100644
--- a/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java
+++ b/server/src/com/vaadin/server/communication/ConnectorHierarchyWriter.java
@@ -21,16 +21,18 @@ import java.io.Serializable;
import java.io.Writer;
import java.util.Collection;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.AbstractClientConnector;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.LegacyCommunicationManager;
import com.vaadin.server.PaintException;
import com.vaadin.ui.UI;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+import elemental.json.JsonObject;
+import elemental.json.impl.JsonUtil;
+
/**
* Serializes a connector hierarchy to JSON.
*
@@ -55,27 +57,27 @@ public class ConnectorHierarchyWriter implements Serializable {
Collection<ClientConnector> dirtyVisibleConnectors = ui
.getConnectorTracker().getDirtyVisibleConnectors();
- JSONObject hierarchyInfo = new JSONObject();
+ JsonObject hierarchyInfo = Json.createObject();
for (ClientConnector connector : dirtyVisibleConnectors) {
String connectorId = connector.getConnectorId();
- JSONArray children = new JSONArray();
+ JsonArray children = Json.createArray();
for (ClientConnector child : AbstractClientConnector
.getAllChildrenIterable(connector)) {
if (LegacyCommunicationManager
.isConnectorVisibleToClient(child)) {
- children.put(child.getConnectorId());
+ children.set(children.length(), child.getConnectorId());
}
}
try {
hierarchyInfo.put(connectorId, children);
- } catch (JSONException e) {
+ } catch (JsonException e) {
throw new PaintException(
"Failed to send hierarchy information about "
+ connectorId + " to the client: "
+ e.getMessage(), e);
}
}
- writer.write(hierarchyInfo.toString());
+ writer.write(JsonUtil.stringify(hierarchyInfo));
}
}
diff --git a/server/src/com/vaadin/server/communication/ConnectorTypeWriter.java b/server/src/com/vaadin/server/communication/ConnectorTypeWriter.java
index 0bafd20a81..d534987061 100644
--- a/server/src/com/vaadin/server/communication/ConnectorTypeWriter.java
+++ b/server/src/com/vaadin/server/communication/ConnectorTypeWriter.java
@@ -21,14 +21,16 @@ import java.io.Serializable;
import java.io.Writer;
import java.util.Collection;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.ClientConnector;
import com.vaadin.server.PaintException;
import com.vaadin.server.PaintTarget;
import com.vaadin.ui.UI;
+import elemental.json.Json;
+import elemental.json.JsonException;
+import elemental.json.JsonObject;
+import elemental.json.impl.JsonUtil;
+
/**
* Serializes connector type mappings to JSON.
*
@@ -56,18 +58,18 @@ public class ConnectorTypeWriter implements Serializable {
Collection<ClientConnector> dirtyVisibleConnectors = ui
.getConnectorTracker().getDirtyVisibleConnectors();
- JSONObject connectorTypes = new JSONObject();
+ JsonObject connectorTypes = Json.createObject();
for (ClientConnector connector : dirtyVisibleConnectors) {
String connectorType = target.getTag(connector);
try {
connectorTypes.put(connector.getConnectorId(), connectorType);
- } catch (JSONException e) {
+ } catch (JsonException e) {
throw new PaintException(
"Failed to send connector type for connector "
+ connector.getConnectorId() + ": "
+ e.getMessage(), e);
}
}
- writer.write(connectorTypes.toString());
+ writer.write(JsonUtil.stringify(connectorTypes));
}
}
diff --git a/server/src/com/vaadin/server/communication/DateSerializer.java b/server/src/com/vaadin/server/communication/DateSerializer.java
index 429941abfd..593728bac7 100644
--- a/server/src/com/vaadin/server/communication/DateSerializer.java
+++ b/server/src/com/vaadin/server/communication/DateSerializer.java
@@ -19,6 +19,8 @@ import java.lang.reflect.Type;
import java.util.Date;
import com.vaadin.ui.ConnectorTracker;
+import elemental.json.Json;
+import elemental.json.JsonValue;
/**
* Server side serializer/deserializer for java.util.Date
@@ -29,14 +31,14 @@ import com.vaadin.ui.ConnectorTracker;
public class DateSerializer implements JSONSerializer<Date> {
@Override
- public Date deserialize(Type type, Object jsonValue,
+ public Date deserialize(Type type, JsonValue jsonValue,
ConnectorTracker connectorTracker) {
- return new Date(Long.valueOf(String.valueOf(jsonValue)));
+ return new Date((long) jsonValue.asNumber());
}
@Override
- public Object serialize(Date value, ConnectorTracker connectorTracker) {
- return value.getTime();
+ public JsonValue serialize(Date value, ConnectorTracker connectorTracker) {
+ return Json.create(value.getTime());
}
}
diff --git a/server/src/com/vaadin/server/communication/JSONSerializer.java b/server/src/com/vaadin/server/communication/JSONSerializer.java
index 91105d6ffd..e318b6b145 100644
--- a/server/src/com/vaadin/server/communication/JSONSerializer.java
+++ b/server/src/com/vaadin/server/communication/JSONSerializer.java
@@ -18,13 +18,14 @@ package com.vaadin.server.communication;
import java.lang.reflect.Type;
import com.vaadin.ui.ConnectorTracker;
+import elemental.json.JsonValue;
/**
* Implementors of this interface knows how to serialize an Object of a given
* type to JSON and how to deserialize the JSON back into an object.
* <p>
* The {@link #serialize(Object, ConnectorTracker)} and
- * {@link #deserialize(Type, Object, ConnectorTracker)} methods must be
+ * {@link #deserialize(Type, JsonValue, ConnectorTracker)} methods must be
* symmetric so they can be chained and produce the original result (or an equal
* result).
* <p>
@@ -42,10 +43,7 @@ public interface JSONSerializer<T> {
* Creates and deserializes an object received from the client. Must be
* compatible with {@link #serialize(Object, ConnectorTracker)} and also
* with the client side com.vaadin.client.communication.JSONSerializer.
- * <p>
- * The json parameter is of type Object as org.json JSON classes have no
- * other common super class
- *
+ *
* @param type
* The expected return type
* @param jsonValue
@@ -54,11 +52,11 @@ public interface JSONSerializer<T> {
* the connector tracker instance for the UI
* @return A deserialized object
*/
- T deserialize(Type type, Object jsonValue, ConnectorTracker connectorTracker);
+ T deserialize(Type type, JsonValue jsonValue, ConnectorTracker connectorTracker);
/**
* Serialize the given object into JSON. Must be compatible with
- * {@link #deserialize(Object, connectorTracker)} and the client side
+ * {@link #deserialize(Type, JsonValue, ConnectorTracker)} and the client side
* com.vaadin.client.communication.JSONSerializer
*
* @param value
@@ -67,6 +65,6 @@ public interface JSONSerializer<T> {
* The connector tracker instance for the UI
* @return A JSON serialized version of the object
*/
- Object serialize(T value, ConnectorTracker connectorTracker);
+ JsonValue serialize(T value, ConnectorTracker connectorTracker);
}
diff --git a/server/src/com/vaadin/server/communication/PortletBootstrapHandler.java b/server/src/com/vaadin/server/communication/PortletBootstrapHandler.java
index 66b08fdadd..1d1a300cd1 100644
--- a/server/src/com/vaadin/server/communication/PortletBootstrapHandler.java
+++ b/server/src/com/vaadin/server/communication/PortletBootstrapHandler.java
@@ -25,9 +25,6 @@ import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceURL;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.BootstrapHandler;
import com.vaadin.server.PaintException;
import com.vaadin.server.VaadinPortlet;
@@ -39,6 +36,7 @@ import com.vaadin.server.VaadinResponse;
import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinSession;
import com.vaadin.shared.ApplicationConstants;
+import elemental.json.JsonObject;
public class PortletBootstrapHandler extends BootstrapHandler {
@Override
@@ -71,7 +69,7 @@ public class PortletBootstrapHandler extends BootstrapHandler {
@Override
protected void appendMainScriptTagContents(BootstrapContext context,
- StringBuilder builder) throws JSONException, IOException {
+ StringBuilder builder) throws IOException {
// fixed base theme to use - all portal pages with Vaadin
// applications will load this exactly once
String portalTheme = ((VaadinPortletRequest) context.getRequest())
@@ -94,9 +92,9 @@ public class PortletBootstrapHandler extends BootstrapHandler {
}
@Override
- protected JSONObject getApplicationParameters(BootstrapContext context)
- throws JSONException, PaintException {
- JSONObject parameters = super.getApplicationParameters(context);
+ protected JsonObject getApplicationParameters(BootstrapContext context)
+ throws PaintException {
+ JsonObject parameters = super.getApplicationParameters(context);
VaadinPortletResponse response = (VaadinPortletResponse) context
.getResponse();
VaadinPortletRequest request = (VaadinPortletRequest) context
diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java
index 67e5f87153..6ee81270cd 100644
--- a/server/src/com/vaadin/server/communication/PushHandler.java
+++ b/server/src/com/vaadin/server/communication/PushHandler.java
@@ -29,7 +29,6 @@ import org.atmosphere.cpr.AtmosphereResource.TRANSPORT;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter;
import org.atmosphere.handler.AbstractReflectorAtmosphereHandler;
-import org.json.JSONException;
import com.vaadin.server.ErrorEvent;
import com.vaadin.server.ErrorHandler;
@@ -46,6 +45,7 @@ import com.vaadin.server.VaadinSession;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.communication.PushMode;
import com.vaadin.ui.UI;
+import elemental.json.JsonException;
/**
* Establishes bidirectional ("push") communication channels
@@ -173,7 +173,7 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter {
try {
new ServerRpcHandler().handleRpc(ui, reader, vaadinRequest);
connection.push(false);
- } catch (JSONException e) {
+ } catch (JsonException e) {
getLogger().log(Level.SEVERE, "Error writing JSON to response",
e);
// Refresh on client side
diff --git a/server/src/com/vaadin/server/communication/ServerRpcHandler.java b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
index ae076e0856..d1b1be6b97 100644
--- a/server/src/com/vaadin/server/communication/ServerRpcHandler.java
+++ b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
@@ -28,10 +28,6 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.ClientConnector;
import com.vaadin.server.JsonCodec;
import com.vaadin.server.LegacyCommunicationManager;
@@ -52,6 +48,12 @@ import com.vaadin.ui.Component;
import com.vaadin.ui.ConnectorTracker;
import com.vaadin.ui.UI;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+import elemental.json.JsonObject;
+import elemental.json.JsonValue;
+import elemental.json.impl.JsonUtil;
+
/**
* Handles a client-to-server message containing serialized {@link ServerRpc
* server RPC} invocations.
@@ -71,28 +73,31 @@ public class ServerRpcHandler implements Serializable {
public static class RpcRequest implements Serializable {
private final String csrfToken;
- private final JSONArray invocations;
+ private final JsonArray invocations;
private final int syncId;
- private final JSONObject json;
+ private final JsonObject json;
- public RpcRequest(String jsonString, VaadinRequest request)
- throws JSONException {
- json = new JSONObject(jsonString);
+ public RpcRequest(String jsonString, VaadinRequest request) {
+ json = JsonUtil.parse(jsonString);
- String csrfToken = json.optString(ApplicationConstants.CSRF_TOKEN);
- if (csrfToken.equals("")) {
- csrfToken = ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE;
+ JsonValue token = json.get(ApplicationConstants.CSRF_TOKEN);
+ if (token == null) {
+ this.csrfToken = ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE;
+ } else {
+ String csrfToken = token.asString();
+ if (csrfToken.equals("")) {
+ csrfToken = ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE;
+ }
+ this.csrfToken = csrfToken;
}
- this.csrfToken = csrfToken;
if (request.getService().getDeploymentConfiguration()
.isSyncIdCheckEnabled()) {
- syncId = json.getInt(ApplicationConstants.SERVER_SYNC_ID);
+ syncId = (int) json.getNumber(ApplicationConstants.SERVER_SYNC_ID);
} else {
syncId = -1;
}
- invocations = json
- .getJSONArray(ApplicationConstants.RPC_INVOCATIONS);
+ invocations = json.getArray(ApplicationConstants.RPC_INVOCATIONS);
}
/**
@@ -110,7 +115,7 @@ public class ServerRpcHandler implements Serializable {
* @return the data describing which RPC should be made, and all their
* data
*/
- public JSONArray getRpcInvocationsData() {
+ public JsonArray getRpcInvocationsData() {
return invocations;
}
@@ -134,7 +139,7 @@ public class ServerRpcHandler implements Serializable {
* @return the raw JSON object that was received from the client
*
*/
- public JSONObject getRawJson() {
+ public JsonObject getRawJson() {
return json;
}
}
@@ -155,11 +160,9 @@ public class ServerRpcHandler implements Serializable {
* @throws InvalidUIDLSecurityKeyException
* If the received security key does not match the one stored in
* the session.
- * @throws JSONException
- * If deserializing the JSON fails.
*/
public void handleRpc(UI ui, Reader reader, VaadinRequest request)
- throws IOException, InvalidUIDLSecurityKeyException, JSONException {
+ throws IOException, InvalidUIDLSecurityKeyException {
ui.getSession().setLastRequestTimestamp(System.currentTimeMillis());
String changeMessage = getMessage(reader);
@@ -205,7 +208,7 @@ public class ServerRpcHandler implements Serializable {
* requested RPC calls.
*/
private void handleInvocations(UI uI, int lastSyncIdSeenByClient,
- JSONArray invocationsData) {
+ JsonArray invocationsData) {
// TODO PUSH Refactor so that this is not needed
LegacyCommunicationManager manager = uI.getSession()
.getCommunicationManager();
@@ -314,7 +317,7 @@ public class ServerRpcHandler implements Serializable {
}
}
}
- } catch (JSONException e) {
+ } catch (JsonException e) {
getLogger().warning(
"Unable to parse RPC call from the client: "
+ e.getMessage());
@@ -334,11 +337,10 @@ public class ServerRpcHandler implements Serializable {
* the most recent sync id the client has seen at the time the
* request was sent
* @return list of MethodInvocation to perform
- * @throws JSONException
*/
private List<MethodInvocation> parseInvocations(
- ConnectorTracker connectorTracker, JSONArray invocationsJson,
- int lastSyncIdSeenByClient) throws JSONException {
+ ConnectorTracker connectorTracker, JsonArray invocationsJson,
+ int lastSyncIdSeenByClient) {
int invocationCount = invocationsJson.length();
ArrayList<MethodInvocation> invocations = new ArrayList<MethodInvocation>(
invocationCount);
@@ -347,7 +349,7 @@ public class ServerRpcHandler implements Serializable {
// parse JSON to MethodInvocations
for (int i = 0; i < invocationCount; ++i) {
- JSONArray invocationJson = invocationsJson.getJSONArray(i);
+ JsonArray invocationJson = invocationsJson.getArray(i);
MethodInvocation invocation = parseInvocation(invocationJson,
previousInvocation, connectorTracker,
@@ -363,17 +365,15 @@ public class ServerRpcHandler implements Serializable {
return invocations;
}
- private MethodInvocation parseInvocation(JSONArray invocationJson,
+ private MethodInvocation parseInvocation(JsonArray invocationJson,
MethodInvocation previousInvocation,
- ConnectorTracker connectorTracker, long lastSyncIdSeenByClient)
- throws JSONException {
+ ConnectorTracker connectorTracker, long lastSyncIdSeenByClient) {
String connectorId = invocationJson.getString(0);
String interfaceName = invocationJson.getString(1);
String methodName = invocationJson.getString(2);
if (connectorTracker.getConnector(connectorId) == null
- && !connectorId
- .equals(ApplicationConstants.DRAG_AND_DROP_CONNECTOR_ID)) {
+ && !connectorId.equals(ApplicationConstants.DRAG_AND_DROP_CONNECTOR_ID)) {
if (!connectorTracker.connectorWasPresentAsRequestWasSent(
connectorId, lastSyncIdSeenByClient)) {
@@ -393,7 +393,7 @@ public class ServerRpcHandler implements Serializable {
return null;
}
- JSONArray parametersJson = invocationJson.getJSONArray(3);
+ JsonArray parametersJson = invocationJson.getArray(3);
if (LegacyChangeVariablesInvocation.isLegacyVariableChange(
interfaceName, methodName)) {
@@ -415,10 +415,9 @@ public class ServerRpcHandler implements Serializable {
private LegacyChangeVariablesInvocation parseLegacyChangeVariablesInvocation(
String connectorId, String interfaceName, String methodName,
LegacyChangeVariablesInvocation previousInvocation,
- JSONArray parametersJson, ConnectorTracker connectorTracker)
- throws JSONException {
+ JsonArray parametersJson, ConnectorTracker connectorTracker) {
if (parametersJson.length() != 2) {
- throw new JSONException(
+ throw new JsonException(
"Invalid parameters in legacy change variables call. Expected 2, was "
+ parametersJson.length());
}
@@ -440,8 +439,8 @@ public class ServerRpcHandler implements Serializable {
private ServerRpcMethodInvocation parseServerRpcInvocation(
String connectorId, String interfaceName, String methodName,
- JSONArray parametersJson, ConnectorTracker connectorTracker)
- throws JSONException {
+ JsonArray parametersJson, ConnectorTracker connectorTracker)
+ throws JsonException {
ClientConnector connector = connectorTracker.getConnector(connectorId);
ServerRpcManager<?> rpcManager = connector.getRpcManager(interfaceName);
@@ -471,7 +470,7 @@ public class ServerRpcHandler implements Serializable {
.getGenericParameterTypes();
for (int j = 0; j < parametersJson.length(); ++j) {
- Object parameterValue = parametersJson.get(j);
+ JsonValue parameterValue = parametersJson.get(j);
Type parameterType = declaredRpcMethodParameterTypes[j];
parameters[j] = JsonCodec.decodeInternalOrCustomType(parameterType,
parameterValue, connectorTracker);
diff --git a/server/src/com/vaadin/server/communication/SharedStateWriter.java b/server/src/com/vaadin/server/communication/SharedStateWriter.java
index 6a318f0758..6ef02955f7 100644
--- a/server/src/com/vaadin/server/communication/SharedStateWriter.java
+++ b/server/src/com/vaadin/server/communication/SharedStateWriter.java
@@ -21,14 +21,16 @@ import java.io.Serializable;
import java.io.Writer;
import java.util.Collection;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.ClientConnector;
import com.vaadin.server.PaintException;
import com.vaadin.shared.communication.SharedState;
import com.vaadin.ui.UI;
+import elemental.json.Json;
+import elemental.json.JsonException;
+import elemental.json.JsonObject;
+import elemental.json.impl.JsonUtil;
+
/**
* Serializes {@link SharedState shared state} changes to JSON.
*
@@ -53,16 +55,16 @@ public class SharedStateWriter implements Serializable {
Collection<ClientConnector> dirtyVisibleConnectors = ui
.getConnectorTracker().getDirtyVisibleConnectors();
- JSONObject sharedStates = new JSONObject();
+ JsonObject sharedStates = Json.createObject();
for (ClientConnector connector : dirtyVisibleConnectors) {
// encode and send shared state
try {
- JSONObject stateJson = connector.encodeState();
+ JsonObject stateJson = connector.encodeState();
- if (stateJson != null && stateJson.length() != 0) {
+ if (stateJson != null && stateJson.keys().length != 0) {
sharedStates.put(connector.getConnectorId(), stateJson);
}
- } catch (JSONException e) {
+ } catch (JsonException e) {
throw new PaintException(
"Failed to serialize shared state for connector "
+ connector.getClass().getName() + " ("
@@ -70,6 +72,6 @@ public class SharedStateWriter implements Serializable {
+ e.getMessage(), e);
}
}
- writer.write(sharedStates.toString());
+ writer.write(JsonUtil.stringify(sharedStates));
}
}
diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java
index cf0de8e9ee..356ad25219 100644
--- a/server/src/com/vaadin/server/communication/UIInitHandler.java
+++ b/server/src/com/vaadin/server/communication/UIInitHandler.java
@@ -23,9 +23,6 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.server.LegacyApplicationUIProvider;
import com.vaadin.server.SynchronizedRequestHandler;
@@ -43,6 +40,11 @@ import com.vaadin.shared.ui.ui.Transport;
import com.vaadin.shared.ui.ui.UIConstants;
import com.vaadin.ui.UI;
+import elemental.json.Json;
+import elemental.json.JsonException;
+import elemental.json.JsonObject;
+import elemental.json.impl.JsonUtil;
+
/**
* Handles an initial request from the client to initialize a {@link UI}.
*
@@ -75,13 +77,13 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
session.getCommunicationManager().repaintAll(uI);
- JSONObject params = new JSONObject();
+ JsonObject params = Json.createObject();
params.put(UIConstants.UI_ID_PARAMETER, uI.getUIId());
String initialUIDL = getInitialUidl(request, uI);
params.put("uidl", initialUIDL);
- stringWriter.write(params.toString());
- } catch (JSONException e) {
+ stringWriter.write(JsonUtil.stringify(params));
+ } catch (JsonException e) {
throw new IOException("Error producing initial UIDL", e);
} finally {
stringWriter.close();
@@ -278,12 +280,10 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
* @param uI
* the UI for which the UIDL should be generated
* @return a string with the initial UIDL message
- * @throws JSONException
- * if an exception occurs while encoding output
* @throws IOException
*/
protected String getInitialUidl(VaadinRequest request, UI uI)
- throws JSONException, IOException {
+ throws IOException {
StringWriter writer = new StringWriter();
try {
writer.write("{");
diff --git a/server/src/com/vaadin/server/communication/UidlRequestHandler.java b/server/src/com/vaadin/server/communication/UidlRequestHandler.java
index 0d8ddb7bc7..d28107e8f8 100644
--- a/server/src/com/vaadin/server/communication/UidlRequestHandler.java
+++ b/server/src/com/vaadin/server/communication/UidlRequestHandler.java
@@ -22,8 +22,6 @@ import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.json.JSONException;
-
import com.vaadin.server.Constants;
import com.vaadin.server.LegacyCommunicationManager.InvalidUIDLSecurityKeyException;
import com.vaadin.server.ServletPortletHelper;
@@ -38,6 +36,7 @@ import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.JsonConstants;
import com.vaadin.shared.Version;
import com.vaadin.ui.UI;
+import elemental.json.JsonException;
/**
* Processes a UIDL request from the client.
@@ -97,7 +96,7 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements
}
writeUidl(request, response, uI, stringWriter, repaintAll);
- } catch (JSONException e) {
+ } catch (JsonException e) {
getLogger().log(Level.SEVERE, "Error writing JSON to response", e);
// Refresh on client side
response.getWriter().write(
@@ -144,8 +143,7 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements
}
private void writeUidl(VaadinRequest request, VaadinResponse response,
- UI ui, Writer writer, boolean repaintAll) throws IOException,
- JSONException {
+ UI ui, Writer writer, boolean repaintAll) throws IOException {
openJsonMessage(writer, response);
new UidlWriter().write(ui, writer, repaintAll, false);
diff --git a/server/src/com/vaadin/server/communication/UidlWriter.java b/server/src/com/vaadin/server/communication/UidlWriter.java
index 9d55f7e197..3b2caba55b 100644
--- a/server/src/com/vaadin/server/communication/UidlWriter.java
+++ b/server/src/com/vaadin/server/communication/UidlWriter.java
@@ -27,9 +27,6 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.annotations.JavaScript;
import com.vaadin.annotations.StyleSheet;
import com.vaadin.server.ClientConnector;
@@ -43,6 +40,10 @@ import com.vaadin.shared.ApplicationConstants;
import com.vaadin.ui.ConnectorTracker;
import com.vaadin.ui.UI;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.impl.JsonUtil;
+
/**
* Serializes pending server-side changes to UI state to JSON. This includes
* shared state, client RPC invocations, connector hierarchy changes, connector
@@ -70,11 +71,9 @@ public class UidlWriter implements Serializable {
*
* @throws IOException
* If the writing fails.
- * @throws JSONException
- * If the JSON serialization fails.
*/
public void write(UI ui, Writer writer, boolean repaintAll, boolean async)
- throws IOException, JSONException {
+ throws IOException {
VaadinSession session = ui.getSession();
VaadinService service = session.getService();
@@ -282,13 +281,13 @@ public class UidlWriter implements Serializable {
// Include script dependencies in output if there are any
if (!scriptDependencies.isEmpty()) {
writer.write(", \"scriptDependencies\": "
- + new JSONArray(scriptDependencies).toString());
+ + JsonUtil.stringify(toJsonArray(scriptDependencies)));
}
// Include style dependencies in output if there are any
if (!styleDependencies.isEmpty()) {
writer.write(", \"styleDependencies\": "
- + new JSONArray(styleDependencies).toString());
+ + JsonUtil.stringify(toJsonArray(styleDependencies)));
}
session.getDragAndDropService().printJSONResponse(writer);
@@ -306,6 +305,15 @@ public class UidlWriter implements Serializable {
}
}
+ private JsonArray toJsonArray(List<String> list) {
+ JsonArray result = Json.createArray();
+ for (int i = 0; i < list.size(); i++) {
+ result.set(i, list.get(i));
+ }
+
+ return result;
+ }
+
/**
* Adds the performance timing data (used by TestBench 3) to the UIDL
* response.
diff --git a/server/src/com/vaadin/ui/Button.java b/server/src/com/vaadin/ui/Button.java
index 58b6f9de81..76b82aa034 100644
--- a/server/src/com/vaadin/ui/Button.java
+++ b/server/src/com/vaadin/ui/Button.java
@@ -19,8 +19,6 @@ package com.vaadin.ui;
import java.io.Serializable;
import java.lang.reflect.Method;
-import org.json.JSONException;
-
import com.vaadin.event.Action;
import com.vaadin.event.FieldEvents;
import com.vaadin.event.FieldEvents.BlurEvent;
@@ -63,12 +61,8 @@ public class Button extends AbstractComponent implements
// Makes sure the enabled=false state is noticed at once - otherwise
// a following setEnabled(true) call might have no effect. see
// ticket #10030
- try {
- getUI().getConnectorTracker().getDiffState(Button.this)
- .put("enabled", false);
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
+ getUI().getConnectorTracker().getDiffState(Button.this)
+ .put("enabled", false);
}
};
diff --git a/server/src/com/vaadin/ui/CheckBox.java b/server/src/com/vaadin/ui/CheckBox.java
index 3c4ce1c528..7d9da30f29 100644
--- a/server/src/com/vaadin/ui/CheckBox.java
+++ b/server/src/com/vaadin/ui/CheckBox.java
@@ -16,8 +16,6 @@
package com.vaadin.ui;
-import org.json.JSONException;
-
import com.vaadin.data.Property;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
@@ -47,12 +45,8 @@ public class CheckBox extends AbstractField<Boolean> {
*
* See #11028, #10030.
*/
- try {
- getUI().getConnectorTracker().getDiffState(CheckBox.this)
- .put("checked", checked);
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
+ getUI().getConnectorTracker().getDiffState(CheckBox.this)
+ .put("checked", checked);
final Boolean oldValue = getValue();
final Boolean newValue = checked;
diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java
index 9b8729f779..5386eb9d64 100644
--- a/server/src/com/vaadin/ui/ConnectorTracker.java
+++ b/server/src/com/vaadin/ui/ConnectorTracker.java
@@ -30,9 +30,6 @@ import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.AbstractClientConnector;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.DragAndDropService;
@@ -40,6 +37,10 @@ import com.vaadin.server.GlobalResourceHandler;
import com.vaadin.server.LegacyCommunicationManager;
import com.vaadin.server.StreamVariable;
+import elemental.json.Json;
+import elemental.json.JsonException;
+import elemental.json.JsonObject;
+
/**
* A class which takes care of book keeping of {@link ClientConnector}s for a
* UI.
@@ -76,7 +77,7 @@ public class ConnectorTracker implements Serializable {
private boolean writingResponse = false;
private UI uI;
- private transient Map<ClientConnector, JSONObject> diffStates = new HashMap<ClientConnector, JSONObject>();
+ private transient Map<ClientConnector, JsonObject> diffStates = new HashMap<ClientConnector, JsonObject>();
/** Maps connectorIds to a map of named StreamVariables */
private Map<String, Map<String, StreamVariable>> pidToNameToStreamVariable;
@@ -556,12 +557,12 @@ public class ConnectorTracker implements Serializable {
return dirtyVisibleConnectors;
}
- public JSONObject getDiffState(ClientConnector connector) {
+ public JsonObject getDiffState(ClientConnector connector) {
assert getConnector(connector.getConnectorId()) == connector;
return diffStates.get(connector);
}
- public void setDiffState(ClientConnector connector, JSONObject diffState) {
+ public void setDiffState(ClientConnector connector, JsonObject diffState) {
assert getConnector(connector.getConnectorId()) == connector;
diffStates.put(connector, diffState);
}
@@ -621,11 +622,11 @@ public class ConnectorTracker implements Serializable {
this.writingResponse = writingResponse;
}
- /* Special serialization to JSONObjects which are not serializable */
+ /* Special serialization to JsonObjects which are not serializable */
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
- // Convert JSONObjects in diff state to String representation as
- // JSONObject is not serializable
+ // Convert JsonObjects in diff state to String representation as
+ // JsonObject is not serializable
HashMap<ClientConnector, String> stringDiffStates = new HashMap<ClientConnector, String>(
diffStates.size() * 2);
for (ClientConnector key : diffStates.keySet()) {
@@ -634,23 +635,23 @@ public class ConnectorTracker implements Serializable {
out.writeObject(stringDiffStates);
}
- /* Special serialization to JSONObjects which are not serializable */
+ /* Special serialization to JsonObjects which are not serializable */
private void readObject(java.io.ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();
- // Read String versions of JSONObjects and parse into JSONObjects as
- // JSONObject is not serializable
- diffStates = new HashMap<ClientConnector, JSONObject>();
+ // Read String versions of JsonObjects and parse into JsonObjects as
+ // JsonObject is not serializable
+ diffStates = new HashMap<ClientConnector, JsonObject>();
@SuppressWarnings("unchecked")
HashMap<ClientConnector, String> stringDiffStates = (HashMap<ClientConnector, String>) in
.readObject();
- diffStates = new HashMap<ClientConnector, JSONObject>(
+ diffStates = new HashMap<ClientConnector, JsonObject>(
stringDiffStates.size() * 2);
for (ClientConnector key : stringDiffStates.keySet()) {
try {
- diffStates.put(key, new JSONObject(stringDiffStates.get(key)));
- } catch (JSONException e) {
+ diffStates.put(key, Json.parse(stringDiffStates.get(key)));
+ } catch (JsonException e) {
throw new IOException(e);
}
}
diff --git a/server/src/com/vaadin/ui/JavaScript.java b/server/src/com/vaadin/ui/JavaScript.java
index 68c8c9a6e4..668ae67056 100644
--- a/server/src/com/vaadin/ui/JavaScript.java
+++ b/server/src/com/vaadin/ui/JavaScript.java
@@ -19,15 +19,15 @@ package com.vaadin.ui;
import java.util.HashMap;
import java.util.Map;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.server.AbstractExtension;
import com.vaadin.server.Page;
import com.vaadin.shared.communication.ServerRpc;
import com.vaadin.shared.extension.javascriptmanager.ExecuteJavaScriptRpc;
import com.vaadin.shared.extension.javascriptmanager.JavaScriptManagerState;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+
/**
* Provides access to JavaScript functionality in the web browser. To get an
* instance of JavaScript, either use Page.getJavaScript() or
@@ -43,7 +43,7 @@ public class JavaScript extends AbstractExtension {
// Can not be defined in client package as this JSONArray is not available
// in GWT
public interface JavaScriptCallbackRpc extends ServerRpc {
- public void call(String name, JSONArray arguments);
+ public void call(String name, JsonArray arguments);
}
/**
@@ -54,12 +54,12 @@ public class JavaScript extends AbstractExtension {
public JavaScript() {
registerRpc(new JavaScriptCallbackRpc() {
@Override
- public void call(String name, JSONArray arguments) {
+ public void call(String name, JsonArray arguments) {
JavaScriptFunction function = functions.get(name);
// TODO handle situation if name is not registered
try {
function.call(arguments);
- } catch (JSONException e) {
+ } catch (JsonException e) {
throw new IllegalArgumentException(e);
}
}
diff --git a/server/src/com/vaadin/ui/JavaScriptFunction.java b/server/src/com/vaadin/ui/JavaScriptFunction.java
index 2c026abd1a..c006a36d58 100644
--- a/server/src/com/vaadin/ui/JavaScriptFunction.java
+++ b/server/src/com/vaadin/ui/JavaScriptFunction.java
@@ -18,14 +18,12 @@ package com.vaadin.ui;
import java.io.Serializable;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.server.AbstractJavaScriptExtension;
+import elemental.json.JsonArray;
/**
* Defines a method that is called by a client-side JavaScript function. When
- * the corresponding JavaScript function is called, the {@link #call(JSONArray)}
+ * the corresponding JavaScript function is called, the {@link #call(JsonArray)}
* method is invoked.
*
* @see JavaScript#addFunction(String, JavaScriptCallback)
@@ -46,8 +44,6 @@ public interface JavaScriptFunction extends Serializable {
* @param arguments
* an array with JSON representations of the arguments with which
* the JavaScript function was called.
- * @throws JSONException
- * if the arguments can not be interpreted
*/
- public void call(JSONArray arguments) throws JSONException;
+ public void call(JsonArray arguments);
}
diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/com/vaadin/ui/Slider.java
index ff6c955e47..66ed1a48f4 100644
--- a/server/src/com/vaadin/ui/Slider.java
+++ b/server/src/com/vaadin/ui/Slider.java
@@ -16,8 +16,6 @@
package com.vaadin.ui;
-import org.json.JSONException;
-
import com.vaadin.shared.ui.slider.SliderOrientation;
import com.vaadin.shared.ui.slider.SliderServerRpc;
import com.vaadin.shared.ui.slider.SliderState;
@@ -42,12 +40,8 @@ public class Slider extends AbstractField<Double> {
*
* See #12133.
*/
- try {
- getUI().getConnectorTracker().getDiffState(Slider.this)
- .put("value", value);
- } catch (JSONException e) {
- throw new RuntimeException(e);
- }
+ getUI().getConnectorTracker().getDiffState(Slider.this)
+ .put("value", value);
try {
setValue(value, true);
diff --git a/server/src/com/vaadin/ui/TabSheet.java b/server/src/com/vaadin/ui/TabSheet.java
index 8b13ecf1a4..0e4ea0d034 100644
--- a/server/src/com/vaadin/ui/TabSheet.java
+++ b/server/src/com/vaadin/ui/TabSheet.java
@@ -193,6 +193,9 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
@Override
public void removeComponent(Component component) {
if (component != null && components.contains(component)) {
+
+ int componentIndex = components.indexOf(component);
+
super.removeComponent(component);
keyMapper.remove(component);
components.remove(component);
@@ -206,6 +209,24 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
if (components.isEmpty()) {
setSelected(null);
} else {
+
+ int newSelectedIndex = selectedTabIndexAfterTabRemove(componentIndex);
+
+ // Make sure the component actually exists, in case someone
+ // override it and provide a non existing component.
+ if (0 <= newSelectedIndex
+ && newSelectedIndex < components.size()) {
+
+ Component newSelectedComponent = components
+ .get(newSelectedIndex);
+
+ // Select only if the tab is enabled.
+ Tab newSelectedTab = tabs.get(newSelectedComponent);
+ if (newSelectedTab.isEnabled()) {
+ setSelected(newSelectedComponent);
+ }
+ }
+
// select the first enabled and visible tab, if any
updateSelection();
fireSelectedTabChange();
@@ -216,6 +237,40 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
}
/**
+ * Called when a selected tab is removed to specify the new tab to select.
+ * Can be overridden to provide another algorithm that calculates the new
+ * selection.
+ *
+ * Current implementation will choose the first enabled tab to the right of
+ * the removed tab if it's not the last one, otherwise will choose the
+ * closer enabled tab to the left.
+ *
+ * @since
+ * @param removedTabIndex
+ * the index of the selected tab which was just remove.
+ * @return the index of the tab to be selected or -1 if there are no more
+ * enabled tabs to select.
+ */
+ protected int selectedTabIndexAfterTabRemove(int removedTabIndex) {
+
+ for (int i = removedTabIndex; i < components.size(); i++) {
+ Tab tab = getTab(i);
+ if (tab.isEnabled()) {
+ return i;
+ }
+ }
+
+ for (int i = removedTabIndex - 1; i >= 0; i--) {
+ Tab tab = getTab(i);
+ if (tab.isEnabled()) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
* Removes a {@link Tab} and the component associated with it, as previously
* added with {@link #addTab(Component)},
* {@link #addTab(Component, String, Resource)} or
diff --git a/server/src/com/vaadin/ui/components/grid/Grid.java b/server/src/com/vaadin/ui/components/grid/Grid.java
index f6a1231f43..962ea8f499 100644
--- a/server/src/com/vaadin/ui/components/grid/Grid.java
+++ b/server/src/com/vaadin/ui/components/grid/Grid.java
@@ -27,9 +27,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.thirdparty.guava.common.collect.Sets.SetView;
import com.vaadin.data.Container;
@@ -68,6 +65,9 @@ import com.vaadin.ui.components.grid.sort.Sort;
import com.vaadin.ui.components.grid.sort.SortOrder;
import com.vaadin.util.ReflectTools;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+
/**
* A grid component for displaying tabular data.
* <p>
@@ -303,19 +303,18 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier,
ignoreSelectionClientSync--;
markAsDirty = false;
- try {
-
- /*
- * Make sure that the diffstate is aware of the
- * "undirty" modification, so that the diffs are
- * calculated correctly the next time we actually want
- * to send the selection state to the client.
- */
- getUI().getConnectorTracker().getDiffState(Grid.this)
- .put("selectedKeys", new JSONArray(keys));
- } catch (JSONException e) {
- throw new RuntimeException("Internal error", e);
+ /*
+ * Make sure that the diffstate is aware of the "undirty"
+ * modification, so that the diffs are calculated correctly
+ * the next time we actually want to send the selection
+ * state to the client.
+ */
+ JsonArray jsonKeys = Json.createArray();
+ for (int i = 0; i < keys.size(); ++i) {
+ jsonKeys.set(i, keys.get(i));
}
+ getUI().getConnectorTracker().getDiffState(Grid.this)
+ .put("selectedKeys", jsonKeys);
}
getState(markAsDirty).selectedKeys = keys;
diff --git a/server/src/com/vaadin/ui/components/grid/Renderer.java b/server/src/com/vaadin/ui/components/grid/Renderer.java
index b9074fb9f7..33bac2ccff 100644
--- a/server/src/com/vaadin/ui/components/grid/Renderer.java
+++ b/server/src/com/vaadin/ui/components/grid/Renderer.java
@@ -18,6 +18,8 @@ package com.vaadin.ui.components.grid;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.Extension;
+import elemental.json.JsonValue;
+
/**
* A ClientConnector for controlling client-side
* {@link com.vaadin.client.ui.grid.Renderer Grid renderers}. Renderers
@@ -41,17 +43,13 @@ public interface Renderer<T> extends Extension {
Class<T> getPresentationType();
/**
- * Encodes the given value into a form that can be transferred to the
- * client. The type of the returned value must be one of the types that are
- * accepted by <a href=
- * "http://www.json.org/javadoc/org/json/JSONObject.html#put%28java.lang.String,%20java.lang.Object%29"
- * >{@code org.json.JSONObject#put(String, Object)}</a>.
+ * Encodes the given value into a {@link JsonValue}.
*
* @param value
* the value to encode
* @return an encoded form of the given value
*/
- Object encode(T value);
+ JsonValue encode(T value);
/**
* This method is inherited from Extension but should never be called
diff --git a/server/src/com/vaadin/ui/components/grid/renderers/DateRenderer.java b/server/src/com/vaadin/ui/components/grid/renderers/DateRenderer.java
index 736b61d9e2..aeb653ae27 100644
--- a/server/src/com/vaadin/ui/components/grid/renderers/DateRenderer.java
+++ b/server/src/com/vaadin/ui/components/grid/renderers/DateRenderer.java
@@ -21,6 +21,9 @@ import java.util.Locale;
import com.vaadin.ui.components.grid.AbstractRenderer;
+import elemental.json.Json;
+import elemental.json.JsonValue;
+
/**
* A renderer for presenting date values.
*
@@ -130,11 +133,11 @@ public class DateRenderer extends AbstractRenderer<Date> {
}
@Override
- public String encode(Date value) {
+ public JsonValue encode(Date value) {
if (dateFormat != null) {
- return dateFormat.format(value);
+ return Json.create(dateFormat.format(value));
} else {
- return String.format(locale, formatString, value);
+ return Json.create(String.format(locale, formatString, value));
}
}
diff --git a/server/src/com/vaadin/ui/components/grid/renderers/HtmlRenderer.java b/server/src/com/vaadin/ui/components/grid/renderers/HtmlRenderer.java
index 6439608c20..acbe4a69e7 100644
--- a/server/src/com/vaadin/ui/components/grid/renderers/HtmlRenderer.java
+++ b/server/src/com/vaadin/ui/components/grid/renderers/HtmlRenderer.java
@@ -17,6 +17,9 @@ package com.vaadin.ui.components.grid.renderers;
import com.vaadin.ui.components.grid.AbstractRenderer;
+import elemental.json.Json;
+import elemental.json.JsonValue;
+
/**
* A renderer for presenting HTML content.
*
@@ -32,7 +35,7 @@ public class HtmlRenderer extends AbstractRenderer<String> {
}
@Override
- public String encode(String value) {
- return value;
+ public JsonValue encode(String value) {
+ return Json.create(value);
}
}
diff --git a/server/src/com/vaadin/ui/components/grid/renderers/NumberRenderer.java b/server/src/com/vaadin/ui/components/grid/renderers/NumberRenderer.java
index 12fcfc890a..0f4619c180 100644
--- a/server/src/com/vaadin/ui/components/grid/renderers/NumberRenderer.java
+++ b/server/src/com/vaadin/ui/components/grid/renderers/NumberRenderer.java
@@ -20,6 +20,9 @@ import java.util.Locale;
import com.vaadin.ui.components.grid.AbstractRenderer;
+import elemental.json.Json;
+import elemental.json.JsonValue;
+
/**
* A renderer for presenting number values.
*
@@ -131,11 +134,11 @@ public class NumberRenderer extends AbstractRenderer<Number> {
}
@Override
- public String encode(Number value) {
+ public JsonValue encode(Number value) {
if (formatString != null && locale != null) {
- return String.format(locale, formatString, value);
+ return Json.create(String.format(locale, formatString, value));
} else if (numberFormat != null) {
- return numberFormat.format(value);
+ return Json.create(numberFormat.format(value));
} else {
throw new IllegalStateException(String.format("Internal bug: "
+ "%s is in an illegal state: "
diff --git a/server/src/com/vaadin/ui/components/grid/renderers/TextRenderer.java b/server/src/com/vaadin/ui/components/grid/renderers/TextRenderer.java
index 61348a9e49..26fc226cfa 100644
--- a/server/src/com/vaadin/ui/components/grid/renderers/TextRenderer.java
+++ b/server/src/com/vaadin/ui/components/grid/renderers/TextRenderer.java
@@ -17,6 +17,9 @@ package com.vaadin.ui.components.grid.renderers;
import com.vaadin.ui.components.grid.AbstractRenderer;
+import elemental.json.Json;
+import elemental.json.JsonValue;
+
/**
* A renderer for presenting simple plain-text string values.
*
@@ -33,7 +36,7 @@ public class TextRenderer extends AbstractRenderer<String> {
}
@Override
- public Object encode(String value) {
- return value;
+ public JsonValue encode(String value) {
+ return Json.create(value);
}
}
diff --git a/server/src/com/vaadin/ui/themes/ValoTheme.java b/server/src/com/vaadin/ui/themes/ValoTheme.java
index d6bd97ed72..da80375114 100644
--- a/server/src/com/vaadin/ui/themes/ValoTheme.java
+++ b/server/src/com/vaadin/ui/themes/ValoTheme.java
@@ -566,7 +566,7 @@ public class ValoTheme {
* Make the progress bar indicator appear as a dot which progresses over the
* progress bar track (instead of a growing bar).
*/
- public static final String PROBRESSBAR_POINT = "point";
+ public static final String PROGRESSBAR_POINT = "point";
/***************************************************************************
*
diff --git a/server/tests/src/com/vaadin/server/JSONSerializerTest.java b/server/tests/src/com/vaadin/server/JSONSerializerTest.java
index 8c1967acb3..393cea1c4c 100644
--- a/server/tests/src/com/vaadin/server/JSONSerializerTest.java
+++ b/server/tests/src/com/vaadin/server/JSONSerializerTest.java
@@ -15,8 +15,8 @@ package com.vaadin.server;
* License for the specific language governing permissions and limitations under
* the License.
*/
+
import java.lang.reflect.Type;
-import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -24,14 +24,15 @@ import java.util.Map;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.JsonCodec.BeanProperty;
import com.vaadin.shared.communication.UidlValue;
import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+import elemental.json.JsonValue;
+
/**
* Tests for {@link JsonCodec}
*
@@ -56,7 +57,7 @@ public class JSONSerializerTest extends TestCase {
stringToStateMap.put("string - state 1", s);
stringToStateMap.put("String - state 2", s2);
- Object encodedMap = JsonCodec.encode(stringToStateMap, null, mapType,
+ JsonValue encodedMap = JsonCodec.encode(stringToStateMap, null, mapType,
null).getEncodedValue();
ensureDecodedCorrectly(stringToStateMap, encodedMap, mapType);
@@ -73,15 +74,16 @@ public class JSONSerializerTest extends TestCase {
stateToStringMap.put(s, "string - state 1");
stateToStringMap.put(s2, "String - state 2");
- Object encodedMap = JsonCodec.encode(stateToStringMap, null, mapType,
+ JsonValue encodedMap = JsonCodec.encode(stateToStringMap, null, mapType,
null).getEncodedValue();
ensureDecodedCorrectly(stateToStringMap, encodedMap, mapType);
}
- public void testNullLegacyValue() throws JSONException {
- JSONArray inputArray = new JSONArray(
- Arrays.asList("n", JSONObject.NULL));
+ public void testNullLegacyValue() throws JsonException {
+ JsonArray inputArray = Json.createArray();
+ inputArray.set(0, "n");
+ inputArray.set(1, Json.createNull());
UidlValue decodedObject = (UidlValue) JsonCodec.decodeInternalType(
UidlValue.class, true, inputArray, null);
assertNull(decodedObject.getValue());
@@ -89,17 +91,19 @@ public class JSONSerializerTest extends TestCase {
public void testNullTypeOtherValue() {
try {
- JSONArray inputArray = new JSONArray(Arrays.asList("n", "a"));
+ JsonArray inputArray = Json.createArray();
+ inputArray.set(0, "n");
+ inputArray.set(1, "a");
UidlValue decodedObject = (UidlValue) JsonCodec.decodeInternalType(
UidlValue.class, true, inputArray, null);
- throw new AssertionFailedError("No JSONException thrown");
- } catch (JSONException e) {
+ throw new AssertionFailedError("No JsonException thrown");
+ } catch (JsonException e) {
// Should throw exception
}
}
- private void ensureDecodedCorrectly(Object original, Object encoded,
+ private void ensureDecodedCorrectly(Object original, JsonValue encoded,
Type type) throws Exception {
Object serverSideDecoded = JsonCodec.decodeInternalOrCustomType(type,
encoded, null);
diff --git a/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java b/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java
index 30f1c85fef..214341371a 100644
--- a/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java
+++ b/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java
@@ -22,7 +22,6 @@ import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import org.easymock.EasyMock;
-import org.json.JSONException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -37,6 +36,7 @@ import com.vaadin.server.communication.ServerRpcHandler.RpcRequest;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.tests.util.AlwaysLockedVaadinSession;
import com.vaadin.tests.util.MockDeploymentConfiguration;
+import elemental.json.JsonException;
/**
* Test the actual csrf token validation by the server.
@@ -141,7 +141,7 @@ public class CsrfTokenMissingTestServer {
private RpcRequest createRequest() {
try {
return new RpcRequest(getPayload(), vaadinRequest);
- } catch (JSONException e) {
+ } catch (JsonException e) {
LOGGER.log(Level.SEVERE, "", e);
Assert.assertTrue(false);
diff --git a/server/tests/src/com/vaadin/tests/server/TestClientMethodSerialization.java b/server/tests/src/com/vaadin/tests/server/TestClientMethodSerialization.java
index 41b71a37fa..ad70024af4 100644
--- a/server/tests/src/com/vaadin/tests/server/TestClientMethodSerialization.java
+++ b/server/tests/src/com/vaadin/tests/server/TestClientMethodSerialization.java
@@ -21,22 +21,23 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
-import java.util.Arrays;
import junit.framework.TestCase;
-import org.json.JSONArray;
-
import com.vaadin.server.ClientMethodInvocation;
import com.vaadin.server.JavaScriptCallbackHelper;
import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc;
import com.vaadin.util.ReflectTools;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.impl.JsonUtil;
+
public class TestClientMethodSerialization extends TestCase {
private static final Method JAVASCRIPT_CALLBACK_METHOD = ReflectTools
.findMethod(JavaScriptCallbackRpc.class, "call", String.class,
- JSONArray.class);
+ JsonArray.class);
private static final Method BASIC_PARAMS_CALL_METHOD = ReflectTools
.findMethod(TestClientMethodSerialization.class,
@@ -60,15 +61,17 @@ public class TestClientMethodSerialization extends TestCase {
*/
public void testClientMethodSerialization_WithJSONArray_ContentStaysSame()
throws Exception {
- JSONArray originalArray = new JSONArray(Arrays.asList(
- "callbackParameter1", "callBackParameter2", "12345"));
+ JsonArray originalArray = Json.createArray();
+ originalArray.set(0, "callbackParameter1");
+ originalArray.set(1, "callBackParameter2");
+ originalArray.set(2, "12345");
ClientMethodInvocation original = new ClientMethodInvocation(null,
"interfaceName", JAVASCRIPT_CALLBACK_METHOD, new Object[] {
"callBackMethodName", originalArray });
ClientMethodInvocation copy = (ClientMethodInvocation) serializeAndDeserialize(original);
- JSONArray copyArray = (JSONArray) copy.getParameters()[1];
- assertEquals(originalArray.toString(), copyArray.toString());
+ JsonArray copyArray = (JsonArray) copy.getParameters()[1];
+ assertEquals(JsonUtil.stringify(originalArray), JsonUtil.stringify(copyArray));
}
public void testClientMethodSerialization_WithBasicParams_NoChanges()
diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/RendererTest.java b/server/tests/src/com/vaadin/tests/server/component/grid/RendererTest.java
index 5583fc02e8..54d15f15d8 100644
--- a/server/tests/src/com/vaadin/tests/server/component/grid/RendererTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/grid/RendererTest.java
@@ -36,6 +36,9 @@ import com.vaadin.ui.components.grid.Grid;
import com.vaadin.ui.components.grid.GridColumn;
import com.vaadin.ui.components.grid.renderers.TextRenderer;
+import elemental.json.Json;
+import elemental.json.JsonValue;
+
public class RendererTest {
private static class TestBean {
@@ -48,8 +51,9 @@ public class RendererTest {
private static class TestRenderer extends TextRenderer {
@Override
- public Object encode(String value) {
- return "renderer(" + super.encode(value) + ")";
+ public JsonValue encode(String value) {
+ return Json.create("renderer(" + super.encode(value).asString()
+ + ")");
}
}
@@ -156,13 +160,13 @@ public class RendererTest {
@Test
public void testEncoding() throws Exception {
- assertEquals("42", render(foo, 42));
+ assertEquals("42", render(foo, 42).asString());
foo.setRenderer(renderer());
- assertEquals("renderer(42)", render(foo, 42));
+ assertEquals("renderer(42)", render(foo, 42).asString());
- assertEquals("2.72", render(bar, "2.72"));
+ assertEquals("2.72", render(bar, "2.72").asString());
bar.setRenderer(new TestRenderer());
- assertEquals("renderer(2.72)", render(bar, "2.72"));
+ assertEquals("renderer(2.72)", render(bar, "2.72").asString());
}
@Test(expected = ConversionException.class)
@@ -175,12 +179,13 @@ public class RendererTest {
baz.setRenderer(renderer(), converter());
bah.setRenderer(renderer(), converter());
- assertEquals("renderer(TestBean(42))", render(baz, new TestBean()));
+ assertEquals("renderer(TestBean(42))", render(baz, new TestBean())
+ .asString());
assertEquals("renderer(ExtendedBean(42, 3.14))",
- render(baz, new ExtendedBean()));
+ render(baz, new ExtendedBean()).asString());
assertEquals("renderer(ExtendedBean(42, 3.14))",
- render(bah, new ExtendedBean()));
+ render(bah, new ExtendedBean()).asString());
}
private TestConverter converter() {
@@ -191,7 +196,7 @@ public class RendererTest {
return new TestRenderer();
}
- private Object render(GridColumn column, Object value) {
+ private JsonValue render(GridColumn column, Object value) {
return RpcDataProviderExtension.encodeValue(value,
column.getRenderer(), column.getConverter(), grid.getLocale());
}
diff --git a/shared/ivy.xml b/shared/ivy.xml
index 2dac7adbc2..dcb7390c04 100644
--- a/shared/ivy.xml
+++ b/shared/ivy.xml
@@ -27,8 +27,6 @@
conf="build,ide,test->default" />
<dependency org="com.vaadin.external.google" name="guava"
rev="16.0.1.vaadin1" conf="build,ide,test->default" />
- <dependency org="com.vaadin.external.json" name="json"
- rev="0.0.20080701" conf="build,ide,test->default" />
<dependency org="junit" name="junit" rev="4.11"
conf="test,ide -> default" />
diff --git a/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java b/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java
index b96a1c9b79..98a1d2b87f 100644
--- a/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java
+++ b/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetState.java
@@ -16,6 +16,7 @@
package com.vaadin.shared.ui.tabsheet;
import java.util.ArrayList;
+import java.util.List;
import com.vaadin.shared.AbstractComponentState;
@@ -32,7 +33,7 @@ public class TabsheetState extends AbstractComponentState {
*/
public int tabIndex;
- public ArrayList<TabState> tabs = new ArrayList<TabState>();
+ public List<TabState> tabs = new ArrayList<TabState>();
/** true to show the tab bar, false to only show the contained component */
public boolean tabsVisible = true;
diff --git a/uitest/src/com/vaadin/tests/components/LayoutAttachListenerInfo.java b/uitest/src/com/vaadin/tests/components/LayoutAttachListenerInfo.java
index b815705883..e118558528 100644
--- a/uitest/src/com/vaadin/tests/components/LayoutAttachListenerInfo.java
+++ b/uitest/src/com/vaadin/tests/components/LayoutAttachListenerInfo.java
@@ -122,6 +122,7 @@ public class LayoutAttachListenerInfo extends TestBase {
final GridLayout g = new GridLayout(4, 4);
g.setWidth("300px");
g.setHeight("300px");
+ g.setHideEmptyRowsAndColumns(true);
g.addComponentAttachListener(new ComponentAttachListener() {
@Override
public void componentAttachedToContainer(ComponentAttachEvent event) {
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarNotifications.html b/uitest/src/com/vaadin/tests/components/calendar/CalendarNotifications.html
deleted file mode 100644
index 15bf29a0fd..0000000000
--- a/uitest/src/com/vaadin/tests/components/calendar/CalendarNotifications.html
+++ /dev/null
@@ -1,41 +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="http://localhost:8080/" />
-<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.calendar.NotificationTestUI?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestscomponentscalendarNotificationTestUI::/VGridLayout[0]/VCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
- <td>83,11</td>
-</tr>
-<tr>
- <td>mouseMove</td>
- <td>vaadin=runcomvaadintestscomponentscalendarNotificationTestUI::/VGridLayout[0]/VCalendar[0]/domChild[0]/domChild[1]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[3]/domChild[0]/domChild[3]</td>
- <td>10,10</td>
-</tr>
-<tr>
- <td>closeNotification</td>
- <td>//div[@id='runcomvaadintestscomponentscalendarNotificationTestUI-1842310749-overlays']/div</td>
- <td>0,0</td>
-</tr>
-<tr>
- <td>screenCapture</td>
- <td></td>
- <td>no-notification</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarNotifications.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarNotifications.java
new file mode 100644
index 0000000000..9b9a64624a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarNotifications.java
@@ -0,0 +1,116 @@
+/*
+ * 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.calendar;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Calendar;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickEvent;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.DateClickHandler;
+import com.vaadin.ui.components.calendar.event.BasicEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEventProvider;
+
+public class CalendarNotifications extends AbstractTestUIWithLog {
+
+ private DummyEventProvider provider;
+
+ private static class DummyEventProvider implements CalendarEventProvider {
+
+ private int index;
+ private List<CalendarEvent> events = new ArrayList<CalendarEvent>();
+
+ public void addEvent(Date date) {
+ BasicEvent e = new BasicEvent();
+ e.setAllDay(true);
+ e.setStart(date);
+ e.setEnd(date);
+ e.setCaption("Some event " + ++index);
+ events.add(e);
+ }
+
+ @Override
+ public List<CalendarEvent> getEvents(Date startDate, Date endDate) {
+ return events;
+ }
+
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ GridLayout content = new GridLayout(1, 2);
+ content.setSizeFull();
+ content.setRowExpandRatio(1, 1.0f);
+ addComponent(content);
+ final Button btn = new Button("Show working notification",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ Notification
+ .show("This will disappear when you move your mouse!");
+ }
+ });
+ content.addComponent(btn);
+
+ provider = new DummyEventProvider();
+ final Calendar cal = new Calendar(provider);
+ cal.setLocale(Locale.US);
+ cal.setSizeFull();
+ cal.setHandler(new DateClickHandler() {
+ @Override
+ public void dateClick(DateClickEvent event) {
+ provider.addEvent(event.getDate());
+ log("Opening a notification");
+ Notification
+ .show("This should disappear when the mouse is moved.");
+
+ // this requestRepaint call interferes with the notification
+ cal.markAsDirty();
+ }
+ });
+ content.addComponent(cal);
+
+ java.util.Calendar javaCal = java.util.Calendar.getInstance();
+ javaCal.set(java.util.Calendar.YEAR, 2000);
+ javaCal.set(java.util.Calendar.MONTH, 0);
+ javaCal.set(java.util.Calendar.DAY_OF_MONTH, 1);
+ Date start = javaCal.getTime();
+ javaCal.set(java.util.Calendar.DAY_OF_MONTH, 31);
+ Date end = javaCal.getTime();
+
+ cal.setStartDate(start);
+ cal.setEndDate(end);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Notifications should be opened and then closed after the user has moved the mouse.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 6769;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarNotificationsTest.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarNotificationsTest.java
new file mode 100644
index 0000000000..2431b2f4d0
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarNotificationsTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.calendar;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.NotificationElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Tests opening and closing of calendar notifications.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class CalendarNotificationsTest extends MultiBrowserTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return NotificationTestUI.class;
+ }
+
+ @Override
+ protected DesiredCapabilities getDesiredCapabilities() {
+ DesiredCapabilities desiredCapabilities = new DesiredCapabilities(
+ super.getDesiredCapabilities());
+ desiredCapabilities.setCapability("enablePersistentHover", false);
+ desiredCapabilities.setCapability("requireWindowFocus", true);
+
+ return desiredCapabilities;
+ }
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ // TODO: IE testing is pending on #14312. For now, IE testing is handled
+ // with a logger.
+ return getBrowsersExcludingIE();
+ }
+
+ @Test
+ public void notificationTest() throws Exception {
+ openTestURL();
+
+ WebElement day = findElements(By.className("v-calendar-day-number"))
+ .get(2);
+ // IE8 requires you to click on the text part to fire the event
+ new Actions(getDriver()).moveToElement(day, 83, 11).click().perform();
+
+ Assert.assertTrue("There should be a notification",
+ $(NotificationElement.class).exists());
+
+ // move the mouse around a bit
+ new Actions(getDriver()).moveByOffset(5, 5).moveByOffset(100, 100)
+ .perform();
+
+ // wait until the notification has animated out
+ sleep(1000);
+
+ Assert.assertFalse("There should be no notification on the page",
+ $(NotificationElement.class).exists());
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarNotificationsTestIE.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarNotificationsTestIE.java
new file mode 100644
index 0000000000..7ab6f01113
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarNotificationsTestIE.java
@@ -0,0 +1,91 @@
+/*
+ * 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.calendar;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.NotificationElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Tests opening and closing of calendar notifications.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class CalendarNotificationsTestIE extends MultiBrowserTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return CalendarNotifications.class;
+ }
+
+ @Override
+ protected DesiredCapabilities getDesiredCapabilities() {
+ DesiredCapabilities desiredCapabilities = new DesiredCapabilities(
+ super.getDesiredCapabilities());
+ desiredCapabilities.setCapability("enablePersistentHover", false);
+ desiredCapabilities.setCapability("requireWindowFocus", true);
+
+ return desiredCapabilities;
+ }
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ List<DesiredCapabilities> browsers = super.getBrowsersToTest();
+ browsers.remove(Browser.CHROME.getDesiredCapabilities());
+ browsers.remove(Browser.FIREFOX.getDesiredCapabilities());
+ browsers.remove(Browser.OPERA.getDesiredCapabilities());
+ browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities());
+ browsers.remove(Browser.SAFARI.getDesiredCapabilities());
+ return browsers;
+ }
+
+ @Test
+ public void notificationTest() throws Exception {
+ openTestURL();
+
+ WebElement day = findElements(By.className("v-calendar-day-number"))
+ .get(2);
+ // IE8 requires you to click on the text part to fire the event
+ new Actions(getDriver()).moveToElement(day, 83, 11).click().perform();
+
+ // check that a notification was opened, this is done with a log instead
+ // of a screenshot or element presence check due to problems with IE
+ // webdriver
+ String text = findElement(By.id("Log")).findElement(
+ By.className("v-label")).getText();
+ Assert.assertTrue("Notification should've opened",
+ "1. Opening a notification".equals(text));
+
+ // move the mouse around a bit
+ new Actions(getDriver()).moveByOffset(5, 5).moveByOffset(100, 100)
+ .perform();
+
+ // wait until the notification has animated out
+ sleep(1000);
+
+ Assert.assertFalse("There should be no notification on the page",
+ $(NotificationElement.class).exists());
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarRescheduleEvent.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarRescheduleEvent.java
new file mode 100644
index 0000000000..824ad0941f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarRescheduleEvent.java
@@ -0,0 +1,105 @@
+/*
+ * 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.calendar;
+
+import java.util.Date;
+import java.util.List;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Calendar;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.components.calendar.event.BasicEvent;
+import com.vaadin.ui.components.calendar.event.BasicEventProvider;
+import com.vaadin.ui.components.calendar.event.CalendarEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEventProvider.EventSetChangeEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEventProvider.EventSetChangeListener;
+
+/**
+ * Test UI to check ability to reschedule events unlimited times.
+ *
+ * @author Vaadin Ltd
+ */
+public class CalendarRescheduleEvent extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final Calendar calendar = new Calendar("Test calendar");
+ final java.util.Calendar cal = getAdjustedCalendar(1);
+
+ Date from = cal.getTime();
+
+ cal.add(java.util.Calendar.HOUR, 1);
+ Date to = cal.getTime();
+
+ final BasicEvent basicEvent = new BasicEvent("event", "description",
+ from, to);
+
+ HorizontalLayout info = new HorizontalLayout();
+ info.setSpacing(true);
+ info.setMargin(true);
+ addComponent(info);
+ final Label startLbl = new Label();
+ startLbl.addStyleName("start");
+ info.addComponent(startLbl);
+
+ final Label endLbl = new Label();
+ endLbl.addStyleName("end");
+ info.addComponent(endLbl);
+
+ BasicEventProvider provider = new BasicEventProvider();
+ provider.addEvent(basicEvent);
+ calendar.setEventProvider(provider);
+ provider.addEventSetChangeListener(new EventSetChangeListener() {
+
+ @Override
+ public void eventSetChange(EventSetChangeEvent event) {
+ List<CalendarEvent> events = event.getProvider().getEvents(
+ new Date(0), new Date(Long.MAX_VALUE));
+ CalendarEvent calEvent = events.get(0);
+ Date startEvent = calEvent.getStart();
+ Date endEvent = calEvent.getEnd();
+
+ startLbl.setValue(String.valueOf(startEvent.getTime()));
+ endLbl.setValue(String.valueOf(endEvent.getTime()));
+ }
+ });
+
+ addComponent(calendar);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "It should be possible to reschedule events unlimited times.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 13233;
+ }
+
+ private java.util.Calendar getAdjustedCalendar(int hour) {
+ final java.util.Calendar cal = java.util.Calendar.getInstance();
+
+ cal.set(java.util.Calendar.HOUR_OF_DAY, hour);
+ cal.set(java.util.Calendar.MINUTE, 0);
+ cal.set(java.util.Calendar.SECOND, 0);
+ cal.set(java.util.Calendar.MILLISECOND, 0);
+ return cal;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarRescheduleEventTest.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarRescheduleEventTest.java
new file mode 100644
index 0000000000..fb8cce7d53
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarRescheduleEventTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.calendar;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.DndActionsTest;
+
+/**
+ * Test to check ability to reschedule events unlimited times.
+ *
+ * @author Vaadin Ltd
+ */
+public class CalendarRescheduleEventTest extends DndActionsTest {
+
+ @Test
+ public void rescheduleEventSeveralTimes() {
+ openTestURL();
+
+ // Reschedule event for the first time
+ int y = rescheduleEvent(20);
+
+ WebElement startElement = getDriver()
+ .findElement(By.className("start"));
+ WebElement endElement = getDriver().findElement(By.className("end"));
+
+ long start = Long.parseLong(startElement.getText());
+ long end = Long.parseLong(endElement.getText());
+
+ long duration = end - start;
+
+ // Reschedule event for the second time
+ int yNew = rescheduleEvent(20);
+
+ startElement = getDriver().findElement(By.className("start"));
+ endElement = getDriver().findElement(By.className("end"));
+
+ long newStart = Long.parseLong(startElement.getText());
+ long newEnd = Long.parseLong(endElement.getText());
+
+ Assert.assertTrue(
+ "Second rescheduling did not change the event start time",
+ newStart > start);
+ Assert.assertEquals(
+ "Duration of the event after second rescheduling has been changed",
+ duration, newEnd - newStart);
+ Assert.assertTrue(
+ "Second rescheduling did not change the event Y coordinate",
+ yNew > y);
+ }
+
+ /*
+ * DnD event by Y axis
+ */
+ private int rescheduleEvent(int yOffset) {
+ WebElement eventCaption = getDriver().findElement(
+ By.className("v-calendar-event-caption"));
+
+ dragAndDrop(eventCaption, 0, yOffset);
+
+ eventCaption = getDriver().findElement(
+ By.className("v-calendar-event-caption"));
+ return eventCaption.getLocation().getY();
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java
index f664149cce..e3e5606089 100644
--- a/uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java
@@ -24,15 +24,14 @@ import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
-import org.openqa.selenium.interactions.Actions;
-import com.vaadin.tests.tb3.MultiBrowserTest;
+import com.vaadin.tests.tb3.DndActionsTest;
/**
*
* @author Vaadin Ltd
*/
-public class CalendarResizeOverlappingEventsTest extends MultiBrowserTest {
+public class CalendarResizeOverlappingEventsTest extends DndActionsTest {
private int noOverlapWidth;
private int oneOverlapWidth;
@@ -100,23 +99,7 @@ public class CalendarResizeOverlappingEventsTest extends MultiBrowserTest {
}
private void dragAndDrop(WebElement element, int yOffset) {
- /*
- * Selenium doesn't properly drag and drop items in IE8. It tries to
- * start dragging an element from a position above the element itself.
- */
- if (BrowserUtil.isIE8(getDesiredCapabilities())) {
- Actions action = new Actions(getDriver());
- action.moveToElement(element);
- action.moveByOffset(0, 1);
- action.clickAndHold();
- action.moveByOffset(0, yOffset);
- action.release();
- action.build().perform();
- } else {
- Actions action = new Actions(getDriver());
- action.dragAndDropBy(element, 0, yOffset);
- action.build().perform();
- }
+ dragAndDrop(element, 0, yOffset);
}
private void initParams() {
diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopen.java b/uitest/src/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopen.java
new file mode 100644
index 0000000000..f65b020bd1
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopen.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.combobox;
+
+import java.util.ArrayList;
+
+import com.vaadin.server.Page;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.MenuBar;
+import com.vaadin.ui.MenuBar.MenuItem;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Notification.Type;
+
+/**
+ * Test UI for combobox popup which should be closed on any click outside it.
+ *
+ * @author Vaadin Ltd
+ */
+public class ComboboxMenuBarAutoopen extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ HorizontalLayout layout = new HorizontalLayout();
+ layout.setSpacing(true);
+ ArrayList<String> options = new ArrayList<String>();
+ options.add("1");
+ options.add("2");
+ options.add("3");
+ ComboBox combo = new ComboBox(null, options);
+ layout.addComponent(combo);
+
+ MenuBar menubar = getMenubar();
+ layout.addComponent(menubar);
+
+ addComponent(layout);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Combobox popup should close on click to other popup or associated components.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14321;
+ }
+
+ private MenuBar getMenubar() {
+ MenuBar menubar = new MenuBar();
+ menubar.setAutoOpen(true);
+ MenuItem item = menubar.addItem("auto-open", null);
+ item.addItem("sub-item 1", new MenuBar.Command() {
+
+ @Override
+ public void menuSelected(MenuItem selectedItem) {
+ Notification notification = new Notification("Test",
+ Type.HUMANIZED_MESSAGE);
+ notification.show(Page.getCurrent());
+ }
+ });
+ return menubar;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopenTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopenTest.java
new file mode 100644
index 0000000000..5c8c971194
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/combobox/ComboboxMenuBarAutoopenTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.combobox;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.testbench.elements.ComboBoxElement;
+import com.vaadin.testbench.elements.MenuBarElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Test that checks whether Combobox popup is closed on click to autoopen
+ * menubar and its item.
+ *
+ * @author Vaadin Ltd
+ */
+public class ComboboxMenuBarAutoopenTest extends MultiBrowserTest {
+
+ @Test
+ public void closeComboboxPopupOnClickToMenuBar() {
+ openTestURL();
+
+ openPopup();
+ MenuBarElement menuBar = selectMenuBar();
+ menuBar.click();
+ Assert.assertFalse("Combobox popup items are visible",
+ isElementPresent(By.className("gwt-MenuItem")));
+
+ openPopup();
+ menuBar = selectMenuBar();
+
+ WebElement menuBarItem = findElement(By
+ .className("v-menubar-menuitem-caption"));
+ Actions actions = new Actions(getDriver());
+ actions.moveToElement(menuBarItem).build().perform();
+ menuBar.click();
+ Assert.assertFalse("Combobox popup items are visible",
+ isElementPresent(By.className("gwt-MenuItem")));
+ }
+
+ private void openPopup() {
+ ComboBoxElement combobox = $(ComboBoxElement.class).first();
+ combobox.click();
+ combobox.openPopup();
+ combobox.focus();
+
+ Actions actions = new Actions(getDriver());
+ actions.moveToElement(
+ getDriver().findElement(By.className("gwt-MenuItem"))).build()
+ .perform();
+ }
+
+ private MenuBarElement selectMenuBar() {
+ MenuBarElement menuBar = $(MenuBarElement.class).first();
+ menuBar.focus();
+
+ Actions actions = new Actions(getDriver());
+ actions.moveToElement(menuBar).build().perform();
+
+ return menuBar;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/grid/IntArrayRenderer.java b/uitest/src/com/vaadin/tests/components/grid/IntArrayRenderer.java
index 142c370e13..ccedcc908a 100644
--- a/uitest/src/com/vaadin/tests/components/grid/IntArrayRenderer.java
+++ b/uitest/src/com/vaadin/tests/components/grid/IntArrayRenderer.java
@@ -15,22 +15,23 @@
*/
package com.vaadin.tests.components.grid;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.ui.components.grid.AbstractRenderer;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonValue;
+
public class IntArrayRenderer extends AbstractRenderer<int[]> {
public IntArrayRenderer() {
super(int[].class);
}
@Override
- public Object encode(int[] value) {
- try {
- return new JSONArray(value);
- } catch (JSONException e) {
- throw new RuntimeException(e);
+ public JsonValue encode(int[] value) {
+ JsonArray valueArray = Json.createArray();
+ for (int i = 0; i < value.length; ++i) {
+ valueArray.set(i, value[i]);
}
+ return valueArray;
}
}
diff --git a/uitest/src/com/vaadin/tests/components/grid/RowAwareRenderer.java b/uitest/src/com/vaadin/tests/components/grid/RowAwareRenderer.java
index f55f5f064c..41ccddc2cf 100644
--- a/uitest/src/com/vaadin/tests/components/grid/RowAwareRenderer.java
+++ b/uitest/src/com/vaadin/tests/components/grid/RowAwareRenderer.java
@@ -15,12 +15,13 @@
*/
package com.vaadin.tests.components.grid;
-import org.json.JSONObject;
-
import com.vaadin.tests.widgetset.client.grid.RowAwareRendererConnector.RowAwareRendererRpc;
import com.vaadin.ui.Label;
import com.vaadin.ui.components.grid.AbstractRenderer;
+import elemental.json.Json;
+import elemental.json.JsonValue;
+
public class RowAwareRenderer extends AbstractRenderer<Void> {
public RowAwareRenderer(final Label debugLabel) {
super(Void.class);
@@ -34,8 +35,8 @@ public class RowAwareRenderer extends AbstractRenderer<Void> {
}
@Override
- public Object encode(Void value) {
- return JSONObject.NULL;
+ public JsonValue encode(Void value) {
+ return Json.createNull();
}
}
diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacing.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacing.java
new file mode 100644
index 0000000000..ce59f9c89f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacing.java
@@ -0,0 +1,91 @@
+/*
+ * 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.gridlayout;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.GridLayout;
+
+public class GridLayoutExtraSpacing extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ getUI().getPage()
+ .getStyles()
+ .add(".v-gridlayout {background: red;} .v-csslayout {background: white;}");
+
+ final GridLayout gl = new GridLayout(4, 4);
+
+ final CheckBox cb = new CheckBox("spacing");
+ cb.addValueChangeListener(new ValueChangeListener() {
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ gl.setSpacing(cb.getValue());
+ }
+ });
+ cb.setValue(true);
+ addComponent(cb);
+
+ final CheckBox cb2 = new CheckBox("hide empty rows/columns");
+ cb2.addValueChangeListener(new ValueChangeListener() {
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ gl.setHideEmptyRowsAndColumns(cb2.getValue());
+ }
+ });
+ addComponent(cb2);
+ gl.setWidth("1000px");
+ gl.setHeight("500px");
+
+ CssLayout ta = new CssLayout();
+ ta.setSizeFull();
+ // Only on last row
+ gl.addComponent(ta, 0, 3, 3, 3);
+
+ gl.setRowExpandRatio(3, 1);
+ addComponent(gl);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription()
+ */
+ @Override
+ protected String getTestDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber()
+ */
+ @Override
+ protected Integer getTicketNumber() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacingTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacingTest.java
new file mode 100644
index 0000000000..64b9997dcc
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacingTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.gridlayout;
+
+import java.io.IOException;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.CheckBoxElement;
+import com.vaadin.testbench.elements.CssLayoutElement;
+import com.vaadin.testbench.elements.GridLayoutElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class GridLayoutExtraSpacingTest extends MultiBrowserTest {
+
+ @Test
+ public void componentRowFour() throws IOException, Exception {
+ openTestURL();
+ CssLayoutElement component = $(CssLayoutElement.class).first();
+ GridLayoutElement gridLayout = $(GridLayoutElement.class).first();
+
+ // Spacing on, not hiding empty rows/columns
+ // There should be 3 * 6px spacing (red) above the csslayout
+ verifySpacingAbove(3 * 6, gridLayout, component);
+
+ CheckBoxElement spacingCheckbox = $(CheckBoxElement.class).caption(
+ "spacing").first();
+ check(spacingCheckbox);
+
+ // Spacing off, not hiding empty rows/columns
+ // There should not be any spacing (red) above the csslayout
+ verifySpacingAbove(0, gridLayout, component);
+
+ CheckBoxElement hideRowsColumnsCheckbox = $(CheckBoxElement.class)
+ .caption("hide empty rows/columns").first();
+ check(hideRowsColumnsCheckbox);
+
+ // Spacing off, hiding empty rows/columns
+ // There should not be any spacing (red) above the csslayout
+ verifySpacingAbove(0, gridLayout, component);
+
+ check(spacingCheckbox);
+ // Spacing on, hiding empty rows/columns
+ // There should not be any spacing (red) above or below the csslayout
+
+ // Oh PhantomJs...
+ sleep(100);
+ // FIXME: This should be 0 but there is a bug somewhere
+ // verifySpacingAbove(0, gridLayout, component);
+ verifySpacingBelow(6, gridLayout, component);
+
+ }
+
+ /**
+ * workaround for http://dev.vaadin.com/ticket/13763
+ */
+ private void check(CheckBoxElement checkbox) {
+ WebElement cb = checkbox.findElement(By.xpath("input"));
+ if (BrowserUtil.isChrome(getDesiredCapabilities())) {
+ testBenchElement(cb).click(0, 0);
+ } else {
+ cb.click();
+ }
+ }
+
+ private void verifySpacingAbove(int spacing, GridLayoutElement gridLayout,
+ CssLayoutElement component) {
+ assertHeight(component, 500 - spacing, 1);
+ int offset = component.getLocation().getY()
+ - gridLayout.getLocation().getY();
+ Assert.assertEquals(spacing, offset);
+
+ }
+
+ private void verifySpacingBelow(int spacing, GridLayoutElement gridLayout,
+ CssLayoutElement component) {
+ assertHeight(component, 500 - spacing, 1);
+
+ int offset = component.getLocation().getY()
+ - gridLayout.getLocation().getY();
+ Assert.assertEquals(0, offset);
+
+ }
+
+ private void assertHeight(WebElement component, int height, int tolerance) {
+ Assert.assertTrue(Math.abs(height - component.getSize().getHeight()) <= tolerance);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java b/uitest/src/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java
index 5a64cb6a00..bd7522aab7 100644
--- a/uitest/src/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java
+++ b/uitest/src/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java
@@ -19,9 +19,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.annotations.JavaScript;
import com.vaadin.server.ConnectorResource;
import com.vaadin.server.DownloadStream;
@@ -39,6 +36,7 @@ import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.JavaScriptFunction;
+import elemental.json.JsonArray;
public class BasicJavaScriptComponent extends AbstractTestUI {
@@ -78,15 +76,15 @@ public class BasicJavaScriptComponent extends AbstractTestUI {
});
addFunction("messageToServer", new JavaScriptFunction() {
@Override
- public void call(JSONArray arguments) throws JSONException {
+ public void call(JsonArray arguments) {
log.log("Got callback message: " + arguments.getString(0));
}
});
addFunction("reportParentIds", new JavaScriptFunction() {
@Override
- public void call(JSONArray arguments) throws JSONException {
- JSONArray parentIds = arguments.getJSONArray(0);
+ public void call(JsonArray arguments) {
+ JsonArray parentIds = arguments.getArray(0);
if (!parentIds.getString(0).equals(getConnectorId())) {
log.log("Connector ids doesn't match");
}
diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewShortcutActionHandler.java b/uitest/src/com/vaadin/tests/components/popupview/PopupViewShortcutActionHandler.java
new file mode 100644
index 0000000000..ca91597aa2
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewShortcutActionHandler.java
@@ -0,0 +1,79 @@
+/*
+ * 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.popupview;
+
+import com.vaadin.event.ShortcutAction;
+import com.vaadin.event.ShortcutListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.PopupView;
+import com.vaadin.ui.TextField;
+
+/**
+ * Test UI to check availability of shortcut action listener in the popup view
+ * oeverlay component.
+ *
+ * @author Vaadin Ltd
+ */
+public class PopupViewShortcutActionHandler extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ addComponent(new PopupView(new DemoPoupView()));
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Shortcut listener search should be executed in the end "
+ + "of request (after legacy UIDL request handling).";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14275;
+ }
+
+ private class DemoPoupView implements PopupView.Content {
+
+ @Override
+ public String getMinimizedValueAsHTML() {
+ return "Click Me";
+ }
+
+ @Override
+ public Component getPopupComponent() {
+ TextField field = new TextField("Enter text");
+ field.setImmediate(true);
+ field.addShortcutListener(new ShortcutListener("SearchAction",
+ ShortcutAction.KeyCode.ENTER, null) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void handleAction(Object sender, Object target) {
+ Label label = new Label(
+ "shortcut addedEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE");
+ label.addStyleName("shortcut-result");
+ addComponent(label);
+ }
+ });
+ return field;
+ }
+
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewShortcutActionHandlerTest.java b/uitest/src/com/vaadin/tests/components/popupview/PopupViewShortcutActionHandlerTest.java
new file mode 100644
index 0000000000..f122e1a415
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewShortcutActionHandlerTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.popupview;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.phantomjs.PhantomJSDriver;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.TestBench;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Check availability of shortcut action listener in the popup view.
+ *
+ * @author Vaadin Ltd
+ */
+public class PopupViewShortcutActionHandlerTest extends MultiBrowserTest {
+
+ @Test
+ public void testShortcutHandling() {
+ openTestURL();
+
+ getDriver().findElement(By.className("v-popupview")).click();
+ WebElement textField = getDriver().findElement(
+ By.className("v-textfield"));
+ textField.sendKeys("a", Keys.ENTER);
+
+ Assert.assertTrue(
+ "Unable to find label component which is the result of"
+ + " shortcut action handling.",
+ isElementPresent(By.className("shortcut-result")));
+ }
+
+ @Override
+ protected void setupDriver() throws Exception {
+ System.setProperty("phantomjs.binary.path",
+ "C:\\tmp\\phantom\\phantomjs.exe");
+ WebDriver dr = TestBench.createDriver(new PhantomJSDriver());
+ setDriver(dr);
+ }
+
+ @Override
+ protected String getScreenshotDirectory() {
+ return "C:\\tmp\\a";
+ }
+
+ @Override
+ protected void openTestURL() {
+ driver.get("http://localhost:8080/vaadin/run/PopupViewShortcutActionHandler");
+ }
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ return Collections.singletonList(Browser.FIREFOX
+ .getDesiredCapabilities());
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/TableMatchesMouseDownMouseUpElement.java b/uitest/src/com/vaadin/tests/components/table/TableMatchesMouseDownMouseUpElement.java
new file mode 100644
index 0000000000..1515589b4c
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableMatchesMouseDownMouseUpElement.java
@@ -0,0 +1,76 @@
+package com.vaadin.tests.components.table;
+
+import com.vaadin.data.Item;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.VerticalLayout;
+
+public class TableMatchesMouseDownMouseUpElement extends AbstractTestUI {
+
+ static final String CLEAR_BUTTON_ID = "clear-button-id";
+
+ @Override
+ protected String getTestDescription() {
+ return "Both mouse down and mouse up should be done on same cell to be considered as a click.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14347;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void setup(VaadinRequest request) {
+ final Table table = new Table();
+ table.setHeight("500px");
+ table.setSelectable(true);
+ table.setNullSelectionAllowed(true);
+ table.addContainerProperty("Column 1", String.class, "");
+ table.addContainerProperty("Column 2", Component.class, "");
+ table.addContainerProperty("Column 3", Component.class, "");
+ table.addContainerProperty("Column 4", Component.class, "");
+
+ Item item = table.addItem("Item 1 (row 1)");
+ item.getItemProperty("Column 1").setValue("String A");
+ item.getItemProperty("Column 2").setValue(new Label("Label A"));
+ item.getItemProperty("Column 3").setValue(
+ new Label("<b>Label A</b>", ContentMode.HTML));
+ VerticalLayout l = new VerticalLayout();
+ l.setId("row-1");
+ l.setHeight(100, Unit.PIXELS);
+ item.getItemProperty("Column 4").setValue(l);
+
+ item = table.addItem("Item 2 (row 2)");
+ item.getItemProperty("Column 1").setValue("String B");
+ item.getItemProperty("Column 2").setValue(new Label("Label B"));
+ item.getItemProperty("Column 3")
+ .setValue(
+ new Label(
+ "<a style=\"color: blue\" href=\"javascript:false\">Label B</a>",
+ ContentMode.HTML));
+ l = new VerticalLayout();
+ l.setId("row-2");
+ l.setSizeFull();
+ item.getItemProperty("Column 4").setValue(l);
+
+ Button clear = new Button("Clear");
+ clear.setId(CLEAR_BUTTON_ID);
+ clear.addClickListener(new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ table.setValue(null);
+ }
+ });
+ addComponent(table);
+ addComponent(clear);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/TableMatchesMouseDownMouseUpElementTest.java b/uitest/src/com/vaadin/tests/components/table/TableMatchesMouseDownMouseUpElementTest.java
new file mode 100644
index 0000000000..ea730ea30e
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/TableMatchesMouseDownMouseUpElementTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.table;
+
+import static com.vaadin.tests.components.table.TableMatchesMouseDownMouseUpElement.CLEAR_BUTTON_ID;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.testbench.elements.TableElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Regular click cases already covered by @LabelEmbeddedClickThroughForTableTest
+ * Testing cases when mouse down and mouse up positions are different
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TableMatchesMouseDownMouseUpElementTest extends MultiBrowserTest {
+
+ TableElement table;
+
+ @Test
+ public void testClick() {
+ openTestURL();
+ table = $(TableElement.class).first();
+
+ testMoveOut(getBoldTag(0, 2));
+ testMoveIn(getBoldTag(0, 2));
+
+ testMoveOut(getLabel(0, 1));
+ testMoveIn(getLabel(0, 1));
+
+ testClickOnDifferentRows();
+ }
+
+ /**
+ * MouseDown on element and mouseUp outside element but on same cell
+ */
+ private void testMoveOut(WebElement element) {
+ clearSelection();
+ clickAndMove(element, 5, 5, 0, 50);
+ checkSelectedRowCount(1);
+ checkRowSelected(0);
+ }
+
+ /**
+ * MouseDown outside element but on same cell and mouseUp on element
+ */
+ private void testMoveIn(WebElement element) {
+ clearSelection();
+ clickAndMove(element, 5, 55, 0, -50);
+ checkSelectedRowCount(1);
+ checkRowSelected(0);
+ }
+
+ /**
+ * Mouse down in cell of row1 holds and mouse up in cell of row 2
+ */
+ public void testClickOnDifferentRows() {
+ clearSelection();
+ WebElement elementFrom = getCell(0, 1);
+ WebElement elementTo = getCell(0, 2);
+ clickAndMove(elementFrom, elementTo);
+ checkSelectedRowCount(0);
+ }
+
+ private WebElement getBoldTag(int row, int column) {
+ return table.getCell(row, column).findElement(By.className("v-label"))
+ .findElement(By.tagName("b"));
+ }
+
+ private WebElement getLabel(int row, int column) {
+ return table.getCell(row, column).findElement(By.className("v-label"));
+ }
+
+ private WebElement getCell(int row, int column) {
+ return table.getCell(row, column);
+ }
+
+ private void clearSelection() {
+ WebElement clearButton = vaadinElementById(CLEAR_BUTTON_ID);
+ clearButton.click();
+ }
+
+ /**
+ * Mouse down on element + initial offset -> Moves the "move offset" ->
+ * Mouse up
+ */
+ private void clickAndMove(WebElement element, int initialX, int initialY,
+ int moveX, int moveY) {
+ new Actions(driver).moveToElement(element, initialX, initialY)
+ .clickAndHold().perform();
+ new Actions(driver).moveByOffset(moveX, moveY).perform();
+ new Actions(driver).release().perform();
+ }
+
+ /**
+ * Mouse down on elementFrom -> Moves to elementTo -> Mouse up
+ */
+ private void clickAndMove(WebElement elementFrom, WebElement elementTo) {
+ new Actions(driver).moveToElement(elementFrom, 5, 5).clickAndHold()
+ .perform();
+ new Actions(driver).moveToElement(elementTo, 5, 5).perform();
+ new Actions(driver).release().perform();
+ }
+
+ private void checkRowSelected(int rowIndex) {
+ assertEquals(
+ "contents of the selected row don't match contents of the row #"
+ + rowIndex,
+ table.getCell(rowIndex, 0).getText(),
+ getSelectedRows().get(0)
+ .findElement(By.className("v-table-cell-wrapper"))
+ .getText());
+ }
+
+ private void checkSelectedRowCount(int expected) {
+ assertEquals("unexpected table selection size", expected,
+ getSelectedRows().size());
+ }
+
+ private List<WebElement> getSelectedRows() {
+ return table.findElement(By.className("v-table-body")).findElements(
+ By.className("v-selected"));
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java b/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java
index c21a38a0ac..710a4f8fe3 100644
--- a/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java
+++ b/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java
@@ -19,8 +19,6 @@ package com.vaadin.tests.components.table;
import java.util.ArrayList;
import java.util.Collection;
-import org.json.JSONObject;
-
import com.vaadin.annotations.Push;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.StreamVariable;
@@ -30,6 +28,7 @@ import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ConnectorTracker;
import com.vaadin.ui.Table;
+import elemental.json.JsonObject;
@Push
public class TableRemovedQuicklySendsInvalidRpcCalls extends AbstractTestUI {
@@ -125,12 +124,12 @@ public class TableRemovedQuicklySendsInvalidRpcCalls extends AbstractTestUI {
}
@Override
- public JSONObject getDiffState(ClientConnector connector) {
+ public JsonObject getDiffState(ClientConnector connector) {
return tracker.getDiffState(connector);
}
@Override
- public void setDiffState(ClientConnector connector, JSONObject diffState) {
+ public void setDiffState(ClientConnector connector, JsonObject diffState) {
tracker.setDiffState(connector, diffState);
}
diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/NewSelectionAfterTabRemove.java b/uitest/src/com/vaadin/tests/components/tabsheet/NewSelectionAfterTabRemove.java
new file mode 100644
index 0000000000..939bd645ea
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/tabsheet/NewSelectionAfterTabRemove.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.tabsheet;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.TabSheet.Tab;
+
+/**
+ * In case a selected tab is removed the new selected one should be a neighbor.
+ *
+ * In case an unselected tab is removed and the selected one is not visible, the
+ * scroll should not jump to the selected one.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class NewSelectionAfterTabRemove extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ TabSheet tabSheet = new TabSheet();
+
+ for (int i = 0; i < 20; i++) {
+
+ String caption = "Tab " + i;
+ Label label = new Label(caption);
+
+ Tab tab = tabSheet.addTab(label, caption);
+ tab.setClosable(true);
+ }
+
+ addComponent(tabSheet);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "When a selected tab is removed, its neighbor should become selected.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 6876;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/NewSelectionAfterTabRemoveTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/NewSelectionAfterTabRemoveTest.java
new file mode 100644
index 0000000000..bffbc3ecdf
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/tabsheet/NewSelectionAfterTabRemoveTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.tabsheet;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Automatic test of the default TabSheet selection algorithm when removing a
+ * selected tab.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class NewSelectionAfterTabRemoveTest extends MultiBrowserTest {
+
+ @Test
+ public void testSelection() throws IOException, InterruptedException {
+ openTestURL();
+
+ while (scrollRight()) {
+ }
+
+ selectAndClose(tab(19));
+
+ Assert.assertTrue("Tab 18 selected", isTabSelected(tab(18)));
+
+ selectAndClose(tab(16));
+
+ Assert.assertTrue("Tab 17 selected", isTabSelected(tab(17)));
+ }
+
+ /*
+ * Select the specified tab and close it.
+ */
+ private void selectAndClose(TestBenchElement tab)
+ throws InterruptedException {
+ tab.click(5, 5);
+
+ sleep(10);
+
+ tabClose(tab).click(2, 2);
+
+ sleep(10);
+ }
+
+ /*
+ * Gets the selected state of the specified tab.
+ */
+ private boolean isTabSelected(TestBenchElement tab) {
+ return tab.getAttribute("class").contains(
+ "v-tabsheet-tabitemcell-selected")
+ && tab.getAttribute("class").contains(
+ "v-tabsheet-tabitemcell-focus");
+ }
+
+ /*
+ * Scroll the tabsheet bar to the right.
+ */
+ private boolean scrollRight() {
+ List<WebElement> scrollElements = getDriver().findElements(
+ By.className("v-tabsheet-scrollerNext"));
+ if (!scrollElements.isEmpty()) {
+ TestBenchElement rightScrollElement = (TestBenchElement) scrollElements
+ .get(0);
+ rightScrollElement.click(5, 5);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /*
+ * Provide the tab close button for the specified tab.
+ */
+ private TestBenchElement tabClose(TestBenchElement tab) {
+ return (TestBenchElement) tab.findElement(By
+ .className("v-tabsheet-caption-close"));
+ }
+
+ /*
+ * Provide the tab at specified index.
+ */
+ private TestBenchElement tab(int index) {
+ By by = By.className("v-tabsheet-tabitemcell");
+
+ List<WebElement> tabs = getDriver().findElements(by);
+
+ String expected = "Tab " + index;
+
+ for (WebElement tab : tabs) {
+ if (tab.getText().startsWith(expected)) {
+ return (TestBenchElement) tab;
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/extensions/JavascriptManagerTest.java b/uitest/src/com/vaadin/tests/extensions/JavascriptManagerTest.java
index b89e16d755..4807bb9029 100644
--- a/uitest/src/com/vaadin/tests/extensions/JavascriptManagerTest.java
+++ b/uitest/src/com/vaadin/tests/extensions/JavascriptManagerTest.java
@@ -16,16 +16,15 @@
package com.vaadin.tests.extensions;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.tests.util.Log;
import com.vaadin.ui.JavaScript;
import com.vaadin.ui.JavaScriptFunction;
+import elemental.json.JsonArray;
+import elemental.json.JsonNull;
+
public class JavascriptManagerTest extends AbstractTestUI {
private Log log = new Log(5);
@@ -36,14 +35,14 @@ public class JavascriptManagerTest extends AbstractTestUI {
final JavaScript js = JavaScript.getCurrent();
js.addFunction("testing.doTest", new JavaScriptFunction() {
@Override
- public void call(JSONArray arguments) throws JSONException {
+ public void call(JsonArray arguments) {
log.log("Got " + arguments.length() + " arguments");
- log.log("Argument 1 as a number: " + arguments.getInt(0));
+ log.log("Argument 1 as a number: " + (int) arguments.getNumber(0));
log.log("Argument 2 as a string: " + arguments.getString(1));
log.log("Argument 3.p as a boolean: "
- + arguments.getJSONObject(2).getBoolean("p"));
+ + arguments.getObject(2).getBoolean("p"));
log.log("Argument 4 is JSONObject.NULL: "
- + (arguments.get(3) == JSONObject.NULL));
+ + (arguments.get(3) instanceof JsonNull));
js.removeFunction("testing.doTest");
}
});
diff --git a/uitest/src/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java b/uitest/src/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java
index d3e0edf04c..6f14fb301c 100644
--- a/uitest/src/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java
+++ b/uitest/src/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java
@@ -16,9 +16,6 @@
package com.vaadin.tests.extensions;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.annotations.JavaScript;
import com.vaadin.annotations.StyleSheet;
import com.vaadin.server.AbstractJavaScriptExtension;
@@ -31,6 +28,7 @@ import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.JavaScriptFunction;
import com.vaadin.ui.Notification;
+import elemental.json.JsonArray;
public class SimpleJavaScriptExtensionTest extends AbstractTestUI {
@@ -71,7 +69,7 @@ public class SimpleJavaScriptExtensionTest extends AbstractTestUI {
});
addFunction("greetToServer", new JavaScriptFunction() {
@Override
- public void call(JSONArray arguments) throws JSONException {
+ public void call(JsonArray arguments) {
Notification.show(getState().getPrefix()
+ arguments.getString(0));
}
diff --git a/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListeners.html b/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListeners.html
deleted file mode 100644
index 496994a60c..0000000000
--- a/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListeners.html
+++ /dev/null
@@ -1,239 +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>TestLayoutClickListeners</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">TestLayoutClickListeners</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.layouts.TestLayoutClickListeners?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>screenCapture</td>
- <td></td>
- <td>initial</td>
-</tr>
-<!--GridLayout-->
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>43,11</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>exact:GridLayout: left click on This is label 1</td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VTextField[0]</td>
- <td>82,14</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>exact:GridLayout: left click on This is tf5</td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VHorizontalLayout[0]/VOrderedLayout$Slot[0]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VGridLayout[0]</td>
- <td>130,41</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>exact:GridLayout: left click on &lt;none&gt;</td>
-</tr>
-<!--VerticalLayout-->
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td>
- <td>74,13</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>exact:VerticalLayout: left click on This is tf6</td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]</td>
- <td>53,13</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>exact:VerticalLayout: left click on This is label 3</td>
-</tr>
-<!--AbsoluteLayout-->
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/VAbsoluteLayout$AbsoluteWrapper[2]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>exact:Button A button with its own click listener was clicked</td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/VAbsoluteLayout$AbsoluteWrapper[0]/VTextField[0]</td>
- <td>101,14</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>exact:AbsoluteLayout: left click on This is its caption</td>
-</tr>
-<!--CssLayout-->
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[3]/VCssLayout[0]/VCssLayout$FlowPane[0]/VTextField[0]</td>
- <td>108,13</td>
-</tr>
-<tr>
- <td>mouseClick</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VHorizontalLayout[0]/VOrderedLayout$Slot[3]/VCssLayout[0]/domChild[0]/domChild[0]</td>
- <td>41,7</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_1</td>
- <td>exact:CSSLayout: left click on This is its caption</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td>
- <td>exact:CSSLayout: left click on This is its caption</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[3]/VCssLayout[0]/VCssLayout$FlowPane[0]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td>
- <td>exact:Button A button with its own click listener was clicked</td>
-</tr>
-<!--Drag in GridLayout-->
-<tr>
- <td>drag</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>40,8</td>
-</tr>
-<tr>
- <td>drop</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>40,8</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td>
- <td>exact:GridLayout: left click on This is label 1</td>
-</tr>
-<tr>
- <td>drag</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VLabel[0]</td>
- <td>24,7</td>
-</tr>
-<tr>
- <td>drop</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VTextField[0]</td>
- <td>46,13</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td>
- <td>exact:GridLayout: left click on This is label 1</td>
-</tr>
-<!--Drag in VerticalLayout-->
-<tr>
- <td>drag</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td>
- <td>25,9</td>
-</tr>
-<tr>
- <td>drop</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td>
- <td>25,9</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td>
- <td>exact:VerticalLayout: left click on This is tf5</td>
-</tr>
-<tr>
- <td>drag</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[8]/domChild[0]</td>
- <td>28,11</td>
-</tr>
-<tr>
- <td>drop</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VTextField[0]</td>
- <td>39,7</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td>
- <td>exact:VerticalLayout: left click on This is tf5</td>
-</tr>
-<!--Drag in AbsoluteLayout-->
-<tr>
- <td>drag</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VHorizontalLayout[0]/VOrderedLayout$Slot[2]/VAbsoluteLayout[0]/domChild[0]/domChild[0]/domChild[3]/domChild[0]</td>
- <td>21,9</td>
-</tr>
-<tr>
- <td>drop</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VHorizontalLayout[0]/VOrderedLayout$Slot[2]/VAbsoluteLayout[0]/domChild[0]/domChild[0]/domChild[3]/domChild[0]</td>
- <td>21,9</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td>
- <td>exact:AbsoluteLayout: left click on This is its caption</td>
-</tr>
-<tr>
- <td>drag</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/VAbsoluteLayout$AbsoluteWrapper[0]/VTextField[0]</td>
- <td>54,7</td>
-</tr>
-<tr>
- <td>drop</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/VAbsoluteLayout$AbsoluteWrapper[1]/VTextField[0]</td>
- <td>52,10</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td>
- <td>exact:AbsoluteLayout: left click on This is its caption</td>
-</tr>
-<!--Drag in CSSLayout-->
-<tr>
- <td>drag</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[3]/VCssLayout[0]/VCssLayout$FlowPane[0]/VTextField[0]</td>
- <td>51,7</td>
-</tr>
-<tr>
- <td>drop</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[3]/VCssLayout[0]/VCssLayout$FlowPane[0]/VTextField[0]</td>
- <td>51,7</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::PID_SLog_row_0</td>
- <td>exact:CSSLayout: left click on This is its caption</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListeners.java b/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListeners.java
index c29e7710b7..22a37022c2 100644
--- a/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListeners.java
+++ b/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListeners.java
@@ -2,8 +2,8 @@ package com.vaadin.tests.layouts;
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.event.LayoutEvents.LayoutClickListener;
-import com.vaadin.tests.components.AbstractTestCase;
-import com.vaadin.tests.util.Log;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
@@ -12,36 +12,22 @@ import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Layout;
-import com.vaadin.ui.LegacyWindow;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
-public class TestLayoutClickListeners extends AbstractTestCase {
-
- private Log log = new Log(5).setNumberLogRows(false);
+public class TestLayoutClickListeners extends AbstractTestUIWithLog {
@Override
- public void init() {
- LegacyWindow w = new LegacyWindow("main window");
- setMainWindow(w);
- setTheme("tests-tickets");
-
+ protected void setup(VaadinRequest request) {
HorizontalLayout layoutsLayout = new HorizontalLayout();
layoutsLayout.setSpacing(true);
- w.setContent(layoutsLayout);
+ addComponent(layoutsLayout);
layoutsLayout.addComponent(createClickableGridLayout());
layoutsLayout.addComponent(createClickableVerticalLayout());
layoutsLayout.addComponent(createClickableAbsoluteLayout());
layoutsLayout.addComponent(createClickableCSSLayout());
-
- VerticalLayout mainLayout = new VerticalLayout();
- mainLayout.setMargin(true);
- mainLayout.setSpacing(true);
- w.setContent(mainLayout);
- mainLayout.addComponent(log);
- mainLayout.addComponent(layoutsLayout);
}
private Component createClickableAbsoluteLayout() {
@@ -62,12 +48,12 @@ public class TestLayoutClickListeners extends AbstractTestCase {
@Override
public void buttonClick(
com.vaadin.ui.Button.ClickEvent event) {
- log.log("Button " + event.getButton().getCaption()
+ log("Button " + event.getButton().getCaption()
+ " was clicked");
}
}));
- al.addListener(new LayoutClickListener() {
+ al.addLayoutClickListener(new LayoutClickListener() {
@Override
public void layoutClick(LayoutClickEvent event) {
@@ -96,12 +82,12 @@ public class TestLayoutClickListeners extends AbstractTestCase {
@Override
public void buttonClick(
com.vaadin.ui.Button.ClickEvent event) {
- log.log("Button " + event.getButton().getCaption()
+ log("Button " + event.getButton().getCaption()
+ " was clicked");
}
}));
- cl.addListener(new LayoutClickListener() {
+ cl.addLayoutClickListener(new LayoutClickListener() {
@Override
public void layoutClick(LayoutClickEvent event) {
@@ -120,13 +106,14 @@ public class TestLayoutClickListeners extends AbstractTestCase {
gl.setWidth("564px");
gl.setStyleName("borders");
gl.setSpacing(true);
+ gl.setHideEmptyRowsAndColumns(true);
addContent(gl, 4);
TextArea largeTextarea = new TextArea("Large textarea");
largeTextarea.setWidth("100%");
largeTextarea.setHeight("99%");
gl.addComponent(largeTextarea, 0, 3, 3, 3);
- gl.addListener(new LayoutClickListener() {
+ gl.addLayoutClickListener(new LayoutClickListener() {
@Override
public void layoutClick(LayoutClickEvent event) {
@@ -151,10 +138,7 @@ public class TestLayoutClickListeners extends AbstractTestCase {
if (event.isDoubleClick()) {
type = "double-click";
}
- log.log(layout + ": " + button + " " + type + " on " + target);
- // + ", coordinates relative to the layout ("
- // + event.getRelativeX() + ", " + event.getRelativeY() + ")");
-
+ log(layout + ": " + button + " " + type + " on " + target);
}
private Layout createClickableVerticalLayout() {
@@ -162,7 +146,7 @@ public class TestLayoutClickListeners extends AbstractTestCase {
VerticalLayout gl = new VerticalLayout();
addContent(gl, 5);
- gl.addListener(new LayoutClickListener() {
+ gl.addLayoutClickListener(new LayoutClickListener() {
@Override
public void layoutClick(LayoutClickEvent event) {
@@ -196,7 +180,7 @@ public class TestLayoutClickListeners extends AbstractTestCase {
}
@Override
- protected String getDescription() {
+ protected String getTestDescription() {
return "All layouts have click listeners attached and the events are shown in the event log at the top";
}
@@ -204,5 +188,4 @@ public class TestLayoutClickListeners extends AbstractTestCase {
protected Integer getTicketNumber() {
return 3541;
}
-
}
diff --git a/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListenersTest.java b/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListenersTest.java
new file mode 100644
index 0000000000..0c6b5cbff4
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/layouts/TestLayoutClickListenersTest.java
@@ -0,0 +1,200 @@
+/*
+ * 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.layouts;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.testbench.elements.AbsoluteLayoutElement;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.CssLayoutElement;
+import com.vaadin.testbench.elements.GridLayoutElement;
+import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.testbench.elements.VerticalLayoutElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Tests LayoutClickListener on different layouts.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TestLayoutClickListenersTest extends MultiBrowserTest {
+
+ @Before
+ public void before() {
+ openTestURL();
+ }
+
+ @Test
+ public void clickInGridLayout() {
+ GridLayoutElement layout = $(GridLayoutElement.class).first();
+
+ // click on a label
+ layout.$(LabelElement.class).first().click();
+ assertLogText("GridLayout 1st child clicked",
+ "1. GridLayout: left click on This is label 1");
+
+ // click on a text field
+ layout.$(TextFieldElement.class).get(1).click();
+ assertLogText("GridLayout 5th child clicked",
+ "2. GridLayout: left click on This is tf5");
+
+ // click on the layout body (not any component inside the layout)
+ layout.click(130, 41);
+ assertLogText("GridLayout body clicked",
+ "3. GridLayout: left click on <none>");
+ }
+
+ @Test
+ public void clickInVerticalLayout() {
+ VerticalLayoutElement layout = $(VerticalLayoutElement.class).get(4);
+
+ // click on a text field
+ layout.$(TextFieldElement.class).get(1).click();
+ assertLogText("VerticalLayout 6th child clicked",
+ "1. VerticalLayout: left click on This is tf6");
+
+ // click on a label
+ layout.$(LabelElement.class).get(3).click();
+ assertLogText("VerticalLayout 4th child clicked",
+ "2. VerticalLayout: left click on This is label 3");
+ }
+
+ @Test
+ public void clickInAbsoluteLayout() {
+ AbsoluteLayoutElement layout = $(AbsoluteLayoutElement.class).first();
+
+ // click on a button that has its own ClickListener (should be ignored
+ // by the LayoutClickListener)
+ layout.$(ButtonElement.class).first().click();
+ assertLogText("A button with a ClickListener clicked",
+ "1. Button A button with its own click listener was clicked");
+
+ // click on a text field's caption
+ layout.$(TextFieldElement.class).first().click();
+ assertLogText("AbsoluteLayout 1st child was clicked",
+ "2. AbsoluteLayout: left click on This is its caption");
+ }
+
+ @Test
+ public void clickInCSSLayout() {
+ CssLayoutElement layout = $(CssLayoutElement.class).first();
+
+ // click on a text field's caption
+ layout.$(TextFieldElement.class).first().click();
+ assertLogText("CSSLayout 1st child clicked",
+ "1. CSSLayout: left click on This is its caption");
+
+ // click on a button that has its own ClickListener (should be ignored
+ // by the LayoutClickListener)
+ layout.$(ButtonElement.class).first().click();
+ assertLogText("Abutton with a ClickListener was clicked",
+ "2. Button A button with its own click listener was clicked");
+ }
+
+ @Test
+ public void dragInGridLayout() {
+ GridLayoutElement layout = $(GridLayoutElement.class).first();
+
+ // Drag inside the first label in this layout
+ new Actions(getDriver())
+ .moveToElement(layout.$(LabelElement.class).first(), 40, 8)
+ .clickAndHold().moveByOffset(-20, 0).release().perform();
+ assertLogText("Mouse dragged in GridLayout",
+ "1. GridLayout: left click on This is label 1");
+
+ // Drag from the third label to a text field in this layout
+ new Actions(getDriver())
+ .moveToElement(layout.$(LabelElement.class).first(), 40, 8)
+ .clickAndHold()
+ .moveToElement(layout.$(TextFieldElement.class).get(3), 46, 33)
+ .release().perform();
+ assertLogText("Expected the drag to be ignored between elements",
+ "1. GridLayout: left click on This is label 1");
+ }
+
+ @Test
+ public void dragInVerticalLayout() {
+ VerticalLayoutElement layout = $(VerticalLayoutElement.class).get(4);
+
+ // Drag inside the first text field
+ new Actions(getDriver())
+ .moveToElement(layout.$(TextFieldElement.class).first(), 25, 9)
+ .clickAndHold().moveByOffset(-20, 0).release().perform();
+ assertLogText("Mouse dragged in VerticalLayout",
+ "1. VerticalLayout: left click on This is tf5");
+
+ // Drag from a caption to its text field
+ new Actions(getDriver())
+ .moveToElement(layout.$(TextFieldElement.class).get(4), 28, 11)
+ .clickAndHold()
+ .moveToElement(layout.$(TextFieldElement.class).get(4), 39, 30)
+ .release().perform();
+ assertLogText("Expected the drag to be ignored between elements",
+ "1. VerticalLayout: left click on This is tf5");
+ }
+
+ @Test
+ public void dragInAbsoluteLayout() {
+ AbsoluteLayoutElement layout = $(AbsoluteLayoutElement.class).first();
+
+ // Drag inside the first text field's caption
+ new Actions(getDriver())
+ .moveToElement(layout.$(TextFieldElement.class).first(), 21, 9)
+ .clickAndHold().moveByOffset(-10, 0).release().perform();
+ assertLogText("Mouse dragged in AbsoluteLayout",
+ "1. AbsoluteLayout: left click on This is its caption");
+
+ // Drag from a text field to another text field
+ new Actions(getDriver())
+ .moveToElement(layout.$(TextFieldElement.class).get(1), 54, 7)
+ .clickAndHold()
+ .moveToElement(layout.$(TextFieldElement.class).first(), 52, 10)
+ .release().perform();
+ assertLogText("Expected the drag to be ignored between elements",
+ "1. AbsoluteLayout: left click on This is its caption");
+ }
+
+ @Test
+ public void dragInCSSLayout() {
+ CssLayoutElement layout = $(CssLayoutElement.class).first();
+
+ // Drag inside the first text field's caption
+ new Actions(getDriver())
+ .moveToElement(layout.$(TextFieldElement.class).first(), 51, 7)
+ .clickAndHold().moveByOffset(-20, 0).release().perform();
+ assertLogText("Mouse dragged in CSSLayout",
+ "1. CSSLayout: left click on This is its caption");
+
+ // Drag from the first text field to the second text field
+ new Actions(getDriver())
+ .moveToElement(layout.$(TextFieldElement.class).first(), 51, 27)
+ .clickAndHold()
+ .moveToElement(layout.$(TextFieldElement.class).get(1), 51, 27)
+ .release().perform();
+ assertLogText("Expected the drag to be ignored between elements",
+ "1. CSSLayout: left click on This is its caption");
+ }
+
+ private void assertLogText(String message, String expected) {
+ String actual = $(LabelElement.class).first().getText();
+ Assert.assertEquals(message, expected, actual);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a3/Flot.java b/uitest/src/com/vaadin/tests/minitutorials/v7a3/Flot.java
index f4aca81ffa..86666b12e8 100644
--- a/uitest/src/com/vaadin/tests/minitutorials/v7a3/Flot.java
+++ b/uitest/src/com/vaadin/tests/minitutorials/v7a3/Flot.java
@@ -20,13 +20,11 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.annotations.JavaScript;
import com.vaadin.ui.AbstractJavaScriptComponent;
import com.vaadin.ui.JavaScriptFunction;
import com.vaadin.ui.Notification;
+import elemental.json.JsonArray;
@JavaScript({
"https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js",
@@ -42,9 +40,9 @@ public class Flot extends AbstractJavaScriptComponent {
});
addFunction("onPlotClick", new JavaScriptFunction() {
@Override
- public void call(JSONArray arguments) throws JSONException {
- int seriesIndex = arguments.getInt(0);
- int dataIndex = arguments.getInt(1);
+ public void call(JsonArray arguments) {
+ int seriesIndex = (int) arguments.getNumber(0);
+ int dataIndex = (int) arguments.getNumber(1);
Notification.show("Clicked on [" + seriesIndex + ", "
+ dataIndex + "]");
}
diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a3/JSAPIUI.java b/uitest/src/com/vaadin/tests/minitutorials/v7a3/JSAPIUI.java
index 8f1eda6816..e98fe6d066 100644
--- a/uitest/src/com/vaadin/tests/minitutorials/v7a3/JSAPIUI.java
+++ b/uitest/src/com/vaadin/tests/minitutorials/v7a3/JSAPIUI.java
@@ -1,8 +1,5 @@
package com.vaadin.tests.minitutorials.v7a3;
-import org.json.JSONArray;
-import org.json.JSONException;
-
import com.vaadin.server.ExternalResource;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.JavaScript;
@@ -12,6 +9,9 @@ import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.UI;
+import elemental.json.JsonArray;
+import elemental.json.JsonException;
+
public class JSAPIUI extends UI {
@Override
public void init(VaadinRequest request) {
@@ -19,7 +19,7 @@ public class JSAPIUI extends UI {
JavaScript.getCurrent().addFunction("com.example.api.notify",
new JavaScriptFunction() {
@Override
- public void call(JSONArray arguments) throws JSONException {
+ public void call(JsonArray arguments) {
try {
String caption = arguments.getString(0);
if (arguments.length() == 1) {
@@ -28,10 +28,10 @@ public class JSAPIUI extends UI {
} else {
// type should be in [1]
Notification.show(caption,
- Type.values()[arguments.getInt(1)]);
+ Type.values()[((int) arguments.getNumber(1))]);
}
- } catch (JSONException e) {
+ } catch (JsonException e) {
// We'll log in the console, you might not want to
JavaScript.getCurrent().execute(
"console.error('" + e.getMessage() + "')");
diff --git a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUI.java b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUI.java
index 6e2784f21d..e7a74775bf 100644
--- a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUI.java
+++ b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUI.java
@@ -23,8 +23,6 @@ import java.net.URL;
import javax.servlet.ServletContext;
import org.apache.commons.io.IOUtils;
-import org.json.JSONArray;
-import org.json.JSONException;
import com.vaadin.annotations.JavaScript;
import com.vaadin.server.VaadinRequest;
@@ -32,6 +30,7 @@ import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinServletService;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.JavaScriptFunction;
+import elemental.json.JsonArray;
// Load vaadinPush.js so that jQueryVaadin is defined
@JavaScript("vaadin://vaadinPush.debug.js")
@@ -58,7 +57,7 @@ public class TrackMessageSizeUI extends AbstractTestUIWithLog {
getPage().getJavaScript().addFunction("logToServer",
new JavaScriptFunction() {
@Override
- public void call(JSONArray arguments) throws JSONException {
+ public void call(JsonArray arguments) {
String message = arguments.getString(0);
log(message);
}
diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java
index 47bb212347..dcba561599 100644
--- a/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java
+++ b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java
@@ -86,9 +86,8 @@ public class SerializerTestTest extends MultiBrowserTest {
getLogRow(logRow++));
Assert.assertEquals("state.floatArray: [57, 0, -12]",
getLogRow(logRow++));
- Assert.assertEquals("state.floatObjectValue: 1.0000001",
- getLogRow(logRow++));
- Assert.assertEquals("state.floatValue: 3.14159", getLogRow(logRow++));
+ Assert.assertTrue(getLogRow(logRow++).startsWith("state.floatObjectValue: 1.0000001"));
+ Assert.assertTrue(getLogRow(logRow++).startsWith("state.floatValue: 3.14159"));
Assert.assertEquals("state.longArray: [-57841235865, 57]",
getLogRow(logRow++));
Assert.assertEquals("state.longObjectValue: 577431841360",
diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
index d2313a0709..1e1cbedbd6 100644
--- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
+++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
@@ -30,13 +30,13 @@ import java.net.URL;
import java.util.Collections;
import java.util.List;
+import elemental.json.JsonObject;
+import elemental.json.impl.JsonUtil;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
-import org.json.JSONException;
-import org.json.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
@@ -1247,7 +1247,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
BasicHttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest(
"POST", sessionURL.toExternalForm());
HttpResponse response = client.execute(host, r);
- JSONObject object = extractObject(response);
+ JsonObject object = extractObject(response);
URL myURL = new URL(object.getString("proxyId"));
if ((myURL.getHost() != null) && (myURL.getPort() != -1)) {
return myURL.getHost();
@@ -1258,13 +1258,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
return null;
}
- private static JSONObject extractObject(HttpResponse resp)
- throws IOException, JSONException {
+ private static JsonObject extractObject(HttpResponse resp) throws IOException {
InputStream contents = resp.getEntity().getContent();
StringWriter writer = new StringWriter();
IOUtils.copy(contents, writer, "UTF8");
- JSONObject objToReturn = new JSONObject(writer.toString());
- return objToReturn;
+ return JsonUtil.parse(writer.toString());
}
}
diff --git a/uitest/src/com/vaadin/tests/tb3/DndActionsTest.java b/uitest/src/com/vaadin/tests/tb3/DndActionsTest.java
new file mode 100644
index 0000000000..e755a00a0d
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/DndActionsTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.tb3;
+
+import org.junit.Ignore;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+/**
+ * Base class for TestBench 3+ tests that use DnD. This class contains utility
+ * methods for DnD operations.
+ *
+ * @author Vaadin Ltd
+ */
+@Ignore
+public abstract class DndActionsTest extends MultiBrowserTest {
+
+ public void dragAndDrop(WebElement element, int xOffset, int yOffset) {
+ /*
+ * Selenium doesn't properly drag and drop items in IE8. It tries to
+ * start dragging an element from a position above the element itself.
+ */
+ if (BrowserUtil.isIE8(getDesiredCapabilities())) {
+ Actions action = new Actions(getDriver());
+ action.moveToElement(element);
+ action.moveByOffset(0, 1);
+ action.clickAndHold();
+ action.moveByOffset(xOffset, yOffset);
+ action.release();
+ action.build().perform();
+ } else {
+ Actions action = new Actions(getDriver());
+ action.dragAndDropBy(element, xOffset, yOffset);
+ action.build().perform();
+ }
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java
index 62d76569dd..f30cec76cc 100644
--- a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java
+++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java
@@ -175,6 +175,7 @@ public class ValoThemeUI extends UI {
break;
}
}
+ menu.removeStyleName("valo-menu-visible");
}
});
diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java
index b5b7e16b34..71f770ab8f 100644
--- a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java
+++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java
@@ -276,6 +276,9 @@ public class ValoThemeUITest extends MultiBrowserTest {
+ getRemoteControlName());
open(link, caption, tries - 1);
+ } else {
+ // Done opening, scroll left panel to the top again for consistency
+ scrollTo(0, 0);
}
}