aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatti Hosio <mhosio@vaadin.com>2014-12-17 10:31:33 +0200
committerMatti Hosio <mhosio@vaadin.com>2014-12-17 10:31:33 +0200
commite547f024533bef83b8c8c8e522240f34765c894d (patch)
tree4610ad629b996df6d7882a8f9190922a467046d2
parent8a0a1bdb4630f39214a039a2689bfa5a1431a413 (diff)
parenta9f24b00e9ddcd5ca19ac2907e0bf2413f036af4 (diff)
downloadvaadin-framework-e547f024533bef83b8c8c8e522240f34765c894d.tar.gz
vaadin-framework-e547f024533bef83b8c8c8e522240f34765c894d.zip
Merge remote-tracking branch 'origin/master' into declarative
Conflicts: server/src/com/vaadin/ui/TextField.java Change-Id: I289cb9ec80d494ab79aec11a43708abf5b403a00
-rw-r--r--LICENSE201
-rw-r--r--README.md7
-rw-r--r--WebContent/VAADIN/themes/chameleon/components/notification/notification.scss4
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/arrow-down.pngbin0 -> 456 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/arrow-left.pngbin0 -> 469 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/arrow-right.pngbin0 -> 467 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/arrow-up.pngbin0 -> 471 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/attention.pngbin0 -> 466 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/calendar.pngbin0 -> 710 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/cancel.pngbin0 -> 590 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document-add.pngbin0 -> 656 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document-delete.pngbin0 -> 655 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document-doc.pngbin0 -> 718 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document-image.pngbin0 -> 703 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document-pdf.pngbin0 -> 703 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document-ppt.pngbin0 -> 718 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document-txt.pngbin0 -> 594 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document-web.pngbin0 -> 710 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document-xsl.pngbin0 -> 747 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/document.pngbin0 -> 553 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/email-reply.pngbin0 -> 762 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/email-send.pngbin0 -> 770 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/email.pngbin0 -> 643 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/error.gifbin0 -> 72 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/error.pngbin0 -> 246 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/folder-add.pngbin0 -> 777 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/folder-delete.pngbin0 -> 771 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/folder.pngbin0 -> 737 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/globe.pngbin0 -> 788 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/help.pngbin0 -> 517 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/lock.pngbin0 -> 738 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/note.pngbin0 -> 747 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/ok.pngbin0 -> 542 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/reload.pngbin0 -> 788 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/settings.pngbin0 -> 716 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/trash-full.pngbin0 -> 942 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/trash.pngbin0 -> 836 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/user.pngbin0 -> 645 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons16/users.pngbin0 -> 685 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/arrow-down.pngbin0 -> 872 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/arrow-left.pngbin0 -> 894 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/arrow-right.pngbin0 -> 889 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/arrow-up.pngbin0 -> 863 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/attention.pngbin0 -> 895 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/calendar.pngbin0 -> 1729 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/cancel.pngbin0 -> 1297 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-add.pngbin0 -> 1578 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-delete.pngbin0 -> 1599 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-doc.pngbin0 -> 1481 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-edit.pngbin0 -> 1654 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-image.pngbin0 -> 1881 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-pdf.pngbin0 -> 1417 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-ppt.pngbin0 -> 1424 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-txt.pngbin0 -> 1182 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-web.pngbin0 -> 1675 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document-xsl.pngbin0 -> 1591 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/document.pngbin0 -> 1015 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/email-reply.pngbin0 -> 1797 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/email-send.pngbin0 -> 1718 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/email.pngbin0 -> 1380 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/folder-add.pngbin0 -> 2081 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/folder-delete.pngbin0 -> 2091 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/folder.pngbin0 -> 1629 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/globe.pngbin0 -> 2074 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/help.pngbin0 -> 1134 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/lock.pngbin0 -> 1734 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/note.pngbin0 -> 1808 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/ok.pngbin0 -> 1181 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/reload.pngbin0 -> 1865 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/settings.pngbin0 -> 1131 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/trash-full.pngbin0 -> 2176 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/trash.pngbin0 -> 1803 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/user.pngbin0 -> 1373 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons32/users.pngbin0 -> 1562 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/arrow-down.pngbin0 -> 981 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/arrow-left.pngbin0 -> 922 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/arrow-right.pngbin0 -> 918 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/arrow-up.pngbin0 -> 977 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/attention.pngbin0 -> 2020 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/calendar.pngbin0 -> 3321 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/cancel.pngbin0 -> 2889 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-add.pngbin0 -> 2037 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-delete.pngbin0 -> 2363 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-doc.pngbin0 -> 2619 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-edit.pngbin0 -> 3212 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-image.pngbin0 -> 4123 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-pdf.pngbin0 -> 2533 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-ppt.pngbin0 -> 2286 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-txt.pngbin0 -> 1421 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-web.pngbin0 -> 3393 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document-xsl.pngbin0 -> 2914 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/document.pngbin0 -> 1270 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/email-reply.pngbin0 -> 3937 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/email-send.pngbin0 -> 3100 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/email.pngbin0 -> 2467 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/folder-add.pngbin0 -> 3641 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/folder-delete.pngbin0 -> 3937 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/folder.pngbin0 -> 3209 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/globe.pngbin0 -> 5014 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/help.pngbin0 -> 2696 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/lock.pngbin0 -> 4243 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/note.pngbin0 -> 3805 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/ok.pngbin0 -> 2619 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/reload.pngbin0 -> 4123 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/settings.pngbin0 -> 1654 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/trash-full.pngbin0 -> 5242 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/trash.pngbin0 -> 3688 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/user.pngbin0 -> 2736 bytes
-rw-r--r--WebContent/VAADIN/themes/runo/icons/icons64/users.pngbin0 -> 3698 bytes
-rw-r--r--WebContent/VAADIN/themes/tests-valo-disabled-animations/_variables.scss3
-rw-r--r--WebContent/VAADIN/themes/tests-valo-disabled-animations/styles.scss6
-rw-r--r--WebContent/VAADIN/themes/valo/components/_checkbox.scss36
-rw-r--r--WebContent/VAADIN/themes/valo/components/_datefield.scss2
-rw-r--r--WebContent/VAADIN/themes/valo/components/_link.scss8
-rw-r--r--WebContent/VAADIN/themes/valo/components/_menubar.scss4
-rw-r--r--WebContent/VAADIN/themes/valo/components/_window.scss11
-rw-r--r--buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java9
-rw-r--r--client/src/com/vaadin/client/ApplicationConfiguration.java45
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java62
-rw-r--r--client/src/com/vaadin/client/VTooltip.java23
-rw-r--r--client/src/com/vaadin/client/debug/internal/InfoSection.java8
-rw-r--r--client/src/com/vaadin/client/ui/VAbstractSplitPanel.java194
-rw-r--r--client/src/com/vaadin/client/ui/VAccordion.java38
-rw-r--r--client/src/com/vaadin/client/ui/VCustomLayout.java2
-rw-r--r--client/src/com/vaadin/client/ui/VMenuBar.java28
-rw-r--r--client/src/com/vaadin/client/ui/VOverlay.java91
-rw-r--r--client/src/com/vaadin/client/ui/VPopupCalendar.java216
-rw-r--r--client/src/com/vaadin/client/ui/VScrollTable.java3
-rw-r--r--client/src/com/vaadin/client/ui/VTabsheet.java27
-rw-r--r--client/src/com/vaadin/client/ui/VTreeTable.java2
-rw-r--r--client/src/com/vaadin/client/ui/accordion/AccordionConnector.java5
-rw-r--r--client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java23
-rw-r--r--client/src/com/vaadin/client/ui/dd/VDragEvent.java5
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java15
-rw-r--r--client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java17
-rw-r--r--client/tests/src/com/vaadin/client/TestVBrowserDetailsUserAgentParser.java10
-rw-r--r--server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java65
-rw-r--r--server/src/com/vaadin/data/fieldgroup/FieldGroup.java89
-rw-r--r--server/src/com/vaadin/data/util/AbstractBeanContainer.java10
-rw-r--r--server/src/com/vaadin/data/util/BeanItem.java132
-rw-r--r--server/src/com/vaadin/data/util/BeanUtil.java177
-rw-r--r--server/src/com/vaadin/data/util/MethodProperty.java10
-rw-r--r--server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java1
-rw-r--r--server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java7
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java11
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToByteConverter.java2
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToEnumConverter.java78
-rw-r--r--server/src/com/vaadin/data/util/converter/StringToShortConverter.java2
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java27
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java6
-rw-r--r--server/src/com/vaadin/navigator/Navigator.java7
-rw-r--r--server/src/com/vaadin/server/BootstrapHandler.java2
-rw-r--r--server/src/com/vaadin/server/FileResource.java3
-rw-r--r--server/src/com/vaadin/server/VaadinService.java8
-rw-r--r--server/src/com/vaadin/server/VaadinServlet.java28
-rw-r--r--server/src/com/vaadin/server/communication/UIInitHandler.java29
-rw-r--r--server/src/com/vaadin/ui/AbsoluteLayout.java2
-rw-r--r--server/src/com/vaadin/ui/AbstractComponentContainer.java2
-rw-r--r--server/src/com/vaadin/ui/AbstractField.java19
-rw-r--r--server/src/com/vaadin/ui/AbstractSelect.java19
-rw-r--r--server/src/com/vaadin/ui/AbstractSplitPanel.java16
-rw-r--r--server/src/com/vaadin/ui/AbstractTextField.java2
-rw-r--r--server/src/com/vaadin/ui/ComboBox.java4
-rw-r--r--server/src/com/vaadin/ui/CssLayout.java4
-rw-r--r--server/src/com/vaadin/ui/CustomLayout.java4
-rw-r--r--server/src/com/vaadin/ui/DateField.java16
-rw-r--r--server/src/com/vaadin/ui/Field.java22
-rw-r--r--server/src/com/vaadin/ui/Form.java9
-rw-r--r--server/src/com/vaadin/ui/GridLayout.java3
-rw-r--r--server/src/com/vaadin/ui/RichTextArea.java2
-rw-r--r--server/src/com/vaadin/ui/TabSheet.java11
-rw-r--r--server/src/com/vaadin/ui/TextField.java15
-rw-r--r--server/src/com/vaadin/ui/UI.java8
-rw-r--r--server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java74
-rw-r--r--server/tests/src/com/vaadin/data/util/BeanContainerTest.java13
-rw-r--r--server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java55
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java188
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestDefaultConverterFactory.java128
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java28
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java16
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java14
-rw-r--r--server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java15
-rw-r--r--server/tests/src/com/vaadin/tests/server/FileResourceTest.java36
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java21
-rw-r--r--server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java50
-rw-r--r--server/tests/src/com/vaadin/ui/AbstractSelectTest.java71
-rw-r--r--server/tests/src/com/vaadin/ui/RichTextAreaTest.java47
-rw-r--r--server/tests/src/com/vaadin/ui/TextAreaTest.java47
-rw-r--r--server/tests/src/com/vaadin/ui/UIThemeEscaping.java89
-rw-r--r--shared/src/com/vaadin/shared/VBrowserDetails.java11
-rw-r--r--uitest/ivy.xml2
-rw-r--r--uitest/src/com/vaadin/tests/components/TooltipPosition.java70
-rw-r--r--uitest/src/com/vaadin/tests/components/TooltipPositionTest.java173
-rw-r--r--uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java13
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java55
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java8
-rw-r--r--uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocale.java57
-rw-r--r--uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocaleTest.java80
-rw-r--r--uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplate.java44
-rw-r--r--uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplateTest.java43
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java43
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java81
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPosition.java52
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPositionTest.java68
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java57
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java51
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPosition.java27
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPositionTest.java43
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPosition.java30
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPositionTest.java43
-rw-r--r--uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidth.java58
-rw-r--r--uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidthTest.java57
-rw-r--r--uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java2
-rw-r--r--uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValo.java60
-rw-r--r--uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValoTest.java72
-rw-r--r--uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java1
-rw-r--r--uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/select/EnumSelect.java69
-rw-r--r--uitest/src/com/vaadin/tests/components/select/EnumSelectTest.java61
-rw-r--r--uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeight.java87
-rw-r--r--uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeightTest.java71
-rw-r--r--uitest/src/com/vaadin/tests/components/table/DelayedColumnLayouting.java72
-rw-r--r--uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndex.html43
-rw-r--r--uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndexTest.java63
-rw-r--r--uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheet.java44
-rw-r--r--uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheetTest.java27
-rw-r--r--uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFields.java106
-rw-r--r--uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFieldsTest.java212
-rw-r--r--uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java1
-rw-r--r--uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumns.java44
-rw-r--r--uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumnsTest.java31
-rw-r--r--uitest/src/com/vaadin/tests/debug/PushVersionInfo.java51
-rw-r--r--uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java102
-rw-r--r--uitest/src/com/vaadin/tests/fieldgroup/BasicCrud.java110
-rw-r--r--uitest/src/com/vaadin/tests/fieldgroup/BasicCrudTest.java68
-rw-r--r--uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java72
-rw-r--r--uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java37
-rw-r--r--uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java31
-rw-r--r--uitest/src/com/vaadin/tests/layouts/HorizontalLayoutWithLabelAndButton.java43
-rw-r--r--uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java2
-rw-r--r--uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonAction.java128
-rw-r--r--uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java95
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java8
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java9
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurationTest.java12
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java5
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurator.java11
-rw-r--r--uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java12
-rw-r--r--uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotification.java30
-rw-r--r--uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotificationTest.java25
-rw-r--r--uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java5
-rw-r--r--uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java16
-rw-r--r--uitest/src/com/vaadin/tests/themes/valo/ModalWindowTest.java34
-rw-r--r--uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java4
255 files changed, 5168 insertions, 837 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000000..5c304d1a4a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ 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.
diff --git a/README.md b/README.md
index 45421f3fbd..2f972ebefa 100644
--- a/README.md
+++ b/README.md
@@ -104,10 +104,15 @@ Note that the included Vaadin TestBench (browser) tests require access to a Test
Building a package
=====
-The distribution files can be built in two steps.
+The distribution files can be built in two steps.
1. Unpack required gwt jars into the project
<pre><code>ant -f gwt-files.xml unpack.gwt</code></pre>
2. Build the project by running
<pre><code>ant</code></pre>
in the project root directory (add -Dvaadin.version=1.2.3 to use a specific version number).
+
+Setting up other IDEs to Develop Vaadin 7
+=========
+- Unofficial instructions
+ - IntelliJ IDEA: http://github.com/Saulis/vaadin-idea-workspace/
diff --git a/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss b/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss
index 85fbb3295f..c1a8d119c7 100644
--- a/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss
+++ b/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss
@@ -9,8 +9,8 @@ div.#{$primaryStyleName} {
-moz-box-shadow: 0 2px 5px rgba(0,0,0,.7);
box-shadow: 0 2px 5px rgba(0,0,0,.7);
//IE8 does not support rgba, using just rgb
- background:rgb(255,255,255) url(../img/grad-light-top.png) repeat-x;
- background:rgba(255,255,255,.90) url(../img/grad-light-top.png) repeat-x;
+ background:rgb(255,255,255) url(../../img/grad-light-top.png) repeat-x;
+ background:rgba(255,255,255,.90) url(../../img/grad-light-top.png) repeat-x;
}
.#{$primaryStyleName} p {
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/arrow-down.png b/WebContent/VAADIN/themes/runo/icons/icons16/arrow-down.png
new file mode 100644
index 0000000000..ffd0ee50a5
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/arrow-down.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/arrow-left.png b/WebContent/VAADIN/themes/runo/icons/icons16/arrow-left.png
new file mode 100644
index 0000000000..27dd25110d
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/arrow-left.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/arrow-right.png b/WebContent/VAADIN/themes/runo/icons/icons16/arrow-right.png
new file mode 100644
index 0000000000..69bf88da8a
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/arrow-right.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/arrow-up.png b/WebContent/VAADIN/themes/runo/icons/icons16/arrow-up.png
new file mode 100644
index 0000000000..76e5b43e08
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/arrow-up.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/attention.png b/WebContent/VAADIN/themes/runo/icons/icons16/attention.png
new file mode 100644
index 0000000000..350de56aa5
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/attention.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/calendar.png b/WebContent/VAADIN/themes/runo/icons/icons16/calendar.png
new file mode 100644
index 0000000000..7717a5e220
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/calendar.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/cancel.png b/WebContent/VAADIN/themes/runo/icons/icons16/cancel.png
new file mode 100644
index 0000000000..19a0783733
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/cancel.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document-add.png b/WebContent/VAADIN/themes/runo/icons/icons16/document-add.png
new file mode 100644
index 0000000000..d84e349526
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document-add.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document-delete.png b/WebContent/VAADIN/themes/runo/icons/icons16/document-delete.png
new file mode 100644
index 0000000000..cc3172224a
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document-delete.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document-doc.png b/WebContent/VAADIN/themes/runo/icons/icons16/document-doc.png
new file mode 100644
index 0000000000..7def77428a
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document-doc.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document-image.png b/WebContent/VAADIN/themes/runo/icons/icons16/document-image.png
new file mode 100644
index 0000000000..8a1bf253e8
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document-image.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document-pdf.png b/WebContent/VAADIN/themes/runo/icons/icons16/document-pdf.png
new file mode 100644
index 0000000000..b58ccf7567
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document-pdf.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document-ppt.png b/WebContent/VAADIN/themes/runo/icons/icons16/document-ppt.png
new file mode 100644
index 0000000000..b60f429be2
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document-ppt.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document-txt.png b/WebContent/VAADIN/themes/runo/icons/icons16/document-txt.png
new file mode 100644
index 0000000000..05659b19b2
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document-txt.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document-web.png b/WebContent/VAADIN/themes/runo/icons/icons16/document-web.png
new file mode 100644
index 0000000000..fcfd8685f0
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document-web.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document-xsl.png b/WebContent/VAADIN/themes/runo/icons/icons16/document-xsl.png
new file mode 100644
index 0000000000..571823847f
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document-xsl.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/document.png b/WebContent/VAADIN/themes/runo/icons/icons16/document.png
new file mode 100644
index 0000000000..a2bab1bb0b
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/document.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/email-reply.png b/WebContent/VAADIN/themes/runo/icons/icons16/email-reply.png
new file mode 100644
index 0000000000..be7fd2244d
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/email-reply.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/email-send.png b/WebContent/VAADIN/themes/runo/icons/icons16/email-send.png
new file mode 100644
index 0000000000..0ef7a1c398
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/email-send.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/email.png b/WebContent/VAADIN/themes/runo/icons/icons16/email.png
new file mode 100644
index 0000000000..68d6c93465
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/email.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/error.gif b/WebContent/VAADIN/themes/runo/icons/icons16/error.gif
new file mode 100644
index 0000000000..c9582b2c28
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/error.gif
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/error.png b/WebContent/VAADIN/themes/runo/icons/icons16/error.png
new file mode 100644
index 0000000000..0141e4dfc3
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/error.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/folder-add.png b/WebContent/VAADIN/themes/runo/icons/icons16/folder-add.png
new file mode 100644
index 0000000000..48aa7c9220
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/folder-add.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/folder-delete.png b/WebContent/VAADIN/themes/runo/icons/icons16/folder-delete.png
new file mode 100644
index 0000000000..7cc389d6b2
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/folder-delete.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/folder.png b/WebContent/VAADIN/themes/runo/icons/icons16/folder.png
new file mode 100644
index 0000000000..f4fec377c6
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/folder.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/globe.png b/WebContent/VAADIN/themes/runo/icons/icons16/globe.png
new file mode 100644
index 0000000000..ea4034c149
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/globe.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/help.png b/WebContent/VAADIN/themes/runo/icons/icons16/help.png
new file mode 100644
index 0000000000..d82a8852bf
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/help.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/lock.png b/WebContent/VAADIN/themes/runo/icons/icons16/lock.png
new file mode 100644
index 0000000000..29f1023613
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/lock.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/note.png b/WebContent/VAADIN/themes/runo/icons/icons16/note.png
new file mode 100644
index 0000000000..efafae5570
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/note.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/ok.png b/WebContent/VAADIN/themes/runo/icons/icons16/ok.png
new file mode 100644
index 0000000000..89591faef2
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/ok.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/reload.png b/WebContent/VAADIN/themes/runo/icons/icons16/reload.png
new file mode 100644
index 0000000000..2c54836bff
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/reload.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/settings.png b/WebContent/VAADIN/themes/runo/icons/icons16/settings.png
new file mode 100644
index 0000000000..019f0df663
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/settings.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/trash-full.png b/WebContent/VAADIN/themes/runo/icons/icons16/trash-full.png
new file mode 100644
index 0000000000..7d790e6c9a
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/trash-full.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/trash.png b/WebContent/VAADIN/themes/runo/icons/icons16/trash.png
new file mode 100644
index 0000000000..8875ae322e
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/trash.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/user.png b/WebContent/VAADIN/themes/runo/icons/icons16/user.png
new file mode 100644
index 0000000000..522f864884
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/user.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons16/users.png b/WebContent/VAADIN/themes/runo/icons/icons16/users.png
new file mode 100644
index 0000000000..01f2a1251c
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons16/users.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/arrow-down.png b/WebContent/VAADIN/themes/runo/icons/icons32/arrow-down.png
new file mode 100644
index 0000000000..20c33b70fb
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/arrow-down.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/arrow-left.png b/WebContent/VAADIN/themes/runo/icons/icons32/arrow-left.png
new file mode 100644
index 0000000000..ed2aae2cb0
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/arrow-left.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/arrow-right.png b/WebContent/VAADIN/themes/runo/icons/icons32/arrow-right.png
new file mode 100644
index 0000000000..bd7707ec8a
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/arrow-right.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/arrow-up.png b/WebContent/VAADIN/themes/runo/icons/icons32/arrow-up.png
new file mode 100644
index 0000000000..01c1a8ec83
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/arrow-up.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/attention.png b/WebContent/VAADIN/themes/runo/icons/icons32/attention.png
new file mode 100644
index 0000000000..6b00733567
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/attention.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/calendar.png b/WebContent/VAADIN/themes/runo/icons/icons32/calendar.png
new file mode 100644
index 0000000000..789ad9031c
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/calendar.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/cancel.png b/WebContent/VAADIN/themes/runo/icons/icons32/cancel.png
new file mode 100644
index 0000000000..725240d558
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/cancel.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-add.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-add.png
new file mode 100644
index 0000000000..26bca0d112
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-add.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-delete.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-delete.png
new file mode 100644
index 0000000000..43e9a43e5b
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-delete.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-doc.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-doc.png
new file mode 100644
index 0000000000..8df20cfdcf
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-doc.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-edit.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-edit.png
new file mode 100644
index 0000000000..1d17383ca7
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-edit.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-image.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-image.png
new file mode 100644
index 0000000000..88c78665b8
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-image.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-pdf.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-pdf.png
new file mode 100644
index 0000000000..048a02fddf
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-pdf.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-ppt.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-ppt.png
new file mode 100644
index 0000000000..7fd7385cbd
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-ppt.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-txt.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-txt.png
new file mode 100644
index 0000000000..25264732c6
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-txt.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-web.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-web.png
new file mode 100644
index 0000000000..72fd847ac3
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-web.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document-xsl.png b/WebContent/VAADIN/themes/runo/icons/icons32/document-xsl.png
new file mode 100644
index 0000000000..2ff4607ad3
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document-xsl.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/document.png b/WebContent/VAADIN/themes/runo/icons/icons32/document.png
new file mode 100644
index 0000000000..1a38dcc304
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/document.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/email-reply.png b/WebContent/VAADIN/themes/runo/icons/icons32/email-reply.png
new file mode 100644
index 0000000000..fd0203f768
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/email-reply.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/email-send.png b/WebContent/VAADIN/themes/runo/icons/icons32/email-send.png
new file mode 100644
index 0000000000..dc34ac694d
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/email-send.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/email.png b/WebContent/VAADIN/themes/runo/icons/icons32/email.png
new file mode 100644
index 0000000000..bef86e6cbb
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/email.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/folder-add.png b/WebContent/VAADIN/themes/runo/icons/icons32/folder-add.png
new file mode 100644
index 0000000000..e0b78d6e1d
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/folder-add.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/folder-delete.png b/WebContent/VAADIN/themes/runo/icons/icons32/folder-delete.png
new file mode 100644
index 0000000000..8e3c4a404c
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/folder-delete.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/folder.png b/WebContent/VAADIN/themes/runo/icons/icons32/folder.png
new file mode 100644
index 0000000000..7577a17ac3
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/folder.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/globe.png b/WebContent/VAADIN/themes/runo/icons/icons32/globe.png
new file mode 100644
index 0000000000..6c7d469ba2
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/globe.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/help.png b/WebContent/VAADIN/themes/runo/icons/icons32/help.png
new file mode 100644
index 0000000000..218910c98d
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/help.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/lock.png b/WebContent/VAADIN/themes/runo/icons/icons32/lock.png
new file mode 100644
index 0000000000..4fc16565f0
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/lock.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/note.png b/WebContent/VAADIN/themes/runo/icons/icons32/note.png
new file mode 100644
index 0000000000..e7e035dc8c
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/note.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/ok.png b/WebContent/VAADIN/themes/runo/icons/icons32/ok.png
new file mode 100644
index 0000000000..ac0438828c
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/ok.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/reload.png b/WebContent/VAADIN/themes/runo/icons/icons32/reload.png
new file mode 100644
index 0000000000..c3556ec890
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/reload.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/settings.png b/WebContent/VAADIN/themes/runo/icons/icons32/settings.png
new file mode 100644
index 0000000000..92eda74c54
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/settings.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/trash-full.png b/WebContent/VAADIN/themes/runo/icons/icons32/trash-full.png
new file mode 100644
index 0000000000..a9707e76d6
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/trash-full.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/trash.png b/WebContent/VAADIN/themes/runo/icons/icons32/trash.png
new file mode 100644
index 0000000000..6eaac86166
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/trash.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/user.png b/WebContent/VAADIN/themes/runo/icons/icons32/user.png
new file mode 100644
index 0000000000..ebb5a7f9f8
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/user.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons32/users.png b/WebContent/VAADIN/themes/runo/icons/icons32/users.png
new file mode 100644
index 0000000000..af225a9e46
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons32/users.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/arrow-down.png b/WebContent/VAADIN/themes/runo/icons/icons64/arrow-down.png
new file mode 100644
index 0000000000..bdf5d0474e
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/arrow-down.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/arrow-left.png b/WebContent/VAADIN/themes/runo/icons/icons64/arrow-left.png
new file mode 100644
index 0000000000..b90ed88840
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/arrow-left.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/arrow-right.png b/WebContent/VAADIN/themes/runo/icons/icons64/arrow-right.png
new file mode 100644
index 0000000000..6331a5ddf3
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/arrow-right.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/arrow-up.png b/WebContent/VAADIN/themes/runo/icons/icons64/arrow-up.png
new file mode 100644
index 0000000000..821fbe348f
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/arrow-up.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/attention.png b/WebContent/VAADIN/themes/runo/icons/icons64/attention.png
new file mode 100644
index 0000000000..77265e48ee
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/attention.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/calendar.png b/WebContent/VAADIN/themes/runo/icons/icons64/calendar.png
new file mode 100644
index 0000000000..f13fbd6efb
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/calendar.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/cancel.png b/WebContent/VAADIN/themes/runo/icons/icons64/cancel.png
new file mode 100644
index 0000000000..1d1a719a6c
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/cancel.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-add.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-add.png
new file mode 100644
index 0000000000..acdcb06123
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-add.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-delete.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-delete.png
new file mode 100644
index 0000000000..2a46863b7f
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-delete.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-doc.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-doc.png
new file mode 100644
index 0000000000..455c1f15bd
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-doc.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-edit.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-edit.png
new file mode 100644
index 0000000000..6af96c9b77
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-edit.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-image.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-image.png
new file mode 100644
index 0000000000..079978e850
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-image.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-pdf.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-pdf.png
new file mode 100644
index 0000000000..cb6bc59675
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-pdf.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-ppt.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-ppt.png
new file mode 100644
index 0000000000..dd501bfbc9
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-ppt.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-txt.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-txt.png
new file mode 100644
index 0000000000..e64f746bd9
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-txt.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-web.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-web.png
new file mode 100644
index 0000000000..9d81eb5702
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-web.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document-xsl.png b/WebContent/VAADIN/themes/runo/icons/icons64/document-xsl.png
new file mode 100644
index 0000000000..6008085a34
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document-xsl.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/document.png b/WebContent/VAADIN/themes/runo/icons/icons64/document.png
new file mode 100644
index 0000000000..224de0bc84
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/document.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/email-reply.png b/WebContent/VAADIN/themes/runo/icons/icons64/email-reply.png
new file mode 100644
index 0000000000..2c6f7b690d
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/email-reply.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/email-send.png b/WebContent/VAADIN/themes/runo/icons/icons64/email-send.png
new file mode 100644
index 0000000000..9ec7198853
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/email-send.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/email.png b/WebContent/VAADIN/themes/runo/icons/icons64/email.png
new file mode 100644
index 0000000000..e11245b2f5
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/email.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/folder-add.png b/WebContent/VAADIN/themes/runo/icons/icons64/folder-add.png
new file mode 100644
index 0000000000..111318cc3c
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/folder-add.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/folder-delete.png b/WebContent/VAADIN/themes/runo/icons/icons64/folder-delete.png
new file mode 100644
index 0000000000..d249983eac
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/folder-delete.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/folder.png b/WebContent/VAADIN/themes/runo/icons/icons64/folder.png
new file mode 100644
index 0000000000..edb7b9f786
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/folder.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/globe.png b/WebContent/VAADIN/themes/runo/icons/icons64/globe.png
new file mode 100644
index 0000000000..1786635b45
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/globe.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/help.png b/WebContent/VAADIN/themes/runo/icons/icons64/help.png
new file mode 100644
index 0000000000..a66e8aafa6
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/help.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/lock.png b/WebContent/VAADIN/themes/runo/icons/icons64/lock.png
new file mode 100644
index 0000000000..deaf7db0a4
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/lock.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/note.png b/WebContent/VAADIN/themes/runo/icons/icons64/note.png
new file mode 100644
index 0000000000..1383847ed1
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/note.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/ok.png b/WebContent/VAADIN/themes/runo/icons/icons64/ok.png
new file mode 100644
index 0000000000..dc0d00c38b
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/ok.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/reload.png b/WebContent/VAADIN/themes/runo/icons/icons64/reload.png
new file mode 100644
index 0000000000..b91f51c67f
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/reload.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/settings.png b/WebContent/VAADIN/themes/runo/icons/icons64/settings.png
new file mode 100644
index 0000000000..1c9b794ab0
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/settings.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/trash-full.png b/WebContent/VAADIN/themes/runo/icons/icons64/trash-full.png
new file mode 100644
index 0000000000..81d060e509
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/trash-full.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/trash.png b/WebContent/VAADIN/themes/runo/icons/icons64/trash.png
new file mode 100644
index 0000000000..41ef761061
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/trash.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/user.png b/WebContent/VAADIN/themes/runo/icons/icons64/user.png
new file mode 100644
index 0000000000..60d6c6e1b3
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/user.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/runo/icons/icons64/users.png b/WebContent/VAADIN/themes/runo/icons/icons64/users.png
new file mode 100644
index 0000000000..3a42c17790
--- /dev/null
+++ b/WebContent/VAADIN/themes/runo/icons/icons64/users.png
Binary files differ
diff --git a/WebContent/VAADIN/themes/tests-valo-disabled-animations/_variables.scss b/WebContent/VAADIN/themes/tests-valo-disabled-animations/_variables.scss
new file mode 100644
index 0000000000..d2411c675c
--- /dev/null
+++ b/WebContent/VAADIN/themes/tests-valo-disabled-animations/_variables.scss
@@ -0,0 +1,3 @@
+$v-animations-enabled: false;
+
+@import "../valo/valo";
diff --git a/WebContent/VAADIN/themes/tests-valo-disabled-animations/styles.scss b/WebContent/VAADIN/themes/tests-valo-disabled-animations/styles.scss
new file mode 100644
index 0000000000..b941c1b3d1
--- /dev/null
+++ b/WebContent/VAADIN/themes/tests-valo-disabled-animations/styles.scss
@@ -0,0 +1,6 @@
+@import "variables";
+@import "../tests-valo/valotest";
+
+.tests-valo-disabled-animations {
+ @include valotest;
+}
diff --git a/WebContent/VAADIN/themes/valo/components/_checkbox.scss b/WebContent/VAADIN/themes/valo/components/_checkbox.scss
index 3c418ec9b7..7283c4cbbf 100644
--- a/WebContent/VAADIN/themes/valo/components/_checkbox.scss
+++ b/WebContent/VAADIN/themes/valo/components/_checkbox.scss
@@ -99,7 +99,7 @@
}
& ~ label:before {
- @include valo-button-style($background-color: $background-color, $unit-size: $size, $border-radius: min(round($size/3), $v-border-radius));
+ @include valo-button-style($background-color: $background-color, $unit-size: $size, $border-radius: min(round($size/3), $v-border-radius), $states: normal);
padding: 0;
height: round($size);
}
@@ -119,24 +119,6 @@
&:checked ~ label:after {
color: $selection-color;
}
-
- &[disabled] {
- ~ label,
- ~ label .v-icon,
- ~ .v-icon {
- cursor: default;
- }
-
- ~ label:before,
- ~ label:after {
- @include opacity($v-disabled-opacity);
- }
-
- &:active ~ label:after {
- background: transparent;
- }
- }
-
}
& > .v-icon,
@@ -146,4 +128,20 @@
cursor: pointer;
}
+ &.v-disabled {
+ > label,
+ > .v-icon {
+ cursor: default;
+ @include opacity($v-disabled-opacity);
+ }
+
+ > label > .v-icon {
+ cursor: default;
+ }
+
+ :root & > input:active ~ label:after {
+ background: transparent;
+ }
+ }
+
}
diff --git a/WebContent/VAADIN/themes/valo/components/_datefield.scss b/WebContent/VAADIN/themes/valo/components/_datefield.scss
index 3201288120..6d36ade43a 100644
--- a/WebContent/VAADIN/themes/valo/components/_datefield.scss
+++ b/WebContent/VAADIN/themes/valo/components/_datefield.scss
@@ -276,6 +276,8 @@
@include valo-overlay-style;
margin-top: ceil($v-unit-size/8) !important;
+ margin-bottom: ceil($v-unit-size/8) !important;
+ margin-right: ceil($v-unit-size/8) !important;
cursor: default;
width: auto;
diff --git a/WebContent/VAADIN/themes/valo/components/_link.scss b/WebContent/VAADIN/themes/valo/components/_link.scss
index b568df1d7b..270de1aace 100644
--- a/WebContent/VAADIN/themes/valo/components/_link.scss
+++ b/WebContent/VAADIN/themes/valo/components/_link.scss
@@ -20,8 +20,8 @@ $v-link-cursor: pointer !default;
/**
*
*
- * @param {string} $primary-stylename (v-link) -
- * @param {bool} $include-additional-styles -
+ * @param {string} $primary-stylename (v-link) -
+ * @param {bool} $include-additional-styles -
*
* @group link
*/
@@ -74,4 +74,8 @@ $v-link-cursor: pointer !default;
&:hover {
color: lighten($v-link-font-color, 10%);
}
+
+ &.v-disabled {
+ @include opacity($v-disabled-opacity);
+ }
}
diff --git a/WebContent/VAADIN/themes/valo/components/_menubar.scss b/WebContent/VAADIN/themes/valo/components/_menubar.scss
index 9075eb7ba8..0f9c61d2ce 100644
--- a/WebContent/VAADIN/themes/valo/components/_menubar.scss
+++ b/WebContent/VAADIN/themes/valo/components/_menubar.scss
@@ -70,10 +70,6 @@
.#{$primary-stylename}-popup {
@include valo-menubar-popup-style($primary-stylename);
-
- &.#{$primary-stylename}-popup-animate-out {
- @include animation(none);
- }
}
diff --git a/WebContent/VAADIN/themes/valo/components/_window.scss b/WebContent/VAADIN/themes/valo/components/_window.scss
index ce7a530c98..23fa5338c2 100644
--- a/WebContent/VAADIN/themes/valo/components/_window.scss
+++ b/WebContent/VAADIN/themes/valo/components/_window.scss
@@ -89,11 +89,12 @@ $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-animate-in-fade($duration: 400ms, $delay: 100ms);
-
- .v-op12 & {
- // Opera 12 has a shitbreak with the fade-in (flickers)
- @include animation(none);
+ @if $v-animations-enabled {
+ @include valo-animate-in-fade($duration: 400ms, $delay: 100ms);
+ .v-op12 & {
+ // Opera 12 has a shitbreak with the fade-in (flickers)
+ @include animation(none);
+ }
}
}
diff --git a/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java b/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java
index 9dd51f8c6d..0d8f117329 100644
--- a/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java
+++ b/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java
@@ -26,6 +26,7 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Logger;
+import java.util.regex.Pattern;
/**
* Generates Export-Packages attribute for OSGi compatible manifest.
@@ -172,6 +173,9 @@ public class GeneratePackageExports {
private static HashSet<String> getPackages(JarFile jar,
List<String> acceptedPackagePrefixes) {
HashSet<String> packages = new HashSet<String>();
+
+ Pattern startsWithNumber = Pattern.compile("\\.\\d");
+
for (Enumeration<JarEntry> it = jar.entries(); it.hasMoreElements();) {
JarEntry entry = it.nextElement();
@@ -189,6 +193,11 @@ public class GeneratePackageExports {
int lastSlash = entry.getName().lastIndexOf('/');
String pkg = entry.getName().substring(0, lastSlash)
.replace('/', '.');
+
+ if (startsWithNumber.matcher(pkg).find()) {
+ continue;
+ }
+
packages.add(pkg);
}
diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java
index 12b1585292..4865e38a4a 100644
--- a/client/src/com/vaadin/client/ApplicationConfiguration.java
+++ b/client/src/com/vaadin/client/ApplicationConfiguration.java
@@ -172,6 +172,33 @@ public class ApplicationConfiguration implements EntryPoint {
return this.getConfig("versionInfo").vaadinVersion;
}-*/;
+ /**
+ * Gets the version of the Atmosphere framework.
+ *
+ * @return a string with the version
+ *
+ * @see org.atmosphere.util#getRawVersion()
+ */
+ private native String getAtmosphereVersion()
+ /*-{
+ return this.getConfig("versionInfo").atmosphereVersion;
+ }-*/;
+
+ /**
+ * Gets the JS version used in the Atmosphere framework.
+ *
+ * @return a string with the version
+ */
+ private native String getAtmosphereJSVersion()
+ /*-{
+ if ($wnd.jQueryVaadin != undefined){
+ return $wnd.jQueryVaadin.atmosphere.version;
+ }
+ else {
+ return null;
+ }
+ }-*/;
+
private native String getUIDL()
/*-{
return this.getConfig("uidl");
@@ -461,6 +488,24 @@ public class ApplicationConfiguration implements EntryPoint {
return getJsoConfiguration(id).getVaadinVersion();
}
+ /**
+ * Return Atmosphere version.
+ *
+ * @return Atmosphere version.
+ */
+ public String getAtmosphereVersion() {
+ return getJsoConfiguration(id).getAtmosphereVersion();
+ }
+
+ /**
+ * Return Atmosphere JS version.
+ *
+ * @return Atmosphere JS version.
+ */
+ public String getAtmosphereJSVersion() {
+ return getJsoConfiguration(id).getAtmosphereJSVersion();
+ }
+
public Class<? extends ServerConnector> getConnectorClassByEncodedTag(
int tag) {
Class<? extends ServerConnector> type = classes.get(tag);
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index d7c1c54a2d..f683181857 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -66,6 +66,7 @@ import com.google.gwt.user.client.Window.ClosingHandler;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConfiguration.ErrorMessage;
+import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadListener;
import com.vaadin.client.communication.HasJavaScriptConnectorHelper;
@@ -202,14 +203,6 @@ public class ApplicationConnection implements HasHandlers {
private boolean hasActiveRequest = false;
/**
- * Some browsers cancel pending XHR requests when a request that might
- * navigate away from the page starts (indicated by a beforeunload event).
- * In that case, we should just send the request again without displaying
- * any error.
- */
- private boolean retryCanceledActiveRequest = false;
-
- /**
* Webkit will ignore outgoing requests while waiting for a response to a
* navigation event (indicated by a beforeunload event). When this happens,
* we should keep trying to send the request every now and then until there
@@ -547,14 +540,6 @@ public class ApplicationConnection implements HasHandlers {
Window.addWindowClosingHandler(new ClosingHandler() {
@Override
public void onWindowClosing(ClosingEvent event) {
- /*
- * Set some flags to avoid potential problems with XHR requests,
- * see javadocs of the flags for details
- */
- if (hasActiveRequest()) {
- retryCanceledActiveRequest = true;
- }
-
webkitMaybeIgnoringRequests = true;
}
});
@@ -858,6 +843,22 @@ public class ApplicationConnection implements HasHandlers {
* The contents of the request to send
*/
protected void doUidlRequest(final String uri, final JSONObject payload) {
+ doUidlRequest(uri, payload, true);
+ }
+
+ /**
+ * 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
+ * The contents of the request to send
+ * @param retry
+ * true when a status code 0 should be retried
+ */
+ protected void doUidlRequest(final String uri, final JSONObject payload,
+ final boolean retry) {
RequestCallback requestCallback = new RequestCallback() {
@Override
public void onError(Request request, Throwable exception) {
@@ -887,15 +888,29 @@ public class ApplicationConnection implements HasHandlers {
switch (statusCode) {
case 0:
- if (retryCanceledActiveRequest) {
+ if (retry) {
/*
- * Request was most likely canceled because the browser
- * is maybe navigating away from the page. Just send the
- * request again without displaying any error in case
- * the navigation isn't carried through.
+ * There are 2 situations where the error can pop up:
+ *
+ * 1) Request was most likely canceled because the
+ * browser is maybe navigating away from the page. Just
+ * send the request again without displaying any error
+ * in case the navigation isn't carried through.
+ *
+ * 2) The browser failed to establish a network
+ * connection. This was observed with keep-alive
+ * requests, and under wi-fi roaming conditions.
+ *
+ * Status code 0 does indicate that there was no server
+ * side processing, so we can retry the request.
*/
- retryCanceledActiveRequest = false;
- doUidlRequest(uri, payload);
+ VConsole.log("Status code 0, retrying");
+ (new Timer() {
+ @Override
+ public void run() {
+ doUidlRequest(uri, payload, false);
+ }
+ }).schedule(100);
} else {
handleCommunicationError(
"Invalid status code 0 (server down?)",
@@ -1269,7 +1284,6 @@ public class ApplicationConnection implements HasHandlers {
// so setting it after used to work but not with the #8505 changes.
hasActiveRequest = false;
- retryCanceledActiveRequest = false;
webkitMaybeIgnoringRequests = false;
if (isApplicationRunning()) {
diff --git a/client/src/com/vaadin/client/VTooltip.java b/client/src/com/vaadin/client/VTooltip.java
index edd1273bf5..47a1b71228 100644
--- a/client/src/com/vaadin/client/VTooltip.java
+++ b/client/src/com/vaadin/client/VTooltip.java
@@ -210,6 +210,14 @@ public class VTooltip extends VOverlay {
x = Window.getClientWidth() - offsetWidth - MARGIN
+ Window.getScrollLeft();
}
+
+ if (tooltipEventMouseX != EVENT_XY_POSITION_OUTSIDE) {
+ // Do not allow x to be zero, for otherwise the tooltip
+ // does not close when the mouse is moved (see
+ // isTooltipOpen()). #15129
+ int minX = Window.getScrollLeft() + MARGIN;
+ x = Math.max(x, minX);
+ }
return x;
}
@@ -245,6 +253,14 @@ public class VTooltip extends VOverlay {
y = Window.getScrollTop();
}
}
+
+ if (tooltipEventMouseY != EVENT_XY_POSITION_OUTSIDE) {
+ // Do not allow y to be zero, for otherwise the tooltip
+ // does not close when the mouse is moved (see
+ // isTooltipOpen()). #15129
+ int minY = Window.getScrollTop() + MARGIN;
+ y = Math.max(y, minY);
+ }
return y;
}
});
@@ -323,6 +339,7 @@ public class VTooltip extends VOverlay {
setPopupPosition(tooltipEventMouseX, tooltipEventMouseY);
}
+ private int EVENT_XY_POSITION_OUTSIDE = -5000;
private int tooltipEventMouseX;
private int tooltipEventMouseY;
@@ -332,11 +349,13 @@ public class VTooltip extends VOverlay {
}
private int getEventX(Event event, boolean isFocused) {
- return isFocused ? -5000 : DOM.eventGetClientX(event);
+ return isFocused ? EVENT_XY_POSITION_OUTSIDE : DOM
+ .eventGetClientX(event);
}
private int getEventY(Event event, boolean isFocused) {
- return isFocused ? -5000 : DOM.eventGetClientY(event);
+ return isFocused ? EVENT_XY_POSITION_OUTSIDE : DOM
+ .eventGetClientY(event);
}
@Override
diff --git a/client/src/com/vaadin/client/debug/internal/InfoSection.java b/client/src/com/vaadin/client/debug/internal/InfoSection.java
index a7a84f5f8f..dfb31cdd18 100644
--- a/client/src/com/vaadin/client/debug/internal/InfoSection.java
+++ b/client/src/com/vaadin/client/debug/internal/InfoSection.java
@@ -193,6 +193,9 @@ public class InfoSection implements Section {
ApplicationConfiguration applicationConfiguration) {
String clientVersion = Version.getFullVersion();
String servletVersion = applicationConfiguration.getServletVersion();
+ String atmosphereVersion = applicationConfiguration
+ .getAtmosphereVersion();
+ String jsVersion = applicationConfiguration.getAtmosphereJSVersion();
String themeVersion;
boolean themeOk;
@@ -213,6 +216,11 @@ public class InfoSection implements Section {
addRow("Server engine version", servletVersion, servletOk ? null
: ERROR_STYLE);
addRow("Theme version", themeVersion, themeOk ? null : ERROR_STYLE);
+ if (jsVersion != null) {
+ addRow("Push server version", atmosphereVersion);
+ addRow("Push client version", jsVersion
+ + " (note: does not need to match server version)");
+ }
}
/**
diff --git a/client/src/com/vaadin/client/ui/VAbstractSplitPanel.java b/client/src/com/vaadin/client/ui/VAbstractSplitPanel.java
index 6ee88d51dd..9d32355b70 100644
--- a/client/src/com/vaadin/client/ui/VAbstractSplitPanel.java
+++ b/client/src/com/vaadin/client/ui/VAbstractSplitPanel.java
@@ -199,6 +199,7 @@ public class VAbstractSplitPanel extends ComplexPanel {
private void setOrientation(Orientation orientation) {
this.orientation = orientation;
+
if (orientation == Orientation.HORIZONTAL) {
splitter.getStyle().setHeight(100, Unit.PCT);
splitter.getStyle().setTop(0, Unit.PX);
@@ -393,107 +394,118 @@ public class VAbstractSplitPanel extends ComplexPanel {
return;
}
- int wholeSize;
- int pixelPosition;
-
switch (orientation) {
case HORIZONTAL:
- wholeSize = DOM.getElementPropertyInt(wrapper, "clientWidth");
- pixelPosition = DOM.getElementPropertyInt(splitter, "offsetLeft");
-
- // reposition splitter in case it is out of box
- if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize)
- || (positionReversed && pixelPosition < 0)) {
- pixelPosition = wholeSize - getSplitterSize();
- if (pixelPosition < 0) {
- pixelPosition = 0;
- }
- // Move splitter within bounds, but don't remember the new value
- setSplitPosition(pixelPosition + "px", false);
- return;
- }
+ horizontalOrientationUpdateSizes();
+ break;
+ case VERTICAL:
+ verticalOrientationUpdateSizes();
+ break;
+ }
+ }
- firstContainer.getStyle().setWidth(pixelPosition, Unit.PX);
- int secondContainerWidth = (wholeSize - pixelPosition - getSplitterSize());
- if (secondContainerWidth < 0) {
- secondContainerWidth = 0;
- }
- secondContainer.getStyle().setWidth(secondContainerWidth, Unit.PX);
- secondContainer.getStyle().setLeft(
- pixelPosition + getSplitterSize(), Unit.PX);
-
- LayoutManager layoutManager = LayoutManager.get(client);
- ConnectorMap connectorMap = ConnectorMap.get(client);
- if (firstChild != null) {
- ComponentConnector connector = connectorMap
- .getConnector(firstChild);
- if (connector.isRelativeWidth()) {
- layoutManager.reportWidthAssignedToRelative(connector,
- pixelPosition);
- } else {
- layoutManager.setNeedsMeasure(connector);
- }
+ private void verticalOrientationUpdateSizes() {
+ int wholeSize = DOM.getElementPropertyInt(wrapper, "clientHeight");
+ int pixelPosition = DOM.getElementPropertyInt(splitter, "offsetTop");
+
+ // reposition splitter in case it is out of box
+ if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize)
+ || (positionReversed && pixelPosition < 0)) {
+ pixelPosition = wholeSize - getSplitterSize();
+ if (pixelPosition < 0) {
+ pixelPosition = 0;
}
- if (secondChild != null) {
- ComponentConnector connector = connectorMap
- .getConnector(secondChild);
- if (connector.isRelativeWidth()) {
- layoutManager.reportWidthAssignedToRelative(connector,
- secondContainerWidth);
- } else {
- layoutManager.setNeedsMeasure(connector);
- }
+ // Move splitter within bounds, but don't remember the new value
+ setSplitPosition(pixelPosition + "px", false);
+ return;
+ }
+
+ firstContainer.getStyle().setHeight(pixelPosition, Unit.PX);
+ int secondContainerHeight = (wholeSize - pixelPosition - getSplitterSize());
+ if (secondContainerHeight < 0) {
+ secondContainerHeight = 0;
+ }
+ secondContainer.getStyle().setHeight(secondContainerHeight, Unit.PX);
+ secondContainer.getStyle().setTop(pixelPosition + getSplitterSize(),
+ Unit.PX);
+
+ LayoutManager layoutManager = LayoutManager.get(client);
+ ConnectorMap connectorMap = ConnectorMap.get(client);
+ if (firstChild != null) {
+ ComponentConnector connector = connectorMap
+ .getConnector(firstChild);
+ if (connector.isRelativeHeight()) {
+ layoutManager.reportHeightAssignedToRelative(connector,
+ pixelPosition);
+ } else {
+ layoutManager.setNeedsMeasure(connector);
}
- break;
- case VERTICAL:
- wholeSize = DOM.getElementPropertyInt(wrapper, "clientHeight");
- pixelPosition = DOM.getElementPropertyInt(splitter, "offsetTop");
-
- // reposition splitter in case it is out of box
- if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize)
- || (positionReversed && pixelPosition < 0)) {
- pixelPosition = wholeSize - getSplitterSize();
- if (pixelPosition < 0) {
- pixelPosition = 0;
- }
- // Move splitter within bounds, but don't remember the new value
- setSplitPosition(pixelPosition + "px", false);
- return;
+ }
+ if (secondChild != null) {
+ ComponentConnector connector = connectorMap
+ .getConnector(secondChild);
+ if (connector.isRelativeHeight()) {
+ layoutManager.reportHeightAssignedToRelative(connector,
+ secondContainerHeight);
+ } else {
+ layoutManager.setNeedsMeasure(connector);
}
+ }
+ }
+
+ private void horizontalOrientationUpdateSizes() {
+ int wholeSize = DOM.getElementPropertyInt(wrapper, "clientWidth");
+ int pixelPosition = DOM.getElementPropertyInt(splitter, "offsetLeft");
- firstContainer.getStyle().setHeight(pixelPosition, Unit.PX);
- int secondContainerHeight = (wholeSize - pixelPosition - getSplitterSize());
- if (secondContainerHeight < 0) {
- secondContainerHeight = 0;
+ // reposition splitter in case it is out of box
+ if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize)
+ || (positionReversed && pixelPosition < 0)) {
+ pixelPosition = wholeSize - getSplitterSize();
+ if (pixelPosition < 0) {
+ pixelPosition = 0;
}
- secondContainer.getStyle()
- .setHeight(secondContainerHeight, Unit.PX);
- secondContainer.getStyle().setTop(
- pixelPosition + getSplitterSize(), Unit.PX);
-
- layoutManager = LayoutManager.get(client);
- connectorMap = ConnectorMap.get(client);
- if (firstChild != null) {
- ComponentConnector connector = connectorMap
- .getConnector(firstChild);
- if (connector.isRelativeHeight()) {
- layoutManager.reportHeightAssignedToRelative(connector,
- pixelPosition);
- } else {
- layoutManager.setNeedsMeasure(connector);
- }
+ // Move splitter within bounds, but don't remember the new value
+ setSplitPosition(pixelPosition + "px", false);
+ return;
+ }
+
+ firstContainer.getStyle().setWidth(pixelPosition, Unit.PX);
+ int secondContainerWidth = (wholeSize - pixelPosition - getSplitterSize());
+ if (secondContainerWidth < 0) {
+ secondContainerWidth = 0;
+ }
+ secondContainer.getStyle().setWidth(secondContainerWidth, Unit.PX);
+ secondContainer.getStyle().setLeft(pixelPosition + getSplitterSize(),
+ Unit.PX);
+
+ LayoutManager layoutManager = LayoutManager.get(client);
+ ConnectorMap connectorMap = ConnectorMap.get(client);
+ if (firstChild != null) {
+ ComponentConnector connector = connectorMap
+ .getConnector(firstChild);
+ if (connector.isRelativeWidth()) {
+ layoutManager.reportWidthAssignedToRelative(connector,
+ pixelPosition);
+ } else {
+ layoutManager.setNeedsMeasure(connector);
}
- if (secondChild != null) {
- ComponentConnector connector = connectorMap
- .getConnector(secondChild);
- if (connector.isRelativeHeight()) {
- layoutManager.reportHeightAssignedToRelative(connector,
- secondContainerHeight);
- } else {
- layoutManager.setNeedsMeasure(connector);
- }
+ }
+ if (secondChild != null) {
+ ComponentConnector connector = connectorMap
+ .getConnector(secondChild);
+ if (connector.isRelativeWidth()) {
+ layoutManager.reportWidthAssignedToRelative(connector,
+ secondContainerWidth);
+ } else {
+ layoutManager.setNeedsMeasure(connector);
}
- break;
+ }
+
+ // previous layout pass may have changed the position already, needs to
+ // be reset before calculating which positioning should be used
+ secondContainer.getStyle().setPosition(Position.ABSOLUTE);
+ if (getOffsetHeight() == 0) {
+ secondContainer.getStyle().setPosition(Position.RELATIVE);
}
}
diff --git a/client/src/com/vaadin/client/ui/VAccordion.java b/client/src/com/vaadin/client/ui/VAccordion.java
index 3e89958a98..ff77a8cb91 100644
--- a/client/src/com/vaadin/client/ui/VAccordion.java
+++ b/client/src/com/vaadin/client/ui/VAccordion.java
@@ -159,6 +159,8 @@ public class VAccordion extends VTabsheetBase {
*/
public class StackItem extends ComplexPanel implements ClickHandler {
+ private Widget widget;
+
public void setHeight(int height) {
if (height == -1) {
super.setHeight("");
@@ -171,10 +173,7 @@ public class VAccordion extends VTabsheetBase {
}
public Widget getComponent() {
- if (getWidgetCount() < 2) {
- return null;
- }
- return getWidget(1);
+ return widget;
}
@Override
@@ -268,24 +267,26 @@ public class VAccordion extends VTabsheetBase {
}
public Widget getChildWidget() {
- if (getWidgetCount() > 1) {
- return getWidget(1);
- } else {
- return null;
- }
+ return widget;
}
public void replaceWidget(Widget newWidget) {
- if (getWidgetCount() > 1) {
- Widget oldWidget = getWidget(1);
- remove(oldWidget);
- widgets.remove(oldWidget);
+ if (widget != null) {
+ widgets.remove(widget);
+ if (open) {
+ remove(widget);
+ }
}
- add(newWidget, content);
+ widget = newWidget;
widgets.add(newWidget);
+ if (open) {
+ add(widget, content);
+ }
+
}
public void open() {
+ add(widget, content);
open = true;
content.getStyle().setTop(getCaptionHeight(), Unit.PX);
content.getStyle().setLeft(0, Unit.PX);
@@ -298,6 +299,9 @@ public class VAccordion extends VTabsheetBase {
}
public void close() {
+ if (widget != null) {
+ remove(widget);
+ }
content.getStyle().setVisibility(Visibility.HIDDEN);
content.getStyle().setTop(-100000, Unit.PX);
content.getStyle().setLeft(-100000, Unit.PX);
@@ -322,10 +326,10 @@ public class VAccordion extends VTabsheetBase {
* new content
*/
public void setContent(Widget newWidget) {
- if (getChildWidget() == null) {
- add(newWidget, content);
+ if (widget == null) {
+ widget = newWidget;
widgets.add(newWidget);
- } else if (getChildWidget() != newWidget) {
+ } else if (widget != newWidget) {
replaceWidget(newWidget);
}
if (isOpen() && isDynamicHeight()) {
diff --git a/client/src/com/vaadin/client/ui/VCustomLayout.java b/client/src/com/vaadin/client/ui/VCustomLayout.java
index 3b2b007b5b..f5d572007a 100644
--- a/client/src/com/vaadin/client/ui/VCustomLayout.java
+++ b/client/src/com/vaadin/client/ui/VCustomLayout.java
@@ -158,7 +158,7 @@ public class VCustomLayout extends ComplexPanel {
// TODO prefix img src:s here with a regeps, cannot work further with IE
- String relImgPrefix = themeUri + "/layouts/";
+ String relImgPrefix = Util.escapeAttribute(themeUri + "/layouts/");
// prefix all relative image elements to point to theme dir with a
// regexp search
diff --git a/client/src/com/vaadin/client/ui/VMenuBar.java b/client/src/com/vaadin/client/ui/VMenuBar.java
index 5102e6faea..66160e691d 100644
--- a/client/src/com/vaadin/client/ui/VMenuBar.java
+++ b/client/src/com/vaadin/client/ui/VMenuBar.java
@@ -476,7 +476,8 @@ public class VMenuBar extends SimpleFocusablePanel implements
if (menuVisible && visibleChildMenu != item.getSubMenu()
&& popup != null) {
- popup.hide();
+ // #15255 - disable animation-in/out when hide in this case
+ popup.hide(false, false, false);
}
if (menuVisible && item.getSubMenu() != null
@@ -707,9 +708,22 @@ public class VMenuBar extends SimpleFocusablePanel implements
* Recursively hide all child menus
*/
public void hideChildren() {
+ hideChildren(true, true);
+ }
+
+ /**
+ *
+ * Recursively hide all child menus
+ *
+ * @param animateIn
+ * enable/disable animate-in animation when hide popup
+ * @param animateOut
+ * enable/disable animate-out animation when hide popup
+ */
+ public void hideChildren(boolean animateIn, boolean animateOut) {
if (visibleChildMenu != null) {
- visibleChildMenu.hideChildren();
- popup.hide();
+ visibleChildMenu.hideChildren(animateIn, animateOut);
+ popup.hide(false, animateIn, animateOut);
}
}
@@ -1326,7 +1340,8 @@ public class VMenuBar extends SimpleFocusablePanel implements
VMenuBar root = getParentMenu();
root.getSelected().getSubMenu().setSelected(null);
- root.hideChildren();
+ // #15255 - disable animate-in/out when hide popup
+ root.hideChildren(false, false);
// Get the root menus items and select the previous one
int idx = root.getItems().indexOf(root.getSelected());
@@ -1383,8 +1398,9 @@ public class VMenuBar extends SimpleFocusablePanel implements
root = root.getParentMenu();
}
- // Hide the submenu
- root.hideChildren();
+ // Hide the submenu (#15255 - disable animate-in/out when hide
+ // popup)
+ root.hideChildren(false, false);
// Get the root menus items and select the next one
int idx = root.getItems().indexOf(root.getSelected());
diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java
index dfd81faf94..9071b6ee47 100644
--- a/client/src/com/vaadin/client/ui/VOverlay.java
+++ b/client/src/com/vaadin/client/ui/VOverlay.java
@@ -51,7 +51,7 @@ import com.vaadin.client.Util;
* temporary float over other components like context menus etc. This is to deal
* stacking order correctly with VWindow objects.
* </p>
- *
+ *
* <h3>Shadow</h3>
* <p>
* The separate shadow element underneath the main overlay element is <strong>
@@ -62,7 +62,7 @@ import com.vaadin.client.Util;
* supports, add <code>-webkit-box-shadow</code> and the standard
* <code>box-shadow</code> properties.
* </p>
- *
+ *
* <p>
* For IE8, which doesn't support CSS box-shadow, you can use the proprietary
* DropShadow filter. It doesn't provide the exact same features as box-shadow,
@@ -70,7 +70,7 @@ import com.vaadin.client.Util;
* border or a pseudo-element underneath the overlay which mimics a shadow, or
* any combination of these.
* </p>
- *
+ *
* <p>
* Read more about the DropShadow filter from <a
* href="http://msdn.microsoft.com/en-us/library/ms532985(v=vs.85).aspx"
@@ -164,7 +164,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* Shadow element style. If an extending class wishes to use a different
* style of shadow, it can use setShadowStyle(String) to give the shadow
* element a new style name.
- *
+ *
* @deprecated See main JavaDoc for VOverlay
*/
@Deprecated
@@ -187,9 +187,9 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* The shadow element for this overlay.
- *
+ *
* @deprecated See main JavaDoc for VOverlay
- *
+ *
*/
@Deprecated
private Element shadow;
@@ -218,7 +218,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* The HTML snippet that is used to render the actual shadow. In consists of
* nine different DIV-elements with the following class names:
- *
+ *
* <pre>
* .v-shadow[-stylename]
* ----------------------------------------------
@@ -231,9 +231,9 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* | .bottom-left | .bottom | .bottom-right |
* ----------------------------------------------
* </pre>
- *
+ *
* See default theme 'shadow.css' for implementation example.
- *
+ *
* @deprecated See main JavaDoc for VOverlay
*/
@Deprecated
@@ -280,7 +280,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* Return true if a separate shadow div should be used. Since Vaadin 7.3,
* shadows are implemented with CSS box-shadow. Thus, a shadow div is only
* used for IE8 by default.
- *
+ *
* @deprecated See main JavaDoc for VOverlay
* @since 7.3
* @return true to use a shadow div
@@ -294,10 +294,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* Method to control whether DOM elements for shadow are added. With this
* method subclasses can control displaying of shadow also after the
* constructor.
- *
+ *
* @param enabled
* true if shadow should be displayed
- *
+ *
* @deprecated See main JavaDoc for VOverlay
*/
@Deprecated
@@ -361,7 +361,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* Set the z-index (visual stack position) for this overlay.
- *
+ *
* @param zIndex
* The new z-index
*/
@@ -574,12 +574,12 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* Sets the shadow style for this overlay. Will override any previous style
* for the shadow. The default style name is defined by CLASSNAME_SHADOW.
* The given style will be prefixed with CLASSNAME_SHADOW.
- *
+ *
* @param style
* The new style name for the shadow element. Will be prefixed by
* CLASSNAME_SHADOW, e.g. style=='foobar' -> actual style
* name=='v-shadow-foobar'.
- *
+ *
* @deprecated See main JavaDoc for VOverlay
*/
@Deprecated
@@ -593,7 +593,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* Extending classes should always call this method after they change the
* size of overlay without using normal 'setWidth(String)' and
* 'setHeight(String)' methods (if not calling super.setWidth/Height).
- *
+ *
*/
public void positionOrSizeUpdated() {
positionOrSizeUpdated(1.0);
@@ -612,7 +612,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* elements. Can be used to animate the related elements, using the
* 'progress' parameter (used to animate the shadow in sync with GWT
* PopupPanel's default animation 'PopupPanel.AnimationType.CENTER').
- *
+ *
* @param progress
* A value between 0.0 and 1.0, indicating the progress of the
* animation (0=start, 1=end).
@@ -721,7 +721,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* Returns true if we should add a shim iframe below the overlay to deal
* with zindex issues with PDFs and applets. Can be overriden to disable
* shim iframes if they are not needed.
- *
+ *
* @return true if a shim iframe should be added, false otherwise
*/
protected boolean needsShimElement() {
@@ -783,13 +783,13 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* Enables or disables sinking the events of the shadow to the same
* onBrowserEvent as events to the actual overlay goes.
- *
+ *
* Please note, that if you enable this, you can't assume that e.g.
* event.getEventTarget returns an element inside the DOM structure of the
* overlay
- *
+ *
* @param sinkShadowEvents
- *
+ *
* @deprecated See main JavaDoc for VOverlay
*/
@Deprecated
@@ -813,7 +813,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* Get owner (Widget that made this VOverlay, not the layout parent) of
* VOverlay
- *
+ *
* @return Owner (creator) or null if not defined
*/
public Widget getOwner() {
@@ -823,7 +823,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* Set owner (Widget that made this VOverlay, not the layout parent) of
* VOverlay
- *
+ *
* @param owner
* Owner (creator) of VOverlay
*/
@@ -834,7 +834,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* Get the {@link ApplicationConnection} that this overlay belongs to. If
* it's not set, {@link #getOwner()} is used to figure it out.
- *
+ *
* @return
*/
protected ApplicationConnection getApplicationConnection() {
@@ -854,7 +854,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* Gets the 'overlay container' element. Tries to find the current
* {@link ApplicationConnection} using {@link #getApplicationConnection()}.
- *
+ *
* @return the overlay container element for the current
* {@link ApplicationConnection} or another element if the current
* {@link ApplicationConnection} cannot be determined.
@@ -878,7 +878,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
* {@link ApplicationConnection}. Each overlay should be created in a
* overlay container element, so that the correct theme and styles can be
* applied.
- *
+ *
* @param ac
* A reference to {@link ApplicationConnection}
* @return The overlay container
@@ -905,7 +905,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* Set the label of the container element, where tooltip, notification and
* dialgs are added to.
- *
+ *
* @param applicationConnection
* the application connection for which to change the label
* @param overlayContainerLabel
@@ -938,10 +938,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* Gets the visual viewport width, which is useful for e.g iOS where the
* view can be zoomed in while keeping the layout viewport intact.
- *
+ *
* Falls back to layout viewport; for those browsers/devices the difference
* is that the scrollbar with is included (if there is a scrollbar).
- *
+ *
* @since 7.0.7
* @return
*/
@@ -957,10 +957,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
/**
* Gets the visual viewport height, which is useful for e.g iOS where the
* view can be zoomed in while keeping the layout viewport intact.
- *
+ *
* Falls back to layout viewport; for those browsers/devices the difference
* is that the scrollbar with is included (if there is a scrollbar).
- *
+ *
* @since 7.0.7
* @return
*/
@@ -1000,10 +1000,33 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
*/
@Override
public void hide(final boolean autoClosed) {
+ hide(autoClosed, true, true);
+ }
+
+ /**
+ *
+ * Hides the popup and detaches it from the page. This has no effect if it
+ * is not currently showing. Animation-in, animation-out can be
+ * enable/disabled for different use cases.
+ *
+ * @see com.google.gwt.user.client.ui.PopupPanel#hide(boolean)
+ *
+ * @param autoClosed
+ * the value that will be passed to
+ * {@link CloseHandler#onClose(CloseEvent)} when the popup is
+ * closed
+ * @param animateIn
+ * enable/disable animate-in animation
+ * @param animateOut
+ * enable/disable animate-out animation
+ */
+ public void hide(final boolean autoClosed, final boolean animateIn,
+ final boolean animateOut) {
if (BrowserInfo.get().isIE8() || BrowserInfo.get().isIE9()) {
super.hide(autoClosed);
} else {
- if (getStyleName().contains(ADDITIONAL_CLASSNAME_ANIMATE_IN)) {
+ if (animateIn
+ && getStyleName().contains(ADDITIONAL_CLASSNAME_ANIMATE_IN)) {
AnimationUtil.addAnimationEndListener(getElement(),
new AnimationEndListener() {
@Override
@@ -1029,7 +1052,9 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
animationName = "";
}
- if (animationName.contains(ADDITIONAL_CLASSNAME_ANIMATE_OUT)) {
+ if (animateOut
+ && animationName
+ .contains(ADDITIONAL_CLASSNAME_ANIMATE_OUT)) {
// Disable GWT PopupPanel closing animation if used
setAnimationEnabled(false);
diff --git a/client/src/com/vaadin/client/ui/VPopupCalendar.java b/client/src/com/vaadin/client/ui/VPopupCalendar.java
index 51b2ee22ec..cf88ceb8d6 100644
--- a/client/src/com/vaadin/client/ui/VPopupCalendar.java
+++ b/client/src/com/vaadin/client/ui/VPopupCalendar.java
@@ -27,6 +27,10 @@ import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.MouseOutEvent;
+import com.google.gwt.event.dom.client.MouseOutHandler;
+import com.google.gwt.event.dom.client.MouseOverEvent;
+import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
@@ -42,6 +46,7 @@ import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.BrowserInfo;
+import com.vaadin.client.ComputedStyle;
import com.vaadin.client.VConsole;
import com.vaadin.client.ui.VCalendarPanel.FocusOutListener;
import com.vaadin.client.ui.VCalendarPanel.SubmitListener;
@@ -76,6 +81,15 @@ public class VPopupCalendar extends VTextualDate implements Field,
private boolean open = false;
+ /*
+ * #14857: If calendarToggle button is clicked when calendar popup is
+ * already open we should prevent calling openCalendarPanel() in onClick,
+ * since we don't want to reopen it again right after it closes.
+ */
+ private boolean preventOpenPopupCalendar = false;
+ private boolean cursorOverCalendarToggleButton = false;
+ private boolean toggleButtonClosesWithGuarantee = false;
+
private boolean textFieldEnabled = true;
private String captionId;
@@ -89,6 +103,21 @@ public class VPopupCalendar extends VTextualDate implements Field,
calendarToggle.setText("");
calendarToggle.addClickHandler(this);
+
+ calendarToggle.addDomHandler(new MouseOverHandler() {
+ @Override
+ public void onMouseOver(MouseOverEvent event) {
+ cursorOverCalendarToggleButton = true;
+ }
+ }, MouseOverEvent.getType());
+
+ calendarToggle.addDomHandler(new MouseOutHandler() {
+ @Override
+ public void onMouseOut(MouseOutEvent event) {
+ cursorOverCalendarToggleButton = false;
+ }
+ }, MouseOutEvent.getType());
+
// -2 instead of -1 to avoid FocusWidget.onAttach to reset it
calendarToggle.getElement().setTabIndex(-2);
@@ -372,60 +401,7 @@ public class VPopupCalendar extends VTextualDate implements Field,
// clear previous values
popup.setWidth("");
popup.setHeight("");
- popup.setPopupPositionAndShow(new PositionCallback() {
- @Override
- public void setPosition(int offsetWidth, int offsetHeight) {
- final int w = offsetWidth;
- final int h = offsetHeight;
- final int browserWindowWidth = Window.getClientWidth()
- + Window.getScrollLeft();
- final int browserWindowHeight = Window.getClientHeight()
- + Window.getScrollTop();
- int t = calendarToggle.getAbsoluteTop();
- int l = calendarToggle.getAbsoluteLeft();
-
- // Add a little extra space to the right to avoid
- // problems with IE7 scrollbars and to make it look
- // nicer.
- int extraSpace = 30;
-
- boolean overflowRight = false;
- if (l + +w + extraSpace > browserWindowWidth) {
- overflowRight = true;
- // Part of the popup is outside the browser window
- // (to the right)
- l = browserWindowWidth - w - extraSpace;
- }
-
- if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) {
- // Part of the popup is outside the browser window
- // (below)
- t = browserWindowHeight - h
- - calendarToggle.getOffsetHeight() - 30;
- if (!overflowRight) {
- // Show to the right of the popup button unless we
- // are in the lower right corner of the screen
- l += calendarToggle.getOffsetWidth();
- }
- }
-
- popup.setPopupPosition(l,
- t + calendarToggle.getOffsetHeight() + 2);
-
- /*
- * We have to wait a while before focusing since the popup
- * needs to be opened before we can focus
- */
- Timer focusTimer = new Timer() {
- @Override
- public void run() {
- setFocus(true);
- }
- };
-
- focusTimer.schedule(100);
- }
- });
+ popup.setPopupPositionAndShow(new PopupPositionCallback());
} else {
VConsole.error("Cannot reopen popup, it is already open!");
}
@@ -441,7 +417,10 @@ public class VPopupCalendar extends VTextualDate implements Field,
@Override
public void onClick(ClickEvent event) {
if (event.getSource() == calendarToggle && isEnabled()) {
- openCalendarPanel();
+ if (!preventOpenPopupCalendar) {
+ openCalendarPanel();
+ }
+ preventOpenPopupCalendar = false;
}
}
@@ -464,15 +443,14 @@ public class VPopupCalendar extends VTextualDate implements Field,
focus();
}
- // TODO resolve what the "Sigh." is all about and document it here
- // Sigh.
- Timer t = new Timer() {
- @Override
- public void run() {
- open = false;
- }
- };
- t.schedule(100);
+ open = false;
+
+ if (cursorOverCalendarToggleButton
+ && !toggleButtonClosesWithGuarantee) {
+ preventOpenPopupCalendar = true;
+ }
+
+ toggleButtonClosesWithGuarantee = false;
}
}
@@ -572,6 +550,7 @@ public class VPopupCalendar extends VTextualDate implements Field,
*/
public void closeCalendarPanel() {
if (open) {
+ toggleButtonClosesWithGuarantee = true;
popup.hide(true);
}
}
@@ -642,4 +621,113 @@ public class VPopupCalendar extends VTextualDate implements Field,
calendar.setRangeEnd(rangeEnd);
}
+ private class PopupPositionCallback implements PositionCallback {
+
+ @Override
+ public void setPosition(int offsetWidth, int offsetHeight) {
+ final int width = offsetWidth;
+ final int height = offsetHeight;
+ final int browserWindowWidth = Window.getClientWidth()
+ + Window.getScrollLeft();
+ final int windowHeight = Window.getClientHeight()
+ + Window.getScrollTop();
+ int left = calendarToggle.getAbsoluteLeft();
+
+ // Add a little extra space to the right to avoid
+ // problems with IE7 scrollbars and to make it look
+ // nicer.
+ int extraSpace = 30;
+
+ boolean overflow = left + width + extraSpace > browserWindowWidth;
+ if (overflow) {
+ // Part of the popup is outside the browser window
+ // (to the right)
+ left = browserWindowWidth - width - extraSpace;
+ }
+
+ int top = calendarToggle.getAbsoluteTop();
+ int extraHeight = 2;
+ boolean verticallyRepositioned = false;
+ ComputedStyle style = new ComputedStyle(popup.getElement());
+ int[] margins = style.getMargin();
+ int desiredPopupBottom = top + height
+ + calendarToggle.getOffsetHeight() + margins[0]
+ + margins[2];
+
+ if (desiredPopupBottom > windowHeight) {
+ int updatedLeft = left;
+ left = getLeftPosition(left, width, style, overflow);
+
+ // if position has not been changed then it means there is no
+ // space to make popup fully visible
+ if (updatedLeft == left) {
+ // let's try to show popup on the top of the field
+ int updatedTop = top - extraHeight - height - margins[0]
+ - margins[2];
+ verticallyRepositioned = updatedTop >= 0;
+ if (verticallyRepositioned) {
+ top = updatedTop;
+ }
+ }
+ // Part of the popup is outside the browser window
+ // (below)
+ if (!verticallyRepositioned) {
+ verticallyRepositioned = true;
+ top = windowHeight - height - extraSpace + extraHeight;
+ }
+ }
+ if (verticallyRepositioned) {
+ popup.setPopupPosition(left, top);
+ } else {
+ popup.setPopupPosition(left,
+ top + calendarToggle.getOffsetHeight() + extraHeight);
+ }
+ doSetFocus();
+ }
+
+ private int getLeftPosition(int left, int width, ComputedStyle style,
+ boolean overflow) {
+ if (positionRightSide()) {
+ // Show to the right of the popup button unless we
+ // are in the lower right corner of the screen
+ if (overflow) {
+ return left;
+ } else {
+ return left + calendarToggle.getOffsetWidth();
+ }
+ } else {
+ int[] margins = style.getMargin();
+ int desiredLeftPosition = calendarToggle.getAbsoluteLeft()
+ - width - margins[1] - margins[3];
+ if (desiredLeftPosition >= 0) {
+ return desiredLeftPosition;
+ } else {
+ return left;
+ }
+ }
+ }
+
+ private boolean positionRightSide() {
+ int buttonRightSide = calendarToggle.getAbsoluteLeft()
+ + calendarToggle.getOffsetWidth();
+ int textRightSide = text.getAbsoluteLeft() + text.getOffsetWidth();
+ return buttonRightSide >= textRightSide;
+ }
+
+ private void doSetFocus() {
+ /*
+ * We have to wait a while before focusing since the popup needs to
+ * be opened before we can focus
+ */
+ Timer focusTimer = new Timer() {
+ @Override
+ public void run() {
+ setFocus(true);
+ }
+ };
+
+ focusTimer.schedule(100);
+ }
+ }
+
}
diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java
index 6c241f1033..14e4c658ad 100644
--- a/client/src/com/vaadin/client/ui/VScrollTable.java
+++ b/client/src/com/vaadin/client/ui/VScrollTable.java
@@ -5392,6 +5392,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private Map<TableCellElement, TooltipInfo> cellToolTips = new HashMap<TableCellElement, TooltipInfo>();
private boolean isDragging = false;
private String rowStyle = null;
+ protected boolean applyZeroWidthFix = true;
private VScrollTableRow(int rowKey) {
this.rowKey = rowKey;
@@ -5497,7 +5498,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* definition of zero width table cells. Instead, use 1px
* and compensate with a negative margin.
*/
- if (width == 0) {
+ if (applyZeroWidthFix && width == 0) {
wrapperWidth = 1;
wrapperStyle.setMarginRight(-1, Unit.PX);
} else {
diff --git a/client/src/com/vaadin/client/ui/VTabsheet.java b/client/src/com/vaadin/client/ui/VTabsheet.java
index bcca117395..090f83c066 100644
--- a/client/src/com/vaadin/client/ui/VTabsheet.java
+++ b/client/src/com/vaadin/client/ui/VTabsheet.java
@@ -78,6 +78,8 @@ import com.vaadin.shared.ui.tabsheet.TabsheetState;
public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware {
+ private static final String PREV_SCROLLER_DISABLED_CLASSNAME = "Prev-disabled";
+
private static class VCloseEvent {
private Tab tab;
@@ -1069,6 +1071,22 @@ public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware
updateOpenTabSize();
}
+ private boolean isAllTabsBeforeIndexInvisible() {
+ boolean invisible = true;
+ for (int i = 0; i < scrollerIndex; i++) {
+ invisible = invisible & !tb.getTab(i).isVisible();
+ }
+ return invisible;
+ }
+
+ private boolean isScrollerPrevDisabled() {
+ return scrollerPrev.getClassName().contains(PREV_SCROLLER_DISABLED_CLASSNAME);
+ }
+
+ private boolean isIndexSkippingHiddenTabs() {
+ return isAllTabsBeforeIndexInvisible() && isScrollerPrevDisabled();
+ }
+
@Override
public void renderTab(final TabState tabState, int index) {
Tab tab = tb.getTab(index);
@@ -1080,10 +1098,15 @@ public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware
tab.setEnabledOnServer((!disabledTabKeys.contains(tabKeys.get(index))));
tab.setHiddenOnServer(!tabState.visible);
- if (scrolledOutOfView(index)) {
+ if (scrolledOutOfView(index) && !isIndexSkippingHiddenTabs()) {
// Should not set tabs visible if they are scrolled out of view
tab.setVisible(false);
} else {
+ //reset the scroller index back to zero if tab is visible
+ //again and tab is in view
+ if(isIndexSkippingHiddenTabs() && tabState.visible) {
+ scrollerIndex = 0;
+ }
tab.setVisible(tabState.visible);
}
@@ -1223,7 +1246,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware
if (tb.getTabCount() > 0 && tb.isVisible() && (scrolled || clipped)) {
scroller.getStyle().clearDisplay();
DOM.setElementProperty(scrollerPrev, "className",
- SCROLLER_CLASSNAME + (scrolled ? "Prev" : "Prev-disabled"));
+ SCROLLER_CLASSNAME + (scrolled ? "Prev" : PREV_SCROLLER_DISABLED_CLASSNAME));
DOM.setElementProperty(scrollerNext, "className",
SCROLLER_CLASSNAME + (clipped ? "Next" : "Next-disabled"));
diff --git a/client/src/com/vaadin/client/ui/VTreeTable.java b/client/src/com/vaadin/client/ui/VTreeTable.java
index 9b7e9702b2..9e5940a2f2 100644
--- a/client/src/com/vaadin/client/ui/VTreeTable.java
+++ b/client/src/com/vaadin/client/ui/VTreeTable.java
@@ -155,6 +155,8 @@ public class VTreeTable extends VScrollTable {
public VTreeTableRow(UIDL uidl, char[] aligns2) {
super(uidl, aligns2);
+ // this fix causes #15118 and doesn't work for treetable anyway
+ applyZeroWidthFix = false;
}
@Override
diff --git a/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java b/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java
index c0caded759..72aa2dbdfd 100644
--- a/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java
+++ b/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java
@@ -50,12 +50,13 @@ public class AccordionConnector extends TabsheetBaseConnector implements
StackItem selectedItem = getWidget().getStackItem(
getWidget().selectedItemIndex);
- getWidget().open(getWidget().selectedItemIndex);
-
ComponentConnector contentConnector = getChildComponents().get(0);
if (contentConnector != null) {
selectedItem.setContent(contentConnector.getWidget());
}
+
+ getWidget().open(getWidget().selectedItemIndex);
+
} else if (getWidget().getOpenStackItem() != null) {
getWidget().close(getWidget().getOpenStackItem());
}
diff --git a/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java b/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java
index a37ce9af38..80979587b9 100644
--- a/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java
+++ b/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java
@@ -34,6 +34,8 @@ import com.vaadin.ui.CustomLayout;
public class CustomLayoutConnector extends AbstractLayoutConnector implements
SimpleManagedLayout, Paintable {
+ private boolean templateUpdated;
+
@Override
public CustomLayoutState getState() {
return (CustomLayoutState) super.getState();
@@ -62,7 +64,7 @@ public class CustomLayoutConnector extends AbstractLayoutConnector implements
}
private void updateHtmlTemplate() {
- if (getWidget().hasTemplate()) {
+ if (templateUpdated) {
// We (currently) only do this once. You can't change the template
// later on.
return;
@@ -76,14 +78,23 @@ public class CustomLayoutConnector extends AbstractLayoutConnector implements
templateContents = getConnection().getResource(
"layouts/" + templateName + ".html");
if (templateContents == null) {
- templateContents = "<em>Layout file layouts/"
- + templateName
- + ".html is missing. Components will be drawn for debug purposes.</em>";
+ // Template missing -> show debug notice and render components
+ // in order.
+ getWidget()
+ .getElement()
+ .setInnerHTML(
+ "<em>Layout file layouts/"
+ + templateName
+ + ".html is missing. Components will be drawn for debug purposes.</em>");
}
}
- getWidget().initializeHTML(templateContents,
- getConnection().getThemeUri());
+ if (templateContents != null) {
+ // Template ok -> initialize.
+ getWidget().initializeHTML(templateContents,
+ getConnection().getThemeUri());
+ }
+ templateUpdated = true;
}
@Override
diff --git a/client/src/com/vaadin/client/ui/dd/VDragEvent.java b/client/src/com/vaadin/client/ui/dd/VDragEvent.java
index 6291a38e42..45f89bdb87 100644
--- a/client/src/com/vaadin/client/ui/dd/VDragEvent.java
+++ b/client/src/com/vaadin/client/ui/dd/VDragEvent.java
@@ -244,6 +244,11 @@ public class VDragEvent {
public void createDragImage(com.google.gwt.user.client.Element element,
boolean alignImageToEvent) {
Element cloneNode = (Element) element.cloneNode(true);
+
+ // Set size explicitly for cloned node to avoid stretching #14617.
+ cloneNode.getStyle().setWidth(element.getOffsetWidth(), Unit.PX);
+ cloneNode.getStyle().setHeight(element.getOffsetHeight(), Unit.PX);
+
syncContent(element, cloneNode);
if (BrowserInfo.get().isIE()) {
if (cloneNode.getTagName().toLowerCase().equals("tr")) {
diff --git a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
index aace349392..0c09ae49c6 100644
--- a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
+++ b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
@@ -152,20 +152,7 @@ public abstract class AbstractOrderedLayoutConnector extends
public void onElementResize(ElementResizeEvent e) {
updateLayoutHeight();
if (needsExpand()) {
- /*
- * updateLayoutHeight causes calling of
- * getLayoutManager().setNeedsMeasure(this) which informs this
- * LayoutManager that the size of a component might have
- * changed. Then a new layout phase is scheduled. So
- * updateExpandCompensation must be delayed until layout phase
- * will be completed. #12672
- */
- Scheduler.get().scheduleFinally(new ScheduledCommand() {
- @Override
- public void execute() {
- getWidget().updateExpandCompensation();
- }
- });
+ getWidget().updateExpandCompensation();
}
}
};
diff --git a/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java b/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java
index 42b045005f..cba827bcef 100644
--- a/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java
+++ b/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java
@@ -84,13 +84,20 @@ public class TextFieldConnector extends AbstractFieldConnector implements
/*
* We skip the text content update if field has been repainted, but text
* has not been changed. Additional sanity check verifies there is no
- * change in the que (in which case we count more on the server side
+ * change in the queue (in which case we count more on the server side
* value).
*/
- if (!(uidl
- .getBooleanAttribute(TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS)
- && getWidget().valueBeforeEdit != null && text
- .equals(getWidget().valueBeforeEdit))) {
+
+ boolean valueChanged = !uidl
+ .getBooleanAttribute(TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS);
+ // null check is not enough since the value is sometimes null but
+ // sometimes empty. Fix for #15144
+ boolean valueBeforeEditEmpty = getWidget().valueBeforeEdit == null
+ || getWidget().valueBeforeEdit.isEmpty();
+ boolean textDoesNotEqualOldValue = !text
+ .equals(getWidget().valueBeforeEdit);
+
+ if (valueChanged || valueBeforeEditEmpty || textDoesNotEqualOldValue) {
getWidget().updateFieldContent(text);
}
diff --git a/client/tests/src/com/vaadin/client/TestVBrowserDetailsUserAgentParser.java b/client/tests/src/com/vaadin/client/TestVBrowserDetailsUserAgentParser.java
index 6cd0630137..cb70fc7a39 100644
--- a/client/tests/src/com/vaadin/client/TestVBrowserDetailsUserAgentParser.java
+++ b/client/tests/src/com/vaadin/client/TestVBrowserDetailsUserAgentParser.java
@@ -10,6 +10,7 @@ public class TestVBrowserDetailsUserAgentParser extends TestCase {
private static final String FIREFOX30_WINDOWS = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6";
private static final String FIREFOX30_LINUX = "Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.0.12) Gecko/2009070811 Ubuntu/9.04 (jaunty) Firefox/3.0.12";
+ private static final String FIREFOX33_ANDROID = "Mozilla/5.0 (Android; Tablet; rv:33.0) Gecko/33.0 Firefox/33.0";
private static final String FIREFOX35_WINDOWS = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 (.NET CLR 3.5.30729) FirePHP/0.4";
private static final String FIREFOX36_WINDOWS = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)";
private static final String FIREFOX36B_MAC = "UAString mozilla/5.0 (macintosh; u; intel mac os x 10.6; en-us; rv:1.9.2) gecko/20100115 firefox/3.6";
@@ -209,6 +210,15 @@ public class TestVBrowserDetailsUserAgentParser extends TestCase {
assertLinux(bd);
}
+ public void testFirefox33Android() {
+ VBrowserDetails bd = new VBrowserDetails(FIREFOX33_ANDROID);
+ assertGecko(bd);
+ assertFirefox(bd);
+ assertBrowserMajorVersion(bd, 33);
+ assertBrowserMinorVersion(bd, 0);
+ assertAndroid(bd, -1, -1);
+ }
+
public void testFirefox35() {
VBrowserDetails bd = new VBrowserDetails(FIREFOX35_WINDOWS);
assertGecko(bd);
diff --git a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
index e5d53b759d..23a72ee1e5 100644
--- a/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
@@ -15,18 +15,20 @@
*/
package com.vaadin.data.fieldgroup;
+import java.beans.IntrospectionException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
+import com.vaadin.data.util.BeanUtil;
import com.vaadin.data.validator.BeanValidator;
import com.vaadin.ui.Field;
public class BeanFieldGroup<T> extends FieldGroup {
- private Class<T> beanType;
+ private final Class<T> beanType;
private static Boolean beanValidationImplementationAvailable = null;
private final Map<Field<?>, BeanValidator> defaultValidators;
@@ -47,17 +49,20 @@ public class BeanFieldGroup<T> extends FieldGroup {
* form "fieldName" or "fieldName.subField[.subField2]" but the
* method declaration comes from parent.
*/
- java.lang.reflect.Field f;
try {
- f = getField(beanType, propertyId.toString());
- return f.getType();
- } catch (SecurityException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'.", e);
- } catch (NoSuchFieldException e) {
+ Class<?> type = BeanUtil.getPropertyType(beanType,
+ propertyId.toString());
+ if (type == null) {
+ throw new BindException(
+ "Cannot determine type of propertyId '"
+ + propertyId
+ + "'. The propertyId was not found in "
+ + beanType.getName());
+ }
+ return type;
+ } catch (IntrospectionException e) {
throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'. The propertyId was not found in "
- + beanType.getName(), e);
+ + propertyId + "'. Unable to introspect " + beanType, e);
}
}
}
@@ -79,32 +84,6 @@ public class BeanFieldGroup<T> extends FieldGroup {
return null;
}
- private static java.lang.reflect.Field getField(Class<?> cls,
- String propertyId) throws SecurityException, NoSuchFieldException {
- if (propertyId.contains(".")) {
- String[] parts = propertyId.split("\\.", 2);
- // Get the type of the field in the "cls" class
- java.lang.reflect.Field field1 = getField(cls, parts[0]);
- // Find the rest from the sub type
- return getField(field1.getType(), parts[1]);
- } else {
- try {
- // Try to find the field directly in the given class
- java.lang.reflect.Field field1 = cls
- .getDeclaredField(propertyId);
- return field1;
- } catch (NoSuchFieldException e) {
- // Try super classes until we reach Object
- Class<?> superClass = cls.getSuperclass();
- if (superClass != null && superClass != Object.class) {
- return getField(superClass, propertyId);
- } else {
- throw e;
- }
- }
- }
- }
-
private static String getFieldName(Class<?> cls, String propertyId)
throws SecurityException, NoSuchFieldException {
for (java.lang.reflect.Field field1 : cls.getDeclaredFields()) {
@@ -125,21 +104,29 @@ public class BeanFieldGroup<T> extends FieldGroup {
* Helper method for setting the data source directly using a bean. This
* method wraps the bean in a {@link BeanItem} and calls
* {@link #setItemDataSource(Item)}.
+ * <p>
+ * For null values, a null item is passed to
+ * {@link #setItemDataSource(Item)} to be properly clear fields.
*
* @param bean
* The bean to use as data source.
*/
public void setItemDataSource(T bean) {
- setItemDataSource(new BeanItem(bean));
+ if (bean == null) {
+ setItemDataSource((Item) null);
+ } else {
+ setItemDataSource(new BeanItem<T>(bean, beanType));
+ }
}
@Override
public void setItemDataSource(Item item) {
- if (!(item instanceof BeanItem)) {
+ if (item == null || (item instanceof BeanItem)) {
+ super.setItemDataSource(item);
+ } else {
throw new RuntimeException(getClass().getSimpleName()
+ " only supports BeanItems as item data source");
}
- super.setItemDataSource(item);
}
@Override
diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
index 5a4e877554..c89b94ace9 100644
--- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
@@ -255,6 +255,9 @@ public class FieldGroup implements Serializable {
fieldToPropertyId.put(field, propertyId);
propertyIdToField.put(propertyId, field);
if (itemDataSource == null) {
+ // Clear any possible existing binding to clear the field
+ field.setPropertyDataSource(null);
+ field.clear();
// Will be bound when data source is set
return;
}
@@ -452,6 +455,56 @@ public class FieldGroup implements Serializable {
// Not using buffered mode, nothing to do
return;
}
+
+ startTransactions();
+
+ try {
+ firePreCommitEvent();
+
+ List<InvalidValueException> invalidValueExceptions = commitFields();
+
+ if (invalidValueExceptions.isEmpty()) {
+ firePostCommitEvent();
+ commitTransactions();
+ } else {
+ throwInvalidValueException(invalidValueExceptions);
+ }
+ } catch (Exception e) {
+ rollbackTransactions();
+
+ throw new CommitException("Commit failed", e);
+ }
+
+ }
+
+ private List<InvalidValueException> commitFields() {
+ List<InvalidValueException> invalidValueExceptions = new ArrayList<InvalidValueException>();
+
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ try {
+ f.commit();
+ } catch (InvalidValueException e) {
+ invalidValueExceptions.add(e);
+ }
+ }
+
+ return invalidValueExceptions;
+ }
+
+ private void throwInvalidValueException(
+ List<InvalidValueException> invalidValueExceptions) {
+ if (invalidValueExceptions.size() == 1) {
+ throw invalidValueExceptions.get(0);
+ } else {
+ InvalidValueException[] causes = invalidValueExceptions
+ .toArray(new InvalidValueException[invalidValueExceptions
+ .size()]);
+
+ throw new InvalidValueException(null, causes);
+ }
+ }
+
+ private void startTransactions() throws CommitException {
for (Field<?> f : fieldToPropertyId.keySet()) {
Property.Transactional<?> property = (Property.Transactional<?>) f
.getPropertyDataSource();
@@ -462,33 +515,23 @@ public class FieldGroup implements Serializable {
}
property.startTransaction();
}
- try {
- firePreCommitEvent();
- // Commit the field values to the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- f.commit();
- }
- firePostCommitEvent();
+ }
- // Commit the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .commit();
- }
+ private void commitTransactions() {
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ ((Property.Transactional<?>) f.getPropertyDataSource()).commit();
+ }
+ }
- } catch (Exception e) {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .rollback();
- } catch (Exception rollbackException) {
- // FIXME: What to do ?
- }
+ private void rollbackTransactions() {
+ for (Field<?> f : fieldToPropertyId.keySet()) {
+ try {
+ ((Property.Transactional<?>) f.getPropertyDataSource())
+ .rollback();
+ } catch (Exception rollbackException) {
+ // FIXME: What to do ?
}
-
- throw new CommitException("Commit failed", e);
}
-
}
/**
diff --git a/server/src/com/vaadin/data/util/AbstractBeanContainer.java b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
index adf6313770..fad0934e53 100644
--- a/server/src/com/vaadin/data/util/AbstractBeanContainer.java
+++ b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
@@ -152,7 +152,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
* A description of the properties found in beans of type {@link #type}.
* Determines the property ids that are present in the container.
*/
- private LinkedHashMap<String, VaadinPropertyDescriptor<BEANTYPE>> model;
+ private final LinkedHashMap<String, VaadinPropertyDescriptor<BEANTYPE>> model;
/**
* Constructs a {@code AbstractBeanContainer} for beans of the given type.
@@ -178,7 +178,11 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
*/
@Override
public Class<?> getType(Object propertyId) {
- return model.get(propertyId).getPropertyType();
+ VaadinPropertyDescriptor<BEANTYPE> descriptor = model.get(propertyId);
+ if (descriptor == null) {
+ return null;
+ }
+ return descriptor.getPropertyType();
}
/**
@@ -876,7 +880,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
model.put(qualifiedPropertyId, pd);
model.remove(propertyId);
for (BeanItem<BEANTYPE> item : itemIdToItem.values()) {
- item.addItemProperty(propertyId,
+ item.addItemProperty(qualifiedPropertyId,
pd.createProperty(item.getBean()));
item.removeItemProperty(propertyId);
}
diff --git a/server/src/com/vaadin/data/util/BeanItem.java b/server/src/com/vaadin/data/util/BeanItem.java
index 12d9b23d0a..1be8b70f47 100644
--- a/server/src/com/vaadin/data/util/BeanItem.java
+++ b/server/src/com/vaadin/data/util/BeanItem.java
@@ -16,12 +16,8 @@
package com.vaadin.data.util;
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
@@ -62,7 +58,30 @@ public class BeanItem<BT> extends PropertysetItem {
*
*/
public BeanItem(BT bean) {
- this(bean, getPropertyDescriptors((Class<BT>) bean.getClass()));
+ this(bean, (Class<BT>) bean.getClass());
+ }
+
+ /**
+ * <p>
+ * Creates a new instance of <code>BeanItem</code> and adds all properties
+ * of a Java Bean to it. The properties are identified by their respective
+ * bean names.
+ * </p>
+ *
+ * <p>
+ * Note : This version only supports introspectable bean properties and
+ * their getter and setter methods. Stand-alone <code>is</code> and
+ * <code>are</code> methods are not supported.
+ * </p>
+ *
+ * @param bean
+ * the Java Bean to copy properties from.
+ * @param beanClass
+ * class of the {@code bean}
+ *
+ */
+ public BeanItem(BT bean, Class<BT> beanClass) {
+ this(bean, getPropertyDescriptors(beanClass));
}
/**
@@ -166,7 +185,8 @@ public class BeanItem<BT> extends PropertysetItem {
// Try to introspect, if it fails, we just have an empty Item
try {
- List<PropertyDescriptor> propertyDescriptors = getBeanPropertyDescriptor(beanClass);
+ List<PropertyDescriptor> propertyDescriptors = BeanUtil
+ .getBeanPropertyDescriptor(beanClass);
// Add all the bean properties as MethodProperties to this Item
// later entries on the list overwrite earlier ones
@@ -187,106 +207,6 @@ public class BeanItem<BT> extends PropertysetItem {
}
/**
- * Returns the property descriptors of a class or an interface.
- *
- * For an interface, superinterfaces are also iterated as Introspector does
- * not take them into account (Oracle Java bug 4275879), but in that case,
- * both the setter and the getter for a property must be in the same
- * interface and should not be overridden in subinterfaces for the discovery
- * to work correctly.
- *
- * For interfaces, the iteration is depth first and the properties of
- * superinterfaces are returned before those of their subinterfaces.
- *
- * @param beanClass
- * @return
- * @throws IntrospectionException
- */
- private static List<PropertyDescriptor> getBeanPropertyDescriptor(
- final Class<?> beanClass) throws IntrospectionException {
- // Oracle bug 4275879: Introspector does not consider superinterfaces of
- // an interface
- if (beanClass.isInterface()) {
- List<PropertyDescriptor> propertyDescriptors = new ArrayList<PropertyDescriptor>();
-
- for (Class<?> cls : beanClass.getInterfaces()) {
- propertyDescriptors.addAll(getBeanPropertyDescriptor(cls));
- }
-
- BeanInfo info = Introspector.getBeanInfo(beanClass);
- propertyDescriptors.addAll(getPropertyDescriptors(info));
-
- return propertyDescriptors;
- } else {
- BeanInfo info = Introspector.getBeanInfo(beanClass);
- return getPropertyDescriptors(info);
- }
- }
-
- // Workaround for Java6 bug JDK-6788525. Do nothing for JDK7+.
- private static List<PropertyDescriptor> getPropertyDescriptors(
- BeanInfo beanInfo) {
- PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
- List<PropertyDescriptor> result = new ArrayList<PropertyDescriptor>(
- descriptors.length);
- for (PropertyDescriptor descriptor : descriptors) {
- try {
- Method readMethod = getMethodFromBridge(descriptor
- .getReadMethod());
- if (readMethod != null) {
- Method writeMethod = getMethodFromBridge(
- descriptor.getWriteMethod(),
- readMethod.getReturnType());
- if (writeMethod == null) {
- writeMethod = descriptor.getWriteMethod();
- }
- PropertyDescriptor descr = new PropertyDescriptor(
- descriptor.getName(), readMethod, writeMethod);
- result.add(descr);
- } else {
- result.add(descriptor);
- }
- } catch (SecurityException ignore) {
- // handle next descriptor
- } catch (IntrospectionException e) {
- result.add(descriptor);
- }
- }
- return result;
- }
-
- /**
- * Return not bridged method for bridge {@code bridgeMethod} method. If
- * method {@code bridgeMethod} is not bridge method then return null.
- */
- private static Method getMethodFromBridge(Method bridgeMethod)
- throws SecurityException {
- if (bridgeMethod == null) {
- return null;
- }
- return getMethodFromBridge(bridgeMethod,
- bridgeMethod.getParameterTypes());
- }
-
- /**
- * Return not bridged method for bridge {@code bridgeMethod} method and
- * declared {@code paramTypes}. If method {@code bridgeMethod} is not bridge
- * method then return null.
- */
- private static Method getMethodFromBridge(Method bridgeMethod,
- Class<?>... paramTypes) throws SecurityException {
- if (bridgeMethod == null || !bridgeMethod.isBridge()) {
- return null;
- }
- try {
- return bridgeMethod.getDeclaringClass().getMethod(
- bridgeMethod.getName(), paramTypes);
- } catch (NoSuchMethodException e) {
- return null;
- }
- }
-
- /**
* Expands nested bean properties by replacing a top-level property with
* some or all of its sub-properties. The expansion is not recursive.
*
diff --git a/server/src/com/vaadin/data/util/BeanUtil.java b/server/src/com/vaadin/data/util/BeanUtil.java
new file mode 100644
index 0000000000..e2f85a765c
--- /dev/null
+++ b/server/src/com/vaadin/data/util/BeanUtil.java
@@ -0,0 +1,177 @@
+/*
+ * 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.data.util;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class for Java Beans information access.
+ *
+ * @author Vaadin Ltd
+ */
+public final class BeanUtil implements Serializable {
+ // Prevent instantiation of util class
+ private BeanUtil() {
+ }
+
+ /**
+ * Returns the property descriptors of a class or an interface.
+ *
+ * For an interface, superinterfaces are also iterated as Introspector does
+ * not take them into account (Oracle Java bug 4275879), but in that case,
+ * both the setter and the getter for a property must be in the same
+ * interface and should not be overridden in subinterfaces for the discovery
+ * to work correctly.
+ *
+ * NOTE : This utility method relies on introspection (and returns
+ * PropertyDescriptor) which is a part of java.beans package. The latter
+ * package could require bigger JDK in the future (with Java 9+). So it may
+ * be changed in the future.
+ *
+ * For interfaces, the iteration is depth first and the properties of
+ * superinterfaces are returned before those of their subinterfaces.
+ *
+ * @param beanClass
+ * @return
+ * @throws IntrospectionException
+ */
+ public static List<PropertyDescriptor> getBeanPropertyDescriptor(
+ final Class<?> beanClass) throws IntrospectionException {
+ // Oracle bug 4275879: Introspector does not consider superinterfaces of
+ // an interface
+ if (beanClass.isInterface()) {
+ List<PropertyDescriptor> propertyDescriptors = new ArrayList<PropertyDescriptor>();
+
+ for (Class<?> cls : beanClass.getInterfaces()) {
+ propertyDescriptors.addAll(getBeanPropertyDescriptor(cls));
+ }
+
+ BeanInfo info = Introspector.getBeanInfo(beanClass);
+ propertyDescriptors.addAll(getPropertyDescriptors(info));
+
+ return propertyDescriptors;
+ } else {
+ BeanInfo info = Introspector.getBeanInfo(beanClass);
+ return getPropertyDescriptors(info);
+ }
+ }
+
+ /**
+ * Returns {@code propertyId} class for property declared in {@code clazz}.
+ * Property could be of form "property.subProperty[.subProperty2]" i.e.
+ * refer to some nested property.
+ *
+ * @param clazz
+ * class where property is declared
+ * @param propertyId
+ * property of form "property" or
+ * "property.subProperty[.subProperty2]"
+ * @return class of the property
+ * @throws IntrospectionException
+ */
+ public static Class<?> getPropertyType(Class<?> clazz, String propertyId)
+ throws IntrospectionException {
+ if (propertyId.contains(".")) {
+ String[] parts = propertyId.split("\\.", 2);
+ // Get the type of the field in the "cls" class
+ Class<?> propertyBean = getPropertyType(clazz, parts[0]);
+ // Find the rest from the sub type
+ return getPropertyType(propertyBean, parts[1]);
+ } else {
+ List<PropertyDescriptor> descriptors = getBeanPropertyDescriptor(clazz);
+
+ for (PropertyDescriptor descriptor : descriptors) {
+ final Method getMethod = descriptor.getReadMethod();
+ if (descriptor.getName().equals(propertyId)
+ && getMethod != null
+ && getMethod.getDeclaringClass() != Object.class) {
+ return descriptor.getPropertyType();
+ }
+ }
+ return null;
+ }
+ }
+
+ // Workaround for Java6 bug JDK-6788525. Do nothing for JDK7+.
+ private static List<PropertyDescriptor> getPropertyDescriptors(
+ BeanInfo beanInfo) {
+ PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
+ List<PropertyDescriptor> result = new ArrayList<PropertyDescriptor>(
+ descriptors.length);
+ for (PropertyDescriptor descriptor : descriptors) {
+ try {
+ Method readMethod = getMethodFromBridge(descriptor
+ .getReadMethod());
+ if (readMethod != null) {
+ Method writeMethod = getMethodFromBridge(
+ descriptor.getWriteMethod(),
+ readMethod.getReturnType());
+ if (writeMethod == null) {
+ writeMethod = descriptor.getWriteMethod();
+ }
+ PropertyDescriptor descr = new PropertyDescriptor(
+ descriptor.getName(), readMethod, writeMethod);
+ result.add(descr);
+ } else {
+ result.add(descriptor);
+ }
+ } catch (SecurityException ignore) {
+ // handle next descriptor
+ } catch (IntrospectionException e) {
+ result.add(descriptor);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return declared method for which {@code bridgeMethod} is generated. If
+ * {@code bridgeMethod} is not a bridge method then return null.
+ */
+ private static Method getMethodFromBridge(Method bridgeMethod)
+ throws SecurityException {
+ if (bridgeMethod == null) {
+ return null;
+ }
+ return getMethodFromBridge(bridgeMethod,
+ bridgeMethod.getParameterTypes());
+ }
+
+ /**
+ * Return declared method for which {@code bridgeMethod} is generated using
+ * its {@code paramTypes}. If {@code bridgeMethod} is not a bridge method
+ * then return null.
+ */
+ private static Method getMethodFromBridge(Method bridgeMethod,
+ Class<?>... paramTypes) throws SecurityException {
+ if (bridgeMethod == null || !bridgeMethod.isBridge()) {
+ return null;
+ }
+ try {
+ return bridgeMethod.getDeclaringClass().getMethod(
+ bridgeMethod.getName(), paramTypes);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+}
diff --git a/server/src/com/vaadin/data/util/MethodProperty.java b/server/src/com/vaadin/data/util/MethodProperty.java
index 5e6b731571..853f68b711 100644
--- a/server/src/com/vaadin/data/util/MethodProperty.java
+++ b/server/src/com/vaadin/data/util/MethodProperty.java
@@ -132,7 +132,7 @@ public class MethodProperty<T> extends AbstractProperty<T> {
setArguments(getArgs, setArgs, setArgumentIndex);
String name = (String) in.readObject();
Class<?>[] paramTypes = SerializerHelper.readClassArray(in);
- if (name != null) {
+ if (instance != null && name != null) {
setMethod = instance.getClass().getMethod(name, paramTypes);
} else {
setMethod = null;
@@ -140,7 +140,7 @@ public class MethodProperty<T> extends AbstractProperty<T> {
name = (String) in.readObject();
paramTypes = SerializerHelper.readClassArray(in);
- if (name != null) {
+ if (instance != null && name != null) {
getMethod = instance.getClass().getMethod(name, paramTypes);
} else {
getMethod = null;
@@ -589,7 +589,11 @@ public class MethodProperty<T> extends AbstractProperty<T> {
@Override
public T getValue() {
try {
- return (T) getMethod.invoke(instance, getArgs);
+ if (instance == null) {
+ return null;
+ } else {
+ return (T) getMethod.invoke(instance, getArgs);
+ }
} catch (final Throwable e) {
throw new MethodException(this, e);
}
diff --git a/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java b/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
index 9054f258c7..81f1a85f89 100644
--- a/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
+++ b/server/src/com/vaadin/data/util/converter/AbstractStringToNumberConverter.java
@@ -88,6 +88,7 @@ public abstract class AbstractStringToNumberConverter<T> implements
// Convert "" to null
return null;
}
+
return parsedValue;
}
diff --git a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
index 26613c5d02..3a1f1a4252 100644
--- a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
+++ b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
@@ -17,6 +17,7 @@
package com.vaadin.data.util.converter;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.Date;
import java.util.logging.Logger;
@@ -112,6 +113,12 @@ public class DefaultConverterFactory implements ConverterFactory {
return new StringToDateConverter();
} else if (Enum.class.isAssignableFrom(sourceType)) {
return new StringToEnumConverter();
+ } else if (BigInteger.class.isAssignableFrom(sourceType)) {
+ return new StringToBigIntegerConverter();
+ } else if (Short.class.isAssignableFrom(sourceType)) {
+ return new StringToShortConverter();
+ } else if (Byte.class.isAssignableFrom(sourceType)) {
+ return new StringToByteConverter();
} else {
return null;
}
diff --git a/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java b/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java
index 1e830c1fd2..d176ac2e0d 100644
--- a/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToBigIntegerConverter.java
@@ -15,6 +15,7 @@
*/
package com.vaadin.data.util.converter;
+import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.NumberFormat;
@@ -32,7 +33,7 @@ import java.util.Locale;
* </p>
*
* @author Vaadin Ltd
- * @since 7.3.1
+ * @since
*/
public class StringToBigIntegerConverter extends
AbstractStringToNumberConverter<BigInteger> {
@@ -41,7 +42,7 @@ public class StringToBigIntegerConverter extends
protected NumberFormat getFormat(Locale locale) {
NumberFormat numberFormat = super.getFormat(locale);
if (numberFormat instanceof DecimalFormat) {
- ((DecimalFormat) numberFormat).setParseIntegerOnly(true);
+ ((DecimalFormat) numberFormat).setParseBigDecimal(true);
}
return numberFormat;
@@ -51,7 +52,11 @@ public class StringToBigIntegerConverter extends
public BigInteger convertToModel(String value,
Class<? extends BigInteger> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
- return (BigInteger) convertToNumber(value, BigInteger.class, locale);
+
+ BigDecimal bigDecimalValue = (BigDecimal) convertToNumber(value,
+ BigDecimal.class, locale);
+
+ return (bigDecimalValue != null) ? bigDecimalValue.toBigInteger() : null;
}
@Override
diff --git a/server/src/com/vaadin/data/util/converter/StringToByteConverter.java b/server/src/com/vaadin/data/util/converter/StringToByteConverter.java
index b14182dc3f..26f52d108a 100644
--- a/server/src/com/vaadin/data/util/converter/StringToByteConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToByteConverter.java
@@ -28,7 +28,7 @@ import java.util.Locale;
* </p>
*
* @author Vaadin Ltd
- * @since 7.3.1
+ * @since
*/
public class StringToByteConverter extends
AbstractStringToNumberConverter<Byte> {
diff --git a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java b/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java
index a1328d831c..e91dd2a303 100644
--- a/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToEnumConverter.java
@@ -34,9 +34,31 @@ public class StringToEnumConverter implements Converter<String, Enum> {
@Override
public Enum convertToModel(String value, Class<? extends Enum> targetType,
Locale locale) throws ConversionException {
- if (value == null) {
+ if (value == null || value.trim().equals("")) {
return null;
}
+
+ return stringToEnum(value, targetType, locale);
+ }
+
+ /**
+ * Converts the given string to the given enum type using the given locale
+ * <p>
+ * Compatible with {@link #enumToString(Enum, Locale)}
+ *
+ * @param value
+ * The string value to convert
+ * @param enumType
+ * The type of enum to create
+ * @param locale
+ * The locale to use for conversion. If null, the JVM default
+ * locale will be used
+ * @return The enum which matches the given string
+ * @throws ConversionException
+ * if the conversion fails
+ */
+ public static <T extends Enum<T>> T stringToEnum(String value,
+ Class<T> enumType, Locale locale) throws ConversionException {
if (locale == null) {
locale = Locale.getDefault();
}
@@ -45,31 +67,41 @@ public class StringToEnumConverter implements Converter<String, Enum> {
// Foo bar -> FOO_BAR
String result = value.replace(" ", "_").toUpperCase(locale);
try {
- return Enum.valueOf(targetType, result);
- } catch (IllegalArgumentException ee) {
+ return Enum.valueOf(enumType, result);
+ } catch (Exception ee) {
// There was no match. Try to compare the available values to see if
// the constant is using something else than all upper case
-
- EnumSet<?> set = EnumSet.allOf(targetType);
- for (Enum e : set) {
- if (e.name().toUpperCase(locale).equals(result)) {
- return e;
+ try {
+ EnumSet<T> set = EnumSet.allOf(enumType);
+ for (T e : set) {
+ if (e.name().toUpperCase(locale).equals(result)) {
+ return e;
+ }
}
+ } catch (Exception e) {
}
- // Fallback did not work either, re-throw original exception so user
- // knows what went wrong
+ // Fallback did not work either, re-throw original exception so
+ // user knows what went wrong
throw new ConversionException(ee);
}
}
- @Override
- public String convertToPresentation(Enum value,
- Class<? extends String> targetType, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
+ /**
+ * Converts the given enum to a human readable string using the given locale
+ * <p>
+ * Compatible with {@link #stringToEnum(String, Class, Locale)}
+ *
+ * @param value
+ * The enum value to convert
+ * @param locale
+ * The locale to use for conversion. If null, the JVM default
+ * locale will be used
+ * @return A human readable string based on the enum
+ * @throws ConversionException
+ * if the conversion fails
+ */
+ public static String enumToString(Enum<?> value, Locale locale) {
if (locale == null) {
locale = Locale.getDefault();
}
@@ -80,11 +112,21 @@ public class StringToEnumConverter implements Converter<String, Enum> {
// _FOO -> _foo
String result = enumString.substring(0, 1).toUpperCase(locale);
result += enumString.substring(1).toLowerCase(locale).replace('_', ' ');
-
return result;
}
@Override
+ public String convertToPresentation(Enum value,
+ Class<? extends String> targetType, Locale locale)
+ throws ConversionException {
+ if (value == null) {
+ return null;
+ }
+
+ return enumToString(value, locale);
+ }
+
+ @Override
public Class<Enum> getModelType() {
return Enum.class;
}
diff --git a/server/src/com/vaadin/data/util/converter/StringToShortConverter.java b/server/src/com/vaadin/data/util/converter/StringToShortConverter.java
index 3761d11227..4ee085286f 100644
--- a/server/src/com/vaadin/data/util/converter/StringToShortConverter.java
+++ b/server/src/com/vaadin/data/util/converter/StringToShortConverter.java
@@ -28,7 +28,7 @@ import java.util.Locale;
* </p>
*
* @author Vaadin Ltd
- * @since 7.3.1
+ * @since
*/
public class StringToShortConverter extends
AbstractStringToNumberConverter<Short> {
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
index 683140d279..c0c660c084 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
@@ -652,7 +652,6 @@ public class SQLContainer implements Container, Container.Filterable,
if (cachedItems.isEmpty()) {
getPage();
}
- int size = size();
// this protects against infinite looping
int counter = 0;
int oldIndex;
@@ -1020,18 +1019,20 @@ public class SQLContainer implements Container, Container.Filterable,
}
/* Perform buffered modifications */
for (RowItem item : modifiedItems) {
- if (queryDelegate.storeRow(item) > 0) {
- /*
- * Also reset the modified state in the item in case it is
- * reused e.g. in a form.
- */
- item.commit();
- } else {
- queryDelegate.rollback();
- refresh();
- throw new ConcurrentModificationException(
- "Item with the ID '" + item.getId()
- + "' has been externally modified.");
+ if (!removedItems.containsKey(item.getId())) {
+ if (queryDelegate.storeRow(item) > 0) {
+ /*
+ * Also reset the modified state in the item in case it
+ * is reused e.g. in a form.
+ */
+ item.commit();
+ } else {
+ queryDelegate.rollback();
+ refresh();
+ throw new ConcurrentModificationException(
+ "Item with the ID '" + item.getId()
+ + "' has been externally modified.");
+ }
}
}
/* Perform buffered additions */
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java b/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
index 84dfe9b865..21a486a017 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
@@ -262,6 +262,12 @@ public class DefaultSQLGenerator implements SQLGenerator {
count++;
}
if (versionColumn != null) {
+ if(!item.getItemPropertyIds().contains(versionColumn)) {
+ throw new IllegalArgumentException(String.format(
+ "Table '%s' does not contain version column '%s'.",
+ tableName, versionColumn));
+ }
+
query.append(String.format(" AND %s = ?",
QueryBuilder.quote(versionColumn)));
sh.addParameterValue(
diff --git a/server/src/com/vaadin/navigator/Navigator.java b/server/src/com/vaadin/navigator/Navigator.java
index 80dad2244e..591f73dc75 100644
--- a/server/src/com/vaadin/navigator/Navigator.java
+++ b/server/src/com/vaadin/navigator/Navigator.java
@@ -371,6 +371,7 @@ public class Navigator implements Serializable {
private View currentView = null;
private List<ViewChangeListener> listeners = new LinkedList<ViewChangeListener>();
private List<ViewProvider> providers = new LinkedList<ViewProvider>();
+ private String currentNavigationState = null;
private ViewProvider errorProvider;
/**
@@ -551,6 +552,11 @@ public class Navigator implements Serializable {
ViewChangeEvent event = new ViewChangeEvent(this, currentView, view,
viewName, parameters);
if (!fireBeforeViewChange(event)) {
+ // #10901. Revert URL to previous state if back-button navigation
+ // was canceled
+ if (currentNavigationState != null) {
+ getStateManager().setState(currentNavigationState);
+ }
return;
}
@@ -561,6 +567,7 @@ public class Navigator implements Serializable {
}
if (!navigationState.equals(getStateManager().getState())) {
getStateManager().setState(navigationState);
+ currentNavigationState = navigationState;
}
}
diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java
index f0666f63fc..c34e986fce 100644
--- a/server/src/com/vaadin/server/BootstrapHandler.java
+++ b/server/src/com/vaadin/server/BootstrapHandler.java
@@ -469,6 +469,8 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
JsonObject versionInfo = Json.createObject();
versionInfo.put("vaadinVersion", Version.getFullVersion());
+ versionInfo.put("atmosphereVersion",
+ org.atmosphere.util.Version.getRawVersion());
appConfig.put("versionInfo", versionInfo);
appConfig.put("widgetset", context.getWidgetsetName());
diff --git a/server/src/com/vaadin/server/FileResource.java b/server/src/com/vaadin/server/FileResource.java
index de14e2f0f2..b32905f972 100644
--- a/server/src/com/vaadin/server/FileResource.java
+++ b/server/src/com/vaadin/server/FileResource.java
@@ -57,6 +57,9 @@ public class FileResource implements ConnectorResource {
* the file that should be served.
*/
public FileResource(File sourceFile) {
+ if (sourceFile == null) {
+ throw new IllegalArgumentException("File cannot be null");
+ }
setSourceFile(sourceFile);
}
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index fb93a44d37..36d6910a7a 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -703,12 +703,12 @@ public abstract class VaadinService implements Serializable {
final boolean closeApplication = hasParameter(request,
URL_PARAMETER_CLOSE_APPLICATION);
- if (restartApplication) {
- closeSession(session, request.getWrappedSession(false));
- return createAndRegisterSession(request);
- } else if (closeApplication) {
+ if (closeApplication) {
closeSession(session, request.getWrappedSession(false));
return null;
+ } else if (restartApplication) {
+ closeSession(session, request.getWrappedSession(false));
+ return createAndRegisterSession(request);
} else {
return session;
}
diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java
index 4656f9a672..d1242676da 100644
--- a/server/src/com/vaadin/server/VaadinServlet.java
+++ b/server/src/com/vaadin/server/VaadinServlet.java
@@ -573,8 +573,8 @@ public class VaadinServlet extends HttpServlet implements Constants {
/**
* A helper method to strip away characters that might somehow be used for
- * XSS attacs. Leaves at least alphanumeric characters intact. Also removes
- * eg. ( and ), so values should be safe in javascript too.
+ * XSS attacks. Leaves at least alphanumeric characters intact. Also removes
+ * e.g. '(' and ')', so values should be safe in javascript too.
*
* @param themeName
* @return
@@ -583,7 +583,7 @@ public class VaadinServlet extends HttpServlet implements Constants {
* version
*/
@Deprecated
- protected static String stripSpecialChars(String themeName) {
+ public static String stripSpecialChars(String themeName) {
StringBuilder sb = new StringBuilder();
char[] charArray = themeName.toCharArray();
for (int i = 0; i < charArray.length; i++) {
@@ -704,6 +704,15 @@ public class VaadinServlet extends HttpServlet implements Constants {
return;
}
+ String cacheControl = "public, max-age=0, must-revalidate";
+ int resourceCacheTime = getCacheTime(filename);
+ if (resourceCacheTime > 0) {
+ cacheControl = "max-age=" + String.valueOf(resourceCacheTime);
+ }
+ response.setHeader("Cache-Control", cacheControl);
+ response.setDateHeader("Expires", System.currentTimeMillis()
+ + (resourceCacheTime * 1000));
+
// Find the modification timestamp
long lastModifiedTime = 0;
URLConnection connection = null;
@@ -714,6 +723,7 @@ public class VaadinServlet extends HttpServlet implements Constants {
// are not returned by the browser in the "If-Modified-Since"
// header).
lastModifiedTime = lastModifiedTime - lastModifiedTime % 1000;
+ response.setDateHeader("Last-Modified", lastModifiedTime);
if (browserHasNewestVersion(request, lastModifiedTime)) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
@@ -748,18 +758,6 @@ public class VaadinServlet extends HttpServlet implements Constants {
response.setContentType(mimetype);
}
- // Provide modification timestamp to the browser if it is known.
- if (lastModifiedTime > 0) {
- response.setDateHeader("Last-Modified", lastModifiedTime);
-
- String cacheControl = "public, max-age=0, must-revalidate";
- int resourceCacheTime = getCacheTime(filename);
- if (resourceCacheTime > 0) {
- cacheControl = "max-age=" + String.valueOf(resourceCacheTime);
- }
- response.setHeader("Cache-Control", cacheControl);
- }
-
writeStaticResourceResponse(request, response, resourceUrl);
}
diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java
index 356ad25219..1216d2b689 100644
--- a/server/src/com/vaadin/server/communication/UIInitHandler.java
+++ b/server/src/com/vaadin/server/communication/UIInitHandler.java
@@ -17,7 +17,7 @@
package com.vaadin.server.communication;
import java.io.IOException;
-import java.io.OutputStreamWriter;
+import java.io.OutputStream;
import java.io.StringWriter;
import java.util.List;
import java.util.logging.Level;
@@ -65,8 +65,6 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
@Override
public boolean synchronizedHandleRequest(VaadinSession session,
VaadinRequest request, VaadinResponse response) throws IOException {
- StringWriter stringWriter = new StringWriter();
-
try {
assert UI.getCurrent() == null;
@@ -82,14 +80,10 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
String initialUIDL = getInitialUidl(request, uI);
params.put("uidl", initialUIDL);
- stringWriter.write(JsonUtil.stringify(params));
+ return commitJsonResponse(request, response, JsonUtil.stringify(params));
} catch (JsonException e) {
throw new IOException("Error producing initial UIDL", e);
- } finally {
- stringWriter.close();
}
-
- return commitJsonResponse(request, response, stringWriter.toString());
}
/**
@@ -116,18 +110,13 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
// iOS 6 Safari requires this (#9732)
response.setHeader("Cache-Control", "no-cache");
- // NOTE! GateIn requires, for some weird reason, getOutputStream
- // to be used instead of getWriter() (it seems to interpret
- // application/json as a binary content type)
- OutputStreamWriter outputWriter = new OutputStreamWriter(
- response.getOutputStream(), "UTF-8");
- try {
- outputWriter.write(json);
- // NOTE GateIn requires the buffers to be flushed to work
- outputWriter.flush();
- } finally {
- outputWriter.close();
- }
+ byte[] b = json.getBytes("UTF-8");
+ response.setHeader("Content-Length", String.valueOf(b.length));
+
+ OutputStream outputStream = response.getOutputStream();
+ outputStream.write(b);
+ // NOTE GateIn requires the buffers to be flushed to work
+ outputStream.flush();
return true;
}
diff --git a/server/src/com/vaadin/ui/AbsoluteLayout.java b/server/src/com/vaadin/ui/AbsoluteLayout.java
index 27ddb86dad..39f00901fc 100644
--- a/server/src/com/vaadin/ui/AbsoluteLayout.java
+++ b/server/src/com/vaadin/ui/AbsoluteLayout.java
@@ -166,7 +166,6 @@ public class AbsoluteLayout extends AbstractLayout implements
internalRemoveComponent(c);
throw e;
}
- markAsDirty();
}
/**
@@ -210,7 +209,6 @@ public class AbsoluteLayout extends AbstractLayout implements
public void removeComponent(Component c) {
internalRemoveComponent(c);
super.removeComponent(c);
- markAsDirty();
}
/**
diff --git a/server/src/com/vaadin/ui/AbstractComponentContainer.java b/server/src/com/vaadin/ui/AbstractComponentContainer.java
index e70b0fa0ce..1095331602 100644
--- a/server/src/com/vaadin/ui/AbstractComponentContainer.java
+++ b/server/src/com/vaadin/ui/AbstractComponentContainer.java
@@ -209,6 +209,7 @@ public abstract class AbstractComponentContainer extends AbstractComponent
c.setParent(this);
fireComponentAttachEvent(c);
+ markAsDirty();
}
/**
@@ -223,6 +224,7 @@ public abstract class AbstractComponentContainer extends AbstractComponent
if (equals(c.getParent())) {
c.setParent(null);
fireComponentDetachEvent(c);
+ markAsDirty();
}
}
diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java
index 6d4b5ff2d7..9b9c7efd86 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/com/vaadin/ui/AbstractField.java
@@ -1508,25 +1508,12 @@ public abstract class AbstractField<T> extends AbstractComponent implements
markAsDirty();
}
- /**
- * Is the field empty?
- *
- * In general, "empty" state is same as null. As an exception, TextField
- * also treats empty string as "empty".
- */
- protected boolean isEmpty() {
+ @Override
+ public boolean isEmpty() {
return (getFieldValue() == null);
}
- /**
- * Clear the value of the field.
- * <p>
- * The field value is typically reset to the initial value of the field but
- * this is not mandatory. Calling {@link #isEmpty()} on a cleared field must
- * always returns true.
- *
- * @since
- */
+ @Override
public void clear() {
setValue(null);
}
diff --git a/server/src/com/vaadin/ui/AbstractSelect.java b/server/src/com/vaadin/ui/AbstractSelect.java
index 2c4dd5be5d..1a3eeb88a3 100644
--- a/server/src/com/vaadin/ui/AbstractSelect.java
+++ b/server/src/com/vaadin/ui/AbstractSelect.java
@@ -33,6 +33,8 @@ import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.ConverterUtil;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.Transferable;
import com.vaadin.event.dd.DragAndDropEvent;
@@ -1181,7 +1183,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
switch (getItemCaptionMode()) {
case ID:
- caption = itemId.toString();
+ caption = idToCaption(itemId);
break;
case INDEX:
@@ -1207,7 +1209,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
case EXPLICIT_DEFAULTS_ID:
caption = itemCaptions.get(itemId);
if (caption == null) {
- caption = itemId.toString();
+ caption = idToCaption(itemId);
}
break;
@@ -1227,6 +1229,17 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
return caption != null ? caption : "";
}
+ private String idToCaption(Object itemId) {
+ try {
+ Converter<String, Object> c = (Converter<String, Object>) ConverterUtil
+ .getConverter(String.class, itemId.getClass(), getSession());
+ return ConverterUtil.convertFromModel(itemId, String.class, c,
+ getLocale());
+ } catch (Exception e) {
+ return itemId.toString();
+ }
+ }
+
/**
* Sets tqhe icon for an item.
*
@@ -1782,7 +1795,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
* @see AbstractField#isEmpty().
*/
@Override
- protected boolean isEmpty() {
+ public boolean isEmpty() {
if (!multiSelect) {
return super.isEmpty();
} else {
diff --git a/server/src/com/vaadin/ui/AbstractSplitPanel.java b/server/src/com/vaadin/ui/AbstractSplitPanel.java
index 29dbadecc4..e366c33593 100644
--- a/server/src/com/vaadin/ui/AbstractSplitPanel.java
+++ b/server/src/com/vaadin/ui/AbstractSplitPanel.java
@@ -221,7 +221,6 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer {
} else if (c == getSecondComponent()) {
getState().secondChild = null;
}
- markAsDirty();
}
/*
@@ -263,7 +262,6 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer {
} else if (oldComponent == getSecondComponent()) {
setSecondComponent(newComponent);
}
- markAsDirty();
}
/**
@@ -349,12 +347,26 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer {
* Returns the unit of position of the splitter
*
* @return unit of position of the splitter
+ * @see #setSplitPosition(float, Unit)
*/
public Unit getSplitPositionUnit() {
return posUnit;
}
/**
+ * Is the split position reversed. By default the split position is measured
+ * by the first region, but if split position is reversed the measuring is
+ * done by the second region instead.
+ *
+ * @since
+ * @return {@code true} if reversed, {@code false} otherwise.
+ * @see #setSplitPosition(float, boolean)
+ */
+ public boolean isSplitPositionReversed() {
+ return getSplitterState(false).positionReversed;
+ }
+
+ /**
* Sets the minimum split position to the given position and unit. If the
* split position is reversed, maximum and minimum are also reversed.
*
diff --git a/server/src/com/vaadin/ui/AbstractTextField.java b/server/src/com/vaadin/ui/AbstractTextField.java
index adeb1cb69f..93025ac0fd 100644
--- a/server/src/com/vaadin/ui/AbstractTextField.java
+++ b/server/src/com/vaadin/ui/AbstractTextField.java
@@ -323,7 +323,7 @@ public abstract class AbstractTextField extends AbstractField<String> implements
}
@Override
- protected boolean isEmpty() {
+ public boolean isEmpty() {
return super.isEmpty() || getValue().length() == 0;
}
diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/com/vaadin/ui/ComboBox.java
index c2b80fae35..4af93113f9 100644
--- a/server/src/com/vaadin/ui/ComboBox.java
+++ b/server/src/com/vaadin/ui/ComboBox.java
@@ -622,7 +622,7 @@ public class ComboBox extends AbstractSelect implements
if (caption == null || caption.equals("")) {
continue;
} else {
- caption = caption.toLowerCase();
+ caption = caption.toLowerCase(getLocale());
}
switch (filteringMode) {
case CONTAINS:
@@ -682,7 +682,7 @@ public class ComboBox extends AbstractSelect implements
currentPage = ((Integer) variables.get("page")).intValue();
filterstring = newFilter;
if (filterstring != null) {
- filterstring = filterstring.toLowerCase();
+ filterstring = filterstring.toLowerCase(getLocale());
}
requestRepaint();
} else if (isNewItemsAllowed()) {
diff --git a/server/src/com/vaadin/ui/CssLayout.java b/server/src/com/vaadin/ui/CssLayout.java
index 9a4da009e9..f3ae6c0695 100644
--- a/server/src/com/vaadin/ui/CssLayout.java
+++ b/server/src/com/vaadin/ui/CssLayout.java
@@ -121,7 +121,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
components.add(c);
try {
super.addComponent(c);
- markAsDirty();
} catch (IllegalArgumentException e) {
components.remove(c);
throw e;
@@ -144,7 +143,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
components.addFirst(c);
try {
super.addComponent(c);
- markAsDirty();
} catch (IllegalArgumentException e) {
components.remove(c);
throw e;
@@ -173,7 +171,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
components.add(index, c);
try {
super.addComponent(c);
- markAsDirty();
} catch (IllegalArgumentException e) {
components.remove(c);
throw e;
@@ -190,7 +187,6 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
public void removeComponent(Component c) {
components.remove(c);
super.removeComponent(c);
- markAsDirty();
}
/**
diff --git a/server/src/com/vaadin/ui/CustomLayout.java b/server/src/com/vaadin/ui/CustomLayout.java
index f4fe7fa66c..a9c266b0b9 100644
--- a/server/src/com/vaadin/ui/CustomLayout.java
+++ b/server/src/com/vaadin/ui/CustomLayout.java
@@ -144,8 +144,8 @@ public class CustomLayout extends AbstractLayout implements LegacyComponent {
}
slots.put(location, c);
getState().childLocations.put(c, location);
- c.setParent(this);
- fireComponentAttachEvent(c);
+
+ super.addComponent(c);
}
/**
diff --git a/server/src/com/vaadin/ui/DateField.java b/server/src/com/vaadin/ui/DateField.java
index 030bd5f6c2..3d683f4902 100644
--- a/server/src/com/vaadin/ui/DateField.java
+++ b/server/src/com/vaadin/ui/DateField.java
@@ -316,10 +316,11 @@ public class DateField extends AbstractField<Date> implements
throw new IllegalStateException(
"startDate cannot be later than endDate");
}
- getState().rangeStart = startDate;
- // rangeStart = startDate;
- // This has to be done to correct for the resolution
- // updateRangeState();
+
+ // Create a defensive copy against issues when using java.sql.Date (and
+ // also against mutable Date).
+ getState().rangeStart = startDate != null ? new Date(
+ startDate.getTime()) : null;
updateRangeValidator();
}
@@ -436,8 +437,11 @@ public class DateField extends AbstractField<Date> implements
throw new IllegalStateException(
"endDate cannot be earlier than startDate");
}
- // rangeEnd = endDate;
- getState().rangeEnd = endDate;
+
+ // Create a defensive copy against issues when using java.sql.Date (and
+ // also against mutable Date).
+ getState().rangeEnd = endDate != null ? new Date(endDate.getTime())
+ : null;
updateRangeValidator();
}
diff --git a/server/src/com/vaadin/ui/Field.java b/server/src/com/vaadin/ui/Field.java
index f191e1bdd7..6dee4de6cb 100644
--- a/server/src/com/vaadin/ui/Field.java
+++ b/server/src/com/vaadin/ui/Field.java
@@ -113,4 +113,26 @@ public interface Field<T> extends Component, BufferedValidatable, Property<T>,
return (Property) getSource();
}
}
+
+ /**
+ * Is the field empty?
+ *
+ * In general, "empty" state is same as null. As an exception, TextField
+ * also treats empty string as "empty".
+ *
+ * @since
+ * @return true if the field is empty, false otherwise
+ */
+ public boolean isEmpty();
+
+ /**
+ * Clears the value of the field.
+ * <p>
+ * The field value is typically reset to the initial value of the field.
+ * Calling {@link #isEmpty()} on a cleared field must always returns true.
+ *
+ * @since
+ */
+ public void clear();
+
}
diff --git a/server/src/com/vaadin/ui/Form.java b/server/src/com/vaadin/ui/Form.java
index 48239b09e3..45532756e5 100644
--- a/server/src/com/vaadin/ui/Form.java
+++ b/server/src/com/vaadin/ui/Form.java
@@ -1186,9 +1186,14 @@ public class Form extends AbstractField<Object> implements Item.Editor,
}
}
- /** Form is empty if all of its fields are empty. */
+ /**
+ * {@inheritDoc}
+ * <p>
+ * A Form is empty if all of its fields are empty.
+ *
+ */
@Override
- protected boolean isEmpty() {
+ public boolean isEmpty() {
for (Iterator<Field<?>> i = fields.values().iterator(); i.hasNext();) {
Field<?> f = i.next();
diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/com/vaadin/ui/GridLayout.java
index 0dd16a03e7..96854c5b1b 100644
--- a/server/src/com/vaadin/ui/GridLayout.java
+++ b/server/src/com/vaadin/ui/GridLayout.java
@@ -255,8 +255,6 @@ public class GridLayout extends AbstractLayout implements
cursorY = row1;
}
}
-
- markAsDirty();
}
/**
@@ -390,7 +388,6 @@ public class GridLayout extends AbstractLayout implements
getState().childData.remove(component);
components.remove(component);
-
super.removeComponent(component);
}
diff --git a/server/src/com/vaadin/ui/RichTextArea.java b/server/src/com/vaadin/ui/RichTextArea.java
index 9d05181541..31327b3a6f 100644
--- a/server/src/com/vaadin/ui/RichTextArea.java
+++ b/server/src/com/vaadin/ui/RichTextArea.java
@@ -285,7 +285,7 @@ public class RichTextArea extends AbstractField<String> implements
}
@Override
- protected boolean isEmpty() {
+ public boolean isEmpty() {
return super.isEmpty() || getValue().length() == 0;
}
diff --git a/server/src/com/vaadin/ui/TabSheet.java b/server/src/com/vaadin/ui/TabSheet.java
index e4060528ee..5528ea2ee9 100644
--- a/server/src/com/vaadin/ui/TabSheet.java
+++ b/server/src/com/vaadin/ui/TabSheet.java
@@ -202,7 +202,6 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
if (component != null && components.contains(component)) {
int componentIndex = components.indexOf(component);
-
super.removeComponent(component);
keyMapper.remove(component);
components.remove(component);
@@ -239,7 +238,6 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
fireSelectedTabChange();
}
}
- markAsDirty();
}
}
@@ -401,8 +399,9 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
setSelected(tabComponent);
fireSelectedTabChange();
}
+
super.addComponent(tabComponent);
- markAsDirty();
+
return tab;
}
}
@@ -974,16 +973,16 @@ public class TabSheet extends AbstractComponentContainer implements Focusable,
/**
* Gets the icon alt text for the tab.
- *
+ *
* @since 7.2
*/
public String getIconAlternateText();
/**
* Sets the icon alt text for the tab.
- *
+ *
* @since 7.2
- *
+ *
* @param iconAltText
* the icon to set
*/
diff --git a/server/src/com/vaadin/ui/TextField.java b/server/src/com/vaadin/ui/TextField.java
index 563810c76a..2a61e93211 100644
--- a/server/src/com/vaadin/ui/TextField.java
+++ b/server/src/com/vaadin/ui/TextField.java
@@ -48,7 +48,7 @@ public class TextField extends AbstractTextField {
* Constructs an empty <code>TextField</code> with no caption.
*/
public TextField() {
- setValue("");
+ clear();
}
/**
@@ -107,7 +107,7 @@ public class TextField extends AbstractTextField {
/*
* (non-Javadoc)
*
- * @see com.vaadin.ui.AbstractField#readDesign(org.jsoup.nodes.Element ,
+ * @see com.vaadin.ui.AbstractTextField#readDesign(org.jsoup.nodes.Element,
* com.vaadin.ui.declarative.DesignContext)
*/
@Override
@@ -135,4 +135,15 @@ public class TextField extends AbstractTextField {
DesignAttributeHandler.writeAttribute("value", attr, getValue(),
def.getValue(), String.class);
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.AbstractField#clear()
+ */
+ @Override
+ public void clear() {
+ setValue("");
+ }
+
}
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 78cb5488e8..4bd4b67259 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -633,7 +633,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements
this.embedId = embedId;
// Actual theme - used for finding CustomLayout templates
- getState().theme = request.getParameter("theme");
+ setTheme(request.getParameter("theme"));
getPage().init(request);
@@ -1164,7 +1164,11 @@ public abstract class UI extends AbstractSingleComponentContainer implements
* The new theme name
*/
public void setTheme(String theme) {
- getState().theme = theme;
+ if(theme == null) {
+ getState().theme = null;
+ } else {
+ getState().theme = VaadinServlet.stripSpecialChars(theme);
+ }
}
/**
diff --git a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
index fcaabcc079..2f51b21f7c 100644
--- a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
+++ b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java
@@ -249,71 +249,33 @@ public class ContainerEventProvider implements CalendarEditableEventProvider,
@Override
public List<CalendarEvent> getEvents(Date startDate, Date endDate) {
eventCache.clear();
-
- int[] rangeIndexes = getFirstAndLastEventIndex(startDate, endDate);
- for (int i = rangeIndexes[0]; i <= rangeIndexes[1]
- && i < container.size(); i++) {
- eventCache.add(getEvent(i));
- }
- return Collections.unmodifiableList(eventCache);
- }
-
- /**
- * Get the first event for a date
- *
- * @param date
- * The date to search for, NUll returns first event in container
- * @return Returns an array where the first item is the start index and the
- * second item is the end item
- */
- private int[] getFirstAndLastEventIndex(Date start, Date end) {
- int startIndex = 0;
int size = container.size();
assert size >= 0;
- int endIndex = size - 1;
- if (start != null) {
- /*
- * Iterating from the start of the container, if range is in the end
- * of the container then this will be slow TODO This could be
- * improved by using some sort of divide and conquer algorithm
- */
- while (startIndex < size) {
- Object id = container.getIdByIndex(startIndex);
- Item item = container.getItem(id);
- Date d = (Date) item.getItemProperty(startDateProperty)
+ for (int i = 0; i < size; i++) {
+ Object id = container.getIdByIndex(i);
+ Item item = container.getItem(id);
+ boolean add = true;
+ if (startDate != null) {
+ Date eventEnd = (Date) item.getItemProperty(endDateProperty)
.getValue();
- if (d.compareTo(start) >= 0) {
- break;
+ if (eventEnd.compareTo(startDate) < 0) {
+ add = false;
}
- startIndex++;
}
- }
-
- if (end != null) {
- /*
- * Iterate from the start index until range ends
- */
- endIndex = startIndex;
- while (endIndex < size - 1) {
- Object id = container.getIdByIndex(endIndex);
- Item item = container.getItem(id);
- Date d = (Date) item.getItemProperty(endDateProperty)
- .getValue();
- if (d == null) {
- // No end date present, use start date
- d = (Date) item.getItemProperty(startDateProperty)
- .getValue();
+ if (add && endDate != null) {
+ Date eventStart = (Date) item
+ .getItemProperty(startDateProperty).getValue();
+ if (eventStart.compareTo(endDate) >= 0) {
+ break; // because container is sorted, all further events
+ // will be even later
}
- if (d.compareTo(end) >= 0) {
- endIndex--;
- break;
- }
- endIndex++;
+ }
+ if (add) {
+ eventCache.add(getEvent(i));
}
}
-
- return new int[] { startIndex, endIndex };
+ return Collections.unmodifiableList(eventCache);
}
/*
diff --git a/server/tests/src/com/vaadin/data/util/BeanContainerTest.java b/server/tests/src/com/vaadin/data/util/BeanContainerTest.java
index 4e0e98ec43..f22ab8478e 100644
--- a/server/tests/src/com/vaadin/data/util/BeanContainerTest.java
+++ b/server/tests/src/com/vaadin/data/util/BeanContainerTest.java
@@ -68,6 +68,19 @@ public class BeanContainerTest extends AbstractBeanContainerTest {
return false;
}
+ public void testGetType_existingProperty_typeReturned() {
+ BeanContainer<String, ClassName> container = getContainer();
+ Assert.assertEquals(
+ "Unexpected type is returned for property 'simpleName'",
+ String.class, container.getType("simpleName"));
+ }
+
+ public void testGetType_notExistingProperty_nullReturned() {
+ BeanContainer<String, ClassName> container = getContainer();
+ Assert.assertNull("Not null type is returned for property ''",
+ container.getType(""));
+ }
+
public void testBasicOperations() {
testBasicContainerOperations(getContainer());
}
diff --git a/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
index b58d962d96..514bf70416 100644
--- a/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
+++ b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java
@@ -12,6 +12,7 @@ import org.junit.Assert;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
+import com.vaadin.data.util.NestedMethodPropertyTest.Address;
/**
* Test basic functionality of BeanItemContainer.
@@ -71,6 +72,19 @@ public class BeanItemContainerTest extends AbstractBeanContainerTest {
return false;
}
+ public void testGetType_existingProperty_typeReturned() {
+ BeanItemContainer<ClassName> container = getContainer();
+ Assert.assertEquals(
+ "Unexpected type is returned for property 'simpleName'",
+ String.class, container.getType("simpleName"));
+ }
+
+ public void testGetType_notExistingProperty_nullReturned() {
+ BeanItemContainer<ClassName> container = getContainer();
+ Assert.assertNull("Not null type is returned for property ''",
+ container.getType(""));
+ }
+
public void testBasicOperations() {
testBasicContainerOperations(getContainer());
}
@@ -727,4 +741,45 @@ public class BeanItemContainerTest extends AbstractBeanContainerTest {
assertNull(container.getContainerProperty(john, "address.street")
.getValue());
}
+
+ public void testAddNestedContainerBeanBeforeData() {
+ BeanItemContainer<NestedMethodPropertyTest.Person> container = new BeanItemContainer<NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+
+ container.addNestedContainerBean("address");
+
+ assertTrue(container.getContainerPropertyIds().contains(
+ "address.street"));
+
+ NestedMethodPropertyTest.Person john = new NestedMethodPropertyTest.Person(
+ "John", new Address("streetname", 12345));
+ container.addBean(john);
+
+ assertTrue(container.getItem(john).getItemPropertyIds()
+ .contains("address.street"));
+ assertEquals("streetname",
+ container.getItem(john).getItemProperty("address.street")
+ .getValue());
+
+ }
+
+ public void testAddNestedContainerBeanAfterData() {
+ BeanItemContainer<NestedMethodPropertyTest.Person> container = new BeanItemContainer<NestedMethodPropertyTest.Person>(
+ NestedMethodPropertyTest.Person.class);
+
+ NestedMethodPropertyTest.Person john = new NestedMethodPropertyTest.Person(
+ "John", new Address("streetname", 12345));
+ container.addBean(john);
+
+ container.addNestedContainerBean("address");
+
+ assertTrue(container.getContainerPropertyIds().contains(
+ "address.street"));
+ assertTrue(container.getItem(john).getItemPropertyIds()
+ .contains("address.street"));
+ assertEquals("streetname",
+ container.getItem(john).getItemProperty("address.street")
+ .getValue());
+
+ }
}
diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
index d907f12321..f82ba49c3e 100644
--- a/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTableQueryTest.java
@@ -24,11 +24,15 @@ import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
import com.vaadin.data.util.sqlcontainer.query.OrderBy;
import com.vaadin.data.util.sqlcontainer.query.TableQuery;
+import static org.junit.Assert.assertTrue;
+
public class SQLContainerTableQueryTest {
private static final int offset = SQLTestsConstants.offset;
private static final String createGarbage = SQLTestsConstants.createGarbage;
private JDBCConnectionPool connectionPool;
+ private TableQuery peopleQuery;
+ private SQLContainer peopleContainer;
@Before
public void setUp() throws SQLException {
@@ -43,6 +47,10 @@ public class SQLContainerTableQueryTest {
}
DataGenerator.addPeopleToDatabase(connectionPool);
+
+ peopleQuery = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ peopleContainer = new SQLContainer(peopleQuery);
}
@After
@@ -53,6 +61,24 @@ public class SQLContainerTableQueryTest {
}
@Test
+ public void itemWithExistingVersionColumnIsRemoved()
+ throws SQLException {
+ peopleContainer.setAutoCommit(true);
+ peopleQuery.setVersionColumn("ID");
+
+ assertTrue(peopleContainer.removeItem(peopleContainer.lastItemId()));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void itemWithNonExistingVersionColumnCannotBeRemoved() throws SQLException {
+ peopleQuery.setVersionColumn("version");
+
+ peopleContainer.removeItem(peopleContainer.lastItemId());
+
+ peopleContainer.commit();
+ }
+
+ @Test
public void constructor_withTableQuery_shouldSucceed() throws SQLException {
new SQLContainer(new TableQuery("people", connectionPool,
SQLTestsConstants.sqlGen));
@@ -63,8 +89,8 @@ public class SQLContainerTableQueryTest {
throws SQLException {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
- Assert.assertTrue(container.containsId(new RowId(
- new Object[] { 1 + offset })));
+ assertTrue(container.containsId(new RowId(
+ new Object[]{1 + offset})));
}
@Test
@@ -410,11 +436,11 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
if (SQLTestsConstants.db == DB.ORACLE) {
- Assert.assertTrue(container.isFirstId(new RowId(
- new Object[] { new BigDecimal(0 + offset) })));
+ assertTrue(container.isFirstId(new RowId(
+ new Object[]{new BigDecimal(0 + offset)})));
} else {
- Assert.assertTrue(container.isFirstId(new RowId(
- new Object[] { 0 + offset })));
+ assertTrue(container.isFirstId(new RowId(
+ new Object[]{0 + offset})));
}
}
@@ -449,11 +475,11 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
if (SQLTestsConstants.db == DB.ORACLE) {
- Assert.assertTrue(container.isLastId(new RowId(
- new Object[] { new BigDecimal(3 + offset) })));
+ assertTrue(container.isLastId(new RowId(
+ new Object[]{new BigDecimal(3 + offset)})));
} else {
- Assert.assertTrue(container.isLastId(new RowId(
- new Object[] { 3 + offset })));
+ assertTrue(container.isLastId(new RowId(
+ new Object[]{3 + offset})));
}
}
@@ -463,11 +489,11 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
if (SQLTestsConstants.db == DB.ORACLE) {
- Assert.assertTrue(container.isLastId(new RowId(
- new Object[] { new BigDecimal(4999 + offset) })));
+ assertTrue(container.isLastId(new RowId(
+ new Object[]{new BigDecimal(4999 + offset)})));
} else {
- Assert.assertTrue(container.isLastId(new RowId(
- new Object[] { 4999 + offset })));
+ assertTrue(container.isLastId(new RowId(
+ new Object[]{4999 + offset})));
}
}
@@ -478,7 +504,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
for (int i = 0; i < 5000; i++) {
- Assert.assertTrue(container.containsId(container.getIdByIndex(i)));
+ assertTrue(container.containsId(container.getIdByIndex(i)));
}
}
@@ -490,7 +516,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
container.setAutoCommit(true);
for (int i = 0; i < 5000; i++) {
- Assert.assertTrue(container.containsId(container.getIdByIndex(i)));
+ assertTrue(container.containsId(container.getIdByIndex(i)));
}
}
@@ -523,7 +549,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
container.setAutoCommit(true);
- Assert.assertTrue(container.isAutoCommit());
+ assertTrue(container.isAutoCommit());
container.setAutoCommit(false);
Assert.assertFalse(container.isAutoCommit());
}
@@ -613,7 +639,7 @@ public class SQLContainerTableQueryTest {
container.setAutoCommit(true);
Object itemId = container.addItem();
Assert.assertNotNull(itemId);
- Assert.assertTrue(itemId instanceof RowId);
+ assertTrue(itemId instanceof RowId);
Assert.assertFalse(itemId instanceof TemporaryRowId);
}
@@ -696,7 +722,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.getItemIds().contains(id));
+ assertTrue(container.getItemIds().contains(id));
}
@Test
@@ -717,7 +743,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.containsId(id));
+ assertTrue(container.containsId(id));
}
@Test
@@ -747,7 +773,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("garbage",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.isFirstId(id));
+ assertTrue(container.isFirstId(id));
}
@Test
@@ -756,7 +782,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.isLastId(id));
+ assertTrue(container.isLastId(id));
}
@Test
@@ -766,7 +792,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
container.addItem();
Object id2 = container.addItem();
- Assert.assertTrue(container.isLastId(id2));
+ assertTrue(container.isLastId(id2));
}
@Test
@@ -785,7 +811,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
int size = container.size();
Object id = container.firstItemId();
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNotSame(id, container.firstItemId());
Assert.assertEquals(size - 1, container.size());
}
@@ -795,7 +821,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.firstItemId();
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.containsId(id));
}
@@ -806,7 +832,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
int size = container.size();
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.containsId(id));
Assert.assertEquals(size - 1, container.size());
}
@@ -816,7 +842,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.firstItemId();
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNull(container.getItem(id));
}
@@ -826,7 +852,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
Assert.assertNotNull(container.getItem(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNull(container.getItem(id));
}
@@ -836,8 +862,8 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.firstItemId();
- Assert.assertTrue(container.getItemIds().contains(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.getItemIds().contains(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.getItemIds().contains(id));
}
@@ -847,8 +873,8 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.getItemIds().contains(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.getItemIds().contains(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.getItemIds().contains(id));
}
@@ -857,8 +883,8 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.firstItemId();
- Assert.assertTrue(container.containsId(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.containsId(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.containsId(id));
}
@@ -869,8 +895,8 @@ public class SQLContainerTableQueryTest {
SQLTestsConstants.sqlGen);
SQLContainer container = new SQLContainer(query);
Object id = container.addItem();
- Assert.assertTrue(container.containsId(id));
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.containsId(id));
+ assertTrue(container.removeItem(id));
Assert.assertFalse(container.containsId(id));
}
@@ -882,7 +908,7 @@ public class SQLContainerTableQueryTest {
Object first = container.getIdByIndex(0);
Object second = container.getIdByIndex(1);
Object third = container.getIdByIndex(2);
- Assert.assertTrue(container.removeItem(second));
+ assertTrue(container.removeItem(second));
Assert.assertEquals(third, container.nextItemId(first));
}
@@ -894,7 +920,7 @@ public class SQLContainerTableQueryTest {
Object first = container.lastItemId();
Object second = container.addItem();
Object third = container.addItem();
- Assert.assertTrue(container.removeItem(second));
+ assertTrue(container.removeItem(second));
Assert.assertEquals(third, container.nextItemId(first));
}
@@ -906,7 +932,7 @@ public class SQLContainerTableQueryTest {
Object first = container.getIdByIndex(0);
Object second = container.getIdByIndex(1);
Object third = container.getIdByIndex(2);
- Assert.assertTrue(container.removeItem(second));
+ assertTrue(container.removeItem(second));
Assert.assertEquals(first, container.prevItemId(third));
}
@@ -918,7 +944,7 @@ public class SQLContainerTableQueryTest {
Object first = container.lastItemId();
Object second = container.addItem();
Object third = container.addItem();
- Assert.assertTrue(container.removeItem(second));
+ assertTrue(container.removeItem(second));
Assert.assertEquals(first, container.prevItemId(third));
}
@@ -928,7 +954,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object first = container.firstItemId();
- Assert.assertTrue(container.removeItem(first));
+ assertTrue(container.removeItem(first));
Assert.assertNotSame(first, container.firstItemId());
}
@@ -941,7 +967,7 @@ public class SQLContainerTableQueryTest {
Object first = container.addItem();
Object second = container.addItem();
Assert.assertSame(first, container.firstItemId());
- Assert.assertTrue(container.removeItem(first));
+ assertTrue(container.removeItem(first));
Assert.assertSame(second, container.firstItemId());
}
@@ -951,7 +977,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object last = container.lastItemId();
- Assert.assertTrue(container.removeItem(last));
+ assertTrue(container.removeItem(last));
Assert.assertNotSame(last, container.lastItemId());
}
@@ -962,7 +988,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Object last = container.addItem();
Assert.assertSame(last, container.lastItemId());
- Assert.assertTrue(container.removeItem(last));
+ assertTrue(container.removeItem(last));
Assert.assertNotSame(last, container.lastItemId());
}
@@ -972,7 +998,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object first = container.firstItemId();
- Assert.assertTrue(container.removeItem(first));
+ assertTrue(container.removeItem(first));
Assert.assertFalse(container.isFirstId(first));
}
@@ -985,7 +1011,7 @@ public class SQLContainerTableQueryTest {
Object first = container.addItem();
container.addItem();
Assert.assertSame(first, container.firstItemId());
- Assert.assertTrue(container.removeItem(first));
+ assertTrue(container.removeItem(first));
Assert.assertFalse(container.isFirstId(first));
}
@@ -995,7 +1021,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object last = container.lastItemId();
- Assert.assertTrue(container.removeItem(last));
+ assertTrue(container.removeItem(last));
Assert.assertFalse(container.isLastId(last));
}
@@ -1006,7 +1032,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Object last = container.addItem();
Assert.assertSame(last, container.lastItemId());
- Assert.assertTrue(container.removeItem(last));
+ assertTrue(container.removeItem(last));
Assert.assertFalse(container.isLastId(last));
}
@@ -1015,7 +1041,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.getIdByIndex(2);
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertEquals(-1, container.indexOfId(id));
}
@@ -1025,8 +1051,8 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.addItem();
- Assert.assertTrue(container.indexOfId(id) != -1);
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.indexOfId(id) != -1);
+ assertTrue(container.removeItem(id));
Assert.assertEquals(-1, container.indexOfId(id));
}
@@ -1036,7 +1062,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Object id = container.getIdByIndex(2);
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNotSame(id, container.getIdByIndex(2));
}
@@ -1048,7 +1074,7 @@ public class SQLContainerTableQueryTest {
Object id = container.addItem();
container.addItem();
int index = container.indexOfId(id);
- Assert.assertTrue(container.removeItem(id));
+ assertTrue(container.removeItem(id));
Assert.assertNotSame(id, container.getIdByIndex(index));
}
@@ -1056,7 +1082,7 @@ public class SQLContainerTableQueryTest {
public void removeAllItems_table_shouldSucceed() throws SQLException {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
- Assert.assertTrue(container.removeAllItems());
+ assertTrue(container.removeAllItems());
Assert.assertEquals(0, container.size());
}
@@ -1067,10 +1093,30 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
container.addItem();
container.addItem();
- Assert.assertTrue(container.removeAllItems());
+ assertTrue(container.removeAllItems());
Assert.assertEquals(0, container.size());
}
+ // Set timeout to ensure there is no infinite looping (#12882)
+ @Test(timeout = 1000)
+ public void removeAllItems_manyItems_commit_shouldSucceed()
+ throws SQLException {
+ SQLContainer container = new SQLContainer(new TableQuery("people",
+ connectionPool, SQLTestsConstants.sqlGen));
+ final int itemNumber = (SQLContainer.CACHE_RATIO + 1)
+ * SQLContainer.DEFAULT_PAGE_LENGTH + 1;
+ container.removeAllItems();
+ Assert.assertEquals(container.size(), 0);
+ for (int i = 0; i < itemNumber; ++i) {
+ container.addItem();
+ }
+ container.commit();
+ Assert.assertEquals(container.size(), itemNumber);
+ assertTrue(container.removeAllItems());
+ container.commit();
+ Assert.assertEquals(container.size(), 0);
+ }
+
@Test
public void commit_tableAddedItem_shouldBeWrittenToDB() throws SQLException {
TableQuery query = new TableQuery("people", connectionPool,
@@ -1078,7 +1124,7 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(query);
Object id = container.addItem();
container.getContainerProperty(id, "NAME").setValue("New Name");
- Assert.assertTrue(id instanceof TemporaryRowId);
+ assertTrue(id instanceof TemporaryRowId);
Assert.assertSame(id, container.lastItemId());
container.commit();
Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId);
@@ -1097,7 +1143,7 @@ public class SQLContainerTableQueryTest {
Object id2 = container.addItem();
container.getContainerProperty(id, "NAME").setValue("Herbert");
container.getContainerProperty(id2, "NAME").setValue("Larry");
- Assert.assertTrue(id2 instanceof TemporaryRowId);
+ assertTrue(id2 instanceof TemporaryRowId);
Assert.assertSame(id2, container.lastItemId());
container.commit();
Object nextToLast = container.getIdByIndex(container.size() - 2);
@@ -1137,6 +1183,20 @@ public class SQLContainerTableQueryTest {
}
@Test
+ public void commit_removeModifiedItem_shouldSucceed() throws SQLException {
+ TableQuery query = new TableQuery("people", connectionPool,
+ SQLTestsConstants.sqlGen);
+ SQLContainer container = new SQLContainer(query);
+ int size = container.size();
+ Object key = container.firstItemId();
+ Item row = container.getItem(key);
+ row.getItemProperty("NAME").setValue("Pekka");
+ assertTrue(container.removeItem(key));
+ container.commit();
+ Assert.assertEquals(size - 1, container.size());
+ }
+
+ @Test
public void rollback_tableItemAdded_discardsAddedItem() throws SQLException {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
@@ -1183,7 +1243,7 @@ public class SQLContainerTableQueryTest {
Assert.assertFalse(container.isModified());
RowItem last = (RowItem) container.getItem(container.lastItemId());
container.itemChangeNotification(last);
- Assert.assertTrue(container.isModified());
+ assertTrue(container.isModified());
}
@Test
@@ -1239,7 +1299,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Assert.assertFalse(container.isModified());
container.removeItem(container.lastItemId());
- Assert.assertTrue(container.isModified());
+ assertTrue(container.isModified());
}
@Test
@@ -1248,7 +1308,7 @@ public class SQLContainerTableQueryTest {
connectionPool, SQLTestsConstants.sqlGen));
Assert.assertFalse(container.isModified());
container.addItem();
- Assert.assertTrue(container.isModified());
+ assertTrue(container.isModified());
}
@Test
@@ -1258,7 +1318,7 @@ public class SQLContainerTableQueryTest {
Assert.assertFalse(container.isModified());
container.getContainerProperty(container.lastItemId(), "NAME")
.setValue("foo");
- Assert.assertTrue(container.isModified());
+ assertTrue(container.isModified());
}
@Test
@@ -1267,9 +1327,9 @@ public class SQLContainerTableQueryTest {
SQLContainer container = new SQLContainer(new TableQuery("people",
connectionPool, SQLTestsConstants.sqlGen));
Collection<?> sortableIds = container.getSortableContainerPropertyIds();
- Assert.assertTrue(sortableIds.contains("ID"));
- Assert.assertTrue(sortableIds.contains("NAME"));
- Assert.assertTrue(sortableIds.contains("AGE"));
+ assertTrue(sortableIds.contains("ID"));
+ assertTrue(sortableIds.contains("NAME"));
+ assertTrue(sortableIds.contains("AGE"));
Assert.assertEquals(3, sortableIds.size());
if (SQLTestsConstants.db == DB.MSSQL
|| SQLTestsConstants.db == DB.ORACLE) {
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestDefaultConverterFactory.java b/server/tests/src/com/vaadin/tests/data/converter/TestDefaultConverterFactory.java
new file mode 100644
index 0000000000..e1becf43e1
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestDefaultConverterFactory.java
@@ -0,0 +1,128 @@
+/*
+ * 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.data.converter;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.converter.DefaultConverterFactory;
+
+public class TestDefaultConverterFactory {
+
+ private DefaultConverterFactory factory = new DefaultConverterFactory();
+
+ @Test
+ public void stringToBigDecimal() {
+ assertConverter("14", new BigDecimal("14"));
+ }
+
+ @Test
+ public void stringToBigInteger() {
+ assertConverter("14", new BigInteger("14"));
+ }
+
+ @Test
+ public void stringToDouble() {
+ assertConverter("14", new Double("14"));
+ }
+
+ @Test
+ public void stringToFloat() {
+ assertConverter("14", new Float("14"));
+ }
+
+ @Test
+ public void stringToInteger() {
+ assertConverter("14", new Integer("14"));
+ }
+
+ @Test
+ public void stringToLong() {
+ assertConverter("14", new Long("14"));
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void stringToDate() {
+ assertConverter("Oct 12, 2014 12:00:00 AM", new Date(2014 - 1900,
+ 10 - 1, 12));
+ }
+
+ @Test
+ public void sqlDateToDate() {
+ long l = 1413071210000L;
+ assertConverter(new java.sql.Date(l), new java.util.Date(l));
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void longToDate() {
+ assertConverter(1413061200000L, new Date(2014 - 1900, 10 - 1, 12));
+ }
+
+ public enum Foo {
+ BAR, BAZ;
+ }
+
+ @Test
+ public void stringToEnum() {
+ assertConverter("Bar", Foo.BAR);
+ }
+
+ @Test
+ public void stringToShort() {
+ assertConverter("14", new Short("14"));
+ }
+
+ @Test
+ public void stringToByte() {
+ assertConverter("14", new Byte("14"));
+ }
+
+ private <T, U> void assertConverter(T t, U u) {
+ Class<T> tClass = (Class<T>) t.getClass();
+ Class<U> uClass = (Class<U>) u.getClass();
+
+ U tConvertedToU = factory.createConverter(tClass, uClass)
+ .convertToModel(t, uClass, Locale.ENGLISH);
+ Assert.assertEquals(
+ "Incorrect type of value converted from "
+ + tClass.getSimpleName() + " to "
+ + uClass.getSimpleName(), uClass,
+ tConvertedToU.getClass());
+ Assert.assertEquals(
+ "Incorrect conversion of " + t + " to "
+ + uClass.getSimpleName(), u, tConvertedToU);
+
+ T uConvertedToT = factory.createConverter(uClass, tClass)
+ .convertToModel(u, tClass, Locale.ENGLISH);
+ Assert.assertEquals(
+ "Incorrect type of value converted from "
+ + uClass.getSimpleName() + " to "
+ + tClass.getSimpleName(), tClass,
+ uConvertedToT.getClass());
+ Assert.assertEquals(
+ "Incorrect conversion of " + u + " to "
+ + tClass.getSimpleName(), t, uConvertedToT);
+
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java
index 641f18c865..8d493609fe 100644
--- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigIntegerConverter.java
@@ -15,39 +15,43 @@
*/
package com.vaadin.tests.data.converter;
-import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.Locale;
import junit.framework.TestCase;
-import com.vaadin.data.util.converter.StringToBigDecimalConverter;
+import com.vaadin.data.util.converter.StringToBigIntegerConverter;
public class TestStringToBigIntegerConverter extends TestCase {
- StringToBigDecimalConverter converter = new StringToBigDecimalConverter();
+ StringToBigIntegerConverter converter = new StringToBigIntegerConverter();
public void testNullConversion() {
- assertEquals(null,
- converter.convertToModel(null, BigDecimal.class, null));
+ assertEquals("Null value was converted incorrectly", null,
+ converter.convertToModel(null, BigInteger.class, null));
}
public void testEmptyStringConversion() {
- assertEquals(null, converter.convertToModel("", BigDecimal.class, null));
+ assertEquals("Empty value was converted incorrectly", null,
+ converter.convertToModel("", BigInteger.class, null));
}
public void testValueParsing() {
- BigDecimal converted = converter.convertToModel("10", BigDecimal.class,
- null);
- BigDecimal expected = new BigDecimal(10);
- assertEquals(expected, converted);
+ String bigInt = "1180591620717411303424"; // 2^70 > 2^63 - 1
+ BigInteger converted = converter.convertToModel(bigInt,
+ BigInteger.class, null);
+ BigInteger expected = new BigInteger(bigInt);
+ assertEquals("Value bigger than max long was converted incorrectly",
+ expected, converted);
}
public void testValueFormatting() {
- BigDecimal bd = new BigDecimal(1000);
+ BigInteger bd = new BigInteger("1000");
String expected = "1.000";
String converted = converter.convertToPresentation(bd, String.class,
Locale.GERMAN);
- assertEquals(expected, converted);
+ assertEquals("Value with specific locale was converted incorrectly",
+ expected, converted);
}
}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java
index 440d056c06..19a68fbfdb 100644
--- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToByteConverter.java
@@ -16,25 +16,28 @@ public class TestStringToByteConverter extends TestCase {
converter);
public void testNullConversion() {
- assertEquals(null, converter.convertToModel(null, Byte.class, null));
+ assertEquals("Null value was converted incorrectly", null,
+ converter.convertToModel(null, Byte.class, null));
}
public void testReverseNullConversion() {
- assertEquals(null,
+ assertEquals("Null value reversely was converted incorrectly", null,
reverseConverter.convertToModel(null, String.class, null));
}
public void testEmptyStringConversion() {
- assertEquals(null, converter.convertToModel("", Byte.class, null));
+ assertEquals("Empty value was converted incorrectly", null,
+ converter.convertToModel("", Byte.class, null));
}
public void testValueConversion() {
- assertEquals(Byte.valueOf((byte) 10),
+ assertEquals("Byte value was converted incorrectly",
+ Byte.valueOf((byte) 10),
converter.convertToModel("10", Byte.class, null));
}
public void testReverseValueConversion() {
- assertEquals(
+ assertEquals("Byte value reversely was converted incorrectly",
reverseConverter.convertToModel((byte) 10, String.class, null),
"10");
}
@@ -43,7 +46,8 @@ public class TestStringToByteConverter extends TestCase {
byte b = converter.convertToModel("127", Byte.class, null);
Assert.assertEquals(Byte.MAX_VALUE, b);
b = converter.convertToModel("-128", Byte.class, null);
- assertEquals(Byte.MIN_VALUE, b);
+ assertEquals("Min byte value was converted incorrectly",
+ Byte.MIN_VALUE, b);
}
public void testValueOutOfRange() {
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java
index 2b19395c08..5dc24ca43a 100644
--- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToEnumConverter.java
@@ -3,6 +3,7 @@ package com.vaadin.tests.data.converter;
import junit.framework.TestCase;
import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.Converter.ConversionException;
import com.vaadin.data.util.converter.ReverseConverter;
import com.vaadin.data.util.converter.StringToEnumConverter;
@@ -16,6 +17,19 @@ public class TestStringToEnumConverter extends TestCase {
Converter<Enum, String> reverseConverter = new ReverseConverter<Enum, String>(
converter);
+ public void testEmptyStringConversion() {
+ assertEquals(null, converter.convertToModel("", Enum.class, null));
+ }
+
+ public void testInvalidEnumClassConversion() {
+ try {
+ converter.convertToModel("Foo", Enum.class, null);
+ fail("No exception thrown");
+ } catch (ConversionException e) {
+ // OK
+ }
+ }
+
public void testNullConversion() {
assertEquals(null, converter.convertToModel(null, Enum.class, null));
}
diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java
index 35547d2570..542c580025 100644
--- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java
+++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToShortConverter.java
@@ -16,25 +16,29 @@ public class TestStringToShortConverter extends TestCase {
converter);
public void testNullConversion() {
- assertEquals(null, converter.convertToModel(null, Short.class, null));
+ assertEquals("Null value was converted incorrectly", null,
+ converter.convertToModel(null, Short.class, null));
}
public void testReverseNullConversion() {
- assertEquals(null,
+ assertEquals("Null value reversely was converted incorrectly", null,
reverseConverter.convertToModel(null, String.class, null));
}
public void testEmptyStringConversion() {
- assertEquals(null, converter.convertToModel("", Short.class, null));
+ assertEquals("Empty value was converted incorrectly", null,
+ converter.convertToModel("", Short.class, null));
}
public void testValueConversion() {
- assertEquals(Short.valueOf((short) 10),
+ assertEquals("Short value was converted incorrectly",
+ Short.valueOf((short) 10),
converter.convertToModel("10", Short.class, null));
}
public void testReverseValueConversion() {
assertEquals(
+ "Short value reversely was converted incorrectly",
reverseConverter.convertToModel((short) 10, String.class, null),
"10");
}
@@ -43,7 +47,8 @@ public class TestStringToShortConverter extends TestCase {
short b = converter.convertToModel("32767", Short.class, null);
Assert.assertEquals(Short.MAX_VALUE, b);
b = converter.convertToModel("-32768", Short.class, null);
- assertEquals(Short.MIN_VALUE, b);
+ assertEquals("Min short value was converted incorrectly",
+ Short.MIN_VALUE, b);
}
public void testValueOutOfRange() {
diff --git a/server/tests/src/com/vaadin/tests/server/FileResourceTest.java b/server/tests/src/com/vaadin/tests/server/FileResourceTest.java
new file mode 100644
index 0000000000..4798fb9f05
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/FileResourceTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.server;
+
+import java.io.File;
+
+import org.junit.Test;
+
+import com.vaadin.server.FileResource;
+
+public class FileResourceTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFile() {
+ new FileResource(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void nonExistingFile() {
+ new FileResource(new File("nonexisting")).getStream();
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java
index 112d36d884..9c37b91ef5 100644
--- a/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/fieldgroup/BeanFieldGroupTest.java
@@ -5,9 +5,11 @@ import static org.junit.Assert.assertEquals;
import org.junit.Assert;
import org.junit.Test;
+import com.vaadin.data.Item;
import com.vaadin.data.fieldgroup.BeanFieldGroup;
import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
import com.vaadin.data.fieldgroup.PropertyId;
+import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.Field;
import com.vaadin.ui.TextField;
@@ -133,4 +135,23 @@ public class BeanFieldGroupTest {
assertEquals(bean.nestedBean.hello, helloField.getValue().toString());
}
+ @Test
+ public void setDataSource_nullBean_nullBeanIsSetInDataSource() {
+ BeanFieldGroup<MyBean> group = new BeanFieldGroup<MyBean>(MyBean.class);
+
+ group.setItemDataSource((MyBean) null);
+
+ BeanItem<MyBean> dataSource = group.getItemDataSource();
+ Assert.assertNull("Data source is null for null bean", dataSource);
+ }
+
+ @Test
+ public void setDataSource_nullItem_nullDataSourceIsSet() {
+ BeanFieldGroup<MyBean> group = new BeanFieldGroup<MyBean>(MyBean.class);
+
+ group.setItemDataSource((Item) null);
+ BeanItem<MyBean> dataSource = group.getItemDataSource();
+ Assert.assertNull("Group returns not null data source", dataSource);
+ }
+
}
diff --git a/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java b/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
index df515795eb..d8b366ffbc 100644
--- a/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
+++ b/server/tests/src/com/vaadin/tests/server/components/ComponentAttachDetachListenerTest.java
@@ -9,6 +9,7 @@ import com.vaadin.ui.AbsoluteLayout.ComponentPosition;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.CustomLayout;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.GridLayout.Area;
import com.vaadin.ui.HasComponents;
@@ -25,6 +26,7 @@ public class ComponentAttachDetachListenerTest extends TestCase {
private GridLayout gridlayout;
private AbsoluteLayout absolutelayout;
private CssLayout csslayout;
+ private CustomLayout customlayout;
// General variables
private int attachCounter = 0;
@@ -143,6 +145,10 @@ public class ComponentAttachDetachListenerTest extends TestCase {
csslayout = new CssLayout();
csslayout.addComponentAttachListener(new MyAttachListener());
csslayout.addComponentDetachListener(new MyDetachListener());
+
+ customlayout = new CustomLayout("<div location='loc'/>");
+ customlayout.addComponentAttachListener(new MyAttachListener());
+ customlayout.addComponentDetachListener(new MyDetachListener());
}
public void testOrderedLayoutAttachListener() {
@@ -342,4 +348,48 @@ public class ComponentAttachDetachListenerTest extends TestCase {
// The detached component should not be found in the container
assertFalse(foundInContainer);
}
+
+ public void testCustomLayoutAttachListener() {
+ // Reset state variables
+ resetVariables();
+
+ // Add component -> Should trigger attach listener
+ Component comp = new Label();
+ customlayout.addComponent(comp, "loc");
+
+ assertEquals("Attach counter should get incremented", 1, attachCounter);
+
+ assertSame("The attached component should be the label", comp,
+ attachedComponent);
+
+ assertSame("The attached target should be the layout", customlayout,
+ attachTarget);
+
+ assertTrue("The attached component should be found in the container",
+ foundInContainer);
+ }
+
+ public void testCustomLayoutDetachListener() {
+ // Add a component to detach
+ Component comp = new Label();
+ customlayout.addComponent(comp);
+
+ // Reset state variables (since they are set by the attach listener)
+ resetVariables();
+
+ // Detach the component -> triggers the detach listener
+ customlayout.removeComponent(comp);
+
+ assertEquals("Detach counter should get incremented", 1, detachCounter);
+
+ assertSame("The detached component should be the label", comp,
+ detachedComponent);
+
+ assertSame("The detached target should be the layout", customlayout,
+ detachedTarget);
+
+ assertFalse(
+ "The detached component should not be found in the container",
+ foundInContainer);
+ }
}
diff --git a/server/tests/src/com/vaadin/ui/AbstractSelectTest.java b/server/tests/src/com/vaadin/ui/AbstractSelectTest.java
index 83d66ee9d5..bd399f088c 100644
--- a/server/tests/src/com/vaadin/ui/AbstractSelectTest.java
+++ b/server/tests/src/com/vaadin/ui/AbstractSelectTest.java
@@ -16,10 +16,13 @@
package com.vaadin.ui;
import java.util.ArrayList;
+import java.util.HashSet;
import org.junit.Assert;
import org.junit.Test;
+import com.vaadin.data.util.ObjectProperty;
+
public class AbstractSelectTest {
@Test
@@ -73,4 +76,72 @@ public class AbstractSelectTest {
.toArray());
}
+
+ @Test
+ public void singleSelectInitiallyEmpty() {
+ AbstractSelect s = new ListSelect();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void singleSelectEmptyAfterClearUsingPDS() {
+ AbstractSelect s = new ListSelect();
+ s.addItem("foo");
+ s.addItem("bar");
+ s.setPropertyDataSource(new ObjectProperty<String>("foo"));
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void singleSelectEmptyAfterClear() {
+ AbstractSelect s = new ListSelect();
+ s.addItem("foo");
+ s.addItem("bar");
+ s.setValue("bar");
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void multiSelectInitiallyEmpty() {
+ AbstractSelect s = new ListSelect();
+ s.setMultiSelect(true);
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void multiSelectEmptyAfterClearUsingPDS() {
+ AbstractSelect s = new ListSelect();
+ s.setMultiSelect(true);
+ s.addItem("foo");
+ s.addItem("bar");
+ HashSet<String> sel = new HashSet<String>();
+ sel.add("foo");
+ sel.add("bar");
+ s.setPropertyDataSource(new ObjectProperty<HashSet>(sel));
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
+ @Test
+ public void multiSelectEmptyAfterClear() {
+ AbstractSelect s = new ListSelect();
+ s.setMultiSelect(true);
+ s.addItem("foo");
+ s.addItem("bar");
+ s.select("foo");
+ s.select("bar");
+
+ Assert.assertFalse(s.isEmpty());
+ s.clear();
+ Assert.assertTrue(s.isEmpty());
+ }
+
}
diff --git a/server/tests/src/com/vaadin/ui/RichTextAreaTest.java b/server/tests/src/com/vaadin/ui/RichTextAreaTest.java
new file mode 100644
index 0000000000..ce0dfdc696
--- /dev/null
+++ b/server/tests/src/com/vaadin/ui/RichTextAreaTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.ui;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+
+public class RichTextAreaTest {
+ @Test
+ public void initiallyEmpty() {
+ RichTextArea tf = new RichTextArea();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearUsingPDS() {
+ RichTextArea tf = new RichTextArea(new ObjectProperty<String>("foo"));
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClear() {
+ RichTextArea tf = new RichTextArea();
+ tf.setValue("foobar");
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/ui/TextAreaTest.java b/server/tests/src/com/vaadin/ui/TextAreaTest.java
new file mode 100644
index 0000000000..e7e99c19e9
--- /dev/null
+++ b/server/tests/src/com/vaadin/ui/TextAreaTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.ui;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.ObjectProperty;
+
+public class TextAreaTest {
+ @Test
+ public void initiallyEmpty() {
+ TextArea tf = new TextArea();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClearUsingPDS() {
+ TextArea tf = new TextArea(new ObjectProperty<String>("foo"));
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+ @Test
+ public void emptyAfterClear() {
+ TextArea tf = new TextArea();
+ tf.setValue("foobar");
+ Assert.assertFalse(tf.isEmpty());
+ tf.clear();
+ Assert.assertTrue(tf.isEmpty());
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/ui/UIThemeEscaping.java b/server/tests/src/com/vaadin/ui/UIThemeEscaping.java
new file mode 100644
index 0000000000..236f283823
--- /dev/null
+++ b/server/tests/src/com/vaadin/ui/UIThemeEscaping.java
@@ -0,0 +1,89 @@
+/*
+ * 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.ui;
+
+import com.vaadin.server.VaadinRequest;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class UIThemeEscaping {
+
+ private UI ui;
+
+ private void initUiWithTheme(String theme) {
+ VaadinRequest request = getRequestWithTheme(theme);
+
+ ui.doInit(request, 1234, "foobar");
+ }
+
+ private VaadinRequest getRequestWithTheme(String theme) {
+ VaadinRequest request = mock(VaadinRequest.class);
+
+ when(request.getParameter("theme")).thenReturn(theme);
+
+ return request;
+ }
+
+ @Before
+ public void setup() {
+ ui = new UI() {
+ @Override
+ protected void init(VaadinRequest request) {
+ // Nothing to do
+ }
+ };
+ }
+
+ @Test
+ public void dangerousCharactersAreRemoved() {
+ ui.setTheme("a<Ã¥(_\"$");
+
+ assertThat(ui.getTheme(), is("aå_$"));
+ }
+
+ @Test
+ public void nullThemeIsSet() {
+ ui.setTheme("foobar");
+
+ ui.setTheme(null);
+
+ assertThat(ui.getTheme(), is(nullValue()));
+ }
+
+ @Test
+ public void themeIsSetOnInit() {
+ ui.setTheme("foobar");
+
+ initUiWithTheme("bar");
+
+ assertThat(ui.getTheme(), is("bar"));
+ }
+
+ @Test
+ public void nullThemeIsSetOnInit() {
+ ui.setTheme("foobar");
+
+ initUiWithTheme(null);
+
+ assertThat(ui.getTheme(), is(nullValue()));
+ }
+}
diff --git a/shared/src/com/vaadin/shared/VBrowserDetails.java b/shared/src/com/vaadin/shared/VBrowserDetails.java
index fa21bddc96..6e45d33e16 100644
--- a/shared/src/com/vaadin/shared/VBrowserDetails.java
+++ b/shared/src/com/vaadin/shared/VBrowserDetails.java
@@ -167,14 +167,11 @@ public class VBrowserDetails implements Serializable {
if (userAgent.contains("windows ")) {
os = OperatingSystem.WINDOWS;
isWindowsPhone = userAgent.contains("windows phone");
+ } else if (userAgent.contains("android")) {
+ os = OperatingSystem.ANDROID;
+ parseAndroidVersion(userAgent);
} else if (userAgent.contains("linux")) {
- if (userAgent.contains("android")) {
- os = OperatingSystem.ANDROID;
- parseAndroidVersion(userAgent);
- } else {
- os = OperatingSystem.LINUX;
-
- }
+ os = OperatingSystem.LINUX;
} else if (userAgent.contains("macintosh")
|| userAgent.contains("mac osx")
|| userAgent.contains("mac os x")) {
diff --git a/uitest/ivy.xml b/uitest/ivy.xml
index 14c8bc6ce3..78171f9a9c 100644
--- a/uitest/ivy.xml
+++ b/uitest/ivy.xml
@@ -27,6 +27,8 @@
<dependency org="javax.validation" name="validation-api"
rev="1.0.0.GA" conf="build,ide -> default,sources" />
+ <dependency org="org.hibernate" name="hibernate-validator"
+ rev="4.2.0.Final" conf="build,ide -> default" />
<!-- Google App Engine -->
<dependency org="com.google.appengine" name="appengine-api-1.0-sdk"
rev="1.2.1" conf="build-provided,ide -> default" />
diff --git a/uitest/src/com/vaadin/tests/components/TooltipPosition.java b/uitest/src/com/vaadin/tests/components/TooltipPosition.java
new file mode 100644
index 0000000000..30222722d9
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/TooltipPosition.java
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * This UI is used for testing that a tooltip is not positioned partially
+ * outside the browser window when there is enough space to display it.
+ *
+ * @author Vaadin Ltd
+ */
+public class TooltipPosition extends AbstractTestUI {
+
+ public static final int NUMBER_OF_BUTTONS = 5;
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ // These tooltip delay settings can be removed once #13854 is resolved.
+ getTooltipConfiguration().setOpenDelay(0);
+ getTooltipConfiguration().setQuickOpenDelay(0);
+ getTooltipConfiguration().setCloseTimeout(1000);
+
+ VerticalLayout layout = new VerticalLayout();
+ layout.setSpacing(true);
+ layout.setHeight(UI.getCurrent().getPage().getBrowserWindowHeight(),
+ Unit.PIXELS);
+ addComponent(layout);
+ for (int i = 0; i < NUMBER_OF_BUTTONS; i++) {
+ Button button = new Button("Button");
+ button.setDescription(generateTooltipText());
+ layout.addComponent(button);
+ }
+ }
+
+ private String generateTooltipText() {
+ StringBuilder result = new StringBuilder();
+ for (int i = 0; i < 50; i++) {
+ result.append("This is the line ").append(i)
+ .append(" of the long tooltip text.<br>");
+ }
+ return result.toString();
+ }
+
+ @Override
+ public String getTestDescription() {
+ return "The tooltips of the buttons should not be clipped when there is enough space to display them.";
+ }
+
+ @Override
+ public Integer getTicketNumber() {
+ return 15129;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/TooltipPositionTest.java b/uitest/src/com/vaadin/tests/components/TooltipPositionTest.java
new file mode 100644
index 0000000000..4106374d64
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/TooltipPositionTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Dimension;
+import org.openqa.selenium.Point;
+import org.openqa.selenium.StaleElementReferenceException;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebDriver.Window;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Tests that the tooltip is positioned so that it fits in the displayed area.
+ *
+ * @author Vaadin Ltd
+ */
+public class TooltipPositionTest extends MultiBrowserTest {
+
+ @Test
+ public void testRegression_EmptyTooltipShouldNotBeAppearedDuringInitialization()
+ throws Exception {
+ openTestURL();
+
+ waitForElementVisible(By.cssSelector(".v-tooltip"));
+ WebElement tooltip = driver.findElement(By.cssSelector(".v-tooltip"));
+
+ Assert.assertTrue(
+ "This init tooltip with text ' ' is present in the DOM and should be entirely outside the browser window",
+ isOutsideOfWindow(tooltip));
+ }
+
+ @Test
+ public void testTooltipPosition() throws Exception {
+ openTestURL();
+ for (int i = 0; i < TooltipPosition.NUMBER_OF_BUTTONS; i++) {
+ ButtonElement button = $(ButtonElement.class).get(i);
+ // Move the mouse to display the tooltip.
+ Actions actions = new Actions(driver);
+ actions.moveToElement(button, 10, 10);
+ actions.build().perform();
+ waitUntil(tooltipToBeInsideWindow(By.cssSelector(".v-tooltip"),
+ driver.manage().window()));
+
+ if (i < TooltipPosition.NUMBER_OF_BUTTONS - 1) {
+ // Remove the tooltip by moving the mouse.
+ actions = new Actions(driver);
+ actions.moveByOffset(300, 0);
+ actions.build().perform();
+ waitUntil(tooltipNotToBeShown(By.cssSelector(".v-tooltip"),
+ driver.manage().window()));
+ }
+ }
+ }
+
+ /*
+ * An expectation for checking that the tooltip found by the given locator
+ * is present in the DOM and entirely inside the browser window. The
+ * coordinate of the top left corner of the window is supposed to be (0, 0).
+ */
+ private ExpectedCondition<Boolean> tooltipToBeInsideWindow(
+ final By tooltipLocator, final Window window) {
+ return new ExpectedCondition<Boolean>() {
+
+ @Override
+ public Boolean apply(WebDriver input) {
+ List<WebElement> elements = findElements(tooltipLocator);
+ if (elements.isEmpty()) {
+ return false;
+ }
+ WebElement element = elements.get(0);
+ try {
+ if (!element.isDisplayed()) {
+ return false;
+ }
+ Point topLeft = element.getLocation();
+ int xLeft = topLeft.getX();
+ int yTop = topLeft.getY();
+ if (xLeft < 0 || yTop < 0) {
+ return false;
+ }
+ Dimension elementSize = element.getSize();
+ int xRight = xLeft + elementSize.getWidth() - 1;
+ int yBottom = yTop + elementSize.getHeight() - 1;
+ Dimension browserSize = window.getSize();
+ return xRight < browserSize.getWidth()
+ && yBottom < browserSize.getHeight();
+ } catch (StaleElementReferenceException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "the tooltip to be displayed inside the window";
+ }
+ };
+ };
+
+ /*
+ * An expectation for checking that the tooltip found by the given locator
+ * is not shown in the window, even partially. The top left corner of window
+ * should have coordinates (0, 0).
+ */
+ private ExpectedCondition<Boolean> tooltipNotToBeShown(
+ final By tooltipLocator, final Window window) {
+ return new ExpectedCondition<Boolean>() {
+
+ @Override
+ public Boolean apply(WebDriver input) {
+ List<WebElement> elements = findElements(tooltipLocator);
+ if (elements.isEmpty()) {
+ return true;
+ }
+ WebElement tooltip = elements.get(0);
+ try {
+ return isOutsideOfWindow(tooltip);
+ } catch (StaleElementReferenceException e) {
+ return true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "the tooltip not to be displayed inside the window";
+ }
+
+ };
+ }
+
+ private boolean isOutsideOfWindow(WebElement tooltip) {
+ if (!tooltip.isDisplayed()) {
+ return true;
+ }
+ // The tooltip is shown, at least partially, if
+ // its intervals of both horizontal and vertical coordinates
+ // overlap those of the window.
+ Point topLeft = tooltip.getLocation();
+ Dimension tooltipSize = tooltip.getSize();
+ Dimension windowSize = driver.manage().window().getSize();
+ int xLeft = topLeft.getX();
+ int yTop = topLeft.getY();
+ int xRight = xLeft + tooltipSize.getWidth() - 1;
+ int yBottom = yTop + tooltipSize.getHeight() - 1;
+ boolean overlapHorizontally = !(xRight < 0 || xLeft >= windowSize
+ .getWidth());
+ boolean overlapVertically = !(yBottom < 0 || yTop >= windowSize
+ .getHeight());
+ return !(overlapHorizontally && overlapVertically);
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java b/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java
index f5651e0ada..1047c070c8 100644
--- a/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java
+++ b/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java
@@ -44,6 +44,19 @@ public class AccordionRemoveTabTest extends MultiBrowserTest {
checkFirstItemHeight("On third tab");
}
+ @Test
+ public void testConsoleErrorOnSwitch() {
+ setDebug(true);
+ openTestURL();
+ WebElement firstItem = driver.findElement(By
+ .className("v-accordion-item-first"));
+ WebElement caption = firstItem.findElement(By
+ .className("v-accordion-item-caption"));
+ caption.click();
+ Assert.assertEquals("Errors present in console", 0,
+ findElements(By.className("SEVERE")).size());
+ }
+
private void checkFirstItemHeight(String text) {
WebElement firstItem = driver.findElement(By
.className("v-accordion-item-first"));
diff --git a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java
new file mode 100644
index 0000000000..0ec196f266
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Tests if long event which began before the view period is shown (#15242)
+ */
+public class BeanItemContainerLongEventTest extends MultiBrowserTest {
+
+ @Override
+ protected String getDeploymentPath() {
+ return "/run/BeanItemContainerTestUI?restartApplication";
+ }
+
+ @Test
+ public void testEventDisplayedInWeekView() {
+ openTestURL();
+ WebElement target = driver.findElements(
+ By.className("v-calendar-week-number")).get(1);
+ target.click();
+ target = driver.findElement(By.className("v-calendar-event"));
+ Assert.assertEquals("Wrong event name", "Long event", target.getText());
+ }
+
+ @Test
+ public void testEventDisplayedInDayView() {
+ openTestURL();
+ WebElement target = driver.findElements(
+ By.className("v-calendar-day-number")).get(5);
+ target.click();
+ target = driver.findElement(By.className("v-calendar-event"));
+ Assert.assertEquals("Wrong event name", "Long event", target.getText());
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java
index 83fc4a03cb..bda3b34875 100644
--- a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java
+++ b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerTestUI.java
@@ -17,6 +17,7 @@ package com.vaadin.tests.components.calendar;
import java.util.Arrays;
import java.util.Date;
+import java.util.GregorianCalendar;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
@@ -69,6 +70,13 @@ public class BeanItemContainerTestUI extends UI {
table.setVisibleColumns(new Object[] { "caption", "description",
"start", "end" });
content.addComponent(table);
+
+ BasicEvent longEvent = new BasicEvent();
+ longEvent.setCaption("Long event");
+ longEvent.setAllDay(true);
+ longEvent.setStart(new GregorianCalendar(2000, 1, 3).getTime());
+ longEvent.setEnd(new GregorianCalendar(2000, 2, 5).getTime());
+ events.addBean(longEvent);
}
/**
diff --git a/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocale.java b/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocale.java
new file mode 100644
index 0000000000..ff7faf1965
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocale.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.combobox;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+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.ComboBox;
+import com.vaadin.ui.NativeSelect;
+
+public class FilteringTurkishLocale extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+
+ final ComboBox comboBox = new ComboBox("Box", Arrays.asList(
+ "I without dot", "Ä° with dot"));
+ comboBox.setNullSelectionAllowed(false);
+
+ NativeSelect localeSelect = new NativeSelect("Locale", Arrays.asList(
+ Locale.ENGLISH, new Locale("tr")));
+ localeSelect.addValueChangeListener(new ValueChangeListener() {
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ comboBox.setLocale((Locale) event.getProperty().getValue());
+ }
+ });
+ localeSelect.setValue(Locale.ENGLISH);
+
+ addComponents(localeSelect, comboBox);
+ }
+
+ @Override
+ public String getDescription() {
+ return "When the Turkish locale is used,"
+ + " filtering for 'i' should show the option with a dot"
+ + " while filtering for 'ı' should show the option witout a dot";
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocaleTest.java b/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocaleTest.java
new file mode 100644
index 0000000000..d7f8e233ec
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/combobox/FilteringTurkishLocaleTest.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 java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ComboBoxElement;
+import com.vaadin.testbench.elements.NativeSelectElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class FilteringTurkishLocaleTest extends MultiBrowserTest {
+
+ @Test
+ public void testEnglishLocale() {
+ openTestURL();
+
+ setLocale("en");
+
+ List<String> suggestions = getFilterSuggestions("i");
+
+ Assert.assertEquals("Both suggestions should be present", 2,
+ suggestions.size());
+ }
+
+ @Test
+ public void testTurkishLocaleWithDot() {
+ openTestURL();
+
+ setLocale("tr");
+
+ List<String> suggestions = getFilterSuggestions("i");
+
+ Assert.assertEquals("There should be only one suggestion", 1,
+ suggestions.size());
+ Assert.assertEquals("Ä° with dot", suggestions.get(0));
+ }
+
+ @Test
+ public void testTurkishLocaleWithoutDot() {
+ openTestURL();
+
+ setLocale("tr");
+
+ List<String> suggestions = getFilterSuggestions("ı");
+
+ Assert.assertEquals("There should be only one suggestion", 1,
+ suggestions.size());
+ Assert.assertEquals("I without dot", suggestions.get(0));
+ }
+
+ private List<String> getFilterSuggestions(String string) {
+ ComboBoxElement comboBox = $(ComboBoxElement.class).first();
+ comboBox.findElement(By.vaadin("#textbox")).sendKeys(string);
+
+ return comboBox.getPopupSuggestions();
+ }
+
+ private void setLocale(String locale) {
+ NativeSelectElement selector = $(NativeSelectElement.class).first();
+ selector.selectByText(locale);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplate.java b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplate.java
new file mode 100644
index 0000000000..54949a053d
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplate.java
@@ -0,0 +1,44 @@
+/*
+ * 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.customlayout;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CustomLayout;
+import com.vaadin.ui.Label;
+
+public class CustomLayoutWithoutTemplate extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ CustomLayout cl = new CustomLayout("missing-layout-file.html");
+ cl.addComponent(new Label("This Label should be visible."), "foo");
+ cl.addComponent(new Button("And this Button too."), "bar");
+
+ addComponent(cl);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Verify that CustomLayout renders child components even if the template is missing.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 8696;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplateTest.java b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplateTest.java
new file mode 100644
index 0000000000..695d9cceff
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithoutTemplateTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.customlayout;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.vaadin.testbench.ElementQuery;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.CustomLayoutElement;
+import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class CustomLayoutWithoutTemplateTest extends SingleBrowserTest {
+
+ @Test
+ public void testChildComponents() {
+ openTestURL();
+
+ ElementQuery<CustomLayoutElement> customLayout = $(CustomLayoutElement.class);
+
+ // Verify the Button and Label are rendered inside the CustomLayout.
+ assertTrue("Button was not rendered.",
+ customLayout.$(ButtonElement.class).exists());
+ assertTrue("Label was not rendered.", customLayout
+ .$(LabelElement.class).exists());
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java
new file mode 100644
index 0000000000..60508a30d4
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosing.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.datefield;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.DateField;
+
+public class DateFieldPopupClosing extends AbstractTestUI {
+
+ static final String DATEFIELD_ID = "datefield";
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final DateField df = new DateField();
+ df.setId(DATEFIELD_ID);
+ addComponent(df);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "DateField popup should be closed when click on popup button";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14857;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java
new file mode 100644
index 0000000000..9fd6fe82e2
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupClosingTest.java
@@ -0,0 +1,81 @@
+package com.vaadin.tests.components.datefield;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+
+import com.vaadin.testbench.elements.DateFieldElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class DateFieldPopupClosingTest extends MultiBrowserTest {
+
+ @Test
+ public void testDateFieldPopupClosingLongClick()
+ throws InterruptedException, IOException {
+ openTestURL();
+
+ fastClickDateDatePickerButton();
+
+ assertThatPopupIsVisible();
+
+ longClickDateDatePickerButton();
+
+ assertThatPopupIsInvisible();
+ }
+
+ private void assertThatPopupIsVisible() {
+ waitUntil(ExpectedConditions.visibilityOfElementLocated(By
+ .className("v-datefield-popup")));
+ }
+
+ private void assertThatPopupIsInvisible() {
+ // ExpectedConditions.invisibilityOfElementLocated doesn't work
+ // with PhantomJS when running with a hub:
+ // https://code.google.com/p/selenium/issues/detail?id=5000
+ // so we need to make our own.
+
+ waitUntil(new ExpectedCondition<Boolean>() {
+ @Override
+ public Boolean apply(WebDriver input) {
+ try {
+ return !(findElement(By.className("v-datefield-popup"))
+ .isDisplayed());
+ } catch (Exception e) {
+ return true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ // Timed out after 10 seconds waiting for ...
+ return "popup to not be visible";
+ }
+ });
+ }
+
+ private void longClickDateDatePickerButton() {
+ WebElement button = getToggleButton();
+
+ new Actions(getDriver()).clickAndHold(button).perform();
+ assertThatPopupIsInvisible();
+
+ new Actions(getDriver()).release(button).perform();
+ }
+
+ private WebElement getToggleButton() {
+ DateFieldElement dateField = $(DateFieldElement.class).first();
+
+ return dateField.findElement(By.tagName("button"));
+ }
+
+ private void fastClickDateDatePickerButton() {
+ getToggleButton().click();
+ }
+
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPosition.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPosition.java
new file mode 100644
index 0000000000..4469ad3b1a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPosition.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.datefield;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.PopupDateField;
+
+/**
+ * Test UI for date field Popup calendar.
+ *
+ * @author Vaadin Ltd
+ */
+public abstract class DateFieldPopupPosition extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ HorizontalLayout layout = new HorizontalLayout();
+ addComponent(layout);
+ Label gap = new Label();
+ gap.setWidth(250, Unit.PIXELS);
+ layout.addComponent(gap);
+ PopupDateField field = new PopupDateField();
+ layout.addComponent(field);
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14757;
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Calendar popup should not placed on the top of text field when "
+ + "there is no space on bottom.";
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPositionTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPositionTest.java
new file mode 100644
index 0000000000..f896519aae
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldPopupPositionTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.datefield;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Dimension;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.DateFieldElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Test for date field popup calendar position.
+ *
+ * @author Vaadin Ltd
+ */
+public abstract class DateFieldPopupPositionTest extends MultiBrowserTest {
+
+ @Test
+ public void testPopupPosition() {
+ openTestURL();
+
+ int height = getFieldBottom() + 150;
+ adjustBrowserWindow(height);
+
+ openPopup();
+
+ checkPopupPosition();
+ }
+
+ protected abstract void checkPopupPosition();
+
+ protected WebElement getPopup() {
+ return findElement(By.className("v-datefield-popup"));
+ }
+
+ private void adjustBrowserWindow(int height) {
+ Dimension size = getDriver().manage().window().getSize();
+ getDriver().manage().window()
+ .setSize(new Dimension(size.getWidth(), height));
+ }
+
+ private int getFieldBottom() {
+ DateFieldElement dateField = $(DateFieldElement.class).first();
+ return dateField.getLocation().getY() + dateField.getSize().getHeight();
+ }
+
+ private void openPopup() {
+ findElement(By.className("v-datefield-button")).click();
+ if (!isElementPresent(By.className("v-datefield-popup"))) {
+ findElement(By.className("v-datefield-button")).click();
+ }
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java
new file mode 100644
index 0000000000..d3bc4267ec
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDate.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.datefield;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.DateField;
+import com.vaadin.ui.InlineDateField;
+
+import java.util.Locale;
+
+public class DateRangeWithSqlDate extends AbstractTestUI {
+
+ // 2014-12-01
+ private static final java.sql.Date startDate = new java.sql.Date(
+ 1417467822699L);
+
+ // 2014-12-02
+ private static final java.sql.Date endDate = new java.sql.Date(
+ 1417554763317L);
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ DateField df = new InlineDateField();
+ df.setLocale(Locale.US);
+ df.setRangeStart(startDate);
+ df.setRangeEnd(endDate);
+
+ df.setValue(startDate);
+
+ addComponent(df);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Test that java.sql.Date can be given to specify date range start and end dates.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 15342;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java
new file mode 100644
index 0000000000..2352011585
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DateRangeWithSqlDateTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.datefield;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class DateRangeWithSqlDateTest extends MultiBrowserTest {
+
+ @Test
+ public void testDateRange() {
+ openTestURL();
+
+ // Get all cells of the inline datefield.
+ List<WebElement> cells = driver.findElements(By
+ .className("v-inline-datefield-calendarpanel-day"));
+
+ // Verify the range is rendered correctly.
+ assertCell(cells.get(0), "30", true);
+ assertCell(cells.get(1), "1", false);
+ assertCell(cells.get(2), "2", false);
+ assertCell(cells.get(3), "3", true);
+ }
+
+ private void assertCell(WebElement cell, String text, boolean outsideRange) {
+ assertEquals(text, cell.getText());
+ assertEquals(outsideRange,
+ cell.getAttribute("class").contains("outside-range"));
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPosition.java b/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPosition.java
new file mode 100644
index 0000000000..8e4de77837
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPosition.java
@@ -0,0 +1,27 @@
+/*
+ * 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.datefield;
+
+/**
+ * Test UI for date field Popup calendar in default theme.
+ *
+ * All UI initialization is defined in super class.
+ *
+ * @author Vaadin Ltd
+ */
+public class DefaultDateFieldPopupPosition extends DateFieldPopupPosition {
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPositionTest.java b/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPositionTest.java
new file mode 100644
index 0000000000..61cc876a3f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/DefaultDateFieldPopupPositionTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.datefield;
+
+import org.junit.Assert;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.DateFieldElement;
+
+/**
+ * Test for date field popup calendar position in default theme.
+ *
+ * Test method is defined in super class.
+ *
+ * @author Vaadin Ltd
+ */
+public class DefaultDateFieldPopupPositionTest extends
+ DateFieldPopupPositionTest {
+
+ @Override
+ protected void checkPopupPosition() {
+ DateFieldElement field = $(DateFieldElement.class).first();
+ int right = field.getLocation().getX() + field.getSize().getWidth();
+ WebElement popup = getPopup();
+
+ Assert.assertTrue("Calendar popup has wrong X coordinate="
+ + popup.getLocation().getX() + " , right side of the field is "
+ + right, popup.getLocation().getX() >= right);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPosition.java b/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPosition.java
new file mode 100644
index 0000000000..59ff6aa9e8
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPosition.java
@@ -0,0 +1,30 @@
+/*
+ * 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.datefield;
+
+import com.vaadin.annotations.Theme;
+
+/**
+ * Test UI for date field Popup calendar in Valo theme.
+ *
+ * All UI initialization is defined in super class.
+ *
+ * @author Vaadin Ltd
+ */
+@Theme("valo")
+public class ValoDateFieldPopupPosition extends DateFieldPopupPosition {
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPositionTest.java b/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPositionTest.java
new file mode 100644
index 0000000000..4009b9d991
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/datefield/ValoDateFieldPopupPositionTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.datefield;
+
+import org.junit.Assert;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.DateFieldElement;
+
+/**
+ * Test for date field popup calendar position in Valo theme.
+ *
+ * Test method is defined in super class.
+ *
+ * @author Vaadin Ltd
+ */
+public class ValoDateFieldPopupPositionTest extends DateFieldPopupPositionTest {
+
+ @Override
+ protected void checkPopupPosition() {
+ DateFieldElement field = $(DateFieldElement.class).first();
+ WebElement popup = getPopup();
+ int left = field.getLocation().getX();
+ int popupRight = popup.getLocation().getX()
+ + popup.getSize().getWidth();
+
+ Assert.assertTrue("Calendar popup has wrong X coordinate=" + popupRight
+ + " , left side of the field is " + left, popupRight <= left);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidth.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidth.java
new file mode 100644
index 0000000000..90ec704a8c
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidth.java
@@ -0,0 +1,58 @@
+/*
+ * 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.draganddropwrapper;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.DragAndDropWrapper;
+import com.vaadin.ui.DragAndDropWrapper.DragStartMode;
+import com.vaadin.ui.Label;
+
+/**
+ * Test UI for DnD image element size
+ *
+ * @author Vaadin Ltd
+ */
+public class DragAndDropRelativeWidth extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ CssLayout layout = new CssLayout();
+ layout.setWidth(300, Unit.PIXELS);
+
+ Label label = new Label("drag source");
+ label.addStyleName("drag-source");
+ label.setWidth(100, Unit.PERCENTAGE);
+ DragAndDropWrapper wrapper = new DragAndDropWrapper(label);
+ wrapper.setWidth(100, Unit.PERCENTAGE);
+ wrapper.setDragStartMode(DragStartMode.COMPONENT);
+
+ layout.addComponent(wrapper);
+ addComponent(layout);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Set explicit size for drag image element using calclulated size from the source";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14617;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidthTest.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidthTest.java
new file mode 100644
index 0000000000..9cb7a63046
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropRelativeWidthTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.draganddropwrapper;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Dimension;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Test to check size of drag image element.
+ *
+ * @author Vaadin Ltd
+ */
+public class DragAndDropRelativeWidthTest extends MultiBrowserTest {
+
+ @Test
+ public void testDragImageElementSize() {
+ openTestURL();
+
+ WebElement label = getDriver().findElement(By.className("drag-source"));
+ Dimension size = label.getSize();
+ int height = size.getHeight();
+ int width = size.getWidth();
+ Actions actions = new Actions(getDriver());
+ actions.moveToElement(label);
+ actions.clickAndHold();
+ actions.moveByOffset(100, 100);
+ actions.build().perform();
+
+ WebElement dragImage = getDriver().findElement(
+ By.className("v-drag-element"));
+
+ Assert.assertEquals("Drag image element height is unexpected", height,
+ dragImage.getSize().getHeight());
+ Assert.assertEquals("Drag image element width is unexpected", width,
+ dragImage.getSize().getWidth());
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java
index ba27ee293e..4e60b43ea2 100644
--- a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java
+++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java
@@ -40,7 +40,7 @@ public class DragStartModesTest extends MultiBrowserTest {
new Actions(driver).moveToElement(draggable, 10, 10).clickAndHold()
.moveByOffset(5, 0).perform();
new Actions(driver).moveToElement(dropTarget, 12, 10).perform();
- compareScreen("dragMode" + dragMode);
+ compareScreen("dragImageMode" + dragMode);
new Actions(driver).release().perform();
}
diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValo.java b/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValo.java
new file mode 100644
index 0000000000..88d89abbf4
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValo.java
@@ -0,0 +1,60 @@
+package com.vaadin.tests.components.menubar;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.MenuBar;
+import com.vaadin.ui.MenuBar.MenuItem;
+
+@Theme("valo")
+public class MenuBarSubmenusClosingValo extends AbstractTestUI {
+
+ private MenuItem edit;
+ private MenuItem file;
+ private MenuItem help;
+
+ @Override
+ protected String getTestDescription() {
+ return "Tests that when moving mouse fast over menu items "
+ + "previous submenu popup closes before new submenu popup opens";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 15255;
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ // here we increase animation time to 1 second for to do auto testing
+ // possible
+ getPage().getStyles().add(
+ ".valo .v-menubar-popup[class*=\"animate-in\"] {"
+ + "-webkit-animation: valo-overlay-animate-in 1000ms; "
+ + "-moz-animation: valo-overlay-animate-in 1000ms; "
+ + "animation: valo-overlay-animate-in 1000ms;};");
+
+ getPage().getStyles().add(
+ ".valo .v-menubar-popup[class*=\"animate-out\"] {"
+ + "-webkit-animation: valo-animate-out-fade 1000ms; "
+ + "-moz-animation: valo-animate-out-fade 1000ms; "
+ + "animation: valo-animate-out-fade 1000ms;};");
+
+ MenuBar mb = new MenuBar();
+ file = mb.addItem("File", null);
+ file.addItem("File1", null);
+ file.addItem("File2", null);
+ file.addItem("File3", null);
+ edit = mb.addItem("Edit", null);
+ edit.addItem("Edit1", null);
+ edit.addItem("Edit2", null);
+ edit.addItem("Edit3", null);
+ help = mb.addItem("Help", null);
+ help.addItem("Help1", null);
+ help.addItem("Help2", null);
+ MenuItem helpMenuItem = help.addItem("Help3", null);
+ helpMenuItem.addItem("SubHelp3", null);
+
+ addComponent(mb);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValoTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValoTest.java
new file mode 100644
index 0000000000..b7ed88c9ca
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/menubar/MenuBarSubmenusClosingValoTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.menubar;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.HasInputDevices;
+import org.openqa.selenium.interactions.Mouse;
+import org.openqa.selenium.internal.Locatable;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.MenuBarElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class MenuBarSubmenusClosingValoTest extends MultiBrowserTest {
+
+ @Test
+ public void testEnableParentLayoutControlByKeyboard() {
+ openTestURL();
+
+ MenuBarElement menu = $(MenuBarElement.class).get(0);
+ menu.focus();
+ menu.sendKeys(Keys.SPACE);
+ menu.sendKeys(Keys.DOWN);
+
+ waitForElementPresent(By.className("v-menubar-popup"));
+
+ menu.sendKeys(Keys.ARROW_RIGHT);
+ menu.sendKeys(Keys.ARROW_RIGHT);
+
+ int count = driver.findElements(By.className("v-menubar-popup")).size();
+ Assert.assertTrue("The count of open popups should be one", count == 1);
+ }
+
+ @Test
+ public void testEnableParentLayoutControlByMouse() {
+ openTestURL();
+
+ Mouse mouse = ((HasInputDevices) getDriver()).getMouse();
+
+ List<WebElement> menuItemList = driver.findElements(By
+ .className("v-menubar-menuitem"));
+
+ mouse.click(((Locatable) menuItemList.get(0)).getCoordinates());
+ waitForElementPresent(By.className("v-menubar-popup"));
+
+ mouse.mouseMove(((Locatable) menuItemList.get(1)).getCoordinates());
+ mouse.mouseMove(((Locatable) menuItemList.get(2)).getCoordinates());
+
+ waitForElementPresent(By.className("v-menubar-popup"));
+
+ int count = driver.findElements(By.className("v-menubar-popup")).size();
+ Assert.assertTrue("The count of open popups should be one", count == 1);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java
index 24025b9f39..091f7be954 100644
--- a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java
+++ b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java
@@ -49,6 +49,7 @@ public class MenuTooltipTest extends MultiBrowserTest {
Coordinates elementCoordinates = getCoordinates($(MenuBarElement.class)
.first());
+ sleep(1000);
Mouse mouse = ((HasInputDevices) getDriver()).getMouse();
diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java
index 6b517e9887..252efe2824 100644
--- a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java
+++ b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java
@@ -19,6 +19,7 @@ import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.WebElement;
+import com.vaadin.data.util.converter.StringToEnumConverter;
import com.vaadin.shared.ui.ui.NotificationRole;
import com.vaadin.testbench.By;
import com.vaadin.testbench.elements.ButtonElement;
@@ -57,7 +58,8 @@ public class NotificationsWaiAriaTest extends MultiBrowserTest {
postfix.clear();
postfix.sendKeys("- press ESC to close");
- type.selectByText(NotificationRole.ALERT.toString());
+ type.selectByText(StringToEnumConverter.enumToString(
+ NotificationRole.ALERT, null));
show.click();
waitForElementPresent(By.className("v-Notification"));
@@ -83,7 +85,8 @@ public class NotificationsWaiAriaTest extends MultiBrowserTest {
} catch (Exception e) {
}
- type.selectByText("STATUS");
+ type.selectByText(StringToEnumConverter.enumToString(
+ NotificationRole.STATUS, null));
show.click();
waitForElementPresent(By.className("v-Notification"));
diff --git a/uitest/src/com/vaadin/tests/components/select/EnumSelect.java b/uitest/src/com/vaadin/tests/components/select/EnumSelect.java
new file mode 100644
index 0000000000..5976952f8c
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/select/EnumSelect.java
@@ -0,0 +1,69 @@
+/*
+ * 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.select;
+
+import java.util.Locale;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.combobox.FilteringMode;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.NativeSelect;
+import com.vaadin.ui.Tree;
+
+public class EnumSelect extends AbstractTestUIWithLog {
+
+ public enum Constant {
+ SOME_VALUE, SOME_OTHER_VALUE, FOO, BAR;
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+
+ setLocale(new Locale("fi", "FI"));
+ ComboBox cb = new ComboBox();
+ cb.setFilteringMode(FilteringMode.CONTAINS);
+ for (Constant c : Constant.values()) {
+ cb.addItem(c);
+ }
+ addComponent(cb);
+
+ NativeSelect ns = new NativeSelect();
+ for (Constant c : Constant.values()) {
+ ns.addItem(c);
+ }
+ addComponent(ns);
+
+ Tree t = new Tree();
+ t.addItem(Constant.SOME_OTHER_VALUE);
+ t.addItem(2500.12);
+ t.setParent(2500.12, Constant.SOME_OTHER_VALUE);
+
+ addComponent(t);
+
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Test formatting captions with enum converters in selection components";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 11433;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/select/EnumSelectTest.java b/uitest/src/com/vaadin/tests/components/select/EnumSelectTest.java
new file mode 100644
index 0000000000..c0429baa31
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/select/EnumSelectTest.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.select;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elements.ComboBoxElement;
+import com.vaadin.testbench.elements.NativeSelectElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class EnumSelectTest extends SingleBrowserTest {
+
+ @Test
+ public void enumInNativeSelect() {
+ openTestURL();
+ NativeSelectElement ns = $(NativeSelectElement.class).first();
+ List<TestBenchElement> options = ns.getOptions();
+ Assert.assertEquals("Some value", options.get(1).getText());
+ Assert.assertEquals("Some other value", options.get(2).getText());
+ }
+
+ @Test
+ public void enumInComboBox() {
+ openTestURL();
+ ComboBoxElement cb = $(ComboBoxElement.class).first();
+ cb.openPopup();
+ List<String> options = cb.getPopupSuggestions();
+ Assert.assertEquals("Some value", options.get(1));
+ Assert.assertEquals("Some other value", options.get(2));
+ }
+
+ @Test
+ public void enumInComboBoxFiltering() {
+ openTestURL();
+ ComboBoxElement cb = $(ComboBoxElement.class).first();
+ cb.findElement(By.vaadin("#textbox")).sendKeys(" other ");
+ List<String> options = cb.getPopupSuggestions();
+ Assert.assertEquals("Only one item should match filter", 1,
+ options.size());
+ Assert.assertEquals("Invalid option matched filter",
+ "Some other value", options.get(0));
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeight.java b/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeight.java
new file mode 100644
index 0000000000..4da5430cb1
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeight.java
@@ -0,0 +1,87 @@
+/*
+ * 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.splitpanel;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.MarginInfo;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.HorizontalSplitPanel;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalSplitPanel;
+
+/**
+ * Test UI for horizontal split panel height.
+ *
+ * @author Vaadin Ltd
+ */
+public class HorizontalSplitPanelHeight extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ getLayout().setMargin(new MarginInfo(true, false, false, false));
+
+ HorizontalSplitPanel panel = new HorizontalSplitPanel();
+ panel.setCaption("Horizontal 1 - no first component, label as second component");
+ panel.setId("Horizontal 1");
+ Label label = new Label("Label");
+ label.addStyleName("target");
+ panel.setSecondComponent(label);
+
+ addComponent(panel);
+
+ panel = new HorizontalSplitPanel();
+ panel.setCaption("Horizontal 2 - button as first component, label as second component");
+ panel.setId("Horizontal 2");
+ label = new Label("Label");
+ label.addStyleName("target");
+ panel.setSecondComponent(label);
+ panel.setFirstComponent(new Button("button"));
+
+ addComponent(panel);
+
+ panel = new HorizontalSplitPanel();
+ panel.setCaption("Horizontal 3 - fixed height, no first component, label as second component");
+ panel.setId("Horizontal 3");
+ label = new Label("Label");
+ label.addStyleName("target");
+ panel.setSecondComponent(label);
+ panel.setHeight(30, Unit.PIXELS);
+
+ addComponent(panel);
+
+ VerticalSplitPanel vPanel = new VerticalSplitPanel();
+ vPanel.setCaption("Vertical 1 - no first component, label as second component");
+ vPanel.setId("Vertical 1");
+ vPanel.setHeight(100, Unit.PIXELS);
+ Label vLabel = new Label("Label");
+ vLabel.addStyleName("target");
+ vPanel.setSecondComponent(vLabel);
+
+ addComponent(vPanel);
+
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 15149;
+ }
+
+ @Override
+ public String getTestDescription() {
+ return "Height of split panel should be greater than height of second component.";
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeightTest.java b/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeightTest.java
new file mode 100644
index 0000000000..0ceca66dd3
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/splitpanel/HorizontalSplitPanelHeightTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.splitpanel;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Test for horizontal split panel height in case when only second component is
+ * set.
+ *
+ * @author Vaadin Ltd
+ */
+public class HorizontalSplitPanelHeightTest extends MultiBrowserTest {
+
+ @Override
+ public void setup() throws Exception {
+ super.setup();
+
+ openTestURL();
+ }
+
+ @Test
+ public void testHorizontalWithoutFirstComponent() {
+ testSplitPanel("Horizontal 1");
+ }
+
+ @Test
+ public void testHorizontalWithFirstComponent() {
+ testSplitPanel("Horizontal 2");
+ }
+
+ @Test
+ public void testHorizontalWithFixedHeight() {
+ testSplitPanel("Horizontal 3");
+ }
+
+ @Test
+ public void testVerticalWithoutFirstComponent() {
+ testSplitPanel("Vertical 1");
+ }
+
+ private void testSplitPanel(String id) {
+ WebElement splitPanel = findElement(By.id(id));
+ WebElement label = splitPanel.findElement(By.className("target"));
+ Assert.assertTrue(id + ": split panel height ("
+ + splitPanel.getSize().getHeight() + ") is less than "
+ + "height of second component (" + label.getSize().getHeight()
+ + ")", splitPanel.getSize().getHeight() >= label.getSize()
+ .getHeight());
+ Assert.assertEquals("Label text in the second panel is not visible",
+ "Label", label.getText());
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/DelayedColumnLayouting.java b/uitest/src/com/vaadin/tests/components/table/DelayedColumnLayouting.java
new file mode 100644
index 0000000000..c327ddb6f3
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/DelayedColumnLayouting.java
@@ -0,0 +1,72 @@
+/*
+ * 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 com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * For tables that are contained in a layout, a delayed column layouting should
+ * not be visible (because it makes the column jump around).
+ *
+ * #15189
+ *
+ * @author Vaadin Ltd
+ */
+public class DelayedColumnLayouting extends UI {
+
+ @Override
+ protected void init(VaadinRequest request) {
+ VerticalLayout verticalLayout = new VerticalLayout();
+ verticalLayout.setSizeFull();
+ final VerticalLayout layout = new VerticalLayout();
+ layout.setSizeFull();
+ layout.setSpacing(true);
+
+ Button reset = new Button("Recreate layout with contained table");
+ verticalLayout.addComponent(reset);
+ reset.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ fillLayout(layout);
+ }
+ });
+
+ fillLayout(layout);
+
+ verticalLayout.addComponent(layout);
+ verticalLayout.setExpandRatio(layout, 1f);
+
+ setContent(verticalLayout);
+ }
+
+ private void fillLayout(VerticalLayout layout) {
+ layout.removeAllComponents();
+
+ Table table = new Table();
+ table.setSizeFull();
+ table.addContainerProperty("First", String.class, "");
+ table.addContainerProperty("This column jumps", String.class, "");
+
+ layout.addComponent(table);
+ layout.setExpandRatio(table, 1f);
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndex.html b/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndex.html
deleted file mode 100644
index 904f3b0470..0000000000
--- a/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndex.html
+++ /dev/null
@@ -1,43 +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:8888/" />
-<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.table.SetCurrentPageFirstItemIndex?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentstableSetCurrentPageFirstItemIndex::/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentstableSetCurrentPageFirstItemIndex::/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>pause</td>
- <td>500</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentstableSetCurrentPageFirstItemIndex::/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td>
- <td>6</td>
-</tr>
-
-</tbody></table>
-</body>
-</html> \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndexTest.java b/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndexTest.java
new file mode 100644
index 0000000000..8102f82834
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/SetCurrentPageFirstItemIndexTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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 org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import junit.framework.Assert;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openqa.selenium.NoSuchElementException;
+
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.TableElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+@Ignore
+// Enable after #15286 is fixed.
+public class SetCurrentPageFirstItemIndexTest extends MultiBrowserTest {
+
+ @Test
+ public void currentPageIndexChangesTwice() {
+ openTestURL();
+
+ ButtonElement button = $(ButtonElement.class).first();
+ button.click(); // change to 20
+ button.click(); // change to 5
+
+ // When failing, the index stays on 20.
+ assertThatRowIsVisible(5);
+ }
+
+ private void assertThatRowIsVisible(int index) {
+ try {
+ TableElement table = $(TableElement.class).first();
+ TestBenchElement cell = table.getCell(index, 0);
+
+ assertThat(cell.getText(), is(Integer.toString(index + 1)));
+ } catch (NoSuchElementException e) {
+ Assert.fail(String.format("Can't locate row for index: %s", index));
+ }
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheet.java b/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheet.java
new file mode 100644
index 0000000000..c21c702bd0
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheet.java
@@ -0,0 +1,44 @@
+package com.vaadin.tests.components.tabsheet;
+
+import com.vaadin.annotations.VaadinServletConfiguration;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinServlet;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.*;
+
+import javax.servlet.annotation.WebServlet;
+
+@SuppressWarnings("serial")
+public class FirstTabNotVisibleInTabsheet extends AbstractTestUI {
+
+ private TabSheet.Tab firstTab;
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ TabSheet tabSheet = new TabSheet();
+ tabSheet.setWidth("600px");
+
+ firstTab = tabSheet.addTab(new Label("first visible tab"), "first visible tab");
+
+ for (int i = 2; i < 10; i++) {
+ tabSheet.addTab(new Label("visible tab " + i), "visible tab " + i);
+ }
+
+ addComponent(new VerticalLayout(tabSheet, new Button("Toggle first tab", new Button.ClickListener() {
+ @Override
+ public void buttonClick(Button.ClickEvent event) {
+ firstTab.setVisible(!firstTab.isVisible());
+ }
+ })));
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14644;
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "First tabsheet tab is not set visible back once it gets invisible";
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheetTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheetTest.java
new file mode 100644
index 0000000000..e57651ba03
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/tabsheet/FirstTabNotVisibleInTabsheetTest.java
@@ -0,0 +1,27 @@
+package com.vaadin.tests.components.tabsheet;
+
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.TabSheetElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import junit.framework.Assert;
+import org.junit.Test;
+
+public class FirstTabNotVisibleInTabsheetTest extends MultiBrowserTest {
+ @Test
+ public void testFirstTabIsVisibleAfterBeingInvisible() {
+ openTestURL();
+
+ toggleFirstTabVisibility();
+ toggleFirstTabVisibility();
+
+ TabSheetElement tabSheet = $(TabSheetElement.class).first();
+
+ Assert.assertTrue("TabSheet should have first tab visible",
+ tabSheet.getTabCaptions().contains("first visible tab"));
+ }
+
+ private void toggleFirstTabVisibility() {
+ $(ButtonElement.class).caption("Toggle first tab").first().click();
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFields.java b/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFields.java
new file mode 100644
index 0000000000..3eda11d999
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFields.java
@@ -0,0 +1,106 @@
+/*
+ * 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.textfield;
+
+import com.vaadin.event.FieldEvents.TextChangeEvent;
+import com.vaadin.event.FieldEvents.TextChangeListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * When two TextFields repeatedly disable each other, ensure that also their
+ * input prompts are removed
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class AlternatingTextFields extends AbstractTestUI {
+
+ public static final String FIRST_TEXTFIELD_INPUT_PROMPT = "Enter first data here";
+ public static final String SECOND_TEXTFIELD_INPUT_PROMPT = "Enter second data here";
+
+ @Override
+ protected void setup(final VaadinRequest request) {
+
+ VerticalLayout layout = new VerticalLayout();
+ layout.setMargin(true);
+ layout.setSpacing(true);
+
+ final TextField firstTextField = createTextField("First",
+ FIRST_TEXTFIELD_INPUT_PROMPT);
+
+ final TextField secondTextField = createTextField("Second",
+ SECOND_TEXTFIELD_INPUT_PROMPT);
+
+ addTextChangeListener(firstTextField, secondTextField);
+ addTextChangeListener(secondTextField, firstTextField);
+
+ layout.addComponent(firstTextField);
+ layout.addComponent(secondTextField);
+
+ addComponent(layout);
+ }
+
+ private static TextField createTextField(String number, String inputPrompt) {
+
+ String caption = " TextField with TextChangeListener";
+
+ TextField textField = new TextField(number + caption);
+ textField.setImmediate(true);
+ textField.setInputPrompt(inputPrompt);
+
+ return textField;
+ }
+
+ private void addTextChangeListener(TextField currentTextField,
+ final TextField otherTextField) {
+
+ final String otherDefaultPrompt = otherTextField.getInputPrompt();
+ currentTextField.addTextChangeListener(new TextChangeListener() {
+
+ @Override
+ public void textChange(TextChangeEvent event) {
+
+ String currentText = event.getText();
+
+ if (currentText.isEmpty() || currentText == null) {
+ // change other to default
+
+ otherTextField.setInputPrompt(otherDefaultPrompt);
+ otherTextField.setEnabled(true);
+ } else {
+ // change other to empty
+
+ otherTextField.setInputPrompt(null);
+ otherTextField.setEnabled(false);
+ }
+
+ }
+ });
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "When two TextFields repeatedly disable each other, ensure that also their input prompts are removed";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 15144;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFieldsTest.java b/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFieldsTest.java
new file mode 100644
index 0000000000..a7ee3fede2
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/textfield/AlternatingTextFieldsTest.java
@@ -0,0 +1,212 @@
+/*
+ * 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.textfield;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class AlternatingTextFieldsTest extends MultiBrowserTest {
+
+ private String RANDOM_INPUT = "Some input here";
+
+ private List<TextFieldElement> textfields;
+
+ @Test
+ public void testInputPrompt() {
+ openTestURL();
+
+ /*
+ * Starting positions
+ */
+
+ createTextFields();
+
+ // test that both input prompts exist in the beginning
+ ensureTextFieldHasInputPrompt(0);
+ ensureTextFieldHasInputPrompt(1);
+
+ /*
+ * Write on and empty the first TextField
+ */
+
+ // select first input prompt
+ ensureSelectionClearsPrompt(0);
+
+ // write on the first TextField
+ ensureWritingDisablesOther(0);
+
+ // empty the text on the first TextField
+ ensureEmptyingAddsPromptAndEnablesOther(0);
+
+ /*
+ * Write on and empty the second TextField
+ */
+
+ // now select the second input prompt
+ ensureSelectionClearsPrompt(1);
+
+ // write on the second TextField
+ ensureWritingDisablesOther(1);
+
+ // empty the text on the second TextField
+ ensureEmptyingAddsPromptAndEnablesOther(1);
+
+ }
+
+ private void ensureEmptyingAddsPromptAndEnablesOther(int index) {
+ // remove the text from the TextField
+ emptyTextField(index);
+
+ // ensure that the TextField really is empty
+ ensureTextFieldEmpty(index);
+
+ // ensure that the other TextField has again been enabled and has an
+ // input prompt
+ if (index == 0) {
+ ensureTextFieldIsEnabledAndHasInputPrompt(1);
+ } else {
+ ensureTextFieldIsEnabledAndHasInputPrompt(0);
+ }
+ }
+
+ private void ensureWritingDisablesOther(int index) {
+ // write some text to the TextField
+ writeOnTextField(index);
+
+ // ensure that the other TextField is disabled and has no input prompt
+ if (index == 0) {
+ ensureTextFieldDisabledAndEmpty(1);
+ } else {
+ ensureTextFieldDisabledAndEmpty(0);
+ }
+ }
+
+ private void ensureSelectionClearsPrompt(int index) {
+ // select the TextField
+ textfields.get(index).click();
+
+ // check that the the prompt was removed
+ ensureTextFieldEmpty(index);
+ }
+
+ /**
+ * Check that the TextField has no input prompt
+ *
+ * @since
+ * @param index
+ * The TextField to be inspected
+ */
+ private void ensureTextFieldEmpty(int index) {
+
+ assertEquals("TextField " + index + " was not empty,", "", textfields
+ .get(index).getValue());
+ }
+
+ /**
+ * Check that the TextField has been enabled and has correct input prompt
+ *
+ * @since
+ * @param index
+ * the TextField to be inspected
+ */
+ private void ensureTextFieldIsEnabledAndHasInputPrompt(final int index) {
+
+ waitUntil(new ExpectedCondition<Boolean>() {
+
+ @Override
+ public Boolean apply(WebDriver input) {
+ return textfields.get(index).isEnabled();
+ }
+
+ @Override
+ public String toString() {
+ // Timed out after 10 seconds waiting for ...
+ return "TextField " + index + " to be enabled";
+ }
+ });
+
+ ensureTextFieldHasInputPrompt(index);
+ }
+
+ /**
+ * Check that the TextField has the correct input prompt
+ *
+ * @since
+ * @param index
+ * The TextField to be inspected
+ */
+ private void ensureTextFieldHasInputPrompt(final int index) {
+
+ if (index == 0) {
+ assertEquals("Incorrect or missing prompt,",
+ AlternatingTextFields.FIRST_TEXTFIELD_INPUT_PROMPT,
+ textfields.get(index).getValue());
+ } else {
+ assertEquals("Incorrect or missing prompt,",
+ AlternatingTextFields.SECOND_TEXTFIELD_INPUT_PROMPT,
+ textfields.get(index).getValue());
+ }
+ }
+
+ /**
+ * Check that the TextField has been disabled and has no input prompt
+ *
+ * @since
+ * @param index
+ * The TextField to be inspected
+ */
+ private void ensureTextFieldDisabledAndEmpty(final int index) {
+
+ waitUntil(new ExpectedCondition<Boolean>() {
+
+ @Override
+ public Boolean apply(WebDriver input) {
+ return !textfields.get(index).isEnabled();
+ }
+
+ @Override
+ public String toString() {
+ // Timed out after 10 seconds waiting for ...
+ return "TextField " + index + " to be disabled";
+ }
+ });
+
+ ensureTextFieldEmpty(index);
+ }
+
+ private void createTextFields() {
+ textfields = $(TextFieldElement.class).all();
+ }
+
+ private void writeOnTextField(int index) {
+ textfields.get(index).sendKeys(RANDOM_INPUT);
+ }
+
+ private void emptyTextField(int index) {
+ for (int i = 0; i < 15; i++) {
+ textfields.get(index).sendKeys(Keys.BACK_SPACE);
+ }
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java b/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java
index 67b3b84688..99e08ae32d 100644
--- a/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java
+++ b/uitest/src/com/vaadin/tests/components/textfield/EnumTextField.java
@@ -31,6 +31,7 @@ public class EnumTextField extends AbstractTestUIWithLog {
@Override
protected void setup(VaadinRequest request) {
final TextField tf = new TextField();
+ tf.setNullRepresentation("");
tf.addValueChangeListener(new ValueChangeListener() {
@Override
diff --git a/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java b/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java
index 113acee3a2..fe26fb7aad 100644
--- a/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java
+++ b/uitest/src/com/vaadin/tests/components/textfield/EnumTextFieldTest.java
@@ -27,8 +27,7 @@ public class EnumTextFieldTest extends SingleBrowserTest {
public void validValues() {
openTestURL();
$(TextFieldElement.class).first().clear();
- $(TextFieldElement.class).first().sendKeys("Value");
- $(TextFieldElement.class).first().sendKeys(Keys.TAB);
+ $(TextFieldElement.class).first().sendKeys("Value", Keys.TAB);
Assert.assertEquals("3. Value (valid)", getLogRow(0));
$(TextFieldElement.class).first().clear();
@@ -41,13 +40,15 @@ public class EnumTextFieldTest extends SingleBrowserTest {
$(TextFieldElement.class).first().sendKeys(Keys.TAB);
Assert.assertEquals("7. The last value (valid)", getLogRow(0));
+ $(TextFieldElement.class).first().clear();
+ Assert.assertEquals("8. null (valid)", getLogRow(0));
+
}
@Test
public void invalidValue() {
openTestURL();
$(TextFieldElement.class).first().clear();
- Assert.assertEquals("2. (INVALID)", getLogRow(0));
$(TextFieldElement.class).first().sendKeys("bar");
$(TextFieldElement.class).first().sendKeys(Keys.TAB);
diff --git a/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumns.java b/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumns.java
new file mode 100644
index 0000000000..c4679f739b
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumns.java
@@ -0,0 +1,44 @@
+package com.vaadin.tests.components.treetable;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.TreeTable;
+
+@Theme("valo")
+public class MinimalWidthColumns extends AbstractTestUI {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server.
+ * VaadinRequest)
+ */
+ @Override
+ protected void setup(VaadinRequest request) {
+ TreeTable tt = new TreeTable();
+ tt.addContainerProperty("Foo", String.class, "");
+ tt.addContainerProperty("Bar", String.class, "");
+
+ Object item1 = tt.addItem(new Object[] { "f", "Bar" }, null);
+ Object item2 = tt.addItem(new Object[] { "Foo2", "Bar2" }, null);
+
+ tt.setParent(item2, item1);
+
+ tt.setColumnWidth("Foo", 0);
+ tt.setColumnWidth("Bar", 50);
+ tt.setWidth("300px");
+ addComponent(tt);
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return Integer.valueOf(15118);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "There should be no 1px discrepancy between vertical borders in headers and rows";
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumnsTest.java b/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumnsTest.java
new file mode 100644
index 0000000000..46c2f397b6
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/treetable/MinimalWidthColumnsTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.treetable;
+
+import org.junit.Test;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class MinimalWidthColumnsTest extends MultiBrowserTest {
+
+ @Test
+ public void testFor1pxDifference() throws Exception {
+ openTestURL();
+ sleep(500);
+ compareScreen("onepixdifference");
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/debug/PushVersionInfo.java b/uitest/src/com/vaadin/tests/debug/PushVersionInfo.java
new file mode 100644
index 0000000000..d8c23a390f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/debug/PushVersionInfo.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.debug;
+
+import org.atmosphere.util.Version;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.communication.PushMode;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Label;
+
+/**
+ * Test UI for PUSH version string in debug window.
+ *
+ * @author Vaadin Ltd
+ */
+public class PushVersionInfo extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ if (request.getParameter("enablePush") != null) {
+ getPushConfiguration().setPushMode(PushMode.AUTOMATIC);
+ Label label = new Label(Version.getRawVersion());
+ label.addStyleName("atmosphere-version");
+ addComponent(label);
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Debug window shows Push version in info Tab.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14904;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java b/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java
new file mode 100644
index 0000000000..90ea645ab8
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.debug;
+
+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.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.tests.annotations.TestCategory;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Test for PUSH version string in debug window.
+ *
+ * @author Vaadin Ltd
+ */
+@TestCategory("push")
+public class PushVersionInfoTest extends MultiBrowserTest {
+
+ @Test
+ public void testDisabledPush() {
+ setDebug(true);
+ openTestURL();
+
+ selectInfoTab();
+ Assert.assertNull("Found push info server string for disabled Push",
+ getPushRowValue("Push server version"));
+ Assert.assertNull("Found push info client string for disabled Push",
+ getPushRowValue("Push client version"));
+ }
+
+ @Test
+ public void testEnabledPush() {
+ setDebug(true);
+ openTestURL("enablePush=true");
+
+ selectInfoTab();
+ WebElement pushRow = getPushRowValue("Push server version");
+ String atmVersion = findElement(By.className("atmosphere-version"))
+ .getText();
+ Assert.assertTrue("Push row doesn't contain Atmosphere version",
+ pushRow.getText().contains(atmVersion));
+ String jsString = getPushRowValue("Push client version").getText();
+ Assert.assertTrue(
+ "Push client version doesn't contain 'vaadin' string",
+ jsString.contains("vaadin"));
+ Assert.assertTrue(
+ "Push client version doesn't contain 'jquery' string",
+ jsString.contains("jquery"));
+ }
+
+ private void selectInfoTab() {
+ if (isElementPresent(By.className("v-ie8"))) {
+
+ int size = findElements(By.className("v-debugwindow-tab")).size();
+ for (int i = 0; i < size; i++) {
+ WebElement tab = findElement(By
+ .className("v-debugwindow-tab-selected"));
+ String title = tab.getAttribute("title");
+ if (title != null && title.startsWith("General information")) {
+ break;
+ }
+ Actions actions = new Actions(getDriver());
+ actions.sendKeys(Keys.TAB);
+ actions.sendKeys(Keys.SPACE);
+ actions.build().perform();
+ }
+ } else {
+ findElements(By.className("v-debugwindow-tab")).get(0).click();
+ findElements(By.className("v-debugwindow-tab")).get(1).click();
+ }
+ }
+
+ private WebElement getPushRowValue(String key) {
+ List<WebElement> rows = findElements(By.className("v-debugwindow-row"));
+ for (WebElement row : rows) {
+ WebElement caption = row.findElement(By.className("caption"));
+ if (caption.getText().startsWith(key)) {
+ return row.findElement(By.className("value"));
+ }
+ }
+ return null;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/fieldgroup/BasicCrud.java b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrud.java
new file mode 100644
index 0000000000..be0368f4ae
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrud.java
@@ -0,0 +1,110 @@
+/*
+ * 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.fieldgroup;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.fieldgroup.BeanFieldGroup;
+import com.vaadin.data.fieldgroup.PropertyId;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.util.Person;
+import com.vaadin.tests.util.PersonContainer;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+@Theme("valo")
+public class BasicCrud extends UI {
+
+ private Form form;
+
+ @Override
+ protected void init(VaadinRequest request) {
+ VerticalLayout main = new VerticalLayout();
+ main.setMargin(true);
+ main.setSpacing(true);
+ final Table t = new Table();
+ // t.setSelectionMode(SelectionMode.SINGLE);
+ t.setSelectable(true);
+
+ PersonContainer c = PersonContainer.createWithTestData();
+
+ c.addBean(new Person("first", "Last", "email", "phone", "street",
+ 12332, "Turku"));
+ c.addBean(new Person("Foo", "Bar", "me@some.where", "123",
+ "homestreet 12", 10000, "Glasgow"));
+ t.setContainerDataSource(c);
+ // t.removeColumn("address");
+ // t.setColumnOrder("firstName", "lastName", "email", "phoneNumber",
+ // "address.streetAddress", "address.postalCode", "address.city");
+ t.setVisibleColumns("firstName", "lastName", "email", "phoneNumber",
+ "address.streetAddress", "address.postalCode", "address.city");
+
+ // t.addSelectionChangeListener(new SelectionChangeListener() {
+ // @Override
+ // public void selectionChange(SelectionChangeEvent event) {
+ // form.edit((Person) t.getSelectedRow());
+ // }
+ // });
+ t.addValueChangeListener(new ValueChangeListener() {
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ form.edit((Person) t.getValue());
+ }
+ });
+
+ form = new Form();
+
+ t.setSizeFull();
+
+ main.setSizeFull();
+ main.addComponent(t);
+ main.addComponent(form);
+ main.setExpandRatio(t, 1);
+ setContent(main);
+ }
+
+ public static class Form extends HorizontalLayout {
+ private TextField firstName = new TextField("First name");
+ private TextField lastName = new TextField("Last name");
+ private TextField email = new TextField("E-mail");
+ @PropertyId("address.streetAddress")
+ private TextField streetAddress = new TextField("Street address");
+ @PropertyId("address.postalCode")
+ private TextField postalCode = new TextField("Postal code");
+
+ BeanFieldGroup<Person> fieldGroup = new BeanFieldGroup<Person>(
+ Person.class);
+
+ public Form() {
+ setSpacing(true);
+ setId("form");
+ fieldGroup.bindMemberFields(this);
+
+ // Stupid integer binding
+ postalCode.setNullRepresentation("");
+ addComponents(firstName, lastName, email, streetAddress, postalCode);
+ }
+
+ public void edit(Person p) {
+ fieldGroup.setItemDataSource(p);
+ }
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudTest.java b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudTest.java
new file mode 100644
index 0000000000..a41725dbc9
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.fieldgroup;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.testbench.elements.AbstractOrderedLayoutElement;
+import com.vaadin.testbench.elements.TableElement;
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class BasicCrudTest extends SingleBrowserTest {
+
+ @Test
+ public void fieldsInitiallyEmpty() {
+ openTestURL();
+ AbstractOrderedLayoutElement fieldsLayout = $(
+ AbstractOrderedLayoutElement.class).id("form");
+ List<TextFieldElement> textFields = fieldsLayout.$(
+ TextFieldElement.class).all();
+
+ for (TextFieldElement e : textFields) {
+ Assert.assertEquals("TextField should be empty", "", e.getValue());
+ }
+ }
+
+ @Test
+ public void fieldsClearedOnDeselect() {
+ openTestURL();
+ AbstractOrderedLayoutElement fieldsLayout = $(
+ AbstractOrderedLayoutElement.class).id("form");
+
+ // Select row
+ $(TableElement.class).first().getCell(2, 2).click();
+
+ List<TextFieldElement> textFields = fieldsLayout.$(
+ TextFieldElement.class).all();
+
+ for (TextFieldElement e : textFields) {
+ Assert.assertNotEquals("TextField should not be empty", "",
+ e.getValue());
+ }
+
+ // Deselect row
+ $(TableElement.class).first().getCell(2, 2).click();
+
+ for (TextFieldElement e : textFields) {
+ Assert.assertEquals("TextField should be empty", "", e.getValue());
+ }
+
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java
new file mode 100644
index 0000000000..5110bf6dcf
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrors.java
@@ -0,0 +1,72 @@
+package com.vaadin.tests.fieldgroup;
+
+import com.vaadin.data.Validator;
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.data.validator.BeanValidator;
+import com.vaadin.server.AbstractErrorMessage;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+import org.apache.commons.lang.StringEscapeUtils;
+
+public class MultipleValidationErrors extends AbstractTestUI {
+
+ public static final String FIRST_NAME_NOT_NULL_VALIDATION_MESSAGE = "first name is null";
+ public static final String LAST_NAME_NOT_NULL_VALIDATION_MESSAGE = "last name is null";
+ public static final String FIRST_NAME_NOT_EMPTY_VALIDATION_MESSAGE = "first name is empty";
+ public static final String LAST_NAME_NOT_EMPTY_VALIDATION_MESSAGE = "last name is empty";
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ BeanItem<PersonBeanWithValidationAnnotations> item = new BeanItem<PersonBeanWithValidationAnnotations>(
+ new PersonBeanWithValidationAnnotations());
+ final FieldGroup fieldGroup = new FieldGroup(item);
+
+ bindTextField(item, fieldGroup, "First Name", "firstName");
+ bindTextField(item, fieldGroup, "Last Name", "lastName");
+
+ final Label validationErrors = new Label();
+ validationErrors.setId("validationErrors");
+ addComponent(validationErrors);
+
+ addButton("Submit", new Button.ClickListener() {
+ @Override
+ public void buttonClick(Button.ClickEvent event) {
+ validationErrors.setValue("");
+ try {
+ fieldGroup.commit();
+ } catch (FieldGroup.CommitException e) {
+ if (e.getCause() != null && e.getCause() instanceof Validator.InvalidValueException) {
+ validationErrors.setValue(StringEscapeUtils.unescapeHtml(
+ AbstractErrorMessage.getErrorMessageForException(e.getCause()).getFormattedHtmlMessage()));
+ }
+ }
+
+
+ }
+ });
+ }
+
+ private void bindTextField(BeanItem<PersonBeanWithValidationAnnotations> item, FieldGroup fieldGroup,
+ String caption, String propertyId) {
+ TextField textfield = new TextField(caption, item.getItemProperty(propertyId));
+ textfield.addValidator(new BeanValidator(PersonBeanWithValidationAnnotations.class, propertyId));
+
+ fieldGroup.bind(textfield, propertyId);
+
+ addComponent(textfield);
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 14742;
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "All validation errors should be included when committing a field group.";
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java
new file mode 100644
index 0000000000..175b650be6
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fieldgroup/MultipleValidationErrorsTest.java
@@ -0,0 +1,37 @@
+package com.vaadin.tests.fieldgroup;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.testbench.elements.TextFieldElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class MultipleValidationErrorsTest extends MultiBrowserTest {
+
+ private void commitTextFields() {
+ $(ButtonElement.class).caption("Submit").first().click();
+ }
+
+ private void clearTextField(String caption) {
+ TextFieldElement textField = $(TextFieldElement.class).caption(caption).first();
+ textField.clear();
+ }
+
+ @Test
+ public void validationErrorsIncludeBothErrors() {
+ openTestURL();
+
+ clearTextField("First Name");
+ clearTextField("Last Name");
+
+ commitTextFields();
+
+ String validationErrors = $(LabelElement.class).id("validationErrors").getText();
+
+ assertThat(validationErrors, containsString(MultipleValidationErrors.FIRST_NAME_NOT_EMPTY_VALIDATION_MESSAGE));
+ assertThat(validationErrors, containsString(MultipleValidationErrors.LAST_NAME_NOT_EMPTY_VALIDATION_MESSAGE));
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java b/uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java
new file mode 100644
index 0000000000..5f81ee248b
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/fieldgroup/PersonBeanWithValidationAnnotations.java
@@ -0,0 +1,31 @@
+package com.vaadin.tests.fieldgroup;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+public class PersonBeanWithValidationAnnotations implements Serializable {
+ @NotNull(message = MultipleValidationErrors.FIRST_NAME_NOT_NULL_VALIDATION_MESSAGE)
+ @Size(min = 1, message = MultipleValidationErrors.FIRST_NAME_NOT_EMPTY_VALIDATION_MESSAGE)
+ private String firstName;
+
+ @NotNull(message = MultipleValidationErrors.LAST_NAME_NOT_NULL_VALIDATION_MESSAGE)
+ @Size(min = 1, message = MultipleValidationErrors.LAST_NAME_NOT_EMPTY_VALIDATION_MESSAGE)
+ private String lastName;
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/layouts/HorizontalLayoutWithLabelAndButton.java b/uitest/src/com/vaadin/tests/layouts/HorizontalLayoutWithLabelAndButton.java
new file mode 100644
index 0000000000..9381f2caeb
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/layouts/HorizontalLayoutWithLabelAndButton.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.layouts;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+
+public class HorizontalLayoutWithLabelAndButton extends AbstractTestUIWithLog {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ HorizontalLayout hl = new HorizontalLayout();
+ hl.setSpacing(true);
+ hl.setWidth("100%");
+ Label l = new Label();
+ l.setCaption("POTUS Database");
+ l.setSizeUndefined();
+
+ Button b = new Button("Add new");
+ hl.addComponents(l, b);
+ b.setStyleName("primary");
+ hl.setExpandRatio(b, 1);
+
+ addComponent(hl);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java b/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java
index 8c14ba8bd7..850fa1044f 100644
--- a/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java
+++ b/uitest/src/com/vaadin/tests/minitutorials/v7a2/WidgetContainer.java
@@ -15,14 +15,12 @@ public class WidgetContainer extends AbstractComponentContainer {
public void addComponent(Component c) {
children.add(c);
super.addComponent(c);
- markAsDirty();
}
@Override
public void removeComponent(Component c) {
children.remove(c);
super.removeComponent(c);
- markAsDirty();
}
@Override
diff --git a/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonAction.java b/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonAction.java
new file mode 100644
index 0000000000..5c78a3f42a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonAction.java
@@ -0,0 +1,128 @@
+package com.vaadin.tests.navigator;
+
+import com.vaadin.navigator.Navigator;
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener;
+import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class NavigatorViewBlocksBackButtonAction extends AbstractTestUI {
+
+ private Navigator navigator;
+
+ protected static final String LABEL_MAINVIEW_ID = "LABEL_MAINVIEW_ID";
+ protected static final String LABEL_PROMPTEDVIEW_ID = "LABEL_PROMPTEDVIEW_ID";
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ navigator = new Navigator(this, this);
+ navigator.addView(MainView.NAME, new MainView());
+ navigator.addView(ViewWithPromptedLeave.NAME,
+ new ViewWithPromptedLeave());
+ navigator.navigateTo(MainView.NAME);
+ }
+
+ class MainView extends VerticalLayout implements View {
+
+ public static final String NAME = "mainview";
+
+ public MainView() {
+ Label label = new Label("MainView content");
+ label.setId(LABEL_MAINVIEW_ID);
+ addComponent(label);
+
+ Button buttonNavToAnotherView = new Button(
+ "Navigate to another view", new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ navigator.navigateTo(ViewWithPromptedLeave.NAME);
+ }
+ });
+ addComponent(buttonNavToAnotherView);
+ }
+
+ @Override
+ public void enter(ViewChangeEvent event) {
+ }
+
+ }
+
+ class ViewWithPromptedLeave extends VerticalLayout implements View,
+ ViewChangeListener {
+
+ public static final String NAME = "prompted";
+
+ protected boolean okToLeave;
+
+ public ViewWithPromptedLeave() {
+ Label label = new Label("ViewWithPromptedLeave content");
+ label.setId(LABEL_PROMPTEDVIEW_ID);
+ addComponent(label);
+ addComponent(new Label(
+ "Try to navigate back to first view with browser back button."));
+ }
+
+ @Override
+ public void enter(ViewChangeEvent event) {
+ event.getNavigator().addViewChangeListener(this);
+ }
+
+ @Override
+ public boolean beforeViewChange(final ViewChangeEvent event) {
+ if (okToLeave) {
+ okToLeave = false;
+ return true;
+ } else {
+ final Window confirmationWindow = new Window("Confirm");
+ confirmationWindow.setModal(true);
+ confirmationWindow.setClosable(true);
+
+ VerticalLayout confirmationWindowLayout = new VerticalLayout();
+ confirmationWindow.setContent(confirmationWindowLayout);
+ confirmationWindowLayout.setMargin(true);
+ confirmationWindowLayout.setSpacing(true);
+ confirmationWindowLayout.addComponent(new Label(
+ "Really exit this view?"));
+ confirmationWindowLayout.addComponent(new Button("Yeah, sure!",
+ new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent buttonEvent) {
+ okToLeave = true;
+ getUI().removeWindow(confirmationWindow);
+ event.getNavigator().navigateTo(
+ event.getViewName() + "/"
+ + event.getParameters());
+ }
+ }));
+ getUI().addWindow(confirmationWindow);
+ return false;
+ }
+ }
+
+ @Override
+ public void afterViewChange(ViewChangeEvent event) {
+ if (event.getNewView() != this) {
+ event.getNavigator().removeViewChangeListener(this);
+ }
+ }
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "URL should not be changed when view blocks navigating away from view using the browser's Back-button";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 10901;
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java b/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java
new file mode 100644
index 0000000000..84abdca24b
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/navigator/NavigatorViewBlocksBackButtonActionTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.navigator;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class NavigatorViewBlocksBackButtonActionTest extends MultiBrowserTest {
+
+ @Test
+ public void testIfConfirmBack() {
+ openTestURL();
+
+ // keep URL of main view
+ final String initialUrl = driver.getCurrentUrl();
+
+ // do it 2 times to verify that login is not broken after first time
+ for (int i = 0; i < 2; i++) {
+ // go to prompted view
+ WebElement button = $(ButtonElement.class).first();
+ button.click();
+
+ // click back button
+ driver.navigate().back();
+
+ // confirm "go back by clicking confirm button
+ WebElement buttonConfirmView = $(ButtonElement.class).first();
+ buttonConfirmView.click();
+
+ // verify we are in main view and url is correct
+ waitForElementPresent(By
+ .id(NavigatorViewBlocksBackButtonAction.LABEL_MAINVIEW_ID));
+ String currentUrl = driver.getCurrentUrl();
+ assertEquals(
+ "Current URL should be equal to initial main view URL",
+ initialUrl, currentUrl);
+ }
+ }
+
+ @Test
+ public void testIfCancelBack() {
+ openTestURL();
+
+ // go to prompted view
+ WebElement button = $(ButtonElement.class).first();
+ button.click();
+
+ // keep URL of prompted view
+ final String initialPromptedUrl = driver.getCurrentUrl();
+
+ // click back button
+ driver.navigate().back();
+
+ // verify url is correct (is not changed)
+ waitForElementPresent(By
+ .id(NavigatorViewBlocksBackButtonAction.LABEL_PROMPTEDVIEW_ID));
+ String currentUrl = driver.getCurrentUrl();
+ assertEquals(
+ "Current URL should be equal to initial prompted view URL",
+ initialPromptedUrl, currentUrl);
+
+ WebElement cancelButton = driver.findElement(By
+ .className("v-window-closebox"));
+
+ // click cancel button
+ cancelButton.click();
+
+ // verify we leave in prompted view and url is correct
+ waitForElementPresent(By
+ .id(NavigatorViewBlocksBackButtonAction.LABEL_PROMPTEDVIEW_ID));
+ currentUrl = driver.getCurrentUrl();
+ assertEquals(
+ "Current URL should be equal to initial prompted view URL",
+ initialPromptedUrl, currentUrl);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java
index a04d569e05..1d5ead7d98 100644
--- a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java
@@ -18,11 +18,7 @@ package com.vaadin.tests.push;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
-import java.util.List;
-
import org.junit.Test;
-import org.openqa.selenium.remote.DesiredCapabilities;
-import org.openqa.selenium.support.ui.Select;
public class PushConfigurationLongPollingTest extends PushConfigurationTest {
@@ -30,13 +26,13 @@ public class PushConfigurationLongPollingTest extends PushConfigurationTest {
public void testLongPolling() throws InterruptedException {
openDebugLogTab();
- new Select(getTransportSelect()).selectByVisibleText("LONG_POLLING");
+ getTransportSelect().selectByText("Long polling");
assertThat(getStatusText(),
containsString("fallbackTransport: long-polling"));
assertThat(getStatusText(), containsString("transport: long-polling"));
clearDebugMessages();
- new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC");
+ getPushModeSelect().selectByText("Automatic");
waitForDebugMessage("Push connection established using long-polling",
10);
waitForServerCounterToUpdate();
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java
index f5c015ad12..202db8d6b7 100644
--- a/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java
@@ -15,25 +15,24 @@
*/
package com.vaadin.tests.push;
-import org.junit.Test;
-import org.openqa.selenium.support.ui.Select;
-
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
+import org.junit.Test;
+
public class PushConfigurationStreamingTest extends PushConfigurationTest {
@Test
public void testStreaming() throws InterruptedException {
openDebugLogTab();
- new Select(getTransportSelect()).selectByVisibleText("STREAMING");
+ getTransportSelect().selectByText("Streaming");
assertThat(getStatusText(),
containsString("fallbackTransport: long-polling"));
assertThat(getStatusText(), containsString("transport: streaming"));
clearDebugMessages();
- new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC");
+ getPushModeSelect().selectByText("Automatic");
waitForDebugMessage("Push connection established using streaming", 10);
waitForServerCounterToUpdate();
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java
index bb5b420259..396160cc7d 100644
--- a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java
@@ -20,8 +20,8 @@ import static org.junit.Assert.assertEquals;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
-import org.openqa.selenium.support.ui.Select;
+import com.vaadin.testbench.elements.NativeSelectElement;
import com.vaadin.tests.annotations.TestCategory;
import com.vaadin.tests.tb3.MultiBrowserTest;
@@ -49,7 +49,7 @@ abstract class PushConfigurationTest extends MultiBrowserTest {
}
protected void disablePush() throws InterruptedException {
- new Select(getPushModeSelect()).selectByVisibleText("DISABLED");
+ getPushModeSelect().selectByText("Disabled");
int counter = getServerCounter();
sleep(2000);
@@ -57,12 +57,12 @@ abstract class PushConfigurationTest extends MultiBrowserTest {
getServerCounter());
}
- protected WebElement getPushModeSelect() {
- return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VNativeSelect[0]/domChild[0]");
+ protected NativeSelectElement getPushModeSelect() {
+ return $(NativeSelectElement.class).caption("Push mode").first();
}
- protected WebElement getTransportSelect() {
- return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[1]/VNativeSelect[0]/domChild[0]");
+ protected NativeSelectElement getTransportSelect() {
+ return $(NativeSelectElement.class).caption("Transport").first();
}
protected int getServerCounter() {
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java
index c9a813fac0..475fa2165f 100644
--- a/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java
@@ -23,7 +23,6 @@ import java.util.List;
import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
-import org.openqa.selenium.support.ui.Select;
public class PushConfigurationWebSocketTest extends PushConfigurationTest {
@@ -40,8 +39,8 @@ public class PushConfigurationWebSocketTest extends PushConfigurationTest {
@Test
public void testWebsocket() throws InterruptedException {
- new Select(getTransportSelect()).selectByVisibleText("WEBSOCKET");
- new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC");
+ getTransportSelect().selectByText("Websocket");
+ getPushModeSelect().selectByText("Automatic");
assertThat(getStatusText(),
containsString("fallbackTransport: long-polling"));
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurator.java b/uitest/src/com/vaadin/tests/push/PushConfigurator.java
index 5a45ab7206..7da58af1da 100644
--- a/uitest/src/com/vaadin/tests/push/PushConfigurator.java
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurator.java
@@ -87,11 +87,9 @@ public class PushConfigurator extends VerticalLayout {
pushMode.addItem(PushMode.AUTOMATIC);
for (Transport t : Transport.values()) {
- transport.addItem(t.toString());
- fallbackTransport.addItem(t.toString());
+ transport.addItem(t);
+ fallbackTransport.addItem(t);
}
- transport.addItem("");
- fallbackTransport.addItem("");
pushMode.setImmediate(true);
transport.setImmediate(true);
@@ -124,7 +122,7 @@ public class PushConfigurator extends VerticalLayout {
transport.addValueChangeListener(new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
- Transport t = Transport.valueOf((String) transport.getValue());
+ Transport t = (Transport) transport.getValue();
ui.getPushConfiguration().setTransport(t);
refreshStatus();
}
@@ -133,8 +131,7 @@ public class PushConfigurator extends VerticalLayout {
fallbackTransport.addValueChangeListener(new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
- Transport t = Transport.valueOf((String) fallbackTransport
- .getValue());
+ Transport t = (Transport) fallbackTransport.getValue();
ui.getPushConfiguration().setFallbackTransport(t);
refreshStatus();
}
diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
index 76b851fd23..b5a345bd30 100644
--- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
+++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
@@ -32,7 +32,6 @@ import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
-import com.vaadin.testbench.elements.TableElement;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
@@ -69,6 +68,7 @@ import com.vaadin.testbench.TestBenchDriverProxy;
import com.vaadin.testbench.TestBenchElement;
import com.vaadin.testbench.TestBenchTestCase;
import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.testbench.elements.TableElement;
import com.vaadin.testbench.elements.VerticalLayoutElement;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.tests.tb3.MultiBrowserTest.Browser;
@@ -257,7 +257,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
@Override
public Object apply(WebDriver input) {
try {
- return table.getCell(row, 0) != null;
+ return table.getCell(row, 0) != null;
} catch (NoSuchElementException e) {
return false;
}
@@ -266,7 +266,8 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
}
protected void scrollTable(TableElement table, int rows, int rowToWait) {
- testBenchElement(table.findElement(By.className("v-scrollable"))).scroll(rows * 30);
+ testBenchElement(table.findElement(By.className("v-scrollable")))
+ .scroll(rows * 30);
waitUntilRowIsVisible(table, rowToWait);
}
@@ -430,6 +431,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
@After
public void tearDown() throws Exception {
if (driver != null) {
+ try {
+ openTestURL("&closeApplication");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
driver.quit();
}
driver = null;
diff --git a/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotification.java b/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotification.java
new file mode 100644
index 0000000000..efb953530c
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotification.java
@@ -0,0 +1,30 @@
+package com.vaadin.tests.themes.chameleon;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.themes.ChameleonTheme;
+
+@Theme(ChameleonTheme.THEME_NAME)
+public class ChameleonNotification extends AbstractTestUI {
+ @Override
+ protected void setup(VaadinRequest request) {
+
+
+ addButton("Notification", new Button.ClickListener() {
+ @Override
+ public void buttonClick(Button.ClickEvent event) {
+ Notification notification = new Notification("Notification");
+ notification.setDelayMsec(30000);
+ notification.show(getUI().getPage());
+ }
+ });
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 15351;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotificationTest.java b/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotificationTest.java
new file mode 100644
index 0000000000..ef41ef3df9
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/themes/chameleon/ChameleonNotificationTest.java
@@ -0,0 +1,25 @@
+package com.vaadin.tests.themes.chameleon;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.NotificationElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThat;
+
+public class ChameleonNotificationTest extends MultiBrowserTest {
+ @Test
+ public void gradientPathIsCorrect() throws IOException {
+ openTestURL();
+ $(ButtonElement.class).first().click();
+
+ NotificationElement notificationElement
+ = $(NotificationElement.class).first();
+
+ assertThat(notificationElement.getCssValue("background-image"),
+ containsString("chameleon/img/grad"));
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java b/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java
index e66cd2668b..9ed48896eb 100644
--- a/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java
+++ b/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java
@@ -178,6 +178,11 @@ public class ButtonsAndLinks extends VerticalLayout implements View {
link.setIcon(testIcon.get());
link.addStyleName("large");
row.addComponent(link);
+
+ link = new Link("Disabled", new ExternalResource("https://vaadin.com"));
+ link.setIcon(testIcon.get());
+ link.setEnabled(false);
+ row.addComponent(link);
}
@Override
diff --git a/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java b/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java
index c7a2610a21..c79447bd86 100644
--- a/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java
+++ b/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java
@@ -79,6 +79,11 @@ public class CheckBoxes extends VerticalLayout implements View {
check.addStyleName("large");
row.addComponent(check);
+ check = new CheckBox("Disabled", true);
+ check.setEnabled(false);
+ check.setIcon(testIcon.get());
+ row.addComponent(check);
+
h1 = new Label("Option Groups");
h1.addStyleName("h1");
addComponent(h1);
@@ -184,6 +189,17 @@ public class CheckBoxes extends VerticalLayout implements View {
options.setItemIcon(two, testIcon.get());
options.setItemIcon("Option Three", testIcon.get());
row.addComponent(options);
+
+ options = new OptionGroup("Disabled items");
+ options.setEnabled(false);
+ options.addItem("Option One");
+ options.addItem("Option Two");
+ options.addItem("Option Three");
+ options.select("Option One");
+ options.setItemIcon("Option One", testIcon.get());
+ options.setItemIcon("Option Two", testIcon.get());
+ options.setItemIcon("Option Three", testIcon.get(true));
+ row.addComponent(options);
}
@Override
diff --git a/uitest/src/com/vaadin/tests/themes/valo/ModalWindowTest.java b/uitest/src/com/vaadin/tests/themes/valo/ModalWindowTest.java
new file mode 100644
index 0000000000..b97ce43ed6
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/themes/valo/ModalWindowTest.java
@@ -0,0 +1,34 @@
+package com.vaadin.tests.themes.valo;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.tests.ModalWindow;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class ModalWindowTest extends SingleBrowserTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return ModalWindow.class;
+ }
+
+ @Test
+ public void modalAnimationsAreDisabled() {
+ openTestURL("theme=tests-valo-disabled-animations");
+
+ openModalWindow();
+
+ WebElement modalityCurtain = findElement(By.className("v-window-modalitycurtain"));
+
+ assertThat(modalityCurtain.getCssValue("-webkit-animation-name"), is("none"));
+ }
+
+ private void openModalWindow() {
+ $(ButtonElement.class).get(1).click();
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java
index 92cb837b38..13b0c7144c 100644
--- a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java
+++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java
@@ -39,7 +39,7 @@ public class ValoThemeUITest extends MultiBrowserTest {
public void buttonsLinks() throws Exception {
openTestURL("test");
open("Buttons & Links", "Buttons");
- compareScreen("buttonsLinks");
+ compareScreen("buttonsLinks_with_disabled");
}
@Test
@@ -85,7 +85,7 @@ public class ValoThemeUITest extends MultiBrowserTest {
public void checkboxes() throws Exception {
openTestURL("test");
open("Check Boxes & Option Groups", "Check Boxes");
- compareScreen("checkboxes");
+ compareScreen("checkboxes_with_disabled");
}
@Test