diff options
237 files changed, 6914 insertions, 2918 deletions
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs index 095a6ca1ed..3717876356 100644 --- a/.settings/org.eclipse.jdt.ui.prefs +++ b/.settings/org.eclipse.jdt.ui.prefs @@ -17,10 +17,12 @@ sp_cleanup.always_use_blocks=true sp_cleanup.always_use_parentheses_in_expressions=false sp_cleanup.always_use_this_for_non_static_field_access=false sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false sp_cleanup.convert_to_enhanced_for_loop=false sp_cleanup.correct_indentation=false sp_cleanup.format_source_code=true sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false sp_cleanup.make_local_variable_final=false sp_cleanup.make_parameters_final=false sp_cleanup.make_private_fields_final=true @@ -36,7 +38,8 @@ sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class= sp_cleanup.qualify_static_member_accesses_with_declaring_class=false sp_cleanup.qualify_static_method_accesses_with_declaring_class=false sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_redundant_type_arguments=false +sp_cleanup.remove_trailing_whitespaces=false sp_cleanup.remove_trailing_whitespaces_all=true sp_cleanup.remove_trailing_whitespaces_ignore_empty=false sp_cleanup.remove_unnecessary_casts=true @@ -49,10 +52,13 @@ sp_cleanup.remove_unused_private_methods=true sp_cleanup.remove_unused_private_types=true sp_cleanup.sort_members=false sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false sp_cleanup.use_blocks=true sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=false sp_cleanup.use_parentheses_in_expressions=false sp_cleanup.use_this_for_non_static_field_access=true sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true sp_cleanup.use_this_for_non_static_method_access=true sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false @@ -25,7 +25,9 @@ Cloning the project repositories The Vaadin repository can be cloned using <pre><code>git clone https://github.com/vaadin/vaadin.git</code></pre> -or using your favorite Git tool +or using your favorite Git tool. + +If using Windows, you might want to add these Git settings: core.autocrlf=false and core.fileMode=false. Setting up Eclipse to Develop Vaadin 7 ========= diff --git a/WebContent/VAADIN/themes/base/notification/notification.scss b/WebContent/VAADIN/themes/base/notification/notification.scss index 0fc7801777..a91e26947d 100644 --- a/WebContent/VAADIN/themes/base/notification/notification.scss +++ b/WebContent/VAADIN/themes/base/notification/notification.scss @@ -33,8 +33,6 @@ } .#{$primaryStyleName}-system { background-color: red; - opacity: .7; - filter: alpha(opacity=70); } .#{$primaryStyleName}-system h1 { display: block; diff --git a/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss b/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss index 783e4bcc1f..85fbb3295f 100644 --- a/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss +++ b/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss @@ -8,6 +8,8 @@ div.#{$primaryStyleName} { -webkit-box-shadow: 0 2px 5px rgba(0,0,0,.7); -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; } diff --git a/WebContent/VAADIN/themes/tests-valo/_blueprint.scss b/WebContent/VAADIN/themes/tests-valo-blueprint/_variables.scss index 696da0b69e..696da0b69e 100644 --- a/WebContent/VAADIN/themes/tests-valo/_blueprint.scss +++ b/WebContent/VAADIN/themes/tests-valo-blueprint/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo-blueprint/styles.scss b/WebContent/VAADIN/themes/tests-valo-blueprint/styles.scss new file mode 100644 index 0000000000..9433f4eba6 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-blueprint/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-blueprint { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_dark.scss b/WebContent/VAADIN/themes/tests-valo-dark/_variables.scss index 21bcd00ae9..21bcd00ae9 100644 --- a/WebContent/VAADIN/themes/tests-valo/_dark.scss +++ b/WebContent/VAADIN/themes/tests-valo-dark/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo-dark/styles.scss b/WebContent/VAADIN/themes/tests-valo-dark/styles.scss new file mode 100644 index 0000000000..13f98ae418 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-dark/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-dark { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_facebook.scss b/WebContent/VAADIN/themes/tests-valo-facebook/_variables.scss index 5b83aae4ca..5b83aae4ca 100644 --- a/WebContent/VAADIN/themes/tests-valo/_facebook.scss +++ b/WebContent/VAADIN/themes/tests-valo-facebook/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo-facebook/styles.scss b/WebContent/VAADIN/themes/tests-valo-facebook/styles.scss new file mode 100644 index 0000000000..7b784627b2 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-facebook/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-facebook { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_flat.scss b/WebContent/VAADIN/themes/tests-valo-flat/_variables.scss index 5d2b8abbb7..5d2b8abbb7 100644 --- a/WebContent/VAADIN/themes/tests-valo/_flat.scss +++ b/WebContent/VAADIN/themes/tests-valo-flat/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo-flat/styles.scss b/WebContent/VAADIN/themes/tests-valo-flat/styles.scss new file mode 100644 index 0000000000..7b981de04a --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-flat/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-flat { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_flat-dark.scss b/WebContent/VAADIN/themes/tests-valo-flatdark/_variables.scss index f68f9c266d..f68f9c266d 100644 --- a/WebContent/VAADIN/themes/tests-valo/_flat-dark.scss +++ b/WebContent/VAADIN/themes/tests-valo-flatdark/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo-flatdark/styles.scss b/WebContent/VAADIN/themes/tests-valo-flatdark/styles.scss new file mode 100644 index 0000000000..d0871fcba2 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-flatdark/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-flatdark { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_metro.scss b/WebContent/VAADIN/themes/tests-valo-metro/_variables.scss index f11cdb8b64..f11cdb8b64 100644 --- a/WebContent/VAADIN/themes/tests-valo/_metro.scss +++ b/WebContent/VAADIN/themes/tests-valo-metro/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo-metro/styles.scss b/WebContent/VAADIN/themes/tests-valo-metro/styles.scss new file mode 100644 index 0000000000..51b3427a12 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-metro/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-metro { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_valotest.scss b/WebContent/VAADIN/themes/tests-valo/_valotest.scss new file mode 100644 index 0000000000..f775938e13 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo/_valotest.scss @@ -0,0 +1,118 @@ +@mixin valotest { + @include valo; + + .valo-menu .v-checkbox { + margin: round($v-unit-size/2); + font-weight: 400; + } + + $color1: hsl(220, 5%, 38%); + $color2: #5d73c0; + $color3: #3dbc1a; + $color4: #d2f4f3; + $color5: #fe902a; + $colors: $color1, $color2, $color3, $color4, $color5; + + .v-textfield-color1 { + @include valo-textfield-style($background-color: $color1); + } + + .v-textfield-color2 { + @include valo-textfield-style($background-color: $color3); + } + + .v-textfield-color3 { + @include valo-textfield-style($background-color: $color4); + } + + + .v-textarea-color1 { + @include valo-textarea-style($background-color: $color1); + } + + .v-textarea-color2 { + @include valo-textarea-style($background-color: $color3); + } + + .v-textarea-color3 { + @include valo-textarea-style($background-color: $color4); + } + + + .v-datefield-color1 { + @include valo-datefield-style($background-color: $color1); + } + + .v-datefield-color2 { + @include valo-datefield-style($background-color: $color3); + } + + .v-datefield-color3 { + @include valo-datefield-style($background-color: $color4); + } + + + .v-filterselect-color1 { + @include valo-combobox-style($background-color: $color1); + } + + .v-filterselect-color2 { + @include valo-combobox-style($background-color: $color3); + } + + .v-filterselect-color3 { + @include valo-combobox-style($background-color: $color4); + } + + + $copy: $v-selection-color; + $v-selection-color: white; + .v-checkbox-color1 { + @include valo-checkbox-style($background-color: $color1); + } + + .v-checkbox-color2 { + @include valo-checkbox-style($background-color: $color2); + } + $v-selection-color: $copy; + + + .v-slider-color1 { + @include valo-slider-handle-style($background-color: $color1); + } + + .v-slider-color2 { + @include valo-slider-track-style($background-color: $color3); + } + + .v-slider-color3 { + @include valo-slider-indicator-style($background-color: #dcdc1e); + } + + + .v-panel-caption-color1 { + @include valo-panel-caption-style($background-color: $color1); + } + + .v-panel-caption-color2 { + @include valo-panel-caption-style($background-color: $color3); + } + + .v-panel-caption-color3 { + @include valo-panel-caption-style($background-color: $color5); + } + + // Show splitpanel borders + .v-splitpanel-vertical, + .v-splitpanel-horizontal { + outline: 1px dotted rgba(gray, .2); + } + + .v-slider-ticks { + @include valo-slider-ticks($tick-count: 5); + } + + .v-accordion-item-color1 .v-accordion-item-caption { + @include valo-accordion-item-caption-style($background-color: $color2); + } +}
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/tests-valo/_default.scss b/WebContent/VAADIN/themes/tests-valo/_variables.scss index c227156e2e..c227156e2e 100644 --- a/WebContent/VAADIN/themes/tests-valo/_default.scss +++ b/WebContent/VAADIN/themes/tests-valo/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo/styles.scss b/WebContent/VAADIN/themes/tests-valo/styles.scss index 89fc5755f4..1ba0b29b04 100644 --- a/WebContent/VAADIN/themes/tests-valo/styles.scss +++ b/WebContent/VAADIN/themes/tests-valo/styles.scss @@ -1,127 +1,5 @@ -@import "default"; -// @import "flat"; -// @import "flat-dark"; -// @import "facebook"; -// @import "metro"; -// @import "dark"; -// @import "blueprint"; - - +@import "variables"; +@import "valotest"; .tests-valo { - @include valo; - - .valo-menu .v-checkbox { - margin: round($v-unit-size/2); - font-weight: 400; - } - - $color1: hsl(220, 5%, 38%); - $color2: #5d73c0; - $color3: #3dbc1a; - $color4: #d2f4f3; - $color5: #fe902a; - $colors: $color1, $color2, $color3, $color4, $color5; - - .v-textfield-color1 { - @include valo-textfield-style($background-color: $color1); - } - - .v-textfield-color2 { - @include valo-textfield-style($background-color: $color3); - } - - .v-textfield-color3 { - @include valo-textfield-style($background-color: $color4); - } - - - .v-textarea-color1 { - @include valo-textarea-style($background-color: $color1); - } - - .v-textarea-color2 { - @include valo-textarea-style($background-color: $color3); - } - - .v-textarea-color3 { - @include valo-textarea-style($background-color: $color4); - } - - - .v-datefield-color1 { - @include valo-datefield-style($background-color: $color1); - } - - .v-datefield-color2 { - @include valo-datefield-style($background-color: $color3); - } - - .v-datefield-color3 { - @include valo-datefield-style($background-color: $color4); - } - - - .v-filterselect-color1 { - @include valo-combobox-style($background-color: $color1); - } - - .v-filterselect-color2 { - @include valo-combobox-style($background-color: $color3); - } - - .v-filterselect-color3 { - @include valo-combobox-style($background-color: $color4); - } - - - $copy: $v-selection-color; - $v-selection-color: white; - .v-checkbox-color1 { - @include valo-checkbox-style($background-color: $color1); - } - - .v-checkbox-color2 { - @include valo-checkbox-style($background-color: $color2); - } - $v-selection-color: $copy; - - - .v-slider-color1 { - @include valo-slider-handle-style($background-color: $color1); - } - - .v-slider-color2 { - @include valo-slider-track-style($background-color: $color3); - } - - .v-slider-color3 { - @include valo-slider-indicator-style($background-color: #dcdc1e); - } - - - .v-panel-caption-color1 { - @include valo-panel-caption-style($background-color: $color1); - } - - .v-panel-caption-color2 { - @include valo-panel-caption-style($background-color: $color3); - } - - .v-panel-caption-color3 { - @include valo-panel-caption-style($background-color: $color5); - } - - // Show splitpanel borders - .v-splitpanel-vertical, - .v-splitpanel-horizontal { - outline: 1px dotted rgba(gray, .2); - } - - .v-slider-ticks { - @include valo-slider-ticks($tick-count: 5); - } - - .v-accordion-item-color1 .v-accordion-item-caption { - @include valo-accordion-item-caption-style($background-color: $color2); - } + @include valotest; } diff --git a/WebContent/VAADIN/themes/valo/components/_button.scss b/WebContent/VAADIN/themes/valo/components/_button.scss index cea1c9fbc8..4930742dad 100644 --- a/WebContent/VAADIN/themes/valo/components/_button.scss +++ b/WebContent/VAADIN/themes/valo/components/_button.scss @@ -241,6 +241,11 @@ .#{$primary-stylename}-wrap { visibility: visible; } + + .#{$primary-stylename}-caption { + // For IE8 + display: inline-block; + } } diff --git a/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss b/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss index 7f1be69553..6527e42ed7 100644 --- a/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss +++ b/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss @@ -7,7 +7,8 @@ } .#{$primary-stylename}.v-active-drag-source { - visibility: hidden; + // This breaks file upload dragging (for some reason the ddwrapper gets this class when an active file drag is over it) + // visibility: hidden; } .#{$primary-stylename} { diff --git a/WebContent/VAADIN/themes/valo/components/_tree.scss b/WebContent/VAADIN/themes/valo/components/_tree.scss index 9ac2f7e43d..1327320cd4 100644 --- a/WebContent/VAADIN/themes/valo/components/_tree.scss +++ b/WebContent/VAADIN/themes/valo/components/_tree.scss @@ -116,11 +116,12 @@ $v-tree-expand-animation-enabled: false !default; &:after { content: ""; - display: inline-block; + display: block; vertical-align: top; position: absolute; z-index: 1; left: 0; + margin-top: -$v-tree-row-height; width: 100%; height: $v-tree-row-height; border-radius: $v-border-radius; @@ -153,8 +154,8 @@ $v-tree-expand-animation-enabled: false !default; @include valo-tree-expanded-icon-style(true); } - .#{$primary-stylename}-node-leaf > .#{$primary-stylename}-node-caption > div:before, - .v-ie8 & .#{$primary-stylename}-node-leaf:before { + .#{$primary-stylename}-node-leaf:before, + .#{$primary-stylename}-node-leaf > .#{$primary-stylename}-node-caption > div:before { visibility: hidden; } diff --git a/WebContent/VAADIN/themes/valo/components/_upload.scss b/WebContent/VAADIN/themes/valo/components/_upload.scss index 103c21b6fe..c54227c704 100644 --- a/WebContent/VAADIN/themes/valo/components/_upload.scss +++ b/WebContent/VAADIN/themes/valo/components/_upload.scss @@ -2,4 +2,15 @@ .#{$primary-stylename} .v-button { @include valo-widget-style; } + + .#{$primary-stylename}-immediate input[type="file"] { + @include opacity(0); + z-index: 2; + position: absolute; + right: 0; + height: $v-unit-size; + text-align: right; + border: none; + background: transparent; + } }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.eot Binary files differindex 5d20d91633..5d20d91633 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.ttf Binary files differindex 2109c958e3..2109c958e3 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.woff Binary files differindex 1205787b0e..1205787b0e 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.eot Binary files differindex 1f639a15ff..1f639a15ff 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.ttf Binary files differindex 242d6b25c3..242d6b25c3 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.woff Binary files differindex ed760c0628..ed760c0628 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.eot Binary files differindex 1e29ad5954..1e29ad5954 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.ttf Binary files differindex 6b9118ee35..6b9118ee35 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.woff Binary files differindex a7b99d2552..a7b99d2552 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.eot Binary files differindex 77184af422..77184af422 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.ttf Binary files differindex 26a07e9392..26a07e9392 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.woff Binary files differindex 45395d1bbe..45395d1bbe 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.eot Binary files differindex 0c8a0ae06e..0c8a0ae06e 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.ttf Binary files differindex 12d25d9a73..12d25d9a73 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.woff Binary files differindex ff652e6435..ff652e6435 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.eot Binary files differindex 14868406aa..14868406aa 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.ttf Binary files differindex 63af664cde..63af664cde 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.woff Binary files differindex e786074813..e786074813 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.eot Binary files differindex 8f445929ff..8f445929ff 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.ttf Binary files differindex 01dda2858a..01dda2858a 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.woff Binary files differindex 43e8b9e6cc..43e8b9e6cc 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.eot Binary files differindex 6bbc3cf58c..6bbc3cf58c 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.ttf Binary files differindex c537f8382a..c537f8382a 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.woff Binary files differindex e231183dce..e231183dce 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.eot Binary files differindex d8375dd0ab..d8375dd0ab 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.ttf Binary files differindex b3290843a7..b3290843a7 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.woff Binary files differindex 28d6adee03..28d6adee03 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.eot Binary files differindex 0ab1db22e6..0ab1db22e6 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.ttf Binary files differindex d2d6318f66..d2d6318f66 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.woff Binary files differindex d4dfca402e..d4dfca402e 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.woff diff --git a/WebContent/VAADIN/vaadinBootstrap.js b/WebContent/VAADIN/vaadinBootstrap.js index df46d8bc72..ced077138f 100644 --- a/WebContent/VAADIN/vaadinBootstrap.js +++ b/WebContent/VAADIN/vaadinBootstrap.js @@ -101,7 +101,7 @@ return value; }; - var fetchRootConfig = function() { + var fetchRootConfig = function(callback) { log('Fetching root config'); var url = getConfig('browserDetailsUrl'); if (!url) { @@ -141,6 +141,12 @@ r.open('POST', url, true); r.onreadystatechange = function (aEvt) { if (r.readyState == 4) { + // Save responseStatus so as Offline Applications know what happened + // when loading root configuration from server, and depending on the + // error status display an error message or the offline UI. + config.rootResponseStatus = r.status; + config.rootResponseText = r.responseText; + var text = r.responseText; if (r.status == 200){ log("Got root config response", text); @@ -166,6 +172,9 @@ appDiv.innerHTML = text; appDiv.style['overflow'] = 'auto'; } + + // Run the fetchRootConfig callback if present. + callback && callback(r); } }; // send parameters as POST data @@ -177,7 +186,10 @@ //Export public data var app = { - 'getConfig': getConfig + getConfig: getConfig, + // Used when the app was started in offline, so as it is possible + // to defer root configuration loading until network is available. + fetchRootConfig: fetchRootConfig }; apps[appId] = app; @@ -224,9 +236,17 @@ return app; }, clients: {}, + getAppIds: function() { + var ids = [ ]; + for (var id in apps) { + if (apps.hasOwnProperty(id)) { + ids.push(id); + } + } + return ids; + }, getApp: function(appId) { - var app = apps[appId]; - return app; + return apps[appId]; }, loadTheme: loadTheme, registerWidgetset: function(widgetset, callback) { diff --git a/WebContent/html-tests/BottomComponentScrollsUp.html b/WebContent/html-tests/BottomComponentScrollsUp.html new file mode 100644 index 0000000000..a264b38ba8 --- /dev/null +++ b/WebContent/html-tests/BottomComponentScrollsUp.html @@ -0,0 +1,96 @@ +<html> + +<head> +<title>Bottom component scroll when focus - test with plain html to see the default behaviour</title> +<link rel="stylesheet" type="text/css" href="./../VAADIN/themes/reindeer/styles.css"> + +<script> + +function setScrollOnPanel() { + var popups = document.getElementsByClassName("v-panel-content"); + popups[0].scrollTop = 756; + + console.log("popups[0]: " + popups[0].scrollTop); +} + +</script> + +</head> + +<body> + +<div id="runBottomComponentScrollsUp-1897366330-overlays" class="v-app reindeer v-overlay-container" aria-live="assertive" aria-label="This content is announced automatically and does not need to be navigated into." aria-relevant="additions"> + +<div class="v-tooltip" role="tooltip" aria-live="assertive" aria-relevant="additions" style="margin-left: 0px; margin-top: 0px; left: -4990px; top: -4990px; z-index: 20000; visibility: visible; position: absolute; overflow: visible;"> + +<div class="popupContent"><div><div class="v-errormessage" aria-hidden="true" style="display: none;"></div><div class="v-tooltip-text"> </div></div></div></div> + +<div class="v-window v-widget v-has-width v-has-height" role="dialog" aria-relevant="additions" aria-labelledby="gwt-uid-2" style="margin-left: 0px; margin-top: 0px; left: 400px; top: 19px; z-index: 10000; width: 300px; height: 300px; visibility: visible; position: absolute; overflow: visible; min-width: 66px; min-height: 52px;"> +<div class="popupContent"> +<div class="v-window-wrap"> + +<div tabindex="0" aria-label="Top of dialog"></div> + +<div class="v-window-outerheader"> +<div class="v-window-header" id="gwt-uid-2"> +<span class="v-assistive-device-only"></span> +<span class="v-assistive-device-only"></span> +</div> +</div> + +<div class="v-window-maximizebox" tabindex="0" role="button" aria-label="maximize button" id="28_window_maximizerestore"></div> +<div class="v-window-closebox" tabindex="0" role="button" aria-label="close button" id="28_window_close"></div> + +<div class="v-window-contents" style="padding-top: 37px; margin-top: -37px; padding-bottom: 15px; margin-bottom: -15px;"> +<div tabindex="0" class="v-scrollable" style="zoom: 1; position: relative;"> +<div class="v-panel v-widget v-has-width v-has-height" style="overflow: hidden; width: 100%; height: 100%; position: absolute; padding-top: 1px; padding-bottom: 1px;"> + +<div class="v-panel-captionwrap" style="margin-top: -1px;"> +<div class="v-panel-nocaption"><span></span> +</div> +</div> + +<div class="v-panel-content v-scrollable" tabindex="-1" style="position: relative;"> +<div class="v-verticallayout v-layout v-vertical v-widget v-has-width v-has-height" style="width: 100%; height: 1000px;"> + +<div class="v-expand" style="padding-top: 0px;"> + +<div class="v-slot" style="height: 50%; margin-top: 0px;"> +<div role="combobox" class="v-filterselect v-widget v-filterselect-prompt"> +<input type="text" class="v-filterselect-input" tabindex="0" style="width: 129px;"> +<div class="v-filterselect-button" aria-hidden="true" role="button"></div> +</div> +</div> + +<div class="v-slot v-align-center v-align-bottom" style="height: 50%;"> +<div tabindex="0" role="button" class="v-button v-widget v-has-height" style="height: 100px;" onclick="setScrollOnPanel();"> +<span class="v-button-wrap"><span class="v-button-caption">Press me</span></span> +</div> +</div> + +</div> + +</div> +</div> + +<div class="v-panel-deco" style="margin-bottom: -1px;"></div> + +</div> +</div> +</div> + +<div class="v-window-footer"> +<div class="v-window-resizebox"></div> +</div> + +<div tabindex="0" aria-label="Bottom of Dialog"></div> + +</div> +</div> +</div> + +</div> + +</body> + +</html>
\ No newline at end of file diff --git a/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html b/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html index 613bb2cd41..cb317dd755 100644 --- a/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html +++ b/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html @@ -11,7 +11,7 @@ </head> <body> - <script type="text/javascript" src="/VAADIN/vaadinBootstrap.js"></script> + <script type="text/javascript" src="../VAADIN/vaadinBootstrap.js"></script> <p>This is a static web page that contains an embedded Vaadin diff --git a/build.properties b/build.properties index 0c0e58cb53..488c2fa32f 100644 --- a/build.properties +++ b/build.properties @@ -5,6 +5,6 @@ vaadin.vendor=Vaadin Ltd vaadin.url=http://vaadin.com vaadin.java.version=1.6 vaadin.version=0.0.0.unversioned-development-build -vaadin.sass.version=0.9.8 +vaadin.sass.version=0.9.9 gwt.version=2.6.0.vaadin3 commons-io.version=2.4 diff --git a/build/ide.xml b/build/ide.xml index 0775a67505..fa8b85ee23 100755 --- a/build/ide.xml +++ b/build/ide.xml @@ -4,61 +4,77 @@ <property name="work.dir" location="work" /> <property file="build.properties" /> - <ivy:resolve log="download-only" file="client-compiler/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="client-compiler.deps" conf="ide" /> - <ivy:resolve log="download-only" file="server/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="server.deps" conf="ide" /> - <ivy:resolve log="download-only" file="client/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="client.deps" conf="ide" /> - <ivy:resolve log="download-only" file="shared/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="shared.deps" conf="ide" /> - <ivy:resolve log="download-only" file="uitest/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="uitest.deps" conf="ide" /> - <ivy:resolve log="download-only" file="buildhelpers/ivy.xml" /> - <ivy:cachepath pathid="buildhelpers.deps" /> - <ivy:resolve log="download-only" file="gwt/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="gwt.deps" conf="ide" /> - - <path id="classpath"> - <path location="bin" /> - <path location="build/classes" /> - <path refid="client-compiler.deps" /> - <path refid="server.deps" /> - <path refid="shared.deps" /> - <path refid="uitest.deps" /> - <path refid="client.deps" /> - <path refid="buildhelpers.deps" /> - <path refid="gwt.deps" /> - <path location="server/src" /> - <path location="shared/src" /> - <path location="uitest/src" /> - <path location="client/src" /> - </path> - - <target name="theme-and-default-widgetset" depends="default-widgetset, themes, vaadinPush.js"> + <!-- Setting this to 0 disables the parallel compilation --> + <property name="threadsPerProcessor" value="1" /> + + <target name="resolve" unless="resolve.done"> + <ivy:resolve log="download-only" file="client-compiler/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="client-compiler.deps" conf="ide" /> + <ivy:resolve log="download-only" file="server/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="server.deps" conf="ide" /> + <ivy:resolve log="download-only" file="client/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="client.deps" conf="ide" /> + <ivy:resolve log="download-only" file="shared/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="shared.deps" conf="ide" /> + <ivy:resolve log="download-only" file="uitest/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="uitest.deps" conf="ide" /> + <ivy:resolve log="download-only" file="buildhelpers/ivy.xml" /> + <ivy:cachepath pathid="buildhelpers.deps" /> + <ivy:resolve log="download-only" file="gwt/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="gwt.deps" conf="ide" /> + + <path id="classpath"> + <path location="bin" /> + <path location="build/classes" /> + <path refid="client-compiler.deps" /> + <path refid="server.deps" /> + <path refid="shared.deps" /> + <path refid="uitest.deps" /> + <path refid="client.deps" /> + <path refid="buildhelpers.deps" /> + <path refid="gwt.deps" /> + <path location="server/src" /> + <path location="shared/src" /> + <path location="uitest/src" /> + <path location="client/src" /> + </path> + <property name="resolve.done" value="true" /> </target> - <target name="themes"> - <antcall target="compile-theme"> - <param name="theme" value="base" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="runo" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="reindeer" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="chameleon" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="liferay" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="valo" /> - </antcall> + + <target name="theme-and-default-widgetset" depends="resolve"> + <!-- threadCount is ignored unless threadsPerProcessor is 0 --> + <parallel threadsPerProcessor="${threadsPerProcessor}" threadCount="1"> + <antcall target="default-widgetset" inheritRefs="true" /> + <antcall target="themes" inheritRefs="true" /> + <antcall target="vaadinPush.js" inheritRefs="true" /> + </parallel> + </target> + + <target name="themes" depends="resolve"> + <!-- threadCount is ignored unless threadsPerProcessor is 0 --> + <parallel threadsPerProcessor="${threadsPerProcessor}" threadCount="1"> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="base" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="runo" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="reindeer" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="chameleon" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="liferay" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="valo" /> + </antcall> + </parallel> </target> - <target name="compile-theme"> + <target name="compile-theme" depends="resolve"> <java classname="com.vaadin.buildhelpers.CompileTheme" failonerror="yes" fork="yes"> <classpath refid="classpath" /> <jvmarg value="-Djava.awt.headless=true" /> @@ -74,18 +90,18 @@ <target name="default-widgetset"> - <antcall target="compile-widgetset"> + <antcall target="compile-widgetset" inheritRefs="true"> <param name="widgetset" value="com.vaadin.DefaultWidgetSet" /> </antcall> </target> <target name="testing-widgetset"> - <antcall target="compile-widgetset"> + <antcall target="compile-widgetset" inheritRefs="true"> <param name="widgetset" value="com.vaadin.tests.widgetset.TestingWidgetSet" /> </antcall> </target> - <target name="compile-widgetset"> + <target name="compile-widgetset" depends="resolve"> <property name="module" value="${widgetset}" /> <property name="module.output.dir" location="WebContent/VAADIN/widgetsets" /> <property name="style" value="PRETTY" /> @@ -125,7 +141,7 @@ <jvmarg value="-Dgwt.persistentunitcache=false" /> </java> </target> - <target name="vaadinPush.js"> + <target name="vaadinPush.js" depends="resolve"> <ant antfile="${basedir}/push/build.xml" target="vaadinPush.js" dir="${basedir}/push" /> <property name="js.output.dir" location="WebContent" /> <property name="push.js.dir" location="${basedir}/push/result/js" /> diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java index ab930310aa..7c3bb1eb77 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java @@ -641,13 +641,18 @@ public class ConnectorBundleLoaderFactory extends Generator { private void writeDelegateToWidget(TreeLogger logger, SplittingSourceWriter w, ConnectorBundle bundle) { - Set<Property> needsDelegateToWidget = bundle.getNeedsDelegateToWidget(); - for (Property property : needsDelegateToWidget) { - w.println("store.setDelegateToWidget(%s, \"%s\", \"%s\");", - getClassLiteralString(property.getBeanType()), - property.getName(), - property.getAnnotation(DelegateToWidget.class).value()); - + Map<JClassType, Set<Property>> needsDelegateToWidget = bundle + .getNeedsDelegateToWidget(); + for (Entry<JClassType, Set<Property>> entry : needsDelegateToWidget + .entrySet()) { + JClassType beanType = entry.getKey(); + for (Property property : entry.getValue()) { + w.println( + "store.setDelegateToWidget(%s, \"%s\", \"%s\");", + getClassLiteralString(beanType),// property.getBeanType()), + property.getName(), + property.getAnnotation(DelegateToWidget.class).value()); + } w.splitIfNeeded(); } } diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java index 80456cdf10..4a079c38b0 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -38,6 +38,7 @@ import com.google.gwt.core.ext.typeinfo.JType; import com.google.gwt.core.ext.typeinfo.NotFoundException; import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.json.client.JSONValue; +import com.google.gwt.thirdparty.guava.common.collect.Sets; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ServerConnector; @@ -74,7 +75,7 @@ public class ConnectorBundle { private final Map<JClassType, Set<JMethod>> needsOnStateChange = new HashMap<JClassType, Set<JMethod>>(); private final Set<Property> needsProperty = new HashSet<Property>(); - private final Set<Property> needsDelegateToWidget = new HashSet<Property>(); + private final Map<JClassType, Set<Property>> needsDelegateToWidget = new HashMap<JClassType, Set<Property>>(); private ConnectorBundle(String name, ConnectorBundle previousBundle, Collection<TypeVisitor> visitors, @@ -593,23 +594,25 @@ public class ConnectorBundle { } } - public void setNeedsDelegateToWidget(Property property) { - if (!isNeedsDelegateToWidget(property)) { - needsDelegateToWidget.add(property); + public void setNeedsDelegateToWidget(Property property, JClassType type) { + if (!isNeedsDelegateToWidget(type)) { + needsDelegateToWidget.put(type, Sets.newHashSet(property)); + } else if (!needsDelegateToWidget.get(type).contains(property)) { + needsDelegateToWidget.get(type).add(property); } } - private boolean isNeedsDelegateToWidget(Property property) { - if (needsDelegateToWidget.contains(property)) { + private boolean isNeedsDelegateToWidget(JClassType type) { + if (needsDelegateToWidget.containsKey(type)) { return true; } else { return previousBundle != null - && previousBundle.isNeedsDelegateToWidget(property); + && previousBundle.isNeedsDelegateToWidget(type); } } - public Set<Property> getNeedsDelegateToWidget() { - return Collections.unmodifiableSet(needsDelegateToWidget); + public Map<JClassType, Set<Property>> getNeedsDelegateToWidget() { + return Collections.unmodifiableMap(needsDelegateToWidget); } public void setNeedsOnStateChangeHandler(JClassType type, JMethod method) { diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java index e3fee8d9ee..a77b523d14 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java @@ -59,7 +59,7 @@ public class WidgetInitVisitor extends TypeVisitor { .getAnnotation(DelegateToWidget.class); if (delegateToWidget != null) { // Generate meta data required for @DelegateToWidget - bundle.setNeedsDelegateToWidget(property); + bundle.setNeedsDelegateToWidget(property, stateType); // Find the delegate target method String methodName = DelegateToWidget.Helper diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java index 3ccbeba6f3..87c8ea465f 100644 --- a/client/src/com/vaadin/client/ApplicationConfiguration.java +++ b/client/src/com/vaadin/client/ApplicationConfiguration.java @@ -51,6 +51,7 @@ import com.vaadin.client.metadata.ConnectorBundleLoader; import com.vaadin.client.metadata.NoDataException; import com.vaadin.client.metadata.TypeData; import com.vaadin.client.ui.UnknownComponentConnector; +import com.vaadin.client.ui.ui.UIConnector; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.ui.ui.UIConstants; @@ -84,7 +85,7 @@ public class ApplicationConfiguration implements EntryPoint { return null; } else { return value +""; - } + } }-*/; /** @@ -105,7 +106,7 @@ public class ApplicationConfiguration implements EntryPoint { } else { // $entry not needed as function is not exported return @java.lang.Boolean::valueOf(Z)(value); - } + } }-*/; /** @@ -126,7 +127,7 @@ public class ApplicationConfiguration implements EntryPoint { } else { // $entry not needed as function is not exported return @java.lang.Integer::valueOf(I)(value); - } + } }-*/; /** @@ -285,14 +286,16 @@ public class ApplicationConfiguration implements EntryPoint { return serviceUrl; } + /** + * @return the theme name used when initializing the application + * @deprecated as of 7.3. Use {@link UIConnector#getActiveTheme()} to get + * the theme currently in use + */ + @Deprecated public String getThemeName() { return getJsoConfiguration(id).getConfigString("theme"); } - public String getThemeUri() { - return getVaadinDirUrl() + "themes/" + getThemeName(); - } - /** * Gets the URL of the VAADIN directory on the server. * diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index 6abcdac487..90aa0a14d6 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -66,7 +66,6 @@ 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; @@ -599,14 +598,23 @@ public class ApplicationConnection implements HasHandlers { } } + /** + * Checks if there is some work to be done on the client side + * + * @return true if the client has some work to be done, false otherwise + */ + private boolean isActive() { + return isWorkPending() || hasActiveRequest() + || isExecutingDeferredCommands(); + } + private native void initializeTestbenchHooks( ComponentLocator componentLocator, String TTAppId) /*-{ var ap = this; var client = {}; client.isActive = $entry(function() { - return ap.@com.vaadin.client.ApplicationConnection::hasActiveRequest()() - || ap.@com.vaadin.client.ApplicationConnection::isExecutingDeferredCommands()(); + return ap.@com.vaadin.client.ApplicationConnection::isActive()(); }); var vi = ap.@com.vaadin.client.ApplicationConnection::getVersionInfo()(); if (vi) { @@ -810,7 +818,8 @@ public class ApplicationConnection implements HasHandlers { startRequest(); JSONObject payload = new JSONObject(); - if (!getCsrfToken().equals(ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE)) { + if (!getCsrfToken().equals( + ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE)) { payload.put(ApplicationConstants.CSRF_TOKEN, new JSONString( getCsrfToken())); } @@ -1320,6 +1329,30 @@ public class ApplicationConnection implements HasHandlers { } /** + * Checks if the client has running or scheduled commands + */ + private boolean isWorkPending() { + ConnectorMap connectorMap = getConnectorMap(); + JsArrayObject<ServerConnector> connectors = connectorMap + .getConnectorsAsJsArray(); + int size = connectors.size(); + for (int i = 0; i < size; i++) { + ServerConnector conn = connectors.get(i); + ComponentConnector compConn = null; + if (conn instanceof ComponentConnector) { + compConn = (ComponentConnector) conn; + Widget wgt = compConn.getWidget(); + if (wgt instanceof DeferredWorker) { + if (((DeferredWorker) wgt).isWorkPending()) { + return true; + } + } + } + } + return false; + } + + /** * Checks if deferred commands are (potentially) still being executed as a * result of an update from the server. Returns true if a deferred command * might still be executing, false otherwise. This will not work correctly @@ -1483,6 +1516,7 @@ public class ApplicationConnection implements HasHandlers { if (json.containsKey("typeMappings")) { configuration.addComponentMappings( json.getValueMap("typeMappings"), widgetSet); + } VConsole.log("Handling resource dependencies"); @@ -1717,6 +1751,7 @@ public class ApplicationConnection implements HasHandlers { for (int i = 0; i < needsUpdateLength; i++) { String childId = dump.get(i); ServerConnector child = connectorMap.getConnector(childId); + if (child instanceof ComponentConnector && ((ComponentConnector) child) .delegateCaptionHandling()) { @@ -3110,7 +3145,7 @@ public class ApplicationConnection implements HasHandlers { return null; } if (uidlUri.startsWith("theme://")) { - final String themeUri = configuration.getThemeUri(); + final String themeUri = getThemeUri(); if (themeUri == null) { VConsole.error("Theme not set: ThemeResource will not be found. (" + uidlUri + ")"); @@ -3176,7 +3211,8 @@ public class ApplicationConnection implements HasHandlers { * @return URI to the current theme */ public String getThemeUri() { - return configuration.getThemeUri(); + return configuration.getVaadinDirUrl() + "themes/" + + getUIConnector().getActiveTheme(); } /** diff --git a/client/src/com/vaadin/client/DeferredWorker.java b/client/src/com/vaadin/client/DeferredWorker.java new file mode 100644 index 0000000000..53f7c79fe6 --- /dev/null +++ b/client/src/com/vaadin/client/DeferredWorker.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.client; + +/** + * Give widgets the possibility to indicate to the framework that there is work + * scheduled to be executed in the near future and that the framework should + * wait for this work to complete before assuming the UI has reached a steady + * state. + */ +public interface DeferredWorker { + /** + * @returns true, if there are operations pending which must be executed + * before reaching a steady state + */ + public boolean isWorkPending(); +} diff --git a/client/src/com/vaadin/client/ResourceLoader.java b/client/src/com/vaadin/client/ResourceLoader.java index 68a16e8162..ceede263fc 100644 --- a/client/src/com/vaadin/client/ResourceLoader.java +++ b/client/src/com/vaadin/client/ResourceLoader.java @@ -375,7 +375,20 @@ public class ResourceLoader { } } - private native void addOnloadHandler(Element element, + /** + * Adds an onload listener to the given element, which should be a link or a + * script tag. The listener is called whenever loading is complete or an + * error occurred. + * + * @since 7.3 + * @param element + * the element to attach a listener to + * @param listener + * the listener to call + * @param event + * the event passed to the listener + */ + public static native void addOnloadHandler(Element element, ResourceLoadListener listener, ResourceLoadEvent event) /*-{ element.onload = $entry(function() { @@ -390,11 +403,11 @@ public class ResourceLoader { element.onreadystatechange = null; listener.@com.vaadin.client.ResourceLoader.ResourceLoadListener::onError(Lcom/vaadin/client/ResourceLoader$ResourceLoadEvent;)(event); }); - element.onreadystatechange = function() { + element.onreadystatechange = function() { if ("loaded" === element.readyState || "complete" === element.readyState ) { element.onload(arguments[0]); } - }; + }; }-*/; /** @@ -520,12 +533,12 @@ public class ResourceLoader { if (rules === undefined) { rules = sheet.rules; } - + if (rules === null) { // Style sheet loaded, but can't access length because of XSS -> assume there's something there return 1; } - + // Return length so we can distinguish 0 (probably 404 error) from normal case. return rules.length; } catch (err) { diff --git a/client/src/com/vaadin/client/Util.java b/client/src/com/vaadin/client/Util.java index f175bbe714..49c862006b 100644 --- a/client/src/com/vaadin/client/Util.java +++ b/client/src/com/vaadin/client/Util.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -16,11 +16,14 @@ package com.vaadin.client; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -36,6 +39,8 @@ import com.google.gwt.dom.client.Style.Display; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.Touch; import com.google.gwt.event.dom.client.KeyEvent; +import com.google.gwt.regexp.shared.MatchResult; +import com.google.gwt.regexp.shared.RegExp; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; @@ -56,9 +61,9 @@ public class Util { /** * Helper method for debugging purposes. - * + * * Stops execution on firefox browsers on a breakpoint. - * + * */ public static native void browserDebugger() /*-{ @@ -86,10 +91,10 @@ public class Util { /** * * Returns the topmost element of from given coordinates. - * + * * TODO fix crossplat issues clientX vs pageX. See quircksmode. Not critical * for vaadin as we scroll div istead of page. - * + * * @param x * @param y * @return the element at given coordinates @@ -98,7 +103,7 @@ public class Util { int clientX, int clientY) /*-{ var el = $wnd.document.elementFromPoint(clientX, clientY); - // Call elementFromPoint two times to make sure IE8 also returns something sensible if the application is running in an iframe + // Call elementFromPoint two times to make sure IE8 also returns something sensible if the application is running in an iframe el = $wnd.document.elementFromPoint(clientX, clientY); if(el != null && el.nodeType == 3) { el = el.parentNode; @@ -110,18 +115,18 @@ public class Util { * This helper method can be called if components size have been changed * outside rendering phase. It notifies components parent about the size * change so it can react. - * + * * When using this method, developer should consider if size changes could * be notified lazily. If lazy flag is true, method will save widget and * wait for a moment until it notifies parents in chunks. This may vastly * optimize layout in various situation. Example: if component have a lot of * images their onload events may fire "layout phase" many times in a short * period. - * + * * @param widget * @param lazy * run componentSizeUpdated lazyly - * + * * @deprecated As of 7.0, use * {@link LayoutManager#setNeedsMeasure(ComponentConnector)} * instead @@ -171,7 +176,7 @@ public class Util { /** * Converts html entities to text. - * + * * @param html * @return escaped string presentation of given html */ @@ -189,7 +194,7 @@ public class Util { /** * Escapes the string so it is safe to write inside an HTML attribute. - * + * * @param attribute * The string to escape * @return An escaped version of <literal>attribute</literal>. @@ -208,9 +213,9 @@ public class Util { /** * Clones given element as in JavaScript. - * + * * Deprecate this if there appears similar method into GWT someday. - * + * * @param element * @param deep * clone child tree also @@ -469,10 +474,28 @@ public class Util { } /** - * Run workaround for webkits overflow auto issue. + * Defers the execution of {@link #runWebkitOverflowAutoFix(Element)} * + * @since + * @param elem + * with overflow auto + */ + public static void runWebkitOverflowAutoFixDeferred(final Element elem) { + Scheduler.get().scheduleDeferred(new Command() { + + @Override + public void execute() { + Util.runWebkitOverflowAutoFix(elem); + } + }); + + } + + /** + * Run workaround for webkits overflow auto issue. + * * See: our bug #2138 and https://bugs.webkit.org/show_bug.cgi?id=21462 - * + * * @param elem * with overflow auto */ @@ -543,7 +566,7 @@ public class Util { * dimension is not specified as relative it will return -1. If the shared * state does not contain width or height specifications this will return * null. - * + * * @param state * @return */ @@ -576,7 +599,7 @@ public class Util { * Checks if a and b are equals using {@link #equals(Object)}. Handles null * values as well. Does not ensure that objects are of the same type. * Assumes that the first object's equals method handle equals properly. - * + * * @param a * The first value to compare * @param b @@ -597,7 +620,7 @@ public class Util { /** * Gets the border-box width for the given element, i.e. element width + * border + padding. Always rounds up to nearest integer. - * + * * @param element * The element to check * @return The border-box width for the element @@ -622,7 +645,7 @@ public class Util { /** * Gets the border-box height for the given element, i.e. element height + * border + padding. Always rounds up to nearest integer. - * + * * @param element * The element to check * @return The border-box height for the element @@ -669,7 +692,7 @@ public class Util { var borderBottomPx = cs.borderBottom; var paddingTopPx = cs.paddingTop; var paddingBottomPx = cs.paddingBottom; - + var height = heightPx.substring(0,heightPx.length-2); var border = borderTopPx.substring(0,borderTopPx.length-2)+borderBottomPx.substring(0,borderBottomPx.length-2); var padding = paddingTopPx.substring(0,paddingTopPx.length-2)+paddingBottomPx.substring(0,paddingBottomPx.length-2); @@ -689,7 +712,7 @@ public class Util { var borderRightPx = cs.borderRight; var paddingLeftPx = cs.paddingLeft; var paddingRightPx = cs.paddingRight; - + var width = widthPx.substring(0,widthPx.length-2); var border = borderLeftPx.substring(0,borderLeftPx.length-2)+borderRightPx.substring(0,borderRightPx.length-2); var padding = paddingLeftPx.substring(0,paddingLeftPx.length-2)+paddingRightPx.substring(0,paddingRightPx.length-2); @@ -719,7 +742,7 @@ public class Util { /** * Detects what is currently the overflow style attribute in given element. - * + * * @param pe * the element to detect * @return true if auto or scroll @@ -741,7 +764,7 @@ public class Util { * A simple helper method to detect "computed style" (aka style sheets + * element styles). Values returned differ a lot depending on browsers. * Always be very careful when using this. - * + * * @param el * the element from which the style property is detected * @param p @@ -752,7 +775,7 @@ public class Util { com.google.gwt.dom.client.Element el, String p) /*-{ try { - + if (el.currentStyle) { // IE return el.currentStyle[p]; @@ -776,9 +799,9 @@ public class Util { * also returned if "element" is part of its caption. If * <literal>element</literal> is not part of any child component, null is * returned. - * + * * This method returns the deepest nested VPaintableWidget. - * + * * @param client * A reference to ApplicationConnection * @param parent @@ -836,7 +859,7 @@ public class Util { /** * Will (attempt) to focus the given DOM Element. - * + * * @param el * the element to focus */ @@ -852,7 +875,7 @@ public class Util { /** * Helper method to find the nearest parent paintable instance by traversing * the DOM upwards from given element. - * + * * @param element * the element to start from */ @@ -870,7 +893,7 @@ public class Util { /** * Helper method to find first instance of given Widget type found by * traversing DOM upwards from given element. - * + * * @param element * the element where to start seeking of Widget * @param class1 @@ -907,7 +930,7 @@ public class Util { /** * Force webkit to redraw an element - * + * * @param element * The element that should be redrawn */ @@ -953,9 +976,9 @@ public class Util { /** * Detaches and re-attaches the element from its parent. The element is * reattached at the same position in the DOM as it was before. - * + * * Does nothing if the element is not attached to the DOM. - * + * * @param element * The element to detach and re-attach */ @@ -990,7 +1013,7 @@ public class Util { /** * Returns the index of the childElement within its parent. - * + * * @param subElement * @return */ @@ -1066,7 +1089,7 @@ public class Util { * Temporarily sets the {@code styleProperty} to {@code tempValue} and then * resets it to its current value. Used mainly to work around rendering * issues in IE (and possibly in other browsers) - * + * * @param element * The target element * @param styleProperty @@ -1089,7 +1112,7 @@ public class Util { * A helper method to return the client position from an event. Returns * position from either first changed touch (if touch event) or from the * event itself. - * + * * @param event * @return */ @@ -1105,7 +1128,7 @@ public class Util { * Find the element corresponding to the coordinates in the passed mouse * event. Please note that this is not always the same as the target of the * event e.g. if event capture is used. - * + * * @param event * the mouse event to get coordinates from * @return the element at the coordinates of the event @@ -1122,7 +1145,7 @@ public class Util { * A helper method to return the client position from an event. Returns * position from either first changed touch (if touch event) or from the * event itself. - * + * * @param event * @return */ @@ -1135,7 +1158,7 @@ public class Util { } /** - * + * * @see #getTouchOrMouseClientY(Event) * @param currentGwtEvent * @return @@ -1146,7 +1169,7 @@ public class Util { /** * @see #getTouchOrMouseClientX(Event) - * + * * @param event * @return */ @@ -1215,7 +1238,7 @@ public class Util { /** * Gets the currently focused element. - * + * * @return The active element or null if no active element could be found. */ public native static com.google.gwt.user.client.Element getFocusedElement() @@ -1223,13 +1246,13 @@ public class Util { if ($wnd.document.activeElement) { return $wnd.document.activeElement; } - + return null; }-*/; /** * Gets the currently focused element for Internet Explorer. - * + * * @return The currently focused element * @deprecated Use #getFocusedElement instead */ @@ -1243,7 +1266,7 @@ public class Util { * this method checks that this widget nor any of its parents is hidden. Can * be e.g used to check whether component should react to some events or * not. - * + * * @param widget * @return true if attached and displayed */ @@ -1276,7 +1299,7 @@ public class Util { /** * Scrolls an element into view vertically only. Modified version of * Element.scrollIntoView. - * + * * @param elem * The element to scroll into view */ @@ -1284,11 +1307,11 @@ public class Util { /*-{ var top = elem.offsetTop; var height = elem.offsetHeight; - + if (elem.parentNode != elem.offsetParent) { top -= elem.parentNode.offsetTop; } - + var cur = elem.parentNode; while (cur && (cur.nodeType == 1)) { if (top < cur.scrollTop) { @@ -1297,12 +1320,12 @@ public class Util { if (top + height > cur.scrollTop + cur.clientHeight) { cur.scrollTop = (top + height) - cur.clientHeight; } - + var offsetTop = cur.offsetTop; if (cur.parentNode != cur.offsetParent) { offsetTop -= cur.parentNode.offsetTop; } - + top += offsetTop - cur.scrollTop; cur = cur.parentNode; } @@ -1311,7 +1334,7 @@ public class Util { /** * Checks if the given event is either a touch event or caused by the left * mouse button - * + * * @param event * @return true if the event is a touch event or caused by the left mouse * button, false otherwise @@ -1323,7 +1346,7 @@ public class Util { /** * Performs a shallow comparison of the collections. - * + * * @param collection1 * The first collection * @param collection2 @@ -1369,7 +1392,7 @@ public class Util { /** * Resolve a relative URL to an absolute URL based on the current document's * location. - * + * * @param url * a string with the relative URL to resolve * @return the corresponding absolute URL as a string @@ -1396,4 +1419,161 @@ public class Util { } } + /** + * Wrap a css size value and its unit and translate back and forth to the + * string representation.<br/> + * Eg. 50%, 123px, ... + * + * @since + * @author Vaadin Ltd + */ + @SuppressWarnings("serial") + public static class CssSize implements Serializable { + + /* + * Map the size units with their type. + */ + private static Map<String, Unit> type2Unit = new HashMap<String, Style.Unit>(); + static { + for (Unit unit : Unit.values()) { + type2Unit.put(unit.getType(), unit); + } + } + + /** + * Gets the unit value by its type. + * + * @since + * @param type + * the type of the unit as found in the style. + * @return the unit value. + */ + public static Unit unitByType(String type) { + return type2Unit.get(type); + } + + /* + * Regex to parse the size. + */ + private static final RegExp sizePattern = RegExp + .compile(SharedUtil.SIZE_PATTERN); + + /** + * Parse the size from string format to {@link CssSize}. + * + * @param s + * the size as string. + * @return a {@link CssSize} object. + */ + public static CssSize fromString(String s) { + if (s == null) { + return null; + } + + s = s.trim(); + if ("".equals(s)) { + return null; + } + + float size = 0; + Unit unit = null; + + MatchResult matcher = sizePattern.exec(s); + if (matcher.getGroupCount() > 1) { + + size = Float.parseFloat(matcher.getGroup(1)); + if (size < 0) { + size = -1; + unit = Unit.PX; + + } else { + String symbol = matcher.getGroup(2); + unit = unitByType(symbol); + } + } else { + throw new IllegalArgumentException("Invalid size argument: \"" + + s + "\" (should match " + sizePattern.getSource() + + ")"); + } + return new CssSize(size, unit); + } + + /** + * Creates a {@link CssSize} using a value and its measurement unit. + * + * @since + * @param value + * the value. + * @param unit + * the unit. + * @return the {@link CssSize} object. + */ + public static CssSize fromValueUnit(float value, Unit unit) { + return new CssSize(value, unit); + } + + /* + * The value. + */ + private final float value; + + /* + * The measure unit. + */ + private final Unit unit; + + private CssSize(float value, Unit unit) { + this.value = value; + this.unit = unit; + } + + /** + * Gets the value for this css size. + * + * @return the value. + */ + public float getValue() { + return value; + } + + /** + * Gets the measurement unit for this css size. + * + * @return the unit. + */ + public Unit getUnit() { + return unit; + } + + @Override + public String toString() { + return value + unit.getType(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof CssSize) { + CssSize size = (CssSize) obj; + return size.value == value && size.unit == unit; + } + + return false; + } + + /** + * Check whether the two sizes are equals. + * + * @since + * @param cssSize1 + * the first size to compare. + * @param cssSize2 + * the other size to compare with the first one. + * @return true if the two sizes are equals, otherwise false. + */ + public static boolean equals(String cssSize1, String cssSize2) { + return CssSize.fromString(cssSize1).equals(CssSize.fromString(cssSize2)); + } + + } + } diff --git a/client/src/com/vaadin/client/communication/Heartbeat.java b/client/src/com/vaadin/client/communication/Heartbeat.java index 1ff0825f0e..b9493d4520 100644 --- a/client/src/com/vaadin/client/communication/Heartbeat.java +++ b/client/src/com/vaadin/client/communication/Heartbeat.java @@ -124,7 +124,9 @@ public class Heartbeat { @Override public void onError(Request request, Throwable exception) { - getLogger().severe("Exception sending heartbeat: " + exception.getMessage()); + getLogger().severe( + "Exception sending heartbeat: " + + exception.getMessage()); // Notify network observers about response status connection.fireEvent(new ConnectionStatusEvent(0)); // Don't break the loop diff --git a/client/src/com/vaadin/client/communication/TranslatedURLReference.java b/client/src/com/vaadin/client/communication/TranslatedURLReference.java new file mode 100644 index 0000000000..b99f4c6e32 --- /dev/null +++ b/client/src/com/vaadin/client/communication/TranslatedURLReference.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.communication; + +import com.vaadin.client.ApplicationConnection; +import com.vaadin.shared.communication.URLReference; + +/** + * A URLReference implementation which does late URL translation to be able to + * re-translate URLs if e.g. the theme changes + * + * @since 7.3 + * @author Vaadin Ltd + */ +public class TranslatedURLReference extends URLReference { + + private ApplicationConnection connection; + + /** + * @param connection + * the connection to set + */ + public void setConnection(ApplicationConnection connection) { + this.connection = connection; + } + + @Override + public String getURL() { + return connection.translateVaadinUri(super.getURL()); + } + +} diff --git a/client/src/com/vaadin/client/communication/URLReference_Serializer.java b/client/src/com/vaadin/client/communication/URLReference_Serializer.java index 586dd626f0..4ecdc606d2 100644 --- a/client/src/com/vaadin/client/communication/URLReference_Serializer.java +++ b/client/src/com/vaadin/client/communication/URLReference_Serializer.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -30,14 +30,16 @@ public class URLReference_Serializer implements JSONSerializer<URLReference> { @Override public URLReference deserialize(Type type, JSONValue jsonValue, ApplicationConnection connection) { - URLReference reference = GWT.create(URLReference.class); + TranslatedURLReference reference = GWT + .create(TranslatedURLReference.class); + reference.setConnection(connection); JSONObject json = (JSONObject) jsonValue; if (json.containsKey(URL_FIELD)) { JSONValue jsonURL = json.get(URL_FIELD); String URL = (String) JsonDecoder.decodeValue( new Type(String.class.getName(), null), jsonURL, null, connection); - reference.setURL(connection.translateVaadinUri(URL)); + reference.setURL(URL); } return reference; } diff --git a/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java b/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java index 6eb732bf46..15a156a815 100644 --- a/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java +++ b/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java @@ -87,8 +87,7 @@ public interface LocatorStrategy { * @return The DOM element identified by {@code path} or null if the element * could not be located. */ - Element getElementByPathStartingAt(String path, - Element root); + Element getElementByPathStartingAt(String path, Element root); /** * Locates all elements that match a String locator (path) which identifies @@ -119,6 +118,5 @@ public interface LocatorStrategy { * found. */ - List<Element> getElementsByPathStartingAt( - String path, Element root); + List<Element> getElementsByPathStartingAt(String path, Element root); } diff --git a/client/src/com/vaadin/client/debug/internal/HierarchySection.java b/client/src/com/vaadin/client/debug/internal/HierarchySection.java index 1eacf286e8..404ac430df 100644 --- a/client/src/com/vaadin/client/debug/internal/HierarchySection.java +++ b/client/src/com/vaadin/client/debug/internal/HierarchySection.java @@ -108,16 +108,14 @@ public class HierarchySection implements Section { hierarchyPanel.addListener(new SelectConnectorListener() { @Override - public void select(ServerConnector connector, - Element element) { + public void select(ServerConnector connector, Element element) { printState(connector, true); } }); analyzeLayoutsPanel.addListener(new SelectConnectorListener() { @Override - public void select(ServerConnector connector, - Element element) { + public void select(ServerConnector connector, Element element) { printState(connector, true); } }); diff --git a/client/src/com/vaadin/client/debug/internal/InfoSection.java b/client/src/com/vaadin/client/debug/internal/InfoSection.java index 23b77a94db..a7a84f5f8f 100644 --- a/client/src/com/vaadin/client/debug/internal/InfoSection.java +++ b/client/src/com/vaadin/client/debug/internal/InfoSection.java @@ -163,7 +163,7 @@ public class InfoSection implements Section { addVersionInfo(configuration); addRow("Widget set", GWT.getModuleName()); - addRow("Theme", connection.getConfiguration().getThemeName()); + addRow("Theme", connection.getUIConnector().getActiveTheme()); String communicationMethodInfo = connection .getCommunicationMethodName(); diff --git a/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java b/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java index c3652c78e8..46c8070b30 100644 --- a/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java +++ b/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java @@ -33,6 +33,5 @@ public interface SelectConnectorListener { * @param element * selected element of the connector or null if unknown */ - public void select(ServerConnector connector, - Element element); + public void select(ServerConnector connector, Element element); } diff --git a/client/src/com/vaadin/client/ui/AbstractConnector.java b/client/src/com/vaadin/client/ui/AbstractConnector.java index a2e0d9cd54..e93ea0f507 100644 --- a/client/src/com/vaadin/client/ui/AbstractConnector.java +++ b/client/src/com/vaadin/client/ui/AbstractConnector.java @@ -28,6 +28,7 @@ import com.google.gwt.event.shared.HandlerManager; import com.google.web.bindery.event.shared.HandlerRegistration; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.FastStringMap; +import com.vaadin.client.FastStringSet; import com.vaadin.client.JsArrayObject; import com.vaadin.client.Profiler; import com.vaadin.client.ServerConnector; @@ -479,4 +480,27 @@ public abstract class AbstractConnector implements ServerConnector, Set<String> reg = getState().registeredEventListeners; return (reg != null && reg.contains(eventIdentifier)); } + + /** + * Force the connector to recheck its state variables as the variables or + * their meaning might have changed. + * + * @since 7.3 + */ + public void forceStateChange() { + StateChangeEvent event = new FullStateChangeEvent(this); + fireEvent(event); + } + + private static class FullStateChangeEvent extends StateChangeEvent { + public FullStateChangeEvent(ServerConnector connector) { + super(connector, FastStringSet.create()); + } + + @Override + public boolean hasPropertyChanged(String property) { + return true; + } + + } } diff --git a/client/src/com/vaadin/client/ui/VCalendarPanel.java b/client/src/com/vaadin/client/ui/VCalendarPanel.java index eaa2292c69..6fc06bb153 100644 --- a/client/src/com/vaadin/client/ui/VCalendarPanel.java +++ b/client/src/com/vaadin/client/ui/VCalendarPanel.java @@ -786,6 +786,21 @@ public class VCalendarPanel extends FocusableFlexTable implements * Updates the calendar and text field with the selected dates. */ public void renderCalendar() { + renderCalendar(true); + } + + /** + * For internal use only. May be removed or replaced in the future. + * + * Updates the calendar and text field with the selected dates. + * + * @param updateDate + * The value false prevents setting the selected date of the + * calendar based on focusedDate. That can be used when only the + * resolution of the calendar is changed and no date has been + * selected. + */ + public void renderCalendar(boolean updateDate) { super.setStylePrimaryName(parent.getStylePrimaryName() + "-calendarpanel"); @@ -798,8 +813,9 @@ public class VCalendarPanel extends FocusableFlexTable implements displayedMonth = new FocusedDate(now.getYear(), now.getMonth(), 1); } - if (getResolution().getCalendarField() <= Resolution.MONTH - .getCalendarField() && focusChangeListener != null) { + if (updateDate + && getResolution().getCalendarField() <= Resolution.MONTH + .getCalendarField() && focusChangeListener != null) { focusChangeListener.focusChanged(new Date(focusedDate.getTime())); } diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java index 7f67c39500..6ba0785acc 100644 --- a/client/src/com/vaadin/client/ui/VFilterSelect.java +++ b/client/src/com/vaadin/client/ui/VFilterSelect.java @@ -46,6 +46,7 @@ import com.google.gwt.event.dom.client.LoadEvent; import com.google.gwt.event.dom.client.LoadHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; +import com.google.gwt.i18n.client.HasDirection.Direction; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; @@ -62,6 +63,7 @@ import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; import com.vaadin.client.ComponentConnector; +import com.vaadin.client.ComputedStyle; import com.vaadin.client.ConnectorMap; import com.vaadin.client.Focusable; import com.vaadin.client.UIDL; @@ -252,7 +254,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, /** * Shows the popup where the user can see the filtered options - * + * * @param currentSuggestions * The filtered suggestions * @param currentPage @@ -264,10 +266,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, final Collection<FilterSelectSuggestion> currentSuggestions, final int currentPage, final int totalSuggestions) { - if (enableDebug) { - debug("VFS.SP: showSuggestions(" + currentSuggestions + ", " - + currentPage + ", " + totalSuggestions + ")"); - } + debug("VFS.SP: showSuggestions(" + currentSuggestions + ", " + + currentPage + ", " + totalSuggestions + ")"); /* * We need to defer the opening of the popup so that the parent DOM @@ -316,8 +316,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, status.setInnerText(""); } // We don't need to show arrows or statusbar if there is - // only one - // page + // only one page if (totalSuggestions <= pageLength || pageLength == 0) { setPagingEnabled(false); } else { @@ -346,7 +345,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, /** * Should the next page button be visible to the user? - * + * * @param active */ private void setNextButtonActive(boolean active) { @@ -366,7 +365,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, /** * Should the previous page button be visible to the user - * + * * @param active */ private void setPrevButtonActive(boolean active) { @@ -391,18 +390,13 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, */ public void selectNextItem() { debug("VFS.SP: selectNextItem()"); - final MenuItem cur = menu.getSelectedItem(); - final int index = 1 + menu.getItems().indexOf(cur); + + final int index = menu.getSelectedIndex() + 1; if (menu.getItems().size() > index) { - final MenuItem newSelectedItem = menu.getItems().get(index); - menu.selectItem(newSelectedItem); - tb.setText(newSelectedItem.getText()); - tb.setSelectionRange(lastFilter.length(), newSelectedItem - .getText().length() - lastFilter.length()); - - } else if (hasNextPage()) { - selectPopupItemWhenResponseIsReceived = Select.FIRST; - filterOptions(currentPage + 1, lastFilter); + selectItem(menu.getItems().get(index)); + + } else { + selectNextPage(); } } @@ -411,29 +405,59 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, */ public void selectPrevItem() { debug("VFS.SP: selectPrevItem()"); - final MenuItem cur = menu.getSelectedItem(); - final int index = -1 + menu.getItems().indexOf(cur); + + final int index = menu.getSelectedIndex() - 1; if (index > -1) { - final MenuItem newSelectedItem = menu.getItems().get(index); - menu.selectItem(newSelectedItem); - tb.setText(newSelectedItem.getText()); - tb.setSelectionRange(lastFilter.length(), newSelectedItem - .getText().length() - lastFilter.length()); + selectItem(menu.getItems().get(index)); + } else if (index == -1) { - if (currentPage > 0) { - selectPopupItemWhenResponseIsReceived = Select.LAST; - filterOptions(currentPage - 1, lastFilter); - } + selectPrevPage(); + } else { - final MenuItem newSelectedItem = menu.getItems().get( - menu.getItems().size() - 1); - menu.selectItem(newSelectedItem); - tb.setText(newSelectedItem.getText()); - tb.setSelectionRange(lastFilter.length(), newSelectedItem - .getText().length() - lastFilter.length()); + selectItem(menu.getItems().get(menu.getItems().size() - 1)); } } + /** + * Select the first item of the suggestions list popup. + * + * @since + */ + public void selectFirstItem() { + debug("VFS.SP: selectFirstItem()"); + selectItem(menu.getFirstItem()); + } + + /** + * Select the last item of the suggestions list popup. + * + * @since + */ + public void selectLastItem() { + debug("VFS.SP: selectLastItem()"); + selectItem(menu.getLastItem()); + } + + /* + * Sets the selected item in the popup menu. + */ + private void selectItem(final MenuItem newSelectedItem) { + menu.selectItem(newSelectedItem); + + String text = newSelectedItem != null ? newSelectedItem.getText() + : ""; + + // Set the icon. + FilterSelectSuggestion suggestion = (FilterSelectSuggestion) newSelectedItem + .getCommand(); + setSelectedItemIcon(suggestion.getIconUri()); + + // Set the text. + setText(text); + + menu.updateKeyboardSelectedItem(); + } + /* * Using a timer to scroll up or down the pages so when we receive lots * of consecutive mouse wheel events the pages does not flicker. @@ -486,17 +510,10 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } } - /* - * (non-Javadoc) - * - * @see - * com.google.gwt.user.client.ui.Widget#onBrowserEvent(com.google.gwt - * .user.client.Event) - */ - @Override public void onBrowserEvent(Event event) { debug("VFS.SP: onBrowserEvent()"); + if (event.getTypeInt() == Event.ONCLICK) { final Element target = DOM.eventGetTarget(event); if (target == up || target == DOM.getChild(up, 0)) { @@ -504,12 +521,24 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } else if (target == down || target == DOM.getChild(down, 0)) { lazyPageScroller.scrollDown(); } + } else if (event.getTypeInt() == Event.ONMOUSEWHEEL) { - int velocity = event.getMouseWheelVelocityY(); - if (velocity > 0) { - lazyPageScroller.scrollDown(); - } else { - lazyPageScroller.scrollUp(); + + boolean scrollNotActive = !menu.isScrollActive(); + + debug("VFS.SP: onBrowserEvent() scrollNotActive: " + + scrollNotActive); + + if (scrollNotActive) { + int velocity = event.getMouseWheelVelocityY(); + + debug("VFS.SP: onBrowserEvent() velocity: " + velocity); + + if (velocity > 0) { + lazyPageScroller.scrollDown(); + } else { + lazyPageScroller.scrollUp(); + } } } @@ -525,7 +554,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * amount of items are visible at a time and a scrollbar or buttons are * visible to change page. If paging is turned of then all options are * rendered into the popup menu. - * + * * @param paging * Should the paging be turned on? */ @@ -546,32 +575,29 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, isPagingEnabled = paging; } - /* - * (non-Javadoc) - * - * @see - * com.google.gwt.user.client.ui.PopupPanel$PositionCallback#setPosition - * (int, int) - */ - @Override public void setPosition(int offsetWidth, int offsetHeight) { - debug("VFS.SP: setPosition()"); + debug("VFS.SP: setPosition(" + offsetWidth + ", " + offsetHeight + + ")"); - int top = -1; - int left = -1; + int top = topPosition; + int left = getPopupLeft(); // reset menu size and retrieve its "natural" size menu.setHeight(""); - if (currentPage > 0) { + if (currentPage > 0 && !hasNextPage()) { // fix height to avoid height change when getting to last page menu.fixHeightTo(pageLength); } - offsetHeight = getOffsetHeight(); + final int desiredHeight = offsetHeight = getOffsetHeight(); final int desiredWidth = getMainWidth(); + + debug("VFS.SP: desired[" + desiredWidth + ", " + desiredHeight + + "]"); + Element menuFirstChild = menu.getElement().getFirstChildElement(); - int naturalMenuWidth = menuFirstChild.getOffsetWidth(); + final int naturalMenuWidth = menuFirstChild.getOffsetWidth(); if (popupOuterPadding == -1) { popupOuterPadding = Util.measureHorizontalPaddingAndBorder( @@ -581,7 +607,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (naturalMenuWidth < desiredWidth) { menu.setWidth((desiredWidth - popupOuterPadding) + "px"); menuFirstChild.getStyle().setWidth(100, Unit.PCT); - naturalMenuWidth = desiredWidth; } if (BrowserInfo.get().isIE()) { @@ -589,48 +614,72 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * IE requires us to specify the width for the container * element. Otherwise it will be 100% wide */ - int rootWidth = naturalMenuWidth - popupOuterPadding; + int rootWidth = Math.max(desiredWidth, naturalMenuWidth) + - popupOuterPadding; getContainerElement().getStyle().setWidth(rootWidth, Unit.PX); } - if (offsetHeight + getPopupTop() > Window.getClientHeight() - + Window.getScrollTop()) { + final int vfsHeight = VFilterSelect.this.getOffsetHeight(); + final int spaceAvailableAbove = top - vfsHeight; + final int spaceAvailableBelow = Window.getClientHeight() - top; + if (spaceAvailableBelow < offsetHeight + && spaceAvailableBelow < spaceAvailableAbove) { // popup on top of input instead - top = getPopupTop() - offsetHeight - - VFilterSelect.this.getOffsetHeight(); + top -= offsetHeight + vfsHeight; if (top < 0) { + offsetHeight += top; top = 0; } } else { - top = getPopupTop(); - /* - * Take popup top margin into account. getPopupTop() returns the - * top value including the margin but the value we give must not - * include the margin. - */ - int topMargin = (top - topPosition); - top -= topMargin; + offsetHeight = Math.min(offsetHeight, spaceAvailableBelow); } // fetch real width (mac FF bugs here due GWT popups overflow:auto ) offsetWidth = menuFirstChild.getOffsetWidth(); - if (offsetWidth + getPopupLeft() > Window.getClientWidth() - + Window.getScrollLeft()) { + + if (offsetHeight < desiredHeight) { + int menuHeight = offsetHeight; + if (isPagingEnabled) { + menuHeight -= up.getOffsetHeight() + down.getOffsetHeight() + + status.getOffsetHeight(); + } else { + final ComputedStyle s = new ComputedStyle(menu.getElement()); + menuHeight -= s.getIntProperty("marginBottom") + + s.getIntProperty("marginTop"); + } + + // If the available page height is really tiny then this will be + // negative and an exception will be thrown on setHeight. + int menuElementHeight = menu.getItemOffsetHeight(); + if (menuHeight < menuElementHeight) { + menuHeight = menuElementHeight; + } + + menu.setHeight(menuHeight + "px"); + + final int naturalMenuWidthPlusScrollBar = naturalMenuWidth + + Util.getNativeScrollbarSize(); + if (offsetWidth < naturalMenuWidthPlusScrollBar) { + menu.setWidth(naturalMenuWidthPlusScrollBar + "px"); + } + } + + if (offsetWidth + left > Window.getClientWidth()) { left = VFilterSelect.this.getAbsoluteLeft() - + VFilterSelect.this.getOffsetWidth() - + Window.getScrollLeft() - offsetWidth; + + VFilterSelect.this.getOffsetWidth() - offsetWidth; if (left < 0) { left = 0; + menu.setWidth(Window.getClientWidth() + "px"); } - } else { - left = getPopupLeft(); } + setPopupPosition(left, top); + menu.scrollSelectionIntoView(); } /** * Was the popup just closed? - * + * * @return true if popup was just closed */ public boolean isJustClosed() { @@ -659,7 +708,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, /** * Updates style names in suggestion popup to help theme building. - * + * * @param uidl * UIDL for the whole combo box * @param componentState @@ -723,23 +772,34 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, super(true); debug("VFS.SM: constructor()"); addDomHandler(this, LoadEvent.getType()); + + setScrollEnabled(true); } /** * Fixes menus height to use same space as full page would use. Needed - * to avoid height changes when quickly "scrolling" to last page + * to avoid height changes when quickly "scrolling" to last page. */ - public void fixHeightTo(int pagelenth) { + public void fixHeightTo(int pageItemsCount) { + setHeight(getPreferredHeight(pageItemsCount)); + } + + /* + * Gets the preferred height of the menu including pageItemsCount items. + */ + String getPreferredHeight(int pageItemsCount) { if (currentSuggestions.size() > 0) { - final int pixels = pagelenth * (getOffsetHeight() - 2) - / currentSuggestions.size(); - setHeight((pixels + 2) + "px"); + final int pixels = (getPreferredHeight() / currentSuggestions + .size()) * pageItemsCount; + return pixels + "px"; + } else { + return ""; } } /** * Sets the suggestions rendered in the menu - * + * * @param suggestions * The suggestions to be rendered in the menu */ @@ -789,6 +849,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, client.updateVariable(paintableId, "page", 0, false); client.updateVariable(paintableId, "selected", new String[] {}, immediate); + afterUpdateClientVariables(); + suggestionPopup.hide(); return; } @@ -837,6 +899,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, lastNewItemString = enteredItemValue; client.updateVariable(paintableId, "newitem", enteredItemValue, immediate); + afterUpdateClientVariables(); } } else if (item != null && !"".equals(lastFilter) @@ -852,11 +915,11 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, && !currentSuggestion.key.equals("")) { // An item (not null) selected String text = currentSuggestion.getReplacementString(); - tb.setText(text); + setText(text); selectedOptionKey = currentSuggestion.key; } else { // Null selected - tb.setText(""); + setText(""); selectedOptionKey = null; } } @@ -909,26 +972,75 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } - public void selectFirstItem() { - debug("VFS.SM: selectFirstItem()"); - MenuItem firstItem = getItems().get(0); - selectItem(firstItem); - } - private MenuItem getKeyboardSelectedItem() { return keyboardSelectedItem; } - public void setKeyboardSelectedItem(MenuItem firstItem) { - keyboardSelectedItem = firstItem; + public void setKeyboardSelectedItem(MenuItem menuItem) { + keyboardSelectedItem = menuItem; } + /** + * @deprecated use {@link SuggestionPopup#selectFirstItem()} instead. + */ + @Deprecated + public void selectFirstItem() { + debug("VFS.SM: selectFirstItem()"); + MenuItem firstItem = getItems().get(0); + selectItem(firstItem); + } + + /** + * @deprecated use {@link SuggestionPopup#selectLastItem()} instead. + */ + @Deprecated public void selectLastItem() { debug("VFS.SM: selectLastItem()"); List<MenuItem> items = getItems(); MenuItem lastItem = items.get(items.size() - 1); selectItem(lastItem); } + + /* + * Sets the keyboard item as the current selected one. + */ + void updateKeyboardSelectedItem() { + setKeyboardSelectedItem(getSelectedItem()); + } + + /* + * Gets the height of one menu item. + */ + int getItemOffsetHeight() { + List<MenuItem> items = getItems(); + return items != null && items.size() > 0 ? items.get(0) + .getOffsetHeight() : 0; + } + + /* + * Gets the width of one menu item. + */ + int getItemOffsetWidth() { + List<MenuItem> items = getItems(); + return items != null && items.size() > 0 ? items.get(0) + .getOffsetWidth() : 0; + } + + /** + * Returns true if the scroll is active on the menu element or if the + * menu currently displays the last page with less items then the + * maximum visibility (in which case the scroll is not active, but the + * scroll is active for any other page in general). + */ + @Override + public boolean isScrollActive() { + String height = getElement().getStyle().getHeight(); + String preferredHeight = getPreferredHeight(pageLength); + + return !(height == null || height.length() == 0 || height + .equals(preferredHeight)); + } + } /** @@ -947,7 +1059,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (textInputEnabled) { super.setSelectionRange(pos, length); } else { - super.setSelectionRange(getValue().length(), 0); + super.setSelectionRange(0, getValue().length()); } } } @@ -1273,10 +1385,9 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * Whether to send the options request immediately */ private void filterOptions(int page, String filter, boolean immediate) { - if (enableDebug) { - debug("VFS: filterOptions(" + page + ", " + filter + ", " - + immediate + ")"); - } + debug("VFS: filterOptions(" + page + ", " + filter + ", " + immediate + + ")"); + if (filter.equals(lastFilter) && currentPage == page) { if (!suggestionPopup.isAttached()) { suggestionPopup.showSuggestions(currentSuggestions, @@ -1297,8 +1408,11 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, waitingForFilteringResponse = true; client.updateVariable(paintableId, "filter", filter, false); client.updateVariable(paintableId, "page", page, immediate); + afterUpdateClientVariables(); + lastFilter = filter; currentPage = page; + } /** For internal use only. May be removed or replaced in the future. */ @@ -1337,7 +1451,19 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (enableDebug) { debug("VFS: setTextboxText(" + text + ")"); } + setText(text); + } + + private void setText(final String text) { + /** + * To leave caret in the beginning of the line. + * SetSelectionRange wouldn't work on IE + * (see #13477) + */ + Direction previousDirection = tb.getDirection(); + tb.setDirection(Direction.RTL); tb.setText(text); + tb.setDirection(previousDirection); } /** @@ -1401,10 +1527,13 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, setPromptingOff(text); } setSelectedItemIcon(suggestion.getIconUri()); + if (!(newKey.equals(selectedOptionKey) || ("".equals(newKey) && selectedOptionKey == null))) { selectedOptionKey = newKey; client.updateVariable(paintableId, "selected", new String[] { selectedOptionKey }, immediate); + afterUpdateClientVariables(); + // currentPage = -1; // forget the page } suggestionPopup.hide(); @@ -1597,28 +1726,22 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, switch (event.getNativeKeyCode()) { case KeyCodes.KEY_DOWN: suggestionPopup.selectNextItem(); - suggestionPopup.menu.setKeyboardSelectedItem(suggestionPopup.menu - .getSelectedItem()); + DOM.eventPreventDefault(DOM.eventGetCurrentEvent()); event.stopPropagation(); break; case KeyCodes.KEY_UP: suggestionPopup.selectPrevItem(); - suggestionPopup.menu.setKeyboardSelectedItem(suggestionPopup.menu - .getSelectedItem()); + DOM.eventPreventDefault(DOM.eventGetCurrentEvent()); event.stopPropagation(); break; case KeyCodes.KEY_PAGEDOWN: - if (hasNextPage()) { - filterOptions(currentPage + 1, lastFilter); - } + selectNextPage(); event.stopPropagation(); break; case KeyCodes.KEY_PAGEUP: - if (currentPage > 0) { - filterOptions(currentPage - 1, lastFilter); - } + selectPrevPage(); event.stopPropagation(); break; case KeyCodes.KEY_TAB: @@ -1664,6 +1787,26 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } + /* + * Show the prev page. + */ + private void selectPrevPage() { + if (currentPage > 0) { + filterOptions(currentPage - 1, lastFilter); + selectPopupItemWhenResponseIsReceived = Select.LAST; + } + } + + /* + * Show the next page. + */ + private void selectNextPage() { + if (hasNextPage()) { + filterOptions(currentPage + 1, lastFilter); + selectPopupItemWhenResponseIsReceived = Select.FIRST; + } + } + /** * Triggered when a key was depressed * @@ -1707,15 +1850,21 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (currentSuggestion != null) { String text = currentSuggestion.getReplacementString(); setPromptingOff(text); + setSelectedItemIcon(currentSuggestion.getIconUri()); + selectedOptionKey = currentSuggestion.key; + } else { if (focused || readonly || !enabled) { setPromptingOff(""); } else { setPromptingOn(); } + setSelectedItemIcon(null); + selectedOptionKey = null; } + lastFilter = ""; suggestionPopup.hide(); } @@ -1837,6 +1986,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (client.hasEventListeners(this, EventId.FOCUS)) { client.updateVariable(paintableId, EventId.FOCUS, "", true); + afterUpdateClientVariables(); } ComponentConnector connector = ConnectorMap.get(client).getConnector( @@ -1913,6 +2063,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (client.hasEventListeners(this, EventId.BLUR)) { client.updateVariable(paintableId, EventId.BLUR, "", true); + afterUpdateClientVariables(); } } @@ -2091,4 +2242,15 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, com.google.gwt.user.client.Element captionElement) { AriaHelper.bindCaption(tb, captionElement); } + + /* + * Anything that should be set after the client updates the server. + */ + private void afterUpdateClientVariables() { + // We need this here to be consistent with the all the calls. + // Then set your specific selection type only after + // client.updateVariable() method call. + selectPopupItemWhenResponseIsReceived = Select.NONE; + } + } diff --git a/client/src/com/vaadin/client/ui/VGridLayout.java b/client/src/com/vaadin/client/ui/VGridLayout.java index 10e5c00a38..17131ce63b 100644 --- a/client/src/com/vaadin/client/ui/VGridLayout.java +++ b/client/src/com/vaadin/client/ui/VGridLayout.java @@ -95,7 +95,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the column widths measured in pixels - * + * * @return */ protected int[] getColumnWidths() { @@ -104,7 +104,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the row heights measured in pixels - * + * * @return */ protected int[] getRowHeights() { @@ -113,7 +113,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the spacing between the cells horizontally in pixels - * + * * @return */ protected int getHorizontalSpacing() { @@ -122,7 +122,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the spacing between the cells vertically in pixels - * + * * @return */ protected int getVerticalSpacing() { @@ -271,7 +271,7 @@ public class VGridLayout extends ComplexPanel { } for (SpanList l : rowSpans) { for (Cell cell : l.cells) { - if (cell.row >= i && i < cell.row + cell.rowspan) { + if (cell.row <= i && i < cell.row + cell.rowspan) { return true; } } @@ -287,7 +287,7 @@ public class VGridLayout extends ComplexPanel { } for (SpanList l : colSpans) { for (Cell cell : l.cells) { - if (cell.col >= i && i < cell.col + cell.colspan) { + if (cell.col <= i && i < cell.col + cell.colspan) { return true; } } @@ -751,7 +751,7 @@ public class VGridLayout extends ComplexPanel { * Creates a new Cell with the given coordinates. * <p> * For internal use only. May be removed or replaced in the future. - * + * * @param row * @param col * @return @@ -767,7 +767,7 @@ public class VGridLayout extends ComplexPanel { * child component is also returned if "element" is part of its caption. * <p> * For internal use only. May be removed or replaced in the future. - * + * * @param element * An element that is a nested sub element of the root element in * this layout @@ -788,13 +788,13 @@ public class VGridLayout extends ComplexPanel { * child component is also returned if "element" is part of its caption. * <p> * For internal use only. May be removed or replaced in the future. - * + * * @param element * An element that is a nested sub element of the root element in * this layout * @return The Paintable which the element is a part of. Null if the element * belongs to the layout and not to a child. - * + * * @since 7.2 */ public ComponentConnector getComponent(Element element) { diff --git a/client/src/com/vaadin/client/ui/VNativeButton.java b/client/src/com/vaadin/client/ui/VNativeButton.java index 93d8d958d6..8e0dd2bce1 100644 --- a/client/src/com/vaadin/client/ui/VNativeButton.java +++ b/client/src/com/vaadin/client/ui/VNativeButton.java @@ -104,7 +104,9 @@ public class VNativeButton extends Button implements ClickHandler { } clickPending = false; } else if (event.getTypeInt() == Event.ONFOCUS) { - if (BrowserInfo.get().isIE() && clickPending) { + if (BrowserInfo.get().isIE() + && BrowserInfo.get().getBrowserMajorVersion() < 11 + && clickPending) { /* * The focus event will mess up IE and IE will not trigger the * mouse up event (which in turn triggers the click event) until diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java index d2c3ee2dae..afa13dc337 100644 --- a/client/src/com/vaadin/client/ui/VOverlay.java +++ b/client/src/com/vaadin/client/ui/VOverlay.java @@ -444,7 +444,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * A "thread local" of sorts, set temporarily so that VOverlayImpl knows * which VOverlay is using it, so that it can be attached to the correct * overlay container. - * + * * TODO this is a strange pattern that we should get rid of when possible. */ protected static VOverlay current; @@ -881,7 +881,9 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { container.setId(id); String styles = ac.getUIConnector().getWidget().getParent() .getStyleName(); - container.addClassName(styles); + if (styles != null && !styles.equals("")) { + container.addClassName(styles); + } container.addClassName(CLASSNAME_CONTAINER); RootPanel.get().getElement().appendChild(container); } @@ -971,7 +973,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /* * (non-Javadoc) - * + * * @see com.google.gwt.user.client.ui.PopupPanel#hide() */ @Override @@ -981,7 +983,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /* * (non-Javadoc) - * + * * @see com.google.gwt.user.client.ui.PopupPanel#hide(boolean) */ @Override @@ -1059,4 +1061,4 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { } } } -}
\ No newline at end of file +} diff --git a/client/src/com/vaadin/client/ui/VPopupCalendar.java b/client/src/com/vaadin/client/ui/VPopupCalendar.java index 7dea959bb4..1474ad3b71 100644 --- a/client/src/com/vaadin/client/ui/VPopupCalendar.java +++ b/client/src/com/vaadin/client/ui/VPopupCalendar.java @@ -145,7 +145,7 @@ public class VPopupCalendar extends VTextualDate implements Field, } }); - popup = new VOverlay(true, true, true); + popup = new VOverlay(true, false, true); popup.setOwner(this); FlowPanel wrapper = new FlowPanel(); diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index d88f7426ef..6a1e8664ed 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -80,6 +80,7 @@ import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorMap; +import com.vaadin.client.DeferredWorker; import com.vaadin.client.Focusable; import com.vaadin.client.MouseEventDetailsBuilder; import com.vaadin.client.StyleConstants; @@ -126,7 +127,7 @@ import com.vaadin.shared.ui.table.TableConstants; */ public class VScrollTable extends FlowPanel implements HasWidgets, ScrollHandler, VHasDropHandler, FocusHandler, BlurHandler, Focusable, - ActionOwner, SubPartAware { + ActionOwner, SubPartAware, DeferredWorker { public static final String STYLENAME = "v-table"; @@ -195,6 +196,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets, /** For internal use only. May be removed or replaced in the future. */ public boolean immediate; + private boolean updatedReqRows = true; + private boolean nullSelectionAllowed = true; private SelectMode selectMode = SelectMode.NONE; @@ -1177,7 +1180,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, @Override public void execute() { - if (firstvisible > 0) { + if (firstvisible >= 0) { firstRowInViewPort = firstvisible; if (firstvisibleOnLastPage > -1) { scrollBodyPanel @@ -2251,13 +2254,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * Ensures the column alignments are correct at initial loading. <br/> * (child components widths are correct) */ - Scheduler.get().scheduleDeferred(new Command() { - - @Override - public void execute() { - Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); - } - }); + Util.runWebkitOverflowAutoFixDeferred(scrollBodyPanel.getElement()); hadScrollBars = willHaveScrollbarz; } @@ -2398,10 +2395,32 @@ public class VScrollTable extends FlowPanel implements HasWidgets, // if client connection is busy, don't bother loading it more VConsole.log("Postponed rowfetch"); schedule(250); + } else if (!updatedReqRows && allRenderedRowsAreNew()) { + + /* + * If all rows are new, there might have been a server-side call + * to Table.setCurrentPageFirstItemIndex(int) In this case, + * scrolling event takes way too late, and all the rows from + * previous viewport to this one were requested. + * + * This should prevent requesting unneeded rows by updating + * reqFirstRow and reqRows before needing them. See (#14135) + */ + + setReqFirstRow((firstRowInViewPort - (int) (pageLength * cache_rate))); + int last = firstRowInViewPort + (int) (cache_rate * pageLength) + + pageLength - 1; + if (last >= totalRows) { + last = totalRows - 1; + } + setReqRows(last - getReqFirstRow() + 1); + updatedReqRows = true; + schedule(250); } else { int firstRendered = scrollBody.getFirstRendered(); int lastRendered = scrollBody.getLastRendered(); + if (lastRendered > totalRows) { lastRendered = totalRows - 1; } @@ -6272,6 +6291,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, public Widget getWidgetForPaintable() { return this; } + } protected class VScrollTableGeneratedRow extends VScrollTableRow { @@ -6720,13 +6740,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets, Util.notifyParentOfSizeChange(VScrollTable.this, rendering); } } - Scheduler.get().scheduleDeferred(new Command() { - @Override - public void execute() { - Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); - } - }); + Util.runWebkitOverflowAutoFixDeferred(scrollBodyPanel.getElement()); forceRealignColumnHeaders(); } @@ -6863,13 +6878,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, // We must run the fix as a deferred command to prevent it from // overwriting the scroll position with an outdated value, see // #7607. - Scheduler.get().scheduleDeferred(new Command() { - - @Override - public void execute() { - Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); - } - }); + Util.runWebkitOverflowAutoFixDeferred(scrollBodyPanel.getElement()); } triggerLazyColumnAdjustment(false); @@ -7014,8 +7023,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return; } - if (firstRowInViewPort - pageLength * cache_rate > lastRendered - || firstRowInViewPort + pageLength + pageLength * cache_rate < firstRendered) { + if (allRenderedRowsAreNew()) { // need a totally new set of rows rowRequestHandler .setReqFirstRow((firstRowInViewPort - (int) (pageLength * cache_rate))); @@ -7026,6 +7034,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } rowRequestHandler.setReqRows(last - rowRequestHandler.getReqFirstRow() + 1); + updatedReqRows = false; rowRequestHandler.deferRowFetch(); return; } @@ -7048,6 +7057,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } } + private boolean allRenderedRowsAreNew() { + int firstRowInViewPort = calcFirstRowInViewPort(); + int firstRendered = scrollBody.getFirstRendered(); + int lastRendered = scrollBody.getLastRendered(); + return (firstRowInViewPort - pageLength * cache_rate > lastRendered || firstRowInViewPort + + pageLength + pageLength * cache_rate < firstRendered); + } + protected int calcFirstRowInViewPort() { return (int) Math.ceil(scrollTop / scrollBody.getRowHeight()); } @@ -7941,4 +7958,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets, addCloseHandler.removeHandler(); } } + + /* + * Return true if component need to perform some work and false otherwise. + */ + @Override + public boolean isWorkPending() { + return lazyAdjustColumnWidths.isRunning(); + } } diff --git a/client/src/com/vaadin/client/ui/VUI.java b/client/src/com/vaadin/client/ui/VUI.java index df24c3b1c7..eae4f6319d 100644 --- a/client/src/com/vaadin/client/ui/VUI.java +++ b/client/src/com/vaadin/client/ui/VUI.java @@ -48,11 +48,12 @@ import com.vaadin.client.Util; import com.vaadin.client.VConsole; import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler; +import com.vaadin.client.ui.ui.UIConnector; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.ui.ui.UIConstants; /** - * + * */ public class VUI extends SimplePanel implements ResizeHandler, Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable, @@ -62,9 +63,6 @@ public class VUI extends SimplePanel implements ResizeHandler, private static int MONITOR_PARENT_TIMER_INTERVAL = 1000; /** For internal use only. May be removed or replaced in the future. */ - public String theme; - - /** For internal use only. May be removed or replaced in the future. */ public String id; /** For internal use only. May be removed or replaced in the future. */ @@ -319,19 +317,15 @@ public class VUI extends SimplePanel implements ResizeHandler, } } - public String getTheme() { - return theme; - } - /** - * Used to reload host page on theme changes. - * <p> - * For internal use only. May be removed or replaced in the future. + * @return the name of the theme in use by this UI. + * @deprecated as of 7.3. Use {@link UIConnector#getActiveTheme()} instead. */ - public static native void reloadHostPage() - /*-{ - $wnd.location.reload(); - }-*/; + @Deprecated + public String getTheme() { + return ((UIConnector) ConnectorMap.get(connection).getConnector(this)) + .getActiveTheme(); + } /** * Returns true if the body is NOT generated, i.e if someone else has made @@ -530,4 +524,5 @@ public class VUI extends SimplePanel implements ResizeHandler, }); } } + } diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java index 1cee727bc9..495e230156 100644 --- a/client/src/com/vaadin/client/ui/VWindow.java +++ b/client/src/com/vaadin/client/ui/VWindow.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -73,7 +73,7 @@ import com.vaadin.shared.ui.window.WindowRole; /** * "Sub window" component. - * + * * @author Vaadin Ltd */ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, @@ -233,7 +233,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /* * Stores the element that has focus in the application UI when the * window is opened, so it can be restored when the window closes. - * + * * This is currently implemented for the case when one non-modal window * can be open at the same time, and the focus is not changed while the * window is open. @@ -253,7 +253,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /* * Restores the previously stored focused element. - * + * * When the focus was changed outside the window while the window was * open, the originally stored element is restored. */ @@ -295,7 +295,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Returns true if this window is the topmost VWindow - * + * * @return */ private boolean isActive() { @@ -437,7 +437,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * is prevented. * <p> * This message is not visible on the screen. - * + * * @param topMessage * String provided when the user navigates with Shift-Tab keys to * the top of the window @@ -452,7 +452,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * key is prevented. * <p> * This message is not visible on the screen. - * + * * @param bottomMessage * String provided when the user navigates with the Tab key to * the bottom of the window @@ -465,7 +465,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * Gets the message that is provided to users of assistive devices when the * user reaches the top of the window when leaving a window with the tab key * is prevented. - * + * * @return the top message */ public String getTabStopTopAssistiveText() { @@ -476,7 +476,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * Gets the message that is provided to users of assistive devices when the * user reaches the bottom of the window when leaving a window with the tab * key is prevented. - * + * * @return the bottom message */ public String getTabStopBottomAssistiveText() { @@ -554,41 +554,11 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /* * Shake up the DOM a bit to make the window shed unnecessary - * scrollbars and resize correctly afterwards. This resulting code - * took over a week to summon forth, and involved some pretty hairy - * black magic. Don't touch it unless you know what you're doing! - * Fixes ticket #11994 + * scrollbars and resize correctly afterwards. The version fixing + * ticket #11994 which was changing the size to 110% was replaced + * with this due to ticket #12943 */ - Scheduler.get().scheduleFinally(new ScheduledCommand() { - @Override - public void execute() { - final com.google.gwt.dom.client.Element scrollable = contents - .getFirstChildElement(); - - // Adjusting the width or height may change the scroll - // position, so store the current position - int horizontalScrollPosition = scrollable.getScrollLeft(); - int verticalScrollPosition = scrollable.getScrollTop(); - - final String oldWidth = scrollable.getStyle().getWidth(); - final String oldHeight = scrollable.getStyle().getHeight(); - - scrollable.getStyle().setWidth(110, Unit.PCT); - scrollable.getOffsetWidth(); - scrollable.getStyle().setProperty("width", oldWidth); - - scrollable.getStyle().setHeight(110, Unit.PCT); - scrollable.getOffsetHeight(); - scrollable.getStyle().setProperty("height", oldHeight); - - // Restore the scroll position - scrollable.setScrollLeft(horizontalScrollPosition); - scrollable.setScrollTop(verticalScrollPosition); - - updateContentsSize(); - positionOrSizeUpdated(); - } - }); + Util.runWebkitOverflowAutoFix(contents.getFirstChildElement()); } } @@ -616,7 +586,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Sets the closable state of the window. Additionally hides/shows the close * button according to the new state. - * + * * @param closable * true if the window can be closed by the user */ @@ -638,7 +608,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * Returns the closable state of the sub window. If the sub window is * closable a decoration (typically an X) is shown to the user. By clicking * on the X the user can close the window. - * + * * @return true if the sub window is closable */ protected boolean isClosable() { @@ -670,7 +640,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * correctly if clicking on the "close" button in the window header but * closing the window from a button for example in the window will fail. * Symptom described in #10776 - * + * * The problematic part is that for the focus to be returned correctly * an input element needs to be focused in the root panel. Focusing some * other element apparently won't work. @@ -902,7 +872,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Setter for the text for assistive devices the window caption is prefixed * with. - * + * * @param assistivePrefix * the assistivePrefix to set */ @@ -913,7 +883,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Getter for the text for assistive devices the window caption is prefixed * with. - * + * * @return the assistivePrefix */ public String getAssistivePrefix() { @@ -923,7 +893,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Setter for the text for assistive devices the window caption is postfixed * with. - * + * * @param assistivePostfix * the assistivePostfix to set */ @@ -934,7 +904,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Getter for the text for assistive devices the window caption is postfixed * with. - * + * * @return the assistivePostfix */ public String getAssistivePostfix() { @@ -1086,14 +1056,14 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * TODO check if we need to support this with touch based devices. - * + * * Checks if the cursor was inside the browser content area when the event * happened. - * + * * @param event * The event to be checked * @return true, if the cursor is inside the browser content area - * + * * false, otherwise */ private boolean cursorInsideBrowserContentArea(Event event) { @@ -1382,7 +1352,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * assistive devices when it is opened. * <p> * When the provided array is empty, an existing description is removed. - * + * * @param connectors * with the connectors of the widgets to use as description */ @@ -1420,7 +1390,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * Gets the connectors that are used as assistive description. Text * contained in these connectors will be read by assistive devices when the * window is opened. - * + * * @return list of previously set connectors */ public List<Connector> getAssistiveDescription() { @@ -1429,19 +1399,19 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Sets the WAI-ARIA role the window. - * + * * This role defines how an assistive device handles a window. Available * roles are alertdialog and dialog (@see <a * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles * Model</a>). - * + * * The default role is dialog. - * + * * @param role * WAI-ARIA role to set for the window */ public void setWaiAriaRole(WindowRole role) { - if ("alertdialog".equals(role)) { + if (role == WindowRole.ALERTDIALOG) { Roles.getAlertdialogRole().set(getElement()); } else { Roles.getDialogRole().set(getElement()); @@ -1455,7 +1425,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * The value of the parameter doTabStop is stored and used for non-modal * windows. For modal windows, the handlers are always registered, while * preserving the stored value. - * + * * @param doTabStop * true to prevent leaving the window, false to allow leaving the * window for non modal windows @@ -1472,9 +1442,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Adds a Handler for when user moves the window. - * + * * @since 7.1.9 - * + * * @return {@link HandlerRegistration} used to remove the handler */ public HandlerRegistration addMoveHandler(WindowMoveHandler handler) { diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java index 78505d034c..8feb349a9e 100644 --- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java +++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java @@ -28,7 +28,6 @@ import com.vaadin.client.ui.AbstractFieldConnector; import com.vaadin.client.ui.SimpleManagedLayout; import com.vaadin.client.ui.VFilterSelect; import com.vaadin.client.ui.VFilterSelect.FilterSelectSuggestion; -import com.vaadin.client.ui.menubar.MenuItem; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.combobox.ComboBoxConstants; import com.vaadin.shared.ui.combobox.ComboBoxState; @@ -157,7 +156,15 @@ public class ComboBoxConnector extends AbstractFieldConnector implements } // handle selection (null or a single value) - if (uidl.hasVariable("selected")) { + if (uidl.hasVariable("selected") + + // In case we're switching page no need to update the selection as the + // selection process didn't finish. + // && getWidget().selectPopupItemWhenResponseIsReceived == + // VFilterSelect.Select.NONE + // + ) { + String[] selectedKeys = uidl.getStringArrayVariable("selected"); if (selectedKeys.length > 0) { performSelection(selectedKeys[0]); @@ -169,12 +176,16 @@ public class ComboBoxConnector extends AbstractFieldConnector implements if ((getWidget().waitingForFilteringResponse && getWidget().lastFilter .toLowerCase().equals(uidl.getStringVariable("filter"))) || popupOpenAndCleared) { + getWidget().suggestionPopup.showSuggestions( getWidget().currentSuggestions, getWidget().currentPage, getWidget().totalMatches); + getWidget().waitingForFilteringResponse = false; + if (!getWidget().popupOpenerClicked && getWidget().selectPopupItemWhenResponseIsReceived != VFilterSelect.Select.NONE) { + // we're paging w/ arrows Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override @@ -222,26 +233,16 @@ public class ComboBoxConnector extends AbstractFieldConnector implements */ private void navigateItemAfterPageChange() { if (getWidget().selectPopupItemWhenResponseIsReceived == VFilterSelect.Select.LAST) { - getWidget().suggestionPopup.menu.selectLastItem(); + getWidget().suggestionPopup.selectLastItem(); } else { - getWidget().suggestionPopup.menu.selectFirstItem(); + getWidget().suggestionPopup.selectFirstItem(); } - // This is used for paging so we update the keyboard selection - // variable as well. - MenuItem activeMenuItem = getWidget().suggestionPopup.menu - .getSelectedItem(); - getWidget().suggestionPopup.menu - .setKeyboardSelectedItem(activeMenuItem); - - // Update text field to contain the correct text - getWidget().setTextboxText(activeMenuItem.getText()); - getWidget().tb.setSelectionRange( - getWidget().lastFilter.length(), - activeMenuItem.getText().length() - - getWidget().lastFilter.length()); - - getWidget().selectPopupItemWhenResponseIsReceived = VFilterSelect.Select.NONE; // reset + // If you're in between 2 requests both changing the page back and + // forth, you don't want this here, instead you need it before any + // other request. + // getWidget().selectPopupItemWhenResponseIsReceived = + // VFilterSelect.Select.NONE; // reset } private void performSelection(String selectedKey) { diff --git a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java index a349eb2993..6f059a7c16 100644 --- a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java +++ b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java @@ -87,15 +87,17 @@ public class PopupDateFieldConnector extends TextualDateConnector { .isShowISOWeekNumbers()); if (getWidget().calendar.getResolution() != getWidget() .getCurrentResolution()) { + boolean hasSelectedDate = false; getWidget().calendar.setResolution(getWidget() .getCurrentResolution()); if (getWidget().calendar.getDate() != null && getWidget().getCurrentDate() != null) { + hasSelectedDate = true; getWidget().calendar.setDate((Date) getWidget() .getCurrentDate().clone()); - // force re-render when changing resolution only - getWidget().calendar.renderCalendar(); } + // force re-render when changing resolution only + getWidget().calendar.renderCalendar(hasSelectedDate); } // Force re-render of calendar if locale has changed (#12153) diff --git a/client/src/com/vaadin/client/ui/dd/DDUtil.java b/client/src/com/vaadin/client/ui/dd/DDUtil.java index dfdafe1352..77de1f9b1a 100644 --- a/client/src/com/vaadin/client/ui/dd/DDUtil.java +++ b/client/src/com/vaadin/client/ui/dd/DDUtil.java @@ -58,8 +58,7 @@ public class DDUtil { } public static HorizontalDropLocation getHorizontalDropLocation( - Element element, NativeEvent event, - double leftRightRatio) { + Element element, NativeEvent event, double leftRightRatio) { int clientX = Util.getTouchOrMouseClientX(event); // Event coordinates are relative to the viewport, element absolute diff --git a/client/src/com/vaadin/client/ui/dd/DragImageModifier.java b/client/src/com/vaadin/client/ui/dd/DragImageModifier.java index f08c082a70..45ab5d9bb3 100644 --- a/client/src/com/vaadin/client/ui/dd/DragImageModifier.java +++ b/client/src/com/vaadin/client/ui/dd/DragImageModifier.java @@ -20,7 +20,8 @@ import com.google.gwt.dom.client.Element; /** * Interface implemented by widgets if the drag image used for drag'n'drop * requires additional initialization/configuration. The method - * {@link #modifyDragImage(Element)} is called for each element in the automatically generated drag image. + * {@link #modifyDragImage(Element)} is called for each element in the + * automatically generated drag image. * * @since 7.2 * @author Vaadin Ltd diff --git a/client/src/com/vaadin/client/ui/menubar/MenuBar.java b/client/src/com/vaadin/client/ui/menubar/MenuBar.java index b00665e766..726defafd5 100644 --- a/client/src/com/vaadin/client/ui/menubar/MenuBar.java +++ b/client/src/com/vaadin/client/ui/menubar/MenuBar.java @@ -38,6 +38,7 @@ import java.util.List; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Style.Overflow; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; @@ -74,6 +75,9 @@ import com.vaadin.client.ui.VOverlay; public class MenuBar extends Widget implements PopupListener { private final Element body; + private final Element table; + private final Element outer; + private final ArrayList<MenuItem> items = new ArrayList<MenuItem>(); private MenuBar parentMenu; private PopupPanel popup; @@ -98,7 +102,7 @@ public class MenuBar extends Widget implements PopupListener { public MenuBar(boolean vertical) { super(); - final Element table = DOM.createTable(); + table = DOM.createTable(); body = DOM.createTBody(); DOM.appendChild(table, body); @@ -109,7 +113,7 @@ public class MenuBar extends Widget implements PopupListener { this.vertical = vertical; - final Element outer = DOM.createDiv(); + outer = DOM.createDiv(); DOM.appendChild(outer, table); setElement(outer); @@ -324,6 +328,37 @@ public class MenuBar extends Widget implements PopupListener { return selectedItem; } + /** + * Gets the first item from the menu or null if no items. + * + * @since + * @return the first item from the menu or null if no items. + */ + public MenuItem getFirstItem() { + return items != null && items.size() > 0 ? items.get(0) : null; + } + + /** + * Gest the last item from the menu or null if no items. + * + * @since + * @return the last item from the menu or null if no items. + */ + public MenuItem getLastItem() { + return items != null && items.size() > 0 ? items.get(items.size() - 1) + : null; + } + + /** + * Gets the index of the selected item. + * + * @since + * @return the index of the selected item. + */ + public int getSelectedIndex() { + return items != null ? items.indexOf(getSelectedItem()) : -1; + } + @Override protected void onDetach() { // When the menu is detached, make sure to close all of its children. @@ -468,6 +503,7 @@ public class MenuBar extends Widget implements PopupListener { public void selectItem(MenuItem item) { if (item == selectedItem) { + scrollItemIntoView(item); return; } @@ -480,6 +516,74 @@ public class MenuBar extends Widget implements PopupListener { } selectedItem = item; + + scrollItemIntoView(item); + } + + /* + * Scroll the specified item into view. + */ + private void scrollItemIntoView(MenuItem item) { + if (item != null) { + item.getElement().scrollIntoView(); + } + } + + /** + * Scroll the selected item into view. + * + * @since + */ + public void scrollSelectionIntoView() { + scrollItemIntoView(selectedItem); + } + + /** + * Sets the menu scroll enabled or disabled. + * + * @since + * @param enabled + * the enabled state of the scroll. + */ + public void setScrollEnabled(boolean enabled) { + if (enabled) { + if (vertical) { + outer.getStyle().setOverflowY(Overflow.AUTO); + } else { + outer.getStyle().setOverflowX(Overflow.AUTO); + } + + } else { + if (vertical) { + outer.getStyle().clearOverflowY(); + } else { + outer.getStyle().clearOverflowX(); + } + } + } + + /** + * Gets whether the scroll is activate for this menu. + * + * @since + * @return true if the scroll is active, otherwise false. + */ + public boolean isScrollActive() { + // Element element = getElement(); + // return element.getOffsetHeight() > DOM.getChild(element, 0) + // .getOffsetHeight(); + int outerHeight = outer.getOffsetHeight(); + int tableHeight = table.getOffsetHeight(); + return outerHeight < tableHeight; + } + + /** + * Gets the preferred height of the menu. + * + * @since + */ + protected int getPreferredHeight() { + return table.getOffsetHeight(); } /** diff --git a/client/src/com/vaadin/client/ui/table/TableConnector.java b/client/src/com/vaadin/client/ui/table/TableConnector.java index 017d1d1024..56b35cce56 100644 --- a/client/src/com/vaadin/client/ui/table/TableConnector.java +++ b/client/src/com/vaadin/client/ui/table/TableConnector.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -21,7 +21,6 @@ import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Position; -import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; @@ -65,7 +64,7 @@ public class TableConnector extends AbstractHasComponentsConnector implements /* * (non-Javadoc) - * + * * @see com.vaadin.client.Paintable#updateFromUIDL(com.vaadin.client.UIDL, * com.vaadin.client.ApplicationConnection) */ @@ -122,7 +121,7 @@ public class TableConnector extends AbstractHasComponentsConnector implements int previousTotalRows = getWidget().totalRows; getWidget().updateTotalRows(uidl); - boolean totalRowsChanged = (getWidget().totalRows != previousTotalRows); + boolean totalRowsHaveChanged = (getWidget().totalRows != previousTotalRows); getWidget().updateDragMode(uidl); @@ -200,7 +199,7 @@ public class TableConnector extends AbstractHasComponentsConnector implements if (getWidget().headerChangedDuringUpdate) { getWidget().triggerLazyColumnAdjustment(true); } else if (!getWidget().isScrollPositionVisible() - || totalRowsChanged + || totalRowsHaveChanged || getWidget().lastRenderedHeight != getWidget().scrollBody .getOffsetHeight()) { // webkits may still bug with their disturbing scrollbar @@ -210,13 +209,8 @@ public class TableConnector extends AbstractHasComponentsConnector implements // by changing overflows as the length of the contents // *shouldn't* have changed (unless the number of rows // or the height of the widget has also changed) - Scheduler.get().scheduleDeferred(new Command() { - @Override - public void execute() { - Util.runWebkitOverflowAutoFix(getWidget().scrollBodyPanel - .getElement()); - } - }); + Util.runWebkitOverflowAutoFixDeferred(getWidget().scrollBodyPanel + .getElement()); } } else { getWidget().initializeRows(uidl, rowData); @@ -390,7 +384,7 @@ public class TableConnector extends AbstractHasComponentsConnector implements /** * Shows a saved row context menu if the row for the context menu is still * visible. Does nothing if a context menu has not been saved. - * + * * @param savedContextMenu */ public void showSavedContextMenu(ContextMenuDetails savedContextMenu) { diff --git a/client/src/com/vaadin/client/ui/textarea/TextAreaConnector.java b/client/src/com/vaadin/client/ui/textarea/TextAreaConnector.java index e406ff5459..e9dc3e1dd7 100644 --- a/client/src/com/vaadin/client/ui/textarea/TextAreaConnector.java +++ b/client/src/com/vaadin/client/ui/textarea/TextAreaConnector.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -16,6 +16,10 @@ package com.vaadin.client.ui.textarea; +import com.google.gwt.dom.client.Element; +import com.google.gwt.event.dom.client.MouseUpEvent; +import com.google.gwt.event.dom.client.MouseUpHandler; +import com.vaadin.client.Util.CssSize; import com.vaadin.client.ui.VTextArea; import com.vaadin.client.ui.textfield.TextFieldConnector; import com.vaadin.shared.ui.Connect; @@ -34,4 +38,54 @@ public class TextAreaConnector extends TextFieldConnector { public VTextArea getWidget() { return (VTextArea) super.getWidget(); } + + @Override + protected void init() { + super.init(); + + getWidget().addMouseUpHandler(new ResizeMouseUpHandler()); + } + + /* + * Workaround to handle the resize on the mouse up. + */ + private class ResizeMouseUpHandler implements MouseUpHandler { + + @Override + public void onMouseUp(MouseUpEvent event) { + Element element = getWidget().getElement(); + + updateSize(element.getStyle().getHeight(), getState().height, + "height"); + updateSize(element.getStyle().getWidth(), getState().width, "width"); + } + + /* + * Update the specified size on the server. + */ + private void updateSize(String sizeText, String stateSizeText, + String sizeType) { + + CssSize stateSize = CssSize.fromString(stateSizeText); + CssSize newSize = CssSize.fromString(sizeText); + + if (stateSize == null && newSize == null) { + return; + + } else if (newSize == null) { + sizeText = ""; + + // Else, if the current stateSize is null, just go ahead and set + // the newSize, so no check on stateSize is needed. + + } else if (stateSize != null && stateSize.equals(newSize)) { + return; + } + + getConnection().updateVariable(getConnectorId(), sizeType, + sizeText, false); + } + + } + } diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index 1d2a49cbd1..c88fd23eca 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -18,6 +18,7 @@ package com.vaadin.client.ui.ui; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.logging.Logger; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -26,8 +27,10 @@ import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.HeadElement; import com.google.gwt.dom.client.LinkElement; import com.google.gwt.dom.client.NativeEvent; +import com.google.gwt.dom.client.NodeList; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Position; +import com.google.gwt.dom.client.StyleElement; import com.google.gwt.dom.client.StyleInjector; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; @@ -51,12 +54,17 @@ import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorHierarchyChangeEvent; import com.vaadin.client.Focusable; import com.vaadin.client.Paintable; +import com.vaadin.client.ResourceLoader; +import com.vaadin.client.ResourceLoader.ResourceLoadEvent; +import com.vaadin.client.ResourceLoader.ResourceLoadListener; import com.vaadin.client.ServerConnector; import com.vaadin.client.UIDL; import com.vaadin.client.VConsole; import com.vaadin.client.ValueMap; +import com.vaadin.client.annotations.OnStateChange; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; +import com.vaadin.client.ui.AbstractConnector; import com.vaadin.client.ui.AbstractSingleComponentContainerConnector; import com.vaadin.client.ui.ClickEventHandler; import com.vaadin.client.ui.ShortcutActionHandler; @@ -66,6 +74,7 @@ import com.vaadin.client.ui.VUI; import com.vaadin.client.ui.layout.MayScrollChildren; import com.vaadin.client.ui.window.WindowConnector; import com.vaadin.server.Page.Styles; +import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.communication.MethodInvocation; import com.vaadin.shared.ui.ComponentStateUtil; @@ -80,6 +89,7 @@ import com.vaadin.shared.ui.ui.UIClientRpc; import com.vaadin.shared.ui.ui.UIConstants; import com.vaadin.shared.ui.ui.UIServerRpc; import com.vaadin.shared.ui.ui.UIState; +import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.UI; @Connect(value = UI.class, loadStyle = LoadStyle.EAGER) @@ -88,6 +98,8 @@ public class UIConnector extends AbstractSingleComponentContainerConnector private HandlerRegistration childStateChangeHandlerRegistration; + private String activeTheme = null; + private final StateChangeHandler childStateChangeHandler = new StateChangeHandler() { @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { @@ -197,14 +209,6 @@ public class UIConnector extends AbstractSingleComponentContainerConnector getWidget().immediate = getState().immediate; getWidget().resizeLazy = uidl.hasAttribute(UIConstants.RESIZE_LAZY); - String newTheme = uidl.getStringAttribute("theme"); - if (getWidget().theme != null && !newTheme.equals(getWidget().theme)) { - // Complete page refresh is needed due css can affect layout - // calculations etc - getWidget().reloadHostPage(); - } else { - getWidget().theme = newTheme; - } // this also implicitly removes old styles String styles = ""; styles += getWidget().getStylePrimaryName() + " "; @@ -405,9 +409,6 @@ public class UIConnector extends AbstractSingleComponentContainerConnector */ private void injectCSS(UIDL uidl) { - final HeadElement head = HeadElement.as(Document.get() - .getElementsByTagName(HeadElement.TAG).getItem(0)); - /* * Search the UIDL stream for CSS resources and strings to be injected. */ @@ -424,8 +425,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector link.setRel("stylesheet"); link.setHref(url); link.setType("text/css"); - head.appendChild(link); - + getHead().appendChild(link); // Check if we have CSS string to inject } else if (cssInjectionsUidl.getTag().equals("css-string")) { for (Iterator<?> it2 = cssInjectionsUidl.getChildIterator(); it2 @@ -437,8 +437,54 @@ public class UIConnector extends AbstractSingleComponentContainerConnector } } + /** + * Internal helper to get the <head> tag of the page + * + * @since 7.3 + * @return the head element + */ + private HeadElement getHead() { + return HeadElement.as(Document.get() + .getElementsByTagName(HeadElement.TAG).getItem(0)); + } + + /** + * Internal helper for removing any stylesheet with the given URL + * + * @since 7.3 + * @param url + * the url to match with existing stylesheets + */ + private void removeStylesheet(String url) { + NodeList<Element> linkTags = getHead().getElementsByTagName( + LinkElement.TAG); + for (int i = 0; i < linkTags.getLength(); i++) { + LinkElement link = LinkElement.as(linkTags.getItem(i)); + if (!"stylesheet".equals(link.getRel())) { + continue; + } + if (!"text/css".equals(link.getType())) { + continue; + } + if (url.equals(link.getHref())) { + getHead().removeChild(link); + } + } + } + public void init(String rootPanelId, ApplicationConnection applicationConnection) { + // Create a style tag for style injections so they don't end up in + // the theme tag in IE8-IE10 (we don't want to wipe them out if we + // change theme). + // StyleInjectorImplIE always injects to the last style tag on the page. + if (BrowserInfo.get().isIE() + && BrowserInfo.get().getBrowserMajorVersion() < 11) { + StyleElement style = Document.get().createStyleElement(); + style.setType("text/css"); + getHead().appendChild(style); + } + DOM.sinkEvents(getWidget().getElement(), Event.ONKEYDOWN | Event.ONSCROLL); @@ -448,9 +494,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector // the user root.getElement().setInnerHTML(""); - String themeName = applicationConnection.getConfiguration() - .getThemeName(); - root.addStyleName(themeName); + activeTheme = applicationConnection.getConfiguration().getThemeName(); root.add(getWidget()); @@ -760,4 +804,229 @@ public class UIConnector extends AbstractSingleComponentContainerConnector getRpcProxy(DebugWindowServerRpc.class).showServerDebugInfo( serverConnector); } + + @OnStateChange("theme") + void onThemeChange() { + final String oldTheme = activeTheme; + final String newTheme = getState().theme; + final String oldThemeUrl = getThemeUrl(oldTheme); + final String newThemeUrl = getThemeUrl(newTheme); + + if (SharedUtil.equals(oldTheme, newTheme)) { + // This should only happen on the initial load when activeTheme has + // been updated in init. + + if (newTheme == null) { + return; + } + + // For the embedded case we cannot be 100% sure that the theme has + // been loaded and that the style names have been set. + + if (findStylesheetTag(oldThemeUrl) == null) { + // If there is no style tag, load it the normal way (the class + // name will be added when theme has been loaded) + replaceTheme(null, newTheme, null, newThemeUrl); + } else if (!getWidget().getParent().getElement() + .hasClassName(newTheme)) { + // If only the class name is missing, add that + activateTheme(newTheme); + } + return; + } + + getLogger().info("Changing theme from " + oldTheme + " to " + newTheme); + replaceTheme(oldTheme, newTheme, oldThemeUrl, newThemeUrl); + } + + /** + * Loads the new theme and removes references to the old theme + * + * @param oldTheme + * The name of the old theme + * @param newTheme + * The name of the new theme + * @param oldThemeUrl + * The url of the old theme + * @param newThemeUrl + * The url of the new theme + */ + private void replaceTheme(final String oldTheme, final String newTheme, + String oldThemeUrl, final String newThemeUrl) { + + LinkElement tagToReplace = null; + + if (oldTheme != null) { + tagToReplace = findStylesheetTag(oldThemeUrl); + + if (tagToReplace == null) { + getLogger() + .warning( + "Did not find the link tag for the old theme (" + + oldThemeUrl + + "), adding a new stylesheet for the new theme (" + + newThemeUrl + ")"); + } + } + + if (newTheme != null) { + loadTheme(newTheme, newThemeUrl, tagToReplace); + } else { + if (tagToReplace != null) { + tagToReplace.getParentElement().removeChild(tagToReplace); + } + + activateTheme(null); + } + + } + + /** + * Finds a link tag for a style sheet with the given URL + * + * @since 7.3 + * @param url + * the URL of the style sheet + * @return the link tag or null if no matching link tag was found + */ + private LinkElement findStylesheetTag(String url) { + NodeList<Element> linkTags = getHead().getElementsByTagName( + LinkElement.TAG); + for (int i = 0; i < linkTags.getLength(); i++) { + final LinkElement link = LinkElement.as(linkTags.getItem(i)); + if ("stylesheet".equals(link.getRel()) + && "text/css".equals(link.getType()) + && url.equals(link.getHref())) { + return link; + } + } + return null; + } + + /** + * Loads the given theme and replaces the given link element with the new + * theme link element. + * + * @param newTheme + * The name of the new theme + * @param newThemeUrl + * The url of the new theme + * @param tagToReplace + * The link element to replace. If null, then the new link + * element is added at the end. + */ + private void loadTheme(final String newTheme, final String newThemeUrl, + final LinkElement tagToReplace) { + LinkElement newThemeLinkElement = Document.get().createLinkElement(); + newThemeLinkElement.setRel("stylesheet"); + newThemeLinkElement.setType("text/css"); + newThemeLinkElement.setHref(newThemeUrl); + ResourceLoader.addOnloadHandler(newThemeLinkElement, + new ResourceLoadListener() { + + @Override + public void onLoad(ResourceLoadEvent event) { + getLogger().info( + "Loading of " + newTheme + " from " + + newThemeUrl + " completed"); + + if (tagToReplace != null) { + tagToReplace.getParentElement().removeChild( + tagToReplace); + } + activateTheme(newTheme); + } + + @Override + public void onError(ResourceLoadEvent event) { + getLogger().warning( + "Could not load theme from " + + getThemeUrl(newTheme)); + } + }, null); + + if (tagToReplace != null) { + getHead().insertBefore(newThemeLinkElement, tagToReplace); + } else { + getHead().appendChild(newThemeLinkElement); + } + } + + /** + * Activates the new theme. Assumes the theme has been loaded and taken into + * use in the browser. + * + * @since 7.3 + * @param newTheme + */ + private void activateTheme(String newTheme) { + if (activeTheme != null) { + getWidget().getParent().removeStyleName(activeTheme); + VOverlay.getOverlayContainer(getConnection()).removeClassName( + activeTheme); + } + + activeTheme = newTheme; + + if (newTheme != null) { + getWidget().getParent().addStyleName(newTheme); + VOverlay.getOverlayContainer(getConnection()).addClassName( + activeTheme); + } + + forceStateChangeRecursively(UIConnector.this); + getLayoutManager().forceLayout(); + } + + /** + * Force a full recursive recheck of every connector's state variables. + * + * @see #forceStateChange() + * + * @since 7.3 + */ + protected static void forceStateChangeRecursively( + AbstractConnector connector) { + connector.forceStateChange(); + + for (ServerConnector child : connector.getChildren()) { + if (child instanceof AbstractConnector) { + forceStateChangeRecursively((AbstractConnector) child); + } else { + getLogger().warning( + "Could not force state change for unknown connector type: " + + child.getClass().getName()); + } + } + + } + + /** + * Internal helper to get the theme URL for a given theme + * + * @since 7.3 + * @param theme + * the name of the theme + * @return The URL the theme can be loaded from + */ + private String getThemeUrl(String theme) { + return getConnection().translateVaadinUri( + ApplicationConstants.VAADIN_PROTOCOL_PREFIX + "themes/" + theme + + "/styles" + ".css"); + } + + /** + * Returns the name of the theme currently in used by the UI + * + * @since 7.3 + * @return the theme name used by this UI + */ + public String getActiveTheme() { + return activeTheme; + } + + private static Logger getLogger() { + return Logger.getLogger(UIConnector.class.getName()); + } + } diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java index 3c75764075..73bafcca25 100644 --- a/server/src/com/vaadin/server/BootstrapHandler.java +++ b/server/src/com/vaadin/server/BootstrapHandler.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -45,10 +45,10 @@ import com.vaadin.shared.communication.PushMode; import com.vaadin.ui.UI; /** - * + * * @author Vaadin Ltd * @since 7.0.0 - * + * * @deprecated As of 7.0. Will likely change or be removed in a future version */ @Deprecated @@ -336,9 +336,9 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { * Override this method if you want to add some custom html around around * the div element into which the actual Vaadin application will be * rendered. - * + * * @param context - * + * * @throws IOException * @throws JSONException */ @@ -397,7 +397,8 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { "type", "text/javascript").attr("src", pushJS)); } - String bootstrapLocation = vaadinLocation + "vaadinBootstrap.js"; + String bootstrapLocation = vaadinLocation + + ApplicationConstants.VAADIN_BOOTSTRAP_JS; fragmentNodes.add(new Element(Tag.valueOf("script"), "").attr("type", "text/javascript").attr("src", bootstrapLocation)); Element mainScriptTag = new Element(Tag.valueOf("script"), "").attr( @@ -543,13 +544,13 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { /** * Get the URI for the application theme. - * + * * A portal-wide default theme is fetched from the portal shared resource * directory (if any), other themes from the portlet. - * + * * @param context * @param themeName - * + * * @return */ public String getThemeUri(BootstrapContext context, String themeName) { @@ -562,7 +563,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { /** * Override if required - * + * * @param context * @return */ @@ -574,7 +575,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { /** * Don not override. - * + * * @param context * @return */ diff --git a/server/src/com/vaadin/server/Page.java b/server/src/com/vaadin/server/Page.java index d58ba548e3..3acea97c0f 100644 --- a/server/src/com/vaadin/server/Page.java +++ b/server/src/com/vaadin/server/Page.java @@ -636,7 +636,8 @@ public class Page implements Serializable { } public void init(VaadinRequest request) { - // NOTE: UI.refresh makes assumptions about the semantics of this method. + // NOTE: UI.refresh makes assumptions about the semantics of this + // method. // It should be kept in sync if this method is changed. // Extract special parameter sent by vaadinBootstrap.js diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java index 2ab8c52dad..f93cb8e070 100644 --- a/server/src/com/vaadin/server/VaadinSession.java +++ b/server/src/com/vaadin/server/VaadinSession.java @@ -114,7 +114,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * deadlocks unless implemented very carefully. get(long, TimeUnit) * does not have the same detection since a sensible timeout should * avoid completely locking up the application. - * + * * Even though no deadlock could occur after the runnable has been * run, the check is always done as the deterministic behavior makes * it easier to detect potential problems. diff --git a/server/src/com/vaadin/server/communication/ClientRpcWriter.java b/server/src/com/vaadin/server/communication/ClientRpcWriter.java index 181bfbb882..1090fdbab9 100644 --- a/server/src/com/vaadin/server/communication/ClientRpcWriter.java +++ b/server/src/com/vaadin/server/communication/ClientRpcWriter.java @@ -81,9 +81,9 @@ public class ClientRpcWriter implements Serializable { // + parameterType.getName()); // } // } - EncodeResult encodeResult = JsonCodec.encode(invocation.getParameters()[i], - referenceParameter, parameterType, - ui.getConnectorTracker()); + EncodeResult encodeResult = JsonCodec.encode( + invocation.getParameters()[i], referenceParameter, + parameterType, ui.getConnectorTracker()); paramJson.put(encodeResult.getEncodedValue()); } invocationJson.put(paramJson); diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java index 5a7ae5b3e8..67e5f87153 100644 --- a/server/src/com/vaadin/server/communication/PushHandler.java +++ b/server/src/com/vaadin/server/communication/PushHandler.java @@ -18,6 +18,7 @@ package com.vaadin.server.communication; import java.io.IOException; import java.io.Reader; +import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; @@ -48,7 +49,7 @@ import com.vaadin.ui.UI; /** * Establishes bidirectional ("push") communication channels - * + * * @author Vaadin Ltd * @since 7.1 */ @@ -70,9 +71,10 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { AtmosphereRequest req = resource.getRequest(); if (req.getMethod().equalsIgnoreCase("GET")) { - callWithUi(resource, establishCallback); + callWithUi(resource, establishCallback, false); } else if (req.getMethod().equalsIgnoreCase("POST")) { - callWithUi(resource, receiveCallback); + callWithUi(resource, receiveCallback, + resource.transport() == TRANSPORT.WEBSOCKET); } } @@ -194,20 +196,27 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { /** * Find the UI for the atmosphere resource, lock it and invoke the callback. - * + * * @param resource * the atmosphere resource for the current request * @param callback * the push callback to call when a UI is found and locked + * @param websocket + * true if this is a websocket message (as opposed to a HTTP + * request) */ private void callWithUi(final AtmosphereResource resource, - final PushEventCallback callback) { + final PushEventCallback callback, boolean websocket) { AtmosphereRequest req = resource.getRequest(); VaadinServletRequest vaadinRequest = new VaadinServletRequest(req, service); VaadinSession session = null; - service.requestStart(vaadinRequest, null); + if (websocket) { + // For any HTTP request we have already started the request in the + // servlet + service.requestStart(vaadinRequest, null); + } try { try { session = service.findVaadinSession(vaadinRequest); @@ -278,7 +287,9 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { } } finally { try { - service.requestEnd(vaadinRequest, null, session); + if (websocket) { + service.requestEnd(vaadinRequest, null, session); + } } catch (Exception e) { getLogger().log(Level.WARNING, "Error while ending request", e); @@ -357,9 +368,31 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { // Sets UI.currentInstance ui = service.findUI(vaadinRequest); if (ui == null) { - getLogger().log(Level.SEVERE, - "Could not get UI. This should never happen"); - return; + /* + * UI not found, could be because FF has asynchronously closed + * the websocket connection and Atmosphere has already done + * cleanup of the request attributes. + * + * In that case, we still have a chance of finding the right UI + * by iterating through the UIs in the session looking for one + * using the same AtmosphereResource. + */ + ui = findUiUsingResource(resource, session.getUIs()); + + if (ui == null) { + getLogger() + .log(Level.SEVERE, + "Could not get UI. This should never happen," + + " except when reloading in Firefox -" + + " see http://dev.vaadin.com/ticket/14251."); + return; + } else { + getLogger() + .log(Level.INFO, + "No UI was found based on data in the request," + + " but a slower lookup based on the AtmosphereResource succeeded." + + " See http://dev.vaadin.com/ticket/14251 for more details."); + } } PushMode pushMode = ui.getPushConfiguration().getPushMode(); @@ -411,6 +444,19 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { } } + private static UI findUiUsingResource(AtmosphereResource resource, + Collection<UI> uIs) { + for (UI ui : uIs) { + PushConnection pushConnection = ui.getPushConnection(); + if (pushConnection instanceof AtmospherePushConnection) { + if (((AtmospherePushConnection) pushConnection).getResource() == resource) { + return ui; + } + } + } + return null; + } + /** * Sends a refresh message to the given atmosphere resource. Uses an * AtmosphereResource instead of an AtmospherePushConnection even though it @@ -419,10 +465,10 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { * two push connections which try to use the same UI. Using the * AtmosphereResource directly guarantees the message goes to the correct * recipient. - * + * * @param resource * The atmosphere resource to send refresh to - * + * */ private static void sendRefreshAndDisconnect(AtmosphereResource resource) throws IOException { diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java index 9dbd9a093d..c9639813ca 100644 --- a/server/src/com/vaadin/ui/AbstractComponent.java +++ b/server/src/com/vaadin/ui/AbstractComponent.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -37,6 +37,7 @@ import com.vaadin.server.VaadinSession; import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.ComponentConstants; import com.vaadin.shared.ui.ComponentStateUtil; +import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.Field.ValueChangeEvent; import com.vaadin.util.ReflectTools; @@ -45,7 +46,7 @@ import com.vaadin.util.ReflectTools; * {@link Component} interface. Basic UI components that are not derived from an * external component can inherit this class to easily qualify as Vaadin * components. Most components in Vaadin do just that. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -83,7 +84,7 @@ public abstract class AbstractComponent extends AbstractClientConnector private Unit widthUnit = Unit.PIXELS; private Unit heightUnit = Unit.PIXELS; private static final Pattern sizePattern = Pattern - .compile("^(-?\\d+(\\.\\d+)?)(%|px|em|rem|ex|in|cm|mm|pt|pc)?$"); + .compile(SharedUtil.SIZE_PATTERN); /** * Keeps track of the Actions added to this component; the actual @@ -240,7 +241,7 @@ public abstract class AbstractComponent extends AbstractClientConnector * Sets the component's caption <code>String</code>. Caption is the visible * name of the component. This method will trigger a * {@link RepaintRequestEvent}. - * + * * @param caption * the new caption <code>String</code> for the component. */ @@ -271,7 +272,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the locale of this component. - * + * * <pre> * // Component for which the locale is meaningful * InlineDateField date = new InlineDateField("Datum"); @@ -283,8 +284,8 @@ public abstract class AbstractComponent extends AbstractClientConnector * date.setResolution(DateField.RESOLUTION_DAY); * layout.addComponent(date); * </pre> - * - * + * + * * @param locale * the locale to become this component's locale. */ @@ -310,7 +311,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the component's icon. This method will trigger a * {@link RepaintRequestEvent}. - * + * * @param icon * the icon to be shown with the component's caption. */ @@ -376,7 +377,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the component's immediate mode to the specified status. - * + * * @param immediate * the boolean value specifying if the component should be in the * immediate mode after the call. @@ -437,11 +438,11 @@ public abstract class AbstractComponent extends AbstractClientConnector * Sets the component's description. See {@link #getDescription()} for more * information on what the description is. This method will trigger a * {@link RepaintRequestEvent}. - * + * * The description is displayed as HTML in tooltips or directly in certain * components so care should be taken to avoid creating the possibility for * HTML injection and possibly XSS vulnerabilities. - * + * * @param description * the new description string for the component. */ @@ -490,7 +491,7 @@ public abstract class AbstractComponent extends AbstractClientConnector * To find the Window that contains the component, use {@code Window w = * getParent(Window.class);} * </p> - * + * * @param <T> * The type of the ancestor * @param parentType @@ -511,7 +512,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Gets the error message for this component. - * + * * @return ErrorMessage containing the description of the error state of the * component or null, if the component contains no errors. Extending * classes should override this method if they support other error @@ -524,9 +525,9 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Gets the component's error message. - * + * * @link Terminal.ErrorMessage#ErrorMessage(String, int) - * + * * @return the component's error message. */ public ErrorMessage getComponentError() { @@ -536,9 +537,9 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the component's error message. The message may contain certain XML * tags, for more information see - * + * * @link Component.ErrorMessage#ErrorMessage(String, int) - * + * * @param componentError * the new <code>ErrorMessage</code> of the component. */ @@ -615,7 +616,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Build CSS compatible string representation of height. - * + * * @return CSS height */ private String getCSSHeight() { @@ -624,7 +625,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Build CSS compatible string representation of width. - * + * * @return CSS width */ private String getCSSWidth() { @@ -634,12 +635,12 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Returns the shared state bean with information to be sent from the server * to the client. - * + * * Subclasses should override this method and set any relevant fields of the * state returned by super.getState(). - * + * * @since 7.0 - * + * * @return updated component shared state */ @Override @@ -730,7 +731,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the data object, that can be used for any application specific data. * The component does not use or modify this data. - * + * * @param data * the Application specific data. * @since 3.1 @@ -741,7 +742,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Gets the application specific data. See {@link #setData(Object)}. - * + * * @return the Application specific data set with setData function. * @since 3.1 */ @@ -916,7 +917,7 @@ public abstract class AbstractComponent extends AbstractClientConnector size = -1; unit = Unit.PIXELS; } else { - String symbol = matcher.group(3); + String symbol = matcher.group(2); unit = Unit.getUnitFromSymbol(symbol); } } else { @@ -951,7 +952,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Gets the {@link ActionManager} used to manage the * {@link ShortcutListener}s added to this {@link Field}. - * + * * @return the ActionManager in use */ protected ActionManager getActionManager() { @@ -995,7 +996,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Determine whether a <code>content</code> component is equal to, or the * ancestor of this component. - * + * * @param content * the potential ancestor element * @return <code>true</code> if the relationship holds diff --git a/server/src/com/vaadin/ui/AbstractTextField.java b/server/src/com/vaadin/ui/AbstractTextField.java index e0318ddf2b..9293d38119 100644 --- a/server/src/com/vaadin/ui/AbstractTextField.java +++ b/server/src/com/vaadin/ui/AbstractTextField.java @@ -147,6 +147,18 @@ public abstract class AbstractTextField extends AbstractField<String> implements try { + // Sets the height set by the user when resize the <textarea>. + String newHeight = (String) variables.get("height"); + if (newHeight != null) { + setHeight(newHeight); + } + + // Sets the width set by the user when resize the <textarea>. + String newWidth = (String) variables.get("width"); + if (newWidth != null) { + setWidth(newWidth); + } + if (variables.containsKey(TextFieldConstants.VAR_CURSOR)) { Integer object = (Integer) variables .get(TextFieldConstants.VAR_CURSOR); diff --git a/server/src/com/vaadin/ui/NotificationConfiguration.java b/server/src/com/vaadin/ui/NotificationConfiguration.java index faab329f88..925c888a51 100644 --- a/server/src/com/vaadin/ui/NotificationConfiguration.java +++ b/server/src/com/vaadin/ui/NotificationConfiguration.java @@ -173,7 +173,8 @@ class NotificationConfigurationImpl implements NotificationConfiguration { NotificationTypeConfiguration styleSetup = getTypeConf(type); if (styleSetup == null) { styleSetup = new NotificationTypeConfiguration(); - ui.getState().notificationConfigurations.put(type.getStyle(), styleSetup); + ui.getState().notificationConfigurations.put(type.getStyle(), + styleSetup); } return styleSetup; diff --git a/server/src/com/vaadin/ui/TabSheet.java b/server/src/com/vaadin/ui/TabSheet.java index 2fdb3b40a7..8b13ecf1a4 100644 --- a/server/src/com/vaadin/ui/TabSheet.java +++ b/server/src/com/vaadin/ui/TabSheet.java @@ -317,7 +317,8 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * the position at where the the tab should be added. * @return the created {@link Tab} */ - public Tab addTab(Component tabComponent, String caption, Resource icon, int position) { + public Tab addTab(Component tabComponent, String caption, Resource icon, + int position) { if (tabComponent == null) { return null; } else if (tabs.containsKey(tabComponent)) { @@ -1070,8 +1071,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, @Override public Resource getIcon() { - return getResource(ComponentConstants.ICON_RESOURCE - + tabState.key); + return getResource(ComponentConstants.ICON_RESOURCE + tabState.key); } @Override @@ -1211,8 +1211,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, @Override public void setIcon(Resource icon, String iconAltText) { - setResource(ComponentConstants.ICON_RESOURCE + tabState.key, - icon); + setResource(ComponentConstants.ICON_RESOURCE + tabState.key, icon); tabState.iconAltText = iconAltText; } } diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java index a8265662ea..84e4eaed13 100644 --- a/server/src/com/vaadin/ui/Table.java +++ b/server/src/com/vaadin/ui/Table.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -68,7 +68,7 @@ import com.vaadin.shared.ui.table.TableConstants; * <code>Table</code> is used for representing data or components in a pageable * and selectable table. * </p> - * + * * <p> * Scalability of the Table is largely dictated by the container. A table does * not have a limit for the number of items and is just as fast with hundreds of @@ -76,11 +76,11 @@ import com.vaadin.shared.ui.table.TableConstants; * scrolling however limits the number of rows to around 500000, depending on * the browser and the pixel height of rows. * </p> - * + * * <p> * Components in a Table will not have their caption nor icon rendered. * </p> - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -583,7 +583,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Creates a new empty table with caption. - * + * * @param caption */ public Table(String caption) { @@ -593,7 +593,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Creates a new table with caption and connect it to a Container. - * + * * @param caption * @param dataSource */ @@ -607,11 +607,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the array of visible column id:s, including generated columns. - * + * * <p> * The columns are show in the order of their appearance in this array. * </p> - * + * * @return an array of currently visible propertyIds and generated column * ids. */ @@ -624,11 +624,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the array of visible column property id:s. - * + * * <p> * The columns are show in the order of their appearance in this array. * </p> - * + * * @param visibleColumns * the Array of shown property id:s. */ @@ -690,7 +690,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the headers of the columns. - * + * * <p> * The headers match the property id:s given my the set visible column * headers. The table must be set in either @@ -699,7 +699,7 @@ public class Table extends AbstractSelect implements Action.Container, * headers. In the defaults mode any nulls in the headers array are replaced * with id.toString(). * </p> - * + * * @return the Array of column headers. */ public String[] getColumnHeaders() { @@ -717,7 +717,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the headers of the columns. - * + * * <p> * The headers match the property id:s given my the set visible column * headers. The table must be set in either @@ -726,7 +726,7 @@ public class Table extends AbstractSelect implements Action.Container, * headers. In the defaults mode any nulls in the headers array are replaced * with id.toString() outputs when rendering. * </p> - * + * * @param columnHeaders * the Array of column headers that match the * {@link #getVisibleColumns()} method. @@ -750,7 +750,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the icons of the columns. - * + * * <p> * The icons in headers match the property id:s given my the set visible * column headers. The table must be set in either @@ -758,7 +758,7 @@ public class Table extends AbstractSelect implements Action.Container, * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the headers * with icons. * </p> - * + * * @return the Array of icons that match the {@link #getVisibleColumns()}. */ public Resource[] getColumnIcons() { @@ -777,7 +777,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the icons of the columns. - * + * * <p> * The icons in headers match the property id:s given my the set visible * column headers. The table must be set in either @@ -785,7 +785,7 @@ public class Table extends AbstractSelect implements Action.Container, * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the headers * with icons. * </p> - * + * * @param columnIcons * the Array of icons that match the {@link #getVisibleColumns()} * . @@ -809,7 +809,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the array of column alignments. - * + * * <p> * The items in the array must match the properties identified by * {@link #getVisibleColumns()}. The possible values for the alignments @@ -822,7 +822,7 @@ public class Table extends AbstractSelect implements Action.Container, * The alignments default to {@link Align#LEFT}: any null values are * rendered as align lefts. * </p> - * + * * @return the Column alignments array. */ public Align[] getColumnAlignments() { @@ -841,7 +841,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the column alignments. - * + * * <p> * The amount of items in the array must match the amount of properties * identified by {@link #getVisibleColumns()}. The possible values for the @@ -853,7 +853,7 @@ public class Table extends AbstractSelect implements Action.Container, * </ul> * The alignments default to {@link Align#LEFT} * </p> - * + * * @param columnAlignments * the Column alignments array. */ @@ -882,11 +882,11 @@ public class Table extends AbstractSelect implements Action.Container, * Sets columns width (in pixels). Theme may not necessary respect very * small or very big values. Setting width to -1 (default) means that theme * will make decision of width. - * + * * <p> * Column can either have a fixed width or expand ratio. The latter one set * is used. See @link {@link #setColumnExpandRatio(Object, float)}. - * + * * @param propertyId * colunmns property id * @param width @@ -920,27 +920,27 @@ public class Table extends AbstractSelect implements Action.Container, * naturally. Excess space is the space that is not used by columns with * explicit width (see {@link #setColumnWidth(Object, int)}) or with natural * width (no width nor expand ratio). - * + * * <p> * By default (without expand ratios) the excess space is divided * proportionally to columns natural widths. - * + * * <p> * Only expand ratios of visible columns are used in final calculations. - * + * * <p> * Column can either have a fixed width or expand ratio. The latter one set * is used. - * + * * <p> * A column with expand ratio is considered to be minimum width by default * (if no excess space exists). The minimum width is defined by terminal * implementation. - * + * * <p> * If terminal implementation supports re-sizable columns the column becomes * fixed width column if users resizes the column. - * + * * @param propertyId * columns property id * @param expandRatio @@ -969,7 +969,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the column expand ratio for a columnd. See * {@link #setColumnExpandRatio(Object, float)} - * + * * @param propertyId * columns property id * @return the expandRatio used to divide excess space for this column @@ -984,7 +984,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the pixel width of column - * + * * @param propertyId * @return width of column or -1 when value not set */ @@ -1003,11 +1003,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the page length. - * + * * <p> * Setting page length 0 disables paging. * </p> - * + * * @return the Length of one page. */ public int getPageLength() { @@ -1016,16 +1016,16 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the page length. - * + * * <p> * Setting page length 0 disables paging. The page length defaults to 15. * </p> - * + * * <p> * If Table has width set ({@link #setWidth(float, int)} ) the client side * may update the page length automatically the correct value. * </p> - * + * * @param pageLength * the length of one page. */ @@ -1039,18 +1039,18 @@ public class Table extends AbstractSelect implements Action.Container, /** * This method adjusts a possible caching mechanism of table implementation. - * + * * <p> * Table component may fetch and render some rows outside visible area. With * complex tables (for example containing layouts and components), the * client side may become unresponsive. Setting the value lower, UI will * become more responsive. With higher values scrolling in client will hit * server less frequently. - * + * * <p> * The amount of cached rows will be cacheRate multiplied with pageLength ( * {@link #setPageLength(int)} both below and above visible area.. - * + * * @param cacheRate * a value over 0 (fastest rendering time). Higher value will * cache more rows on server (smoother scrolling). Default value @@ -1069,7 +1069,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * @see #setCacheRate(double) - * + * * @return the current cache rate value */ public double getCacheRate() { @@ -1078,7 +1078,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Getter for property currentPageFirstItem. - * + * * @return the Value of property currentPageFirstItem. */ public Object getCurrentPageFirstItemId() { @@ -1106,14 +1106,14 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the item ID for the item represented by the index given. Assumes * that the current container implements {@link Container.Indexed}. - * + * * See {@link Container.Indexed#getIdByIndex(int)} for more information * about the exceptions that can be thrown. - * + * * @param index * the index for which the item ID should be fetched * @return the item ID for the given index - * + * * @throws ClassCastException * if container does not implement {@link Container.Indexed} * @throws IndexOutOfBoundsException @@ -1126,7 +1126,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Setter for property currentPageFirstItemId. - * + * * @param currentPageFirstItemId * the New value of property currentPageFirstItemId. */ @@ -1183,7 +1183,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the icon Resource for the specified column. - * + * * @param propertyId * the propertyId indentifying the column. * @return the icon for the specified column; null if the column has no icon @@ -1198,7 +1198,7 @@ public class Table extends AbstractSelect implements Action.Container, * <p> * Throws IllegalArgumentException if the specified column is not visible. * </p> - * + * * @param propertyId * the propertyId identifying the column. * @param icon @@ -1217,7 +1217,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the header for the specified column. - * + * * @param propertyId * the propertyId identifying the column. * @return the header for the specified column if it has one. @@ -1238,7 +1238,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the column header for the specified column; - * + * * @param propertyId * the propertyId identifying the column. * @param header @@ -1257,7 +1257,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the specified column's alignment. - * + * * @param propertyId * the propertyID identifying the column. * @return the specified column's alignment if it as one; {@link Align#LEFT} @@ -1270,13 +1270,13 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the specified column's alignment. - * + * * <p> * Throws IllegalArgumentException if the alignment is not one of the * following: {@link Align#LEFT}, {@link Align#CENTER} or * {@link Align#RIGHT} * </p> - * + * * @param propertyId * the propertyID identifying the column. * @param alignment @@ -1296,7 +1296,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if the specified column is collapsed. - * + * * @param propertyId * the propertyID identifying the column. * @return true if the column is collapsed; false otherwise; @@ -1308,8 +1308,8 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets whether the specified column is collapsed or not. - * - * + * + * * @param propertyId * the propertyID identifying the column. * @param collapsed @@ -1338,7 +1338,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if column collapsing is allowed. - * + * * @return true if columns can be collapsed; false otherwise. */ public boolean isColumnCollapsingAllowed() { @@ -1347,7 +1347,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets whether column collapsing is allowed or not. - * + * * @param collapsingAllowed * specifies whether column collapsing is allowed. */ @@ -1369,7 +1369,7 @@ public class Table extends AbstractSelect implements Action.Container, * {@link #setColumnCollapsed(Object, boolean) setColumnCollapsed()}) if * {@link #isColumnCollapsingAllowed()} is true. By default all columns are * collapsible. - * + * * @param propertyId * the propertyID identifying the column. * @param collapsible @@ -1391,7 +1391,7 @@ public class Table extends AbstractSelect implements Action.Container, * UI or with {@link #setColumnCollapsed(Object, boolean) * setColumnCollapsed()}) if {@link #isColumnCollapsingAllowed()} is also * true. - * + * * @return true if the column can be collapsed; false otherwise. */ public boolean isColumnCollapsible(Object propertyId) { @@ -1400,7 +1400,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if column reordering is allowed. - * + * * @return true if columns can be reordered; false otherwise. */ public boolean isColumnReorderingAllowed() { @@ -1409,7 +1409,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets whether column reordering is allowed or not. - * + * * @param columnReorderingAllowed * specifies whether column reordering is allowed. */ @@ -1453,7 +1453,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Getter for property currentPageFirstItem. - * + * * @return the Value of property currentPageFirstItem. */ public int getCurrentPageFirstItemIndex() { @@ -1513,7 +1513,22 @@ public class Table extends AbstractSelect implements Action.Container, * position not be updated correctly when the lazy rows are * finally rendered. */ - currentPageFirstItemIndexOnLastPage = indexOnLastPage; + + boolean isLastRowPossiblyPartiallyVisible = true; + if (indexOnLastPage != -1) { + /* + * If the requested row was greater than maxIndex, the last + * row should be fully visible (See + * TestCurrentPageFirstItem). + */ + isLastRowPossiblyPartiallyVisible = false; + } + + int extraRows = isLastRowPossiblyPartiallyVisible ? 0 : 1; + currentPageFirstItemIndexOnLastPage = currentPageFirstItemIndex + + extraRows; + } else { + currentPageFirstItemIndexOnLastPage = -1; } } else { @@ -1569,7 +1584,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Setter for property currentPageFirstItem. - * + * * @param newIndex * the New value of property currentPageFirstItem. */ @@ -1579,11 +1594,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Getter for property selectable. - * + * * <p> * The table is not selectable by default. * </p> - * + * * @return the Value of property selectable. */ public boolean isSelectable() { @@ -1592,11 +1607,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Setter for property selectable. - * + * * <p> * The table is not selectable by default. * </p> - * + * * @param selectable * the New value of property selectable. */ @@ -1609,7 +1624,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Getter for property columnHeaderMode. - * + * * @return the Value of property columnHeaderMode. */ public ColumnHeaderMode getColumnHeaderMode() { @@ -1618,7 +1633,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Setter for property columnHeaderMode. - * + * * @param columnHeaderMode * the New value of property columnHeaderMode. */ @@ -1727,7 +1742,7 @@ public class Table extends AbstractSelect implements Action.Container, * occurred exception is set as the cause of this exception. All occurred * exceptions can be accessed using {@link #getCauses()}. * </p> - * + * */ public static class CacheUpdateException extends RuntimeException { private Throwable[] causes; @@ -1751,7 +1766,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the cause(s) for this exception - * + * * @return the exception(s) which caused this exception */ public Throwable[] getCauses() { @@ -1807,11 +1822,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Requests that the Table should be repainted as soon as possible. - * + * * Note that a {@code Table} does not necessarily repaint its contents when * this method has been called. See {@link #refreshRowCache()} for forcing * an update of the contents. - * + * * @deprecated As of 7.0, use {@link #markAsDirty()} instead */ @@ -1823,7 +1838,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Requests that the Table should be repainted as soon as possible. - * + * * Note that a {@code Table} does not necessarily repaint its contents when * this method has been called. See {@link #refreshRowCache()} for forcing * an update of the contents. @@ -2110,9 +2125,9 @@ public class Table extends AbstractSelect implements Action.Container, /** * Render rows with index "firstIndex" to "firstIndex+rows-1" to a new * buffer. - * + * * Reuses values from the current page buffer if the rows are found there. - * + * * @param firstIndex * @param rows * @param replaceListeners @@ -2221,7 +2236,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Update a cache array for a row, register any relevant listeners etc. - * + * * This is an internal method extracted from * {@link #getVisibleCellsNoCache(int, int, boolean)} and should be removed * when the Table is rewritten. @@ -2439,7 +2454,7 @@ public class Table extends AbstractSelect implements Action.Container, * Helper method to remove listeners and maintain correct component * hierarchy. Detaches properties and components if those are no more * rendered in client. - * + * * @param oldListenedProperties * set of properties that where listened in last render * @param oldVisibleComponents @@ -2475,12 +2490,12 @@ public class Table extends AbstractSelect implements Action.Container, * if it is a field, it needs to be detached from its property data source * in order to allow garbage collection to take care of removing the unused * component from memory. - * + * * Override this method and getPropertyValue(Object, Object, Property) with * custom logic if you need to deal with buffered fields. - * + * * @see #getPropertyValue(Object, Object, Property) - * + * * @param oldVisibleComponents * a set of components that should be unregistered. */ @@ -2531,7 +2546,7 @@ public class Table extends AbstractSelect implements Action.Container, * </ul> * The default value is {@link #ROW_HEADER_MODE_HIDDEN} * </p> - * + * * @param mode * the One of the modes listed above. */ @@ -2550,7 +2565,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the row header mode. - * + * * @return the Row header mode. * @see #setRowHeaderMode(int) */ @@ -2561,7 +2576,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds the new row to table and fill the visible cells (except generated * columns) with given values. - * + * * @param cells * the Object array that is used for filling the visible cells * new row. The types must be settable to visible column property @@ -2630,7 +2645,7 @@ public class Table extends AbstractSelect implements Action.Container, * <p> * <i>Note that calling this method is not cheap so avoid calling it * unnecessarily.</i> - * + * * @since 6.7.2 */ public void refreshRowCache() { @@ -2651,7 +2666,7 @@ public class Table extends AbstractSelect implements Action.Container, * Keeps propertyValueConverters if the corresponding id exists in the new * data source and is of a compatible type. * </p> - * + * * @param newDataSource * the new data source. */ @@ -2689,11 +2704,11 @@ public class Table extends AbstractSelect implements Action.Container, * Keeps propertyValueConverters if the corresponding id exists in the new * data source and is of a compatible type. * </p> - * + * * @see Table#setContainerDataSource(Container) * @see Table#setVisibleColumns(Object[]) * @see Table#setConverter(Object, Converter<String, ?>) - * + * * @param newDataSource * the new data source. * @param visibleIds @@ -2768,7 +2783,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if class b can be safely assigned to class a. - * + * * @param a * @param b * @return @@ -2782,7 +2797,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets items ids from a range of key values - * + * * @param startRowKey * The start key * @param endRowKey @@ -2803,7 +2818,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Handles selection if selection is a multiselection - * + * * @param variables * The variables */ @@ -2882,7 +2897,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Invoked when the value of a variable has changed. - * + * * @see com.vaadin.ui.Select#changeVariables(java.lang.Object, * java.util.Map) */ @@ -3084,7 +3099,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Handles click event - * + * * @param variables */ private void handleClickEvent(Map<String, Object> variables) { @@ -3138,7 +3153,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Handles the column resize event sent by the client. - * + * * @param variables */ private void handleColumnResizeEvent(Map<String, Object> variables) { @@ -3197,7 +3212,7 @@ public class Table extends AbstractSelect implements Action.Container, * Go to mode where content updates are not done. This is due we want to * bypass expensive content for some reason (like when we know we may have * other content changes on their way). - * + * * @return true if content refresh flag was enabled prior this call */ protected boolean disableContentRefreshing() { @@ -3208,7 +3223,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Go to mode where content content refreshing has effect. - * + * * @param refreshContent * true if content refresh needs to be done */ @@ -3408,7 +3423,7 @@ public class Table extends AbstractSelect implements Action.Container, * Subclass and override this to enable partial row updates and additions, * which bypass the normal caching mechanism. This is useful for e.g. * TreeTable. - * + * * @return true if this update is a partial row update, false if not. For * plain Table it is always false. */ @@ -3420,7 +3435,7 @@ public class Table extends AbstractSelect implements Action.Container, * Subclass and override this to enable partial row additions, bypassing the * normal caching mechanism. This is useful for e.g. TreeTable, where * expanding a node should only fetch and add the items inside of that node. - * + * * @return The index of the first added item. For plain Table it is always * 0. */ @@ -3432,7 +3447,7 @@ public class Table extends AbstractSelect implements Action.Container, * Subclass and override this to enable partial row additions, bypassing the * normal caching mechanism. This is useful for e.g. TreeTable, where * expanding a node should only fetch and add the items inside of that node. - * + * * @return the number of rows to be added, starting at the index returned by * {@link #getFirstAddedItemIndex()}. For plain Table it is always * 0. @@ -3445,11 +3460,11 @@ public class Table extends AbstractSelect implements Action.Container, * Subclass and override this to enable removing of rows, bypassing the * normal caching and lazy loading mechanism. This is useful for e.g. * TreeTable, when you need to hide certain rows as a node is collapsed. - * + * * This should return true if the rows pointed to by * {@link #getFirstAddedItemIndex()} and {@link #getAddedRowCount()} should * be hidden instead of added. - * + * * @return whether the rows to add (see {@link #getFirstAddedItemIndex()} * and {@link #getAddedRowCount()}) should be added or hidden. For * plain Table it is always false. @@ -3463,7 +3478,7 @@ public class Table extends AbstractSelect implements Action.Container, * normal caching and lazy loading mechanism. This is useful for updating * the state of certain rows, e.g. in the TreeTable the collapsed state of a * single node is updated using this mechanism. - * + * * @return the index of the first item to be updated. For plain Table it is * always 0. */ @@ -3476,7 +3491,7 @@ public class Table extends AbstractSelect implements Action.Container, * normal caching and lazy loading mechanism. This is useful for updating * the state of certain rows, e.g. in the TreeTable the collapsed state of a * single node is updated using this mechanism. - * + * * @return the number of rows to update, starting at the index returned by * {@link #getFirstUpdatedItemIndex()}. For plain table it is always * 0. @@ -3990,7 +4005,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * A method where extended Table implementations may add their custom * attributes for rows. - * + * * @param target * @param itemId */ @@ -4001,7 +4016,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the cached visible table contents. - * + * * @return the cached visible table contents. */ private Object[][] getVisibleCells() { @@ -4013,11 +4028,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the value of property. - * + * * By default if the table is editable the fieldFactory is used to create * editors for table cells. Otherwise formatPropertyValue is used to format * the value representation. - * + * * @param rowId * the Id of the row (same as item Id). * @param colId @@ -4049,7 +4064,7 @@ public class Table extends AbstractSelect implements Action.Container, * default behavior is to bind property straight to Field. If * Property.Viewer type property (e.g. PropertyFormatter) is already set for * field, the property is bound to that Property.Viewer. - * + * * @param rowId * @param colId * @param property @@ -4074,7 +4089,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Formats table cell property values. By default the property.toString() * and return a empty string for null properties. - * + * * @param rowId * the Id of the row (same as item Id). * @param colId @@ -4109,7 +4124,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Registers a new action handler for this container - * + * * @see com.vaadin.event.Action.Container#addActionHandler(Action.Handler) */ @@ -4137,7 +4152,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a previously registered action handler for the contents of this * container. - * + * * @see com.vaadin.event.Action.Container#removeActionHandler(Action.Handler) */ @@ -4176,9 +4191,9 @@ public class Table extends AbstractSelect implements Action.Container, /** * Notifies this listener that the Property's value has changed. - * + * * Also listens changes in rendered items to refresh content area. - * + * * @see com.vaadin.data.Property.ValueChangeListener#valueChange(Property.ValueChangeEvent) */ @@ -4209,7 +4224,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Notifies the component that it is connected to an application. - * + * * @see com.vaadin.ui.Component#attach() */ @@ -4222,7 +4237,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Notifies the component that it is detached from the application - * + * * @see com.vaadin.ui.Component#detach() */ @@ -4233,7 +4248,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes all Items from the Container. - * + * * @see com.vaadin.data.Container#removeAllItems() */ @@ -4246,7 +4261,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes the Item identified by <code>ItemId</code> from the Container. - * + * * @see com.vaadin.data.Container#removeItem(Object) */ @@ -4265,7 +4280,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a Property specified by the given Property ID from the Container. - * + * * @see com.vaadin.data.Container#removeContainerProperty(Object) */ @@ -4287,7 +4302,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds a new property to the table and show it as a visible column. - * + * * @param propertyId * the Id of the proprty. * @param type @@ -4322,7 +4337,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds a new property to the table and show it as a visible column. - * + * * @param propertyId * the Id of the proprty * @param type @@ -4378,7 +4393,7 @@ public class Table extends AbstractSelect implements Action.Container, * Also note that getVisibleColumns() will return the generated columns, * while getContainerPropertyIds() will not. * </p> - * + * * @param id * the id of the column to be added * @param generatedColumn @@ -4407,7 +4422,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the ColumnGenerator used to generate the given column. - * + * * @param columnId * The id of the generated column * @return The ColumnGenerator used for the given columnId or null. @@ -4419,7 +4434,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a generated column previously added with addGeneratedColumn. - * + * * @param columnId * id of the generated column to remove * @return true if the column could be removed (existed in the Table) @@ -4450,7 +4465,7 @@ public class Table extends AbstractSelect implements Action.Container, * architecture. Using {@link #getCurrentPageFirstItemId()} combined with * {@link #getPageLength()} may produce good enough estimates in some * situations. - * + * * @see com.vaadin.ui.Select#getVisibleItemIds() */ @@ -4474,7 +4489,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Container datasource item set change. Table must flush its buffers on * change. - * + * * @see com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange(com.vaadin.data.Container.ItemSetChangeEvent) */ @@ -4499,7 +4514,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Container datasource property set change. Table must flush its buffers on * change. - * + * * @see com.vaadin.data.Container.PropertySetChangeListener#containerPropertySetChange(com.vaadin.data.Container.PropertySetChangeEvent) */ @@ -4545,7 +4560,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adding new items is not supported. - * + * * @throws UnsupportedOperationException * if set to true. * @see com.vaadin.ui.Select#setNewItemsAllowed(boolean) @@ -4561,7 +4576,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the ID of the Item following the Item that corresponds to itemId. - * + * * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object) */ @@ -4573,7 +4588,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the ID of the Item preceding the Item that corresponds to the * itemId. - * + * * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object) */ @@ -4584,7 +4599,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the ID of the first Item in the Container. - * + * * @see com.vaadin.data.Container.Ordered#firstItemId() */ @@ -4595,7 +4610,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the ID of the last Item in the Container. - * + * * @see com.vaadin.data.Container.Ordered#lastItemId() */ @@ -4607,7 +4622,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Tests if the Item corresponding to the given Item ID is the first Item in * the Container. - * + * * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object) */ @@ -4619,7 +4634,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Tests if the Item corresponding to the given Item ID is the last Item in * the Container. - * + * * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object) */ @@ -4630,7 +4645,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds new item after the given item. - * + * * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object) */ @@ -4647,7 +4662,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds new item after the given item. - * + * * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, * java.lang.Object) */ @@ -4665,10 +4680,10 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the TableFieldFactory that is used to create editor for table cells. - * + * * The TableFieldFactory is only used if the Table is editable. By default * the DefaultFieldFactory is used. - * + * * @param fieldFactory * the field factory to set. * @see #isEditable @@ -4683,9 +4698,9 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the TableFieldFactory that is used to create editor for table cells. - * + * * The FieldFactory is only used if the Table is editable. - * + * * @return TableFieldFactory used to create the Field instances. * @see #isEditable */ @@ -4695,18 +4710,18 @@ public class Table extends AbstractSelect implements Action.Container, /** * Is table editable. - * + * * If table is editable a editor of type Field is created for each table * cell. The assigned FieldFactory is used to create the instances. - * + * * To provide custom editors for table cells create a class implementins the * FieldFactory interface, and assign it to table, and set the editable * property to true. - * + * * @return true if table is editable, false oterwise. * @see Field * @see FieldFactory - * + * */ public boolean isEditable() { return editable; @@ -4714,19 +4729,19 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the editable property. - * + * * If table is editable a editor of type Field is created for each table * cell. The assigned FieldFactory is used to create the instances. - * + * * To provide custom editors for table cells create a class implementins the * FieldFactory interface, and assign it to table, and set the editable * property to true. - * + * * @param editable * true if table should be editable by user. * @see Field * @see FieldFactory - * + * */ public void setEditable(boolean editable) { this.editable = editable; @@ -4737,13 +4752,13 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sorts the table. - * + * * @throws UnsupportedOperationException * if the container data source does not implement * Container.Sortable * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], * boolean[]) - * + * */ @Override @@ -4775,7 +4790,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sorts the table by currently selected sorting column. - * + * * @throws UnsupportedOperationException * if the container data source does not implement * Container.Sortable @@ -4795,7 +4810,7 @@ public class Table extends AbstractSelect implements Action.Container, * returns. Disabling sorting causes this method to always return an empty * collection. * </p> - * + * * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds() */ @@ -4811,7 +4826,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the currently sorted column property ID. - * + * * @return the Container property id of the currently sorted column. */ public Object getSortContainerPropertyId() { @@ -4820,7 +4835,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the currently sorted column property id. - * + * * @param propertyId * the Container property id of the currently sorted column. */ @@ -4831,7 +4846,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Internal method to set currently sorted column property id. With doSort * flag actual sorting may be bypassed. - * + * * @param propertyId * @param doSort */ @@ -4852,7 +4867,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Is the table currently sorted in ascending order. - * + * * @return <code>true</code> if ascending, <code>false</code> if descending. */ public boolean isSortAscending() { @@ -4861,7 +4876,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the table in ascending order. - * + * * @param ascending * <code>true</code> if ascending, <code>false</code> if * descending. @@ -4873,7 +4888,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Internal method to set sort ascending. With doSort flag actual sort can * be bypassed. - * + * * @param ascending * @param doSort */ @@ -4891,10 +4906,10 @@ public class Table extends AbstractSelect implements Action.Container, /** * Is sorting disabled altogether. - * + * * True iff no sortable columns are given even in the case where data source * would support this. - * + * * @return True iff sorting is disabled. * @deprecated As of 7.0, use {@link #isSortEnabled()} instead */ @@ -4905,7 +4920,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if sorting is enabled. - * + * * @return true if sorting by the user is allowed, false otherwise */ public boolean isSortEnabled() { @@ -4914,7 +4929,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Disables the sorting by the user altogether. - * + * * @param sortDisabled * True iff sorting is disabled. * @deprecated As of 7.0, use {@link #setSortEnabled(boolean)} instead @@ -4930,7 +4945,7 @@ public class Table extends AbstractSelect implements Action.Container, * Setting this to false disallows sorting by the user. It is still possible * to call {@link #sort()}. * </p> - * + * * @param sortEnabled * true to allow the user to sort the table, false to disallow it */ @@ -4945,14 +4960,14 @@ public class Table extends AbstractSelect implements Action.Container, * Used to create "generated columns"; columns that exist only in the Table, * not in the underlying Container. Implement this interface and pass it to * Table.addGeneratedColumn along with an id for the column to be generated. - * + * */ public interface ColumnGenerator extends Serializable { /** * Called by Table when a cell in a generated column needs to be * generated. - * + * * @param source * the source Table * @param itemId @@ -4970,7 +4985,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Set cell style generator for Table. - * + * * @param cellStyleGenerator * New cell style generator or null to remove generator. */ @@ -4984,7 +4999,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Get the current cell style generator. - * + * */ public CellStyleGenerator getCellStyleGenerator() { return cellStyleGenerator; @@ -5001,7 +5016,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Called by Table when a cell (and row) is painted. - * + * * @param source * the source Table * @param itemId @@ -5064,7 +5079,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the drag start mode of the Table. Drag start mode controls how Table * behaves as a drag source. - * + * * @param newDragMode */ public void setDragMode(TableDragMode newDragMode) { @@ -5083,9 +5098,9 @@ public class Table extends AbstractSelect implements Action.Container, /** * Concrete implementation of {@link DataBoundTransferable} for data * transferred from a table. - * + * * @see {@link DataBoundTransferable}. - * + * * @since 6.3 */ public class TableTransferable extends DataBoundTransferable { @@ -5147,7 +5162,7 @@ public class Table extends AbstractSelect implements Action.Container, * Note, that on some clients the mode may not be respected. E.g. on touch * based devices CTRL/SHIFT base selection method is invalid, so touch based * browsers always use the {@link MultiSelectMode#SIMPLE}. - * + * * @param mode * The select mode of the table */ @@ -5158,7 +5173,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the select mode in which multi-select is used. - * + * * @return The multi select mode */ public MultiSelectMode getMultiSelectMode() { @@ -5170,7 +5185,7 @@ public class Table extends AbstractSelect implements Action.Container, * from server once per drag and drop operation. Developer must override one * method that decides on which rows the currently dragged data can be * dropped. - * + * * <p> * Initially pretty much no data is sent to client. On first required * criterion check (per drag request) the client side data structure is @@ -5287,7 +5302,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the property id of the column which header was pressed - * + * * @return The column propety id */ public Object getPropertyId() { @@ -5321,7 +5336,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Constructor - * + * * @param source * The source of the component * @param propertyId @@ -5337,7 +5352,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the property id of the column which header was pressed - * + * * @return The column propety id */ public Object getPropertyId() { @@ -5353,7 +5368,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Called when a user clicks a header column cell - * + * * @param event * The event which contains information about the column and * the mouse click event @@ -5369,7 +5384,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Called when a user clicks a footer column cell - * + * * @param event * The event which contains information about the column and * the mouse click event @@ -5384,7 +5399,7 @@ public class Table extends AbstractSelect implements Action.Container, * The listener will receive events which contain information about which * column was clicked and some details about the mouse event. * </p> - * + * * @param listener * The handler which should handle the header click events. */ @@ -5405,7 +5420,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a header click listener - * + * * @param listener * The listener to remove. */ @@ -5430,7 +5445,7 @@ public class Table extends AbstractSelect implements Action.Container, * The listener will receive events which contain information about which * column was clicked and some details about the mouse event. * </p> - * + * * @param listener * The handler which should handle the footer click events. */ @@ -5451,7 +5466,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a footer click listener - * + * * @param listener * The listener to remove. */ @@ -5471,7 +5486,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the footer caption beneath the rows - * + * * @param propertyId * The propertyId of the column * * @return The caption of the footer or NULL if not set @@ -5483,10 +5498,10 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the column footer caption. The column footer caption is the text * displayed beneath the column if footers have been set visible. - * + * * @param propertyId * The properyId of the column - * + * * @param footer * The caption of the footer */ @@ -5506,7 +5521,7 @@ public class Table extends AbstractSelect implements Action.Container, * The footer can be used to add column related data like sums to the bottom * of the Table using setColumnFooter(Object propertyId, String footer). * </p> - * + * * @param visible * Should the footer be visible */ @@ -5519,7 +5534,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Is the footer currently visible? - * + * * @return Returns true if visible else false */ public boolean isFooterVisible() { @@ -5551,7 +5566,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Constructor - * + * * @param source * The source of the event * @param propertyId @@ -5571,7 +5586,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Get the column property id of the column that was resized. - * + * * @return The column property id */ public Object getPropertyId() { @@ -5580,7 +5595,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Get the width in pixels of the column before the resize event - * + * * @return Width in pixels */ public int getPreviousWidth() { @@ -5589,7 +5604,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Get the width in pixels of the column after the resize event - * + * * @return Width in pixels */ public int getCurrentWidth() { @@ -5604,7 +5619,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * This method is triggered when the column has been resized - * + * * @param event * The event which contains the column property id, the * previous width of the column and the current width of the @@ -5616,7 +5631,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds a column resize listener to the Table. A column resize listener is * called when a user resizes a columns width. - * + * * @param listener * The listener to attach to the Table */ @@ -5637,7 +5652,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a column resize listener from the Table. - * + * * @param listener * The listener to remove */ @@ -5674,7 +5689,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Constructor - * + * * @param source * The source of the event */ @@ -5691,7 +5706,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * This method is triggered when the column has been reordered - * + * * @param event */ public void columnReorder(ColumnReorderEvent event); @@ -5700,7 +5715,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds a column reorder listener to the Table. A column reorder listener is * called when a user reorders columns. - * + * * @param listener * The listener to attach to the Table */ @@ -5720,7 +5735,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a column reorder listener from the Table. - * + * * @param listener * The listener to remove */ @@ -5741,7 +5756,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Set the item description generator which generates tooltips for cells and * rows in the Table - * + * * @param generator * The generator to use or null to disable */ @@ -5766,7 +5781,7 @@ public class Table extends AbstractSelect implements Action.Container, * Row generators can be used to replace certain items in a table with a * generated string. The generator is called each time the table is * rendered, which means that new strings can be generated each time. - * + * * Row generators can be used for e.g. summary rows or grouping of items. */ public interface RowGenerator extends Serializable { @@ -5792,7 +5807,7 @@ public class Table extends AbstractSelect implements Action.Container, * For custom styling of a generated row you can combine a RowGenerator * with a CellStyleGenerator. * <p> - * + * * @param table * The Table that is being painted * @param itemId @@ -5811,7 +5826,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Creates a new generated row. If only one string is passed in, columns * are automatically spanned. - * + * * @param text */ public GeneratedRow(String... text) { @@ -5846,7 +5861,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * If set to true, all strings passed to {@link #setText(String...)} * will be rendered as HTML. - * + * * @param htmlContentAllowed */ public void setHtmlContentAllowed(boolean htmlContentAllowed) { @@ -5860,7 +5875,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * If set to true, only one string will be rendered, spanning the entire * row. - * + * * @param spanColumns */ public void setSpanColumns(boolean spanColumns) { @@ -5871,7 +5886,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Assigns a row generator to the table. The row generator will be able to * replace rows in the table when it is rendered. - * + * * @param generator * the new row generator */ @@ -5893,7 +5908,7 @@ public class Table extends AbstractSelect implements Action.Container, * The converter is used to format the the data for the given property id * before displaying it in the table. * </p> - * + * * @param propertyId * The propertyId to format using the converter * @param converter @@ -5918,7 +5933,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if there is a converter set explicitly for the given property id. - * + * * @param propertyId * The propertyId to check * @return true if a converter has been set for the property id, false @@ -5930,7 +5945,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the converter used to format the given propertyId. - * + * * @param propertyId * The propertyId to check * @return The converter used to format the propertyId or null if no diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index a72cbe5c30..5abeea9480 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -549,8 +549,6 @@ public abstract class UI extends AbstractSingleComponentContainer implements private boolean resizeLazy = false; - private String theme; - private Navigator navigator; private PushConnection pushConnection = null; @@ -633,7 +631,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements this.embedId = embedId; // Actual theme - used for finding CustomLayout templates - theme = request.getParameter("theme"); + getState().theme = request.getParameter("theme"); getPage().init(request); @@ -1135,12 +1133,31 @@ public abstract class UI extends AbstractSingleComponentContainer implements } /** - * Gets the theme that was used when the UI was initialized. + * Gets the theme currently in use by this UI * * @return the theme name */ public String getTheme() { - return theme; + return getState(false).theme; + } + + /** + * Sets the theme currently in use by this UI + * <p> + * Calling this method will remove the old theme (CSS file) from the + * application and add the new theme. + * <p> + * Note that this method is NOT SAFE to call in a portal environment or + * other environment where there are multiple UIs on the same page. The old + * CSS file will be removed even if there are other UIs on the page which + * are still using it. + * + * @since 7.3 + * @param theme + * The new theme name + */ + public void setTheme(String theme) { + getState().theme = theme; } /** diff --git a/server/src/com/vaadin/ui/themes/ValoTheme.java b/server/src/com/vaadin/ui/themes/ValoTheme.java index 63fa13dce4..ad949c6a32 100644 --- a/server/src/com/vaadin/ui/themes/ValoTheme.java +++ b/server/src/com/vaadin/ui/themes/ValoTheme.java @@ -15,6 +15,7 @@ */ package com.vaadin.ui.themes; +import com.vaadin.server.FontAwesome; import com.vaadin.ui.Notification.Type; import com.vaadin.ui.Table.ColumnHeaderMode; @@ -185,6 +186,18 @@ public class ValoTheme { */ public static final String LABEL_FAILURE = "failure"; + /** + * Spinner style. Add this style name to an empty Label to create a spinner. + * + * <h4>Example</h4> + * + * <pre> + * Label spinner = new Label(); + * spinner.addStyleName(ValoTheme.LABEL_SPINNER); + * </pre> + */ + public static final String LABEL_SPINNER = "spinner"; + /*************************************************************************** * * Button styles @@ -457,6 +470,12 @@ public class ValoTheme { */ public static final String OPTIONGROUP_LARGE = "large"; + /** + * Display the options horizontally in a row (by default the items are + * stacked vertically). + */ + public static final String OPTIONGROUP_HORIZONTAL = "horizontal"; + /*************************************************************************** * * Slider styles @@ -738,7 +757,7 @@ public class ValoTheme { /** * Removes the borders and background from any direct child field components * (TextField, TextArea, DateField, ComboBox) in the layout. Reduces the - * spacing between the form rows adds separator lines between them. + * spacing between the form rows and adds separator lines between them. */ public static final String FORMLAYOUT_LIGHT = "light"; @@ -762,6 +781,31 @@ public class ValoTheme { */ public static final String LAYOUT_WELL = "well"; + /** + * Make a HorizontalLayout wrap contained components to a new line when the + * isn't enough space. + */ + public static final String LAYOUT_HORIZONTAL_WRAPPING = "wrapping"; + + /** + * Add this style name to a CssLayout to create a grouped set of components, + * i.e. a row of components which are joined seamlessly together. + * + * <h4>Example</h4> + * + * <pre> + * CssLayout group = new CssLayout(); + * group.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); + * + * TextField field = new TextField(); + * group.addComponent(field); + * + * Button button = new Button("Action"); + * group.addComponent(button); + * </pre> + */ + public static final String LAYOUT_COMPONENT_GROUP = "v-component-group"; + /*************************************************************************** * * Valo menu styles @@ -769,8 +813,25 @@ public class ValoTheme { **************************************************************************/ /** - * Set the primary style name of a CssLayout to this, and add any number of - * layouts with the {@link #MENU_PART} style inside it. + * <p> + * Set the <em><b>primary</b></em> style name of a CssLayout to this, and + * add any number of layouts with the {@link #MENU_PART} style inside it. + * </p> + * + * <p> + * The menu style is used to create a sidebar navigation menu for the + * application, usually action as the main navigation for the different + * sections of the application. It usually consists of at least a number of + * {@link #MENU_ITEM}s, and possibly some {@link #MENU_SUBTITLE}s and a + * {@link #MENU_TITLE}. + * </p> + * + * <h4>Example</h4> + * + * <pre> + * CssLayout menuArea = new CssLayout(); + * menuArea.setPrimaryStyleName(ValoTheme.MENU_ROOT); + * </pre> */ public static final String MENU_ROOT = "valo-menu"; @@ -778,31 +839,124 @@ public class ValoTheme { * Add this style name to any layout and place it inside a layout with the * {@link #MENU_ROOT} style to build a menu component. Use the additional * MENU styles for individual components inside the layout. + * + * <h4>Example</h4> + * + * <pre> + * CssLayout menu = new CssLayout(); + * menu.addStyleName(ValoTheme.MENU_PART); + * </pre> */ public static final String MENU_PART = "valo-menu-part"; /** - * TODO + * Add this style name to any layout with the {@link #MENU_PART} style name + * to make any menu items inside the menu emphasize the icons more than the + * captions. Useful on narrower viewport widths, since the menu width is + * decreased quite dramatically, making more space for the content of the + * application. + * + * <h4>Example</h4> + * + * <pre> + * CssLayout menu = new CssLayout(); + * menu.addStyleName(ValoTheme.MENU_PART); + * menu.addStyleName(ValoTheme.MENU_PART_LARGE_ICONS); + * </pre> + */ + public static final String MENU_PART_LARGE_ICONS = "large-icons"; + + /** + * <p> + * Add this style name to any layout to make a header area for a menu + * (intended to be placed in side a {@link #MENU_PART} layout). You can add + * any components inside it, but usually you would place a Label inside. + * </p> + * + * <p> + * Any MenuBar component that you place inside this layout will match the + * style of the title, allowing an easy way to add a toolbar to the title + * layout. + * </p> */ public static final String MENU_TITLE = "valo-menu-title"; /** - * TODO + * Set the <em><b>primary</b></em> style name of a Label or a Button to this + * style name to create a section divider in a menu. */ public static final String MENU_SUBTITLE = "valo-menu-subtitle"; /** - * TODO + * <p> + * Set the <em><b>primary</b></em> style name of a Button to this style name + * to create a clickable menu item in the menu. + * </p> + * + * <h4>Selected item</h4> + * <p> + * Add an additional style name <b><code>selected</code></b> to it to make + * it the selected item in the menu. + * </p> + * + * <h4>Example</h4> + * + * <pre> + * Button item = new Button(); + * item.setPrimaryStyleName(ValoTheme.MENU_ITEM); + * item.addStyleName("selected"); + * </pre> */ - public static final String MENU_ITEM = "valo-menu-title"; + public static final String MENU_ITEM = "valo-menu-item"; /** - * TODO + * Add a SPAN element with this style name inside a {@link #MENU_SUBTITLE} + * or {@link #MENU_ITEM} to add an additional badge indicator to the + * subtitle/item. The Label/Button needs to allow HTML content in order to + * use this style name. + * + * <h4>Examples</h4> + * + * <pre> + * Button item = new Button(); + * item.setPrimaryStyleName(ValoTheme.MENU_ITEM); + * item.setHtmlContentAllowed(true); + * item.setCaption("Item Caption <span class=\"" + ValoTheme.MENU_BADGE + * + "\">Badge text</span>"); + * </pre> + * + * <pre> + * Label item = new Label(); + * item.setPrimaryStyleName(ValoTheme.MENU_ITEM); + * item.setContentMode(ContentMode.HTML); + * item.setCaption("Item Caption <span class=\"" + ValoTheme.MENU_BADGE + * + "\">Badge text</span>"); + * </pre> */ public static final String MENU_BADGE = "valo-menu-badge"; /** - * TODO + * <p> + * Set the <em><b>primary</b></em> style name of a Label or a Button to this + * style name to create an application logo. The logo is designed to be + * placed inside a {@link #MENU_PART} layout. + * </p> + * + * <p> + * The text content of the logo should be very short, since the logo area + * only shows approximately three letters. Using one of the + * {@link FontAwesome} icons is a good way to quickly create a logo for your + * application. + * </p> + * </p> + * + * <h4>Example</h4> + * + * <pre> + * Label logo = new Label(FontAwesome.ROCKET.getHtml(), ContentMode.HTML); + * logo.setSizeUndefined(); + * logo.setPrimaryStyleName(ValoTheme.MENU_LOGO); + * </pre> */ public static final String MENU_LOGO = "valo-menu-logo"; diff --git a/server/src/com/vaadin/util/CurrentInstance.java b/server/src/com/vaadin/util/CurrentInstance.java index 6f2c0a2eca..d11fa175ac 100644 --- a/server/src/com/vaadin/util/CurrentInstance.java +++ b/server/src/com/vaadin/util/CurrentInstance.java @@ -112,7 +112,7 @@ public class CurrentInstance implements Serializable { * ThreadLocal should only outlive the referenced object on * threads that are not doing anything related to Vaadin, which * should thus never invoke CurrentInstance.get(). - * + * * At this point, there might also be other values that have * been collected, so we'll scan the entire map and remove stale * CurrentInstance objects. Using a ReferenceQueue could make @@ -250,7 +250,7 @@ public class CurrentInstance implements Serializable { * CurrentInstance. Without this a reference to an already * collected instance may be left in the CurrentInstance when it * really should be restored to null. - * + * * One example case that this fixes: * VaadinService.runPendingAccessTasks() clears all current * instances and then sets everything but the UI. This makes diff --git a/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java b/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java index 6e40c57718..bf2b809529 100644 --- a/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java +++ b/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java @@ -42,7 +42,8 @@ public class VaadinPortletRequestTests { @Test public void defaultValueForPortletPreferenceIsNull() { - when(preferences.getValue(anyString(), isNull(String.class))).thenReturn(null); + when(preferences.getValue(anyString(), isNull(String.class))) + .thenReturn(null); String value = sut.getPortletPreference("foo"); diff --git a/shared/src/com/vaadin/shared/ApplicationConstants.java b/shared/src/com/vaadin/shared/ApplicationConstants.java index 15eefe3b21..44c972462a 100644 --- a/shared/src/com/vaadin/shared/ApplicationConstants.java +++ b/shared/src/com/vaadin/shared/ApplicationConstants.java @@ -78,6 +78,14 @@ public class ApplicationConstants implements Serializable { public static final String VAADIN_DIR_URL = "vaadinDir"; /** + * The name of the javascript containing the bootstrap code. The file is + * located in the VAADIN directory. + * + * @since 7.3 + */ + public static final String VAADIN_BOOTSTRAP_JS = "vaadinBootstrap.js"; + + /** * The name of the javascript containing push support. The file is located * in the VAADIN directory. */ diff --git a/shared/src/com/vaadin/shared/ui/ui/UIState.java b/shared/src/com/vaadin/shared/ui/ui/UIState.java index 3c3785b7d5..2f51fef6ee 100644 --- a/shared/src/com/vaadin/shared/ui/ui/UIState.java +++ b/shared/src/com/vaadin/shared/ui/ui/UIState.java @@ -62,6 +62,12 @@ public class UIState extends TabIndexState { * Configuration for the push channel */ public PushConfigurationState pushConfiguration = new PushConfigurationState(); + /** + * Currently used theme. + * + * @since 7.3 + */ + public String theme; { primaryStyleName = "v-ui"; // Default is 1 for legacy reasons @@ -95,7 +101,7 @@ public class UIState extends TabIndexState { NotificationRole role) { this.prefix = prefix; this.postfix = postfix; - this.notificationRole = role; + notificationRole = role; } } diff --git a/shared/src/com/vaadin/shared/util/SharedUtil.java b/shared/src/com/vaadin/shared/util/SharedUtil.java index 497a8cab01..7276f418fa 100644 --- a/shared/src/com/vaadin/shared/util/SharedUtil.java +++ b/shared/src/com/vaadin/shared/util/SharedUtil.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -19,17 +19,17 @@ import java.io.Serializable; /** * Misc internal utility methods used by both the server and the client package. - * + * * @author Vaadin Ltd * @since 7.1 - * + * */ public class SharedUtil implements Serializable { /** * Checks if a and b are equals using {@link #equals(Object)}. Handles null * values as well. Does not ensure that objects are of the same type. * Assumes that the first object's equals method handle equals properly. - * + * * @param o1 * The first value to compare * @param o2 @@ -46,11 +46,18 @@ public class SharedUtil implements Serializable { /** * Trims trailing slashes (if any) from a string. - * @param value The string value to be trimmed. Cannot be null. + * + * @param value + * The string value to be trimmed. Cannot be null. * @return String value without trailing slashes. */ public static String trimTrailingSlashes(String value) { return value.replaceAll("/*$", ""); } + /** + * RegEx pattern to extract the width/height values. + */ + public static final String SIZE_PATTERN = "^(-?\\d*(?:\\.\\d+)?)(%|px|em|rem|ex|in|cm|mm|pt|pc)?$"; + } diff --git a/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRoles.java b/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRoles.java new file mode 100644 index 0000000000..2ab6be25ac --- /dev/null +++ b/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRoles.java @@ -0,0 +1,107 @@ +/* + * 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.accessibility; + +import java.util.Stack; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.window.WindowRole; +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.Window; + +/** + * UI to test if subwindows get the correct assistive roles. + * + * @author Vaadin Ltd + */ +public class WindowWaiAriaRoles extends AbstractTestUI { + Stack<Window> windows = new Stack<Window>(); + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + Button closeButton = new Button("Close windows"); + closeButton.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + while (!windows.isEmpty()) { + Window window = windows.pop(); + removeWindow(window); + } + } + + }); + + Button regularButton = new Button("Regular"); + regularButton.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + Window regularWindow = new Window("Regular window"); + openWindow(regularWindow); + } + }); + + Button alertButton = new Button("Alert"); + alertButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + Window alertWindow = new Window("Alert window"); + alertWindow.setAssistiveRole(WindowRole.ALERTDIALOG); + openWindow(alertWindow); + } + }); + addComponent(closeButton); + addComponent(regularButton); + addComponent(alertButton); + } + + void openWindow(Window window) { + windows.push(window); + window.center(); + addWindow(window); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "The alert window should have the role 'alertdialog' and the regular window should have the role 'dialog'"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 14289; + } + +} diff --git a/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRolesTest.java b/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRolesTest.java new file mode 100644 index 0000000000..e1d0452708 --- /dev/null +++ b/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRolesTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.accessibility; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.WindowElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test to see if regular and alert windows get the correct wai-aria roles + * + * @author Vaadin Ltd + */ +public class WindowWaiAriaRolesTest extends MultiBrowserTest { + + @Test + public void testRegularWindowRole() { + openTestURL(); + + $(ButtonElement.class).caption("Regular").first().click(); + String role = getWindowRole(); + Assert.assertTrue("Dialog has incorrect role '" + role + + "', expected 'dialog'", "dialog".equals(role)); + } + + @Test + public void testAlertWindowRole() { + openTestURL(); + $(ButtonElement.class).caption("Alert").first().click(); + String role = getWindowRole(); + Assert.assertTrue("Dialog has incorrect role '" + role + + "', expected 'alertdialog'", "alertdialog".equals(role)); + } + + public String getWindowRole() { + return $(WindowElement.class).first().getAttribute("role"); + } +} diff --git a/uitest/src/com/vaadin/tests/components/abstractcomponent/PrimaryStyleTest.java b/uitest/src/com/vaadin/tests/components/abstractcomponent/PrimaryStyleTest.java index ce99c4a3d5..8500fbe18d 100644 --- a/uitest/src/com/vaadin/tests/components/abstractcomponent/PrimaryStyleTest.java +++ b/uitest/src/com/vaadin/tests/components/abstractcomponent/PrimaryStyleTest.java @@ -43,7 +43,8 @@ public class PrimaryStyleTest extends MultiBrowserTest { $(ButtonElement.class).id("update-button").click(); // Verify that the class names where updated as expected. - List<WebElement> updatedElements = driver.findElements(By.className("updated-correctly")); + List<WebElement> updatedElements = driver.findElements(By + .className("updated-correctly")); assertThat(updatedElements, hasSize(initialElements.size())); } diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonToggleIcons.java b/uitest/src/com/vaadin/tests/components/button/ButtonToggleIcons.java index 25dd469903..cee71fdf4e 100644 --- a/uitest/src/com/vaadin/tests/components/button/ButtonToggleIcons.java +++ b/uitest/src/com/vaadin/tests/components/button/ButtonToggleIcons.java @@ -35,4 +35,4 @@ public class ButtonToggleIcons extends UI { layout.addComponent(new Button("Toggle icon", iconToggleListener));
layout.addComponent(new NativeButton("Toggle icon", iconToggleListener));
}
-} +}
diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.html b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.html deleted file mode 100644 index 0aaa01f05b..0000000000 --- a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.html +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>ButtonUndefinedWidth</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">ButtonUndefinedWidth</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.button.ButtonUndefinedWidth</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VNativeButton[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VNativeButton[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[2]</td> - <td>636,149</td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>1</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.java b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.java index 89b03df92a..e8a2e10d9a 100644 --- a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.java +++ b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.java @@ -1,15 +1,22 @@ package com.vaadin.tests.components.button; import com.vaadin.data.Item; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.NativeButton; import com.vaadin.ui.Table; -public class ButtonUndefinedWidth extends TestBase { +/** + * Test UI for buttons with undefined width. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class ButtonUndefinedWidth extends AbstractTestUI { @Override - protected String getDescription() { + protected String getTestDescription() { return "Both the button outside the table and inside the table should be only as wide as necessary. There should be empty space in the table to the right of the button."; } @@ -18,8 +25,9 @@ public class ButtonUndefinedWidth extends TestBase { return 3257; } + @SuppressWarnings("unchecked") @Override - protected void setup() { + protected void setup(VaadinRequest request) { Button b = new Button("Undefined wide"); addComponent(b); NativeButton b2 = new NativeButton("Undefined wide"); @@ -36,5 +44,4 @@ public class ButtonUndefinedWidth extends TestBase { addComponent(t); } - } diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidthTest.java b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidthTest.java new file mode 100644 index 0000000000..850dd1229c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidthTest.java @@ -0,0 +1,109 @@ +/* + * 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.button; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.NativeButtonElement; +import com.vaadin.testbench.elements.VerticalLayoutElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Validates button Widths for Buttons or Native Buttons, inside or outside + * tables. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class ButtonUndefinedWidthTest extends MultiBrowserTest { + + @Test + public void undefinedButtonWidthTest() throws Exception { + openTestURL(); + + // make sure all the elements are rendered before commencing tests + waitForElementVisible(By.className("v-table-row-odd")); + + // click all of the buttons + for (NativeButtonElement button : $(NativeButtonElement.class).all()) { + button.click(); + } + for (ButtonElement button : $(ButtonElement.class).all()) { + button.click(); + } + + // remove focus + getDriver().findElement(By.className("v-app")).click(); + + // check button widths in VerticalLayout + VerticalLayoutElement vLayout = $(VerticalLayoutElement.class).$( + VerticalLayoutElement.class).first(); + int containerWidth = vLayout.getSize().getWidth(); + + NativeButtonElement nativeButton = vLayout.$(NativeButtonElement.class) + .first(); + int buttonWidth = nativeButton.getSize().getWidth(); + + assertButtonWidth(buttonWidth, containerWidth); + + ButtonElement button = vLayout.$(ButtonElement.class).first(); + buttonWidth = button.getSize().getWidth(); + assertButtonWidth(buttonWidth, containerWidth); + + // check button widths in table, also make sure that there is some + // spacing between the table edges and buttons + List<WebElement> rows = findElements(By + .className("v-table-cell-content")); + int rowWidth = rows.get(0).getSize().getWidth(); + + List<WebElement> rowWrappers = findElements(By + .className("v-table-cell-wrapper")); + WebElement row = rowWrappers.get(0); + + containerWidth = row.getSize().getWidth(); + assertRowWrapperWidth(containerWidth, rowWidth); + + buttonWidth = row.findElement(By.className("v-button")).getSize() + .getWidth(); + assertButtonWidth(buttonWidth, containerWidth); + + row = rowWrappers.get(1); + containerWidth = row.getSize().getWidth(); + assertRowWrapperWidth(containerWidth, rowWidth); + + buttonWidth = row.findElement(By.className("v-nativebutton")).getSize() + .getWidth(); + assertButtonWidth(buttonWidth, containerWidth); + + } + + private void assertRowWrapperWidth(int wrapperWidth, int rowWidth) { + Assert.assertTrue("Wrapper should be narrower than its parent: " + + wrapperWidth + " < " + rowWidth, wrapperWidth < rowWidth); + } + + private void assertButtonWidth(int buttonWidth, int containerWidth) { + Assert.assertTrue("Button should be narrower than its parent: " + + buttonWidth + " < " + containerWidth, + buttonWidth < containerWidth); + } +} diff --git a/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRpcCountTest.java b/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRpcCountTest.java index 9d6640eb6d..69a919497b 100644 --- a/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRpcCountTest.java +++ b/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRpcCountTest.java @@ -40,7 +40,7 @@ public class CheckBoxRpcCountTest extends MultiBrowserTest { // Click on the actual checkbox. inputElem.click(); - //Have to use waitUntil to make this test more stable. + // Have to use waitUntil to make this test more stable. waitUntilLabelIsUpdated(countElem, "1 RPC call(s) made."); // Click on the checkbox label. @@ -52,7 +52,8 @@ public class CheckBoxRpcCountTest extends MultiBrowserTest { waitUntilLabelIsUpdated(countElem, "3 RPC call(s) made."); } - private void waitUntilLabelIsUpdated(final WebElement countElem, final String expectedText) { + private void waitUntilLabelIsUpdated(final WebElement countElem, + final String expectedText) { waitUntil(new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver input) { diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxFiltering.html b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxFiltering.html deleted file mode 100644 index 3de221871d..0000000000 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxFiltering.html +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.combobox.ComboBoxSlow?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSlow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>92,19</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSlow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>1</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>filter-no-match</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSlow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>Item 12</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>filter-11-matches-paging</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>filter-11-matches-page-2</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSlow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>Item 100</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>filter-2-matches-no-paging</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.html b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.html deleted file mode 100644 index 3ad7d62a09..0000000000 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.html +++ /dev/null @@ -1,116 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.combobox.ComboBoxIdenticalItems?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>66,8</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>enter</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::PID_SLog_row_0</td> - <td>1. Item one-1 selected</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>enter</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::PID_SLog_row_0</td> - <td>2. Item one-2 selected</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>enter</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::PID_SLog_row_0</td> - <td>3. Item two selected</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>up</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>up</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>up</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>enter</td> -</tr> -<tr> - <td>pause</td> - <td>100</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::PID_SLog_row_0</td> - <td>4. Item one-1 selected</td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.java index 5f33b96a73..cdae1c8e38 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.java @@ -3,16 +3,18 @@ package com.vaadin.tests.components.combobox; import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.tests.util.Log; import com.vaadin.ui.ComboBox; -public class ComboBoxIdenticalItems extends TestBase { +public class ComboBoxIdenticalItems extends AbstractTestUI { private Log log = new Log(5); + @SuppressWarnings("unchecked") @Override - public void setup() { + protected void setup(VaadinRequest request) { final ComboBox select = new ComboBox("ComboBox"); select.addContainerProperty("caption", String.class, null); Item item = select.addItem("one-1"); @@ -24,9 +26,7 @@ public class ComboBoxIdenticalItems extends TestBase { select.setItemCaptionPropertyId("caption"); select.setNullSelectionAllowed(false); select.setImmediate(true); - select.addListener(new Property.ValueChangeListener() { - private static final long serialVersionUID = -7932700771673919620L; - + select.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { log.log("Item " + select.getValue() + " selected"); @@ -39,7 +39,7 @@ public class ComboBoxIdenticalItems extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Keyboard selecting of a value is broken in combobox if two " + "items have the same caption. The first item's id is \"One-1\" " + "while the second one is \"One-2\". Selecting with mouse works " @@ -49,7 +49,6 @@ public class ComboBoxIdenticalItems extends TestBase { @Override protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; + return 6125; } } diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java new file mode 100644 index 0000000000..d2cb80ae67 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.combobox; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * @author Vaadin Ltd + */ +public class ComboBoxIdenticalItemsTest extends MultiBrowserTest { + + private WebElement select; + + /* This test has been directly ported from a TB2 test */ + @Test + public void identicalItemsKeyboardTest() throws Exception { + openTestURL(); + + // wait for the UI to be fully loaded + waitForElementVisible(By.className("v-filterselect")); + waitForElementVisible(By.id("Log")); + + select = findElement(By + .vaadin("/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]")); + select.click(); + + Keys[] downDownEnter = new Keys[] { Keys.ARROW_DOWN, Keys.ARROW_DOWN, + Keys.ENTER }; + sendKeys(downDownEnter); + assertLogText("1. Item one-1 selected"); + + sendKeys(downDownEnter); + assertLogText("2. Item one-2 selected"); + + sendKeys(downDownEnter); + assertLogText("3. Item two selected"); + + sendKeys(new Keys[] { Keys.ARROW_UP, Keys.ARROW_UP, Keys.ARROW_UP, + Keys.ENTER }); + assertLogText("4. Item one-1 selected"); + } + + private void assertLogText(String expected) throws Exception { + String text = findElement(By.vaadin("PID_SLog_row_0")).getText(); + Assert.assertTrue("Expected '" + expected + "' found '" + text + "'", + text.equals(expected)); + } + + private void sendKeys(Keys[] keys) throws Exception { + for (Keys key : keys) { + select.sendKeys(key); + // wait a while between the key presses, at least PhantomJS fails if + // they are sent too fast + sleep(10); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxInputPromptTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxInputPromptTest.java index 96151022ff..cbd83c5734 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxInputPromptTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxInputPromptTest.java @@ -40,13 +40,16 @@ public class ComboBoxInputPromptTest extends MultiBrowserTest { ComboBoxElement disabledComboBox = getComboBoxWithCaption("Disabled"); ComboBoxElement readOnlyComboBox = getComboBoxWithCaption("Read-only"); - assertThat(getInputPromptValue(normalComboBox), is("Normal input prompt")); + assertThat(getInputPromptValue(normalComboBox), + is("Normal input prompt")); assertThat(getInputPromptValue(disabledComboBox), isEmptyString()); assertThat(getInputPromptValue(readOnlyComboBox), isEmptyString()); toggleDisabledAndReadonly(); - assertThat(getInputPromptValue(disabledComboBox), is("Disabled input prompt")); - assertThat(getInputPromptValue(readOnlyComboBox), is("Read-only input prompt")); + assertThat(getInputPromptValue(disabledComboBox), + is("Disabled input prompt")); + assertThat(getInputPromptValue(readOnlyComboBox), + is("Read-only input prompt")); toggleDisabledAndReadonly(); assertThat(getInputPromptValue(disabledComboBox), isEmptyString()); diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreen.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreen.java new file mode 100644 index 0000000000..044214cecf --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreen.java @@ -0,0 +1,76 @@ +/* + * 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 com.vaadin.data.Item; +import com.vaadin.server.ClassResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.ComboBox; + +/** + * Test UI for issue #11929 where ComboBox suggestion popup hides the ComboBox + * itself obscuring the text input field. + * + * @author Vaadin Ltd + */ +public class ComboBoxOnSmallScreen extends AbstractTestUI { + + private static final String PID = "captionPID"; + + @Override + protected void setup(VaadinRequest request) { + addComponents(createComboBox()); + } + + @Override + protected String getTestDescription() { + return "Combobox hides what you are typing on small screen"; + } + + @Override + protected Integer getTicketNumber() { + return 11929; + } + + private ComboBox createComboBox() { + ComboBox cb = new ComboBox(); + cb.addContainerProperty(PID, String.class, ""); + cb.setItemCaptionPropertyId(PID); + + Object selectId = null; + + for (int i = 1; i < 22; ++i) { + final String v = "Item #" + i; + Object itemId = cb.addItem(); + + if (i == 9) { + selectId = itemId; + } + + Item item = cb.getItem(itemId); + item.getItemProperty(PID).setValue(v); + int flagIndex = i % 3; + cb.setItemIcon(itemId, new ClassResource( + flagIndex == 0 ? "fi_small.png" : flagIndex == 1 ? "fi.gif" + : "se.gif")); + } + + cb.select(selectId); + + return cb; + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreenTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreenTest.java new file mode 100644 index 0000000000..f48f2bbdeb --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreenTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.combobox; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.WebDriver.Window; +import org.openqa.selenium.WebElement; + +import com.vaadin.client.ui.VFilterSelect; +import com.vaadin.testbench.elements.ComboBoxElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * ComboBox suggestion popup should not obscure the text input box. + * + * @author Vaadin Ltd + */ +public class ComboBoxOnSmallScreenTest extends MultiBrowserTest { + + private static final Dimension TARGETSIZE = new Dimension(600, 300); + private static final String POPUPCLASSNAME = VFilterSelect.CLASSNAME + + "-suggestpopup"; + + ComboBoxElement combobox; + WebElement popup; + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + + getWindow().setSize(TARGETSIZE); + + combobox = $(ComboBoxElement.class).first(); + combobox.openPopup(); + + popup = findElement(By.className(POPUPCLASSNAME)); + } + + @Test + public void testSuggestionPopupOverlayPosition() { + final int popupTop = popup.getLocation().y; + final int popupBottom = popupTop + popup.getSize().getHeight(); + final int cbTop = combobox.getLocation().y; + final int cbBottom = cbTop + combobox.getSize().getHeight(); + + assertThat("Popup overlay overlaps with the textbox", + popupTop >= cbBottom || popupBottom <= cbTop, is(true)); + } + + @Test + public void testSuggestionPopupOverlaySize() { + final int popupTop = popup.getLocation().y; + final int popupBottom = popupTop + popup.getSize().getHeight(); + final int rootHeight = findElement(By.tagName("body")).getSize().height; + + assertThat("Popup overlay out of the screen", popupTop < 0 + || popupBottom > rootHeight, is(false)); + } + + private Window getWindow() { + return getDriver().manage().window(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java index fa6f5a3a93..bc1fe39fe5 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java @@ -52,8 +52,7 @@ public class ComboBoxScrollingWithArrowsTest extends MultiBrowserTest { // provide any way to access the popup and send keys to it. // Ticket #13756 - return driver.findElement(By - .className("v-filterselect-input")); + return driver.findElement(By.className("v-filterselect-input")); } private void openPopup() { @@ -70,7 +69,7 @@ public class ComboBoxScrollingWithArrowsTest extends MultiBrowserTest { dropDownComboBox.sendKeys(Keys.DOWN); } - assertThat(getSelectedItemText(), is("item " + PAGESIZE)); //item 10 + assertThat(getSelectedItemText(), is("item " + PAGESIZE)); // item 10 } private String getSelectedItemText() { @@ -92,7 +91,8 @@ public class ComboBoxScrollingWithArrowsTest extends MultiBrowserTest { waitUntilNextPageIsVisible(); dropDownComboBox.sendKeys(Keys.UP); - assertThat(getSelectedItemText(), is("item " + (PAGESIZE - 1))); //item 9 + assertThat(getSelectedItemText(), is("item " + (PAGESIZE - 1))); // item + // 9 } private void waitUntilNextPageIsVisible() { diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSlowTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSlowTest.java new file mode 100644 index 0000000000..f030c0f5a0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSlowTest.java @@ -0,0 +1,108 @@ +/* + * 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Verifies SlowComboBox filtering works when user inputs text. Also verifies + * pagination works when the matching results number more than those that can be + * displayed. + * + * @since + * @author Vaadin Ltd + */ +public class ComboBoxSlowTest extends MultiBrowserTest { + + @Before + public void init() { + openTestURL(); + } + + @Test + public void testZeroMatches() throws InterruptedException { + clickComboBoxTextArea(); + sleep(250); + typeString("1"); + assertEquals(0, getNumberOfSuggestions()); + } + + @Test + public void testElevenMatchesAndPaging() throws InterruptedException { + clickComboBoxTextArea(); + sleep(250); + typeString("Item 12"); + + assertEquals(10, getNumberOfSuggestions()); + assertTrue(isPagingActive()); + goToNextPage(); + + sleep(500); + assertEquals(1, getNumberOfSuggestions()); + + } + + @Test + public void testTwoMatchesNoPaging() { + clickComboBoxTextArea(); + typeString("Item 100"); + assertEquals(2, getNumberOfSuggestions()); + assertFalse(isPagingActive()); + } + + private void clickComboBoxTextArea() { + WebElement cb = getDriver().findElement( + By.className("v-filterselect-input")); + cb.click(); + } + + private void typeString(String s) { + Actions action = new Actions(getDriver()); + action.sendKeys(s); + action.build().perform(); + } + + private int getNumberOfSuggestions() { + + List<WebElement> elements = getDriver().findElements( + By.className("gwt-MenuItem")); + return elements.size(); + } + + private boolean isPagingActive() { + List<WebElement> elements = getDriver().findElements( + By.className("v-filterselect-nextpage")); + return elements.size() == 1; + } + + private void goToNextPage() { + WebElement nextPage = getDriver().findElement( + By.className("v-filterselect-nextpage")); + nextPage.click(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxUndefinedWidthAndIcon.html b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxUndefinedWidthAndIcon.html index ae0dfec828..8366f2dc8c 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxUndefinedWidthAndIcon.html +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxUndefinedWidthAndIcon.html @@ -1,3 +1,16 @@ +<?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.combobox.ComboBoxUndefinedWidthAndIcon?restartApplication</td> @@ -83,3 +96,6 @@ <td></td> <td>item33-selected-after-popup-opened-and-closed</td> </tr> +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/combobox/fi.png b/uitest/src/com/vaadin/tests/components/combobox/fi.png Binary files differnew file mode 100644 index 0000000000..976a9663ce --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/fi.png diff --git a/uitest/src/com/vaadin/tests/components/combobox/fi_small.png b/uitest/src/com/vaadin/tests/components/combobox/fi_small.png Binary files differnew file mode 100644 index 0000000000..2908973fa4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/fi_small.png diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java new file mode 100644 index 0000000000..9dbd8fa6dc --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.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.datefield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.datefield.Resolution; +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.DateField; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.PopupDateField; + +public class DateFieldChangeResolution extends AbstractTestUI { + + public static final String DATEFIELD_ID = "datefield"; + // The ID of a button is BUTTON_BASE_ID + resolution, e.g. button-month + public static final String BUTTON_BASE_ID = "button-"; + + @Override + protected void setup(VaadinRequest request) { + final DateField dateField = new PopupDateField("Enter date"); + dateField.setResolution(Resolution.YEAR); + dateField.setId(DATEFIELD_ID); + dateField.setImmediate(true); + addComponent(dateField); + + Label l = new Label("Select resolution"); + addComponent(l); + HorizontalLayout hlayout = new HorizontalLayout(); + addComponent(hlayout); + for (final Resolution value : Resolution.values()) { + String resolutionString = value.toString().toLowerCase(); + Button b = new Button(resolutionString); + b.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + dateField.setResolution(value); + } + }); + b.setId(BUTTON_BASE_ID + resolutionString); + hlayout.addComponent(b); + } + + } + + @Override + protected String getTestDescription() { + return "The calendar should always have the correct resolution and the text field should be empty before selecting a date."; + } + + @Override + protected Integer getTicketNumber() { + return 14174; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java new file mode 100644 index 0000000000..6820410059 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java @@ -0,0 +1,197 @@ +/* + * 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 com.vaadin.tests.components.datefield.DateFieldChangeResolution.BUTTON_BASE_ID; +import static com.vaadin.tests.components.datefield.DateFieldChangeResolution.DATEFIELD_ID; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateFieldChangeResolutionTest extends MultiBrowserTest { + + private WebElement dateFieldButton, textField; + private WebElement resolutionSecond, resolutionMinute, resolutionHour, + resolutionDay, resolutionMonth, resolutionYear; + + @Test + public void changeResolutionBetweenYearAndMonth() throws Exception { + initialize(); + click(resolutionMonth); + checkHeaderAndBody(Resolution.MONTH, true); + click(resolutionYear); + checkHeaderAndBody(Resolution.YEAR, true); + } + + @Test + public void changeResolutionBetweenYearAndSecond() throws Exception { + initialize(); + click(resolutionSecond); + checkHeaderAndBody(Resolution.SECOND, true); + click(resolutionYear); + checkHeaderAndBody(Resolution.YEAR, true); + } + + @Test + public void changeResolutionToDayThenMonth() throws Exception { + initialize(); + checkHeaderAndBody(Resolution.YEAR, true); // check the initial state + click(resolutionDay); + checkHeaderAndBody(Resolution.DAY, true); + click(resolutionMonth); + checkHeaderAndBody(Resolution.MONTH, true); + } + + @Test + public void setDateAndChangeResolution() throws Exception { + initialize(); + // Set the date to previous month. + click(resolutionMonth); + openPopupDateField(); + click(driver.findElement(By.className("v-button-prevmonth"))); + closePopupDateField(); + assertFalse( + "The text field of the calendar should not be empty after selecting a date", + textField.getAttribute("value").isEmpty()); + // Change resolutions and check that the selected date is not lost and + // that the calendar has the correct resolution. + click(resolutionHour); + checkHeaderAndBody(Resolution.HOUR, false); + click(resolutionYear); + checkHeaderAndBody(Resolution.YEAR, false); + click(resolutionMinute); + checkHeaderAndBody(Resolution.MINUTE, false); + } + + private void initialize() { + openTestURL(); + WebElement dateField = driver.findElement(By.id(DATEFIELD_ID)); + dateFieldButton = dateField.findElement(By + .className("v-datefield-button")); + textField = dateField + .findElement(By.className("v-datefield-textfield")); + resolutionSecond = driver.findElement(By.id(BUTTON_BASE_ID + "second")); + resolutionMinute = driver.findElement(By.id(BUTTON_BASE_ID + "minute")); + resolutionHour = driver.findElement(By.id(BUTTON_BASE_ID + "hour")); + resolutionDay = driver.findElement(By.id(BUTTON_BASE_ID + "day")); + resolutionMonth = driver.findElement(By.id(BUTTON_BASE_ID + "month")); + resolutionYear = driver.findElement(By.id(BUTTON_BASE_ID + "year")); + } + + private void checkHeaderAndBody(Resolution resolution, + boolean textFieldIsEmpty) { + // Open the popup calendar, perform checks and close the popup. + openPopupDateField(); + if (resolution.getCalendarField() >= Resolution.MONTH + .getCalendarField()) { + checkMonthHeader(); + } else { + checkYearHeader(); + } + if (resolution.getCalendarField() >= Resolution.DAY.getCalendarField()) { + assertTrue( + "A calendar with the chosen resolution should have a body", + calendarHasBody()); + } else { + assertFalse( + "A calendar with the chosen resolution should not have a body", + calendarHasBody()); + } + if (textFieldIsEmpty) { + assertTrue("The text field of the calendar should be empty", + textField.getAttribute("value").isEmpty()); + } else { + assertFalse("The text field of the calendar should not be empty", + textField.getAttribute("value").isEmpty()); + } + closePopupDateField(); + } + + private void checkMonthHeader() { + checkHeaderForYear(); + checkHeaderForMonth(true); + } + + private void checkYearHeader() { + checkHeaderForYear(); + checkHeaderForMonth(false); + } + + private boolean calendarHasBody() { + return isElementPresent(By.className("v-datefield-calendarpanel-body")); + } + + private void checkHeaderForMonth(boolean buttonsExpected) { + // If buttonsExpected is true, check that there are buttons for changing + // the month. Otherwise check that there are no such buttons. + if (buttonsExpected) { + assertTrue( + "The calendar should have a button for switching to the previous month", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-prevmonth .v-button-prevmonth"))); + assertTrue( + "The calendar should have a button for switching to the next month", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-nextmonth .v-button-nextmonth"))); + } else { + assertFalse( + "The calendar should not have a button for switching to the previous month", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-prevmonth .v-button-prevmonth"))); + assertFalse( + "The calendar should not have a button for switching to the next month", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-nextmonth .v-button-nextmonth"))); + } + } + + private void checkHeaderForYear() { + assertTrue( + "The calendar should have a button for switching to the previous year", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-prevyear .v-button-prevyear"))); + assertTrue( + "The calendar header should show the selected year", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-month"))); + assertTrue( + "The calendar should have a button for switching to the next year", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-nextyear .v-button-nextyear"))); + + } + + private void click(WebElement element) { + testBenchElement(element).click(5, 5); + } + + private void openPopupDateField() { + click(dateFieldButton); + } + + private void closePopupDateField() { + WebElement element = driver.findElement(By + .cssSelector(".v-datefield-calendarpanel")); + element.sendKeys(Keys.ESCAPE); + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldClose.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldClose.java new file mode 100644 index 0000000000..9ce190a293 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldClose.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 DateFieldClose 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 "A click on the button should open a calendar and a second click should close it."; + } + + @Override + protected Integer getTicketNumber() { + return 14086; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldCloseTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldCloseTest.java new file mode 100644 index 0000000000..e6f7520813 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldCloseTest.java @@ -0,0 +1,66 @@ +/* + * 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 com.vaadin.tests.components.datefield.DateFieldClose.DATEFIELD_ID; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateFieldCloseTest extends MultiBrowserTest { + private WebElement dateField; + + @Test + public void closeByClickingCalendarButton() throws Exception { + openTestURL(); + dateField = driver.findElement(By.id(DATEFIELD_ID)); + clickButton(); + checkForCalendarHeader(true); + closePopup(); + checkForCalendarHeader(false); + } + + private void checkForCalendarHeader(boolean headerShouldExist) { + boolean headerExists = isElementPresent(By + .className("v-datefield-calendarpanel-header")); + if (headerShouldExist) { + assertTrue("The calendar should be visible", headerExists); + } else { + assertFalse("The calendar should not be visible", headerExists); + } + } + + private void clickButton() { + WebElement dateFieldButton = dateField.findElement(By + .className("v-datefield-button")); + testBenchElement(dateFieldButton).click(5, 5); + } + + private void closePopup() { + WebElement dateFieldButton = dateField.findElement(By + .className("v-datefield-button")); + // To work reliably with IE, need to click and hold instead of just + // clicking the button. + Actions actions = new Actions(driver); + actions.clickAndHold(dateFieldButton).perform(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldRanges_MonthChangeMeansFocusDayRolledInsideRange.html b/uitest/src/com/vaadin/tests/components/datefield/DateFieldRanges_MonthChangeMeansFocusDayRolledInsideRange.html index 6e1ca024cb..1135c650f5 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/DateFieldRanges_MonthChangeMeansFocusDayRolledInsideRange.html +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldRanges_MonthChangeMeansFocusDayRolledInsideRange.html @@ -1,3 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> <tr> <td>open</td> <td>/run/com.vaadin.tests.components.datefield.DateFieldRanges</td> @@ -98,3 +111,6 @@ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr/td[3]/span</td> <td>February 2010</td> </tr> +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldReadOnlyTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldReadOnlyTest.java index 289a5988ee..cfab13e205 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/DateFieldReadOnlyTest.java +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldReadOnlyTest.java @@ -1,6 +1,5 @@ package com.vaadin.tests.components.datefield; - import com.vaadin.testbench.By; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.DateFieldElement; @@ -14,7 +13,8 @@ import java.io.IOException; public class DateFieldReadOnlyTest extends MultiBrowserTest { @Test - public void readOnlyDateFieldPopupShouldNotOpen() throws IOException, InterruptedException { + public void readOnlyDateFieldPopupShouldNotOpen() throws IOException, + InterruptedException { openTestURL(); compareScreen("initial"); @@ -29,12 +29,15 @@ public class DateFieldReadOnlyTest extends MultiBrowserTest { } private void closePopup() { - findElement(By.className("v-datefield-calendarpanel")).sendKeys(Keys.RETURN); + findElement(By.className("v-datefield-calendarpanel")).sendKeys( + Keys.RETURN); } private void openPopup() { - //waiting for openPopup() in TB4 beta1: http://dev.vaadin.com/ticket/13766 - $(DateFieldElement.class).first().findElement(By.tagName("button")).click(); + // waiting for openPopup() in TB4 beta1: + // http://dev.vaadin.com/ticket/13766 + $(DateFieldElement.class).first().findElement(By.tagName("button")) + .click(); } private void toggleReadOnly() { diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/MoveComponentsFromGridLayoutToInnerLayoutTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/MoveComponentsFromGridLayoutToInnerLayoutTest.java index eb4888ea1a..95152e1416 100644 --- a/uitest/src/com/vaadin/tests/components/gridlayout/MoveComponentsFromGridLayoutToInnerLayoutTest.java +++ b/uitest/src/com/vaadin/tests/components/gridlayout/MoveComponentsFromGridLayoutToInnerLayoutTest.java @@ -9,7 +9,8 @@ import java.io.IOException; import static org.junit.Assert.*; -public class MoveComponentsFromGridLayoutToInnerLayoutTest extends MultiBrowserTest { +public class MoveComponentsFromGridLayoutToInnerLayoutTest extends + MultiBrowserTest { @Test public void buttonIsMovedInsideInnerLayout() throws IOException { diff --git a/uitest/src/com/vaadin/tests/components/label/LabelTooltip-chameleon.html b/uitest/src/com/vaadin/tests/components/label/LabelTooltip-chameleon.html index 4a724795b3..8a042ede92 100644 --- a/uitest/src/com/vaadin/tests/components/label/LabelTooltip-chameleon.html +++ b/uitest/src/com/vaadin/tests/components/label/LabelTooltip-chameleon.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.label.LabelTooltip?restartApplication&theme=chameleon</td> + <td>/run/com.vaadin.tests.components.label.LabelTooltip?restartApplication&theme=chameleon</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/label/LabelTooltip-runo.html b/uitest/src/com/vaadin/tests/components/label/LabelTooltip-runo.html index 9877493b3b..34fb088ff9 100644 --- a/uitest/src/com/vaadin/tests/components/label/LabelTooltip-runo.html +++ b/uitest/src/com/vaadin/tests/components/label/LabelTooltip-runo.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.label.LabelTooltip?restartApplication&theme=runo</td> + <td>/run/com.vaadin.tests.components.label.LabelTooltip?restartApplication&theme=runo</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java index bb8f87daaa..24025b9f39 100644 --- a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java +++ b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java @@ -47,7 +47,8 @@ public class MenuTooltipTest extends MultiBrowserTest { public void testToolTipDelay() throws InterruptedException { openTestURL(); - Coordinates elementCoordinates = getCoordinates($(MenuBarElement.class).first()); + Coordinates elementCoordinates = getCoordinates($(MenuBarElement.class) + .first()); Mouse mouse = ((HasInputDevices) getDriver()).getMouse(); diff --git a/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClick.java b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClick.java new file mode 100644 index 0000000000..b6c80aea0c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClick.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.tests.components.nativebutton; + +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.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.NativeButton; + +/** + * UI used to validate click coordinates reported from clicks on NativeButton + * elements. + * + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class NativeButtonClick extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + final Label label1 = new Label("0,0"); + final Label label2 = new Label("0,0"); + + Button button1 = new NativeButton("Button1", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + label1.setValue(event.getClientX() + "," + + event.getClientY()); + } + }); + Button button2 = new NativeButton("Button2", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + label2.setValue(event.getClientX() + "," + + event.getClientY()); + } + }); + + HorizontalLayout layout = new HorizontalLayout(); + layout.addComponents(button1, button2, label1, label2); + layout.setSpacing(true); + addComponent(layout); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Validate click event coordinates not erroneously returned as x=0, y=0"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 14022; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClickTest.java b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClickTest.java new file mode 100644 index 0000000000..cab2acefff --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClickTest.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.nativebutton; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test to see if coordinates returned by click event on NativeButtons look + * good. (see #14022) + * + * @author Vaadin Ltd + */ +public class NativeButtonClickTest extends MultiBrowserTest { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.tb3.MultiBrowserTest#getBrowsersToTest() + */ + + @Test + public void testClickCoordinates() { + openTestURL(); + + clickFirstButton(); + String eventCoordinates = getFirstLabelValue(); + Assert.assertNotEquals("0,0", eventCoordinates); + + clickSecondButton(); + eventCoordinates = getSecondLabelValue(); + Assert.assertNotEquals("0,0", eventCoordinates); + } + + private void clickFirstButton() { + ButtonElement button = $(ButtonElement.class).first(); + button.click(); + } + + private void clickSecondButton() { + ButtonElement button = $(ButtonElement.class).get(1); + button.click(); + } + + private String getFirstLabelValue() { + LabelElement label = $(LabelElement.class).get(1); + return label.getText(); + } + + private String getSecondLabelValue() { + LabelElement label = $(LabelElement.class).get(2); + return label.getText(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.html b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.html deleted file mode 100644 index fb00953e48..0000000000 --- a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.html +++ /dev/null @@ -1,107 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>NotificationsWaiAria</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">NotificationsWaiAria</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.notification.NotificationsWaiAria?restartApplication</td> - <td></td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTextField[0]</td> - <td>Prefix:</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VTextField[0]</td> - <td>- press ESC to close</td> -</tr> -<tr> - <td>select</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VNativeSelect[0]/domChild[0]</td> - <td>label=ALERT</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertElementPresent</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]</td> - <td></td> -</tr> -<tr> - <td>assertAttribute</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]@role</td> - <td>alert</td> -</tr> -<tr> - <td>assertText</td> - <td>xpath=//div[@class='v-Notification humanized v-Notification-humanized']//span[@class='v-assistive-device-only'][1]</td> - <td>Prefix:</td> -</tr> -<tr> - <td>assertText</td> - <td>xpath=//div[@class='v-Notification humanized v-Notification-humanized']//span[@class='v-assistive-device-only'][2]</td> - <td>- press ESC to close</td> -</tr> -<tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]</td> - <td>0,0</td> -</tr> -<tr> - <td>select</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VNativeSelect[0]/domChild[0]</td> - <td>label=STATUS</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertAttribute</td> - <td>xpath=/html/body/div[2]/div@role</td> - <td>status</td> -</tr> -<tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]</td> - <td>0,0</td> -</tr> -<tr> - <td>type</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTextField[0]</td> - <td></td> -</tr> -<tr> - <td>type</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VTextField[0]</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]/domChild[0]/domChild[0]/domChild[1]</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java index ecf704835f..e85d60d7c2 100644 --- a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java +++ b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java @@ -2,8 +2,9 @@ package com.vaadin.tests.components.notification; import com.vaadin.data.Item; import com.vaadin.server.Page; +import com.vaadin.server.VaadinRequest; import com.vaadin.shared.ui.ui.NotificationRole; -import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; @@ -16,10 +17,15 @@ import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; -public class NotificationsWaiAria extends TestBase { +/** + * Test UI for different roles of Notifications. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class NotificationsWaiAria extends AbstractTestUI { private static final String CAPTION = "CAPTION"; - private static final String ROLE = "ROLE"; private TextField prefix; private TextField postfix; @@ -28,9 +34,9 @@ public class NotificationsWaiAria extends TestBase { private TextArea tf; private ComboBox type; - @SuppressWarnings("deprecation") + @SuppressWarnings("unchecked") @Override - protected void setup() { + protected void setup(VaadinRequest request) { prefix = new TextField("Prefix", "Info"); addComponent(prefix); @@ -53,16 +59,16 @@ public class NotificationsWaiAria extends TestBase { type.setItemCaptionPropertyId(CAPTION); - Item item = type.addItem(Notification.TYPE_HUMANIZED_MESSAGE); + Item item = type.addItem(Notification.Type.HUMANIZED_MESSAGE); item.getItemProperty(CAPTION).setValue("Humanized"); - item = type.addItem(Notification.TYPE_ERROR_MESSAGE); + item = type.addItem(Notification.Type.ERROR_MESSAGE); item.getItemProperty(CAPTION).setValue("Error"); - item = type.addItem(Notification.TYPE_WARNING_MESSAGE); + item = type.addItem(Notification.Type.WARNING_MESSAGE); item.getItemProperty(CAPTION).setValue("Warning"); - item = type.addItem(Notification.TYPE_TRAY_NOTIFICATION); + item = type.addItem(Notification.Type.TRAY_NOTIFICATION); item.getItemProperty(CAPTION).setValue("Tray"); item = type.addItem(Notification.Type.ASSISTIVE_NOTIFICATION); @@ -81,13 +87,12 @@ public class NotificationsWaiAria extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Generic test case for notifications"; } @Override protected Integer getTicketNumber() { - // TODO Auto-generated method stub return null; } @@ -97,13 +102,14 @@ public class NotificationsWaiAria extends TestBase { Type typeValue = (Type) type.getValue(); Notification n = new Notification(tf.getValue(), typeValue); + n.setDelayMsec(-1); n.setHtmlContentAllowed(true); NotificationConfiguration notificationConf = UI.getCurrent() .getNotificationConfiguration(); notificationConf.setAssistivePrefix(typeValue, prefix.getValue()); notificationConf.setAssistivePostfix(typeValue, postfix.getValue()); - notificationConf - .setAssistiveRole(typeValue, (NotificationRole) role.getValue()); + notificationConf.setAssistiveRole(typeValue, + (NotificationRole) role.getValue()); n.show(Page.getCurrent()); } @@ -118,4 +124,5 @@ public class NotificationsWaiAria extends TestBase { n.show(Page.getCurrent()); } } + } diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java new file mode 100644 index 0000000000..6b517e9887 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java @@ -0,0 +1,126 @@ +/* + * 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.notification; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.shared.ui.ui.NotificationRole; +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.NativeSelectElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Unit test class for Notification ARIA (Accessible Rich Internet Applications) + * roles. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class NotificationsWaiAriaTest extends MultiBrowserTest { + + /** + * Checks if the ARIA roles are correctly applied to Notification. + * + * @since 7.2 + * @throws Exception + */ + @Test + public void notificationTest() throws Exception { + openTestURL(); + + TextFieldElement prefix = $(TextFieldElement.class).first(); + TextFieldElement postfix = $(TextFieldElement.class).get(1); + NativeSelectElement type = $(NativeSelectElement.class).first(); + ButtonElement show = $(ButtonElement.class).first(); + + prefix.clear(); + prefix.sendKeys("Prefix:"); + + postfix.clear(); + postfix.sendKeys("- press ESC to close"); + + type.selectByText(NotificationRole.ALERT.toString()); + + show.click(); + waitForElementPresent(By.className("v-Notification")); + + NotificationElement notification = $(NotificationElement.class).first(); + + String text = notification.getAttribute("role"); + Assert.assertTrue("Expected attribute 'role' to equal 'alert', found " + + text, text.equals("alert")); + + text = getHiddenText(notification.findElements( + By.className("v-assistive-device-only")).get(0)); + Assert.assertTrue("Expected 'Prefix:', found " + text, + text.equals("Prefix:")); + + text = getHiddenText(notification.findElements( + By.className("v-assistive-device-only")).get(1)); + Assert.assertTrue("Expected '- press ESC to close', found " + text, + text.equals("- press ESC to close")); + + try { + notification.closeNotification(); + } catch (Exception e) { + } + + type.selectByText("STATUS"); + + show.click(); + waitForElementPresent(By.className("v-Notification")); + + notification = $(NotificationElement.class).first(); + + text = notification.getAttribute("role"); + Assert.assertTrue("Expected attribute 'role' to equal 'status', found " + + text, text.equals("status")); + + try { + notification.closeNotification(); + } catch (Exception e) { + } + + prefix.clear(); + postfix.clear(); + + show.click(); + waitForElementPresent(By.className("v-Notification")); + + WebElement element; + try { + element = getDriver() + .findElement( + By.vaadin("Root/VNotification[0]/domChild[0]/domChild[0]/domChild[1]")); + } catch (Exception e) { + element = null; + } + Assert.assertNull( + "Notification shouldn't have assistive-device-only spans", + element); + + } + + private String getHiddenText(WebElement element) { + return (String) getTestBenchCommandExecutor().executeScript( + "return arguments[0].innerHTML", element); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/EditableModeChange.html b/uitest/src/com/vaadin/tests/components/table/EditableModeChange.html deleted file mode 100644 index 6414c9bc03..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/EditableModeChange.html +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.EditableModeChange?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>24,8</td> -</tr> -<!--Set into editable mode--> -<tr> - <td>doubleClick</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>24,8</td> -</tr> -<!--Update name for selected row--> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>baa</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> - <td>34,11</td> -</tr> -<!--Ensure the name was updated--> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>baa</td> -</tr> -<!--Ensure the correct row is selected--> -<tr> - <td>screenCapture</td> - <td></td> - <td>selected-teemu</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/EditableModeChange.java b/uitest/src/com/vaadin/tests/components/table/EditableModeChange.java index fa8ab8f0f5..e792c90af1 100644 --- a/uitest/src/com/vaadin/tests/components/table/EditableModeChange.java +++ b/uitest/src/com/vaadin/tests/components/table/EditableModeChange.java @@ -7,22 +7,24 @@ import java.util.Locale; import com.vaadin.data.Container; import com.vaadin.event.ItemClickEvent; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Component; import com.vaadin.ui.DefaultFieldFactory; import com.vaadin.ui.Field; import com.vaadin.ui.Table; import com.vaadin.ui.TableFieldFactory; -public class EditableModeChange extends TestBase { +public class EditableModeChange extends AbstractTestUI { private ItemClickEvent selectionEvent; private final String[] names = { "Teemu", "Teppo", "Seppo", "Matti", "Pekka" }; + @SuppressWarnings("unchecked") @Override - public void setup() { + public void setup(VaadinRequest request) { final Table items = new Table("Items - double-click to edit"); items.setSelectable(true); @@ -42,7 +44,7 @@ public class EditableModeChange extends TestBase { .setValue(new FormattedDate(cal.getTime().getTime())); } - items.addListener(new ItemClickEvent.ItemClickListener() { + items.addItemClickListener(new ItemClickEvent.ItemClickListener() { @Override public void itemClick(ItemClickEvent event) { @@ -89,7 +91,7 @@ public class EditableModeChange extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Double click a cell to edit, then click on another row to select it (editmode is set to false). The clicked row should now be selected without any flickering."; } diff --git a/uitest/src/com/vaadin/tests/components/table/EditableModeChangeTest.java b/uitest/src/com/vaadin/tests/components/table/EditableModeChangeTest.java new file mode 100644 index 0000000000..56b30dcb7c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/EditableModeChangeTest.java @@ -0,0 +1,90 @@ +/* + * 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.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that editing and selecting work correctly. + * + * @author Vaadin Ltd + */ +public class EditableModeChangeTest extends MultiBrowserTest { + + @Test + public void testNotification() throws IOException, InterruptedException { + openTestURL(); + + TableElement table = $(TableElement.class).first(); + + // check original value + TestBenchElement cell_1_0 = table.getCell(1, 0); + assertEquals( + "original value not found, wrong cell or contents (1st column of the 2nd row expected)", + "Teppo", cell_1_0.getText()); + + // double-click to edit cell contents + cell_1_0.click(); + new Actions(getDriver()).doubleClick(cell_1_0).build().perform(); + sleep(100); + + // fetch the updated cell + WebElement textField = table.getCell(1, 0).findElement( + By.className("v-textfield")); + assertEquals( + "original value not found, wrong cell or contents (1st column of the 2nd row expected)", + "Teppo", textField.getAttribute("value")); + + // update value + textField.clear(); + textField.sendKeys("baa"); + + // click on another row + table.getCell(0, 1).click(); + + // check the value got updated correctly + assertEquals( + "updated value not found, wrong cell or contents (1st column of the 2nd row expected)", + "baa", table.getCell(1, 0).getText()); + + // check that selection got updated correctly + List<WebElement> selected = table.findElement( + By.className("v-table-body")).findElements( + By.className("v-selected")); + assertEquals(1, selected.size()); + + WebElement content = selected.get(0).findElement( + By.className("v-table-cell-wrapper")); + assertEquals( + "expected value not found, wrong cell or contents (1st column of the 1st row expected)", + "Teemu", content.getText()); + + compareScreen("selection"); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnly.java b/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnly.java new file mode 100644 index 0000000000..e643ef5fa0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnly.java @@ -0,0 +1,109 @@ +/* + * 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 java.io.Serializable; +import java.util.List; + +import com.vaadin.data.util.BeanContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; + +/** + * + * @author Vaadin Ltd + */ + +@SuppressWarnings("serial") +public class SetPageFirstItemLoadsNeededRowsOnly extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + final VerticalLayout layout = new VerticalLayout(); + addComponent(layout); + + final Label label = new Label(""); + addComponent(label); + + BeanContainer<String, Bean> beans = new BeanContainer<String, Bean>( + Bean.class) { + @Override + public List<String> getItemIds(int startIndex, int numberOfIds) { + label.setValue("rows requested: " + numberOfIds); + return super.getItemIds(startIndex, numberOfIds); + } + }; + + beans.setBeanIdProperty("i"); + for (int i = 0; i < 2000; i++) { + beans.addBean(new Bean(i)); + } + + final Table table = new Table("Beans", beans); + table.setVisibleColumns(new Object[] { "i" }); + layout.addComponent(table); + + table.setCurrentPageFirstItemIndex(table.size() - 1); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Only cached rows and rows in viewport should be rendered after " + + "calling table.setCurrentPageFirstItemIndex(n) - as opposed to all rows " + + "between the previous position and new position"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 14135; + } + + public class Bean implements Serializable { + + private Integer i; + + public Bean(Integer i) { + this.i = i; + } + + public Integer getI() { + return i; + } + + public void setI(Integer i) { + this.i = i; + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnlyTest.java b/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnlyTest.java new file mode 100644 index 0000000000..ebf53e9a6d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnlyTest.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.table; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * + * @author Vaadin Ltd + */ +public class SetPageFirstItemLoadsNeededRowsOnlyTest extends MultiBrowserTest { + + /* + * expectedRowsRequested is related to VScrollTable's cache_rate and + * pageLength. See for instance VScrollTable.ensureCacheFilled(). + * + * This also takes into account if the visible rows are at the very start or + * end of the table, if the user scrolled or the + * Table.setCurrentPageFirstItemIndex(int) method was used. + * + * This value should not change if cache_rate and pageLength are not changed + * as well, and if this test remains constant: the table is scrolled to the + * very end (done in the actual UI: SetPageFirstItemLoadsNeededRowsOnly). + */ + private int expectedRowsRequested = 45; + + @Test + public void verifyLoadedRows() throws InterruptedException { + + openTestURL(); + + // wait for events to be processed in UI after loading page + sleep(2000); + + String labelValue = $(LabelElement.class).get(1).getText(); + String expectedLabelValue = "rows requested: " + expectedRowsRequested; + String errorMessage = "Too many rows were requested"; + assertEquals(errorMessage, expectedLabelValue, labelValue); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.html b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.html deleted file mode 100644 index 7ad0873c0f..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.html +++ /dev/null @@ -1,132 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>TableClickAndDragOnIconAndComponents</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TableClickAndDragOnIconAndComponents</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.TableClickAndDragOnIconAndComponents?restartApplication</td> - <td></td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td> - <td>38,13</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td> - <td>1,1</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VLabel[0]</td> - <td>30,9</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>71,11</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]/VTextField[1]</td> - <td>34,9</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VEmbedded[0]/domChild[0]</td> - <td>9,8</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>drag</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[4]/domChild[1]</td> - <td>2,16</td> -</tr> -<tr> - <td>drop</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[1]/domChild[0]</td> - <td>22,18</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[1]/domChild[0]</td> - <td>foo 4foo</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java index 62a131cbbf..64f1a64558 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java +++ b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java @@ -9,29 +9,31 @@ import com.vaadin.event.dd.acceptcriteria.AcceptAll; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; import com.vaadin.server.Resource; import com.vaadin.server.ThemeResource; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails; import com.vaadin.ui.Component; import com.vaadin.ui.Embedded; import com.vaadin.ui.Label; import com.vaadin.ui.Table; import com.vaadin.ui.Table.ColumnGenerator; +import com.vaadin.ui.Table.RowHeaderMode; import com.vaadin.ui.Table.TableDragMode; import com.vaadin.ui.TextField; -public class TableClickAndDragOnIconAndComponents extends TestBase { +public class TableClickAndDragOnIconAndComponents extends AbstractTestUI { private static final long serialVersionUID = -2534880024131980135L; private Table table; @Override - protected void setup() { + protected void setup(VaadinRequest request) { table = new Table(); table.addContainerProperty("foo", String.class, "foo"); table.addContainerProperty("red", String.class, "red"); table.addContainerProperty("icon", Resource.class, null); table.setSelectable(true); - table.setRowHeaderMode(Table.ROW_HEADER_MODE_ICON_ONLY); + table.setRowHeaderMode(RowHeaderMode.ICON_ONLY); table.setItemIconPropertyId("icon"); table.setId("testable-table"); addComponent(table); @@ -122,6 +124,7 @@ public class TableClickAndDragOnIconAndComponents extends TestBase { }); } + @SuppressWarnings("unchecked") private void addItemAfter(Object itemId, Object afterItemId) { Item item; if (afterItemId != null) { @@ -136,7 +139,7 @@ public class TableClickAndDragOnIconAndComponents extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Tests that you can click on a row icon in a table to select the row, or to drag the row. Verifies also that the table doesn't capture the click events meant for components inside the table"; } diff --git a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponentsTest.java b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponentsTest.java new file mode 100644 index 0000000000..4a46342cab --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponentsTest.java @@ -0,0 +1,238 @@ +/* + * 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.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that clicking on active fields doesn't change Table selection, nor does + * dragging rows. + * + * @author Vaadin Ltd + */ +public class TableClickAndDragOnIconAndComponentsTest extends MultiBrowserTest { + @Test + public void testClickingAndDragging() { + openTestURL(); + + TableElement table = $(TableElement.class).first(); + + // ensure there's no initial selection + List<WebElement> selected = table.findElements(By + .className("v-selected")); + assertTrue("selection found when there should be none", + selected.isEmpty()); + + // click a cell + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 2nd row expected)", + "red 1foo", table.getCell(1, 2).getText()); + table.getCell(1, 2).click(); + + // ensure the correct row and nothing but that got selected + selected = table.findElements(By.className("v-selected")); + assertFalse("no selection found when there should be some", + selected.isEmpty()); + // find cell contents (row header included) + List<WebElement> cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 2nd row expected)", + "red 1foo", cellContents.get(2).getText()); + assertEquals("unexpected table selection size", 1, selected.size()); + + List<WebElement> rows = table.findElement(By.className("v-table-body")) + .findElements(By.tagName("tr")); + assertEquals("unexpected table row count", 5, rows.size()); + + // find a row that isn't the one selected + cellContents = rows.get(2).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + + // click on a TextField on that row + WebElement textField = rows.get(2) + .findElements(By.className("v-textfield")).get(0); + assertEquals( + "expected value not found, wrong cell or contents (6th column of the 3rd row expected)", + "foo 2foo", textField.getAttribute("value")); + textField.click(); + + // ensure the focus shifted correctly + List<WebElement> focused = table.findElements(By + .className("v-textfield-focus")); + assertEquals("unexpected amount of focused textfields", 1, + focused.size()); + assertEquals( + "expected value not found, wrong cell or contents (6th column of the 3rd row expected)", + "foo 2foo", focused.get(0).getAttribute("value")); + + // ensure the selection didn't change + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 2nd row expected)", + "red 1foo", cellContents.get(2).getText()); + + // click on a Label on that row + WebElement label = rows.get(2).findElements(By.className("v-label")) + .get(0); + assertEquals( + "expected value not found, wrong cell or contents (5th column of the 3rd row expected)", + "foo 2foo", label.getText()); + label.click(); + + // ensure the focus shifted correctly + focused = table.findElements(By.className("v-textfield-focus")); + assertTrue("focused textfields found when there should be none", + focused.isEmpty()); + + // ensure the selection changed + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + + // click on the selected row's textfield (same as earlier) + textField.click(); + + // ensure the focus shifted correctly + focused = table.findElements(By.className("v-textfield-focus")); + assertEquals("unexpected amount of focused textfields", 1, + focused.size()); + assertEquals( + "expected value not found, wrong cell or contents (6th column of the 3rd row expected)", + "foo 2foo", focused.get(0).getAttribute("value")); + + // ensure the selection didn't change + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + + // find the readOnly TextField of the previously selected row + textField = rows.get(1).findElements(By.className("v-textfield")) + .get(1); + assertEquals( + "expected value not found, wrong cell or contents (7th column of the 2nd row expected)", + "foo 1foo", textField.getAttribute("value")); + assertEquals( + "expected readonly status not found, wrong cell or contents (7th column of the 2nd row expected)", + "true", textField.getAttribute("readonly")); + + // click on that TextField + textField.click(); + + // ensure the focus shifted correctly + focused = table.findElements(By.className("v-textfield-focus")); + assertTrue("focused textfields found when there should be none", + focused.isEmpty()); + + // ensure the selection changed + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 2nd row expected)", + "red 1foo", cellContents.get(2).getText()); + + // click the embedded icon of the other row + WebElement embedded = rows.get(2).findElement( + By.className("v-embedded")); + embedded.click(); + + // ensure the selection changed + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + + // check row you are about to drag + cellContents = rows.get(4).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 5th row expected)", + "red 4foo", cellContents.get(2).getText()); + + // check the row above it + cellContents = rows.get(3).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 4th row expected)", + "red 3foo", cellContents.get(2).getText()); + + // drag the row to the row that's two places above it (gets dropped + // below that) + cellContents = rows.get(4).findElements( + By.className("v-table-cell-content")); + new Actions(getDriver()).moveToElement(cellContents.get(2)) + .clickAndHold().moveToElement(rows.get(2)).release().perform(); + + // find the current order of the rows + rows = table.findElement(By.className("v-table-body")).findElements( + By.tagName("tr")); + assertEquals("unexpected table row count", 5, rows.size()); + + // ensure the row got dragged + cellContents = rows.get(3).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the dragged row expected, should be on 4th row now)", + "red 4foo", cellContents.get(2).getText()); + + cellContents = rows.get(4).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the previous 4th row expected, should be on 5th row now)", + "red 3foo", cellContents.get(2).getText()); + + // ensure the selection didn't change + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-chameleon.html b/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-chameleon.html index a9a572e468..efb99410fe 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-chameleon.html +++ b/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-chameleon.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=chameleon</td> + <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=chameleon</td> <td></td> </tr> <!--Add icons to property 1,5,10--> diff --git a/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-runo.html b/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-runo.html index 641d9480ca..d565fb5140 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-runo.html +++ b/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-runo.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=runo</td> + <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=runo</td> <td></td> </tr> <!--Add icons to property 1,5,10--> diff --git a/uitest/src/com/vaadin/tests/components/table/TableGeneratedRows-chameleon.html b/uitest/src/com/vaadin/tests/components/table/TableGeneratedRows-chameleon.html index 8a83f27701..c382a7c766 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableGeneratedRows-chameleon.html +++ b/uitest/src/com/vaadin/tests/components/table/TableGeneratedRows-chameleon.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=chameleon</td> + <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=chameleon</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html deleted file mode 100644 index 4c2dec9784..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html +++ /dev/null @@ -1,418 +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>TableItemDescriptionGeneratorTest</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TableItemDescriptionGeneratorTest</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/TableItemDescriptionGeneratorTest?restartApplication</td> - <td></td> -</tr> -<!--All on--> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Text</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Button 1 description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Cell and row tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>12,6</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Text</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Component</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Generated component</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Row and Component tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>7,8</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VCheckBox[0]/domChild[0]</td> - <td>7,5</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Button 1 description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Row tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>7,8</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.java b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUI.java index ec81194f14..809e639448 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.java +++ b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUI.java @@ -5,7 +5,8 @@ import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.data.util.IndexedContainer; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; import com.vaadin.ui.Button; import com.vaadin.ui.CheckBox; @@ -13,7 +14,7 @@ import com.vaadin.ui.Component; import com.vaadin.ui.Table; import com.vaadin.ui.TextField; -public class TableItemDescriptionGeneratorTest extends TestBase { +public class TableItemDescriptionGeneratorUI extends AbstractTestUI { private final String TEXT_PROPERTY_ID = "Text"; private final String GEN_WIDGET_PROPERTY_ID = "Generated component"; @@ -23,7 +24,7 @@ public class TableItemDescriptionGeneratorTest extends TestBase { private CheckBox tableRowItemDescription; @Override - protected void setup() { + protected void setup(VaadinRequest request) { final Table table = createTable(); table.setId("table"); componentDescription = new CheckBox("Tooltip on components"); @@ -73,7 +74,7 @@ public class TableItemDescriptionGeneratorTest extends TestBase { if (propertyId == null && tableRowItemDescription.getValue()) { return "Row description " + itemId; } else if (tableCellItemDescription.getValue()) { - return "Cell description " + itemId + "," + propertyId; + return "Cell description " + itemId + ", " + propertyId; } return null; } @@ -100,7 +101,7 @@ public class TableItemDescriptionGeneratorTest extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Cells and rows should have tooltips"; } @@ -109,13 +110,12 @@ public class TableItemDescriptionGeneratorTest extends TestBase { return 5414; } + @SuppressWarnings("unchecked") private Container createContainer(boolean description) { IndexedContainer container = new IndexedContainer(); container.addContainerProperty(TEXT_PROPERTY_ID, String.class, ""); container.addContainerProperty(WIDGET_PROPERTY_ID, Component.class, null); - // container.addContainerProperty(COLUMN3_PROPERTY_ID, String.class, - // ""); for (int i = 0; i < 5; i++) { Item item = container.addItem("item " + i); @@ -125,7 +125,6 @@ public class TableItemDescriptionGeneratorTest extends TestBase { b.setDescription("Button " + i + " description"); } item.getItemProperty(WIDGET_PROPERTY_ID).setValue(b); - // item.getItemProperty(COLUMN3_PROPERTY_ID).setValue("last" + i); } return container; diff --git a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUITest.java b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUITest.java new file mode 100644 index 0000000000..555a38a91e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUITest.java @@ -0,0 +1,241 @@ +/* + * 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.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.CheckBoxElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.TooltipTest; + +/** + * Tests Table tooltips with various settings. + * + * @author Vaadin Ltd + */ +public class TableItemDescriptionGeneratorUITest extends TooltipTest { + + @Test + public void testDescriptions() throws Exception { + openTestURL(); + + checkTooltipNotPresent(); + + TableElement table = $(TableElement.class).first(); + List<CheckBoxElement> checkboxes = $(CheckBoxElement.class).all(); + assertEquals(3, checkboxes.size()); + + // check text description + TestBenchElement cell_1_0 = table.getCell(1, 0); + cell_1_0.showTooltip(); + checkTooltip("Cell description item 1, Text"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check button description + TestBenchElement cell_1_1 = table.getCell(1, 1); + cell_1_1.showTooltip(); + checkTooltip("Button 1 description"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check textfield's description + TestBenchElement cell_1_2 = table.getCell(1, 2); + cell_1_2.showTooltip(); + checkTooltip("Textfield's own description"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // uncheck component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = table.getCell(1, 0); + cell_1_0.showTooltip(); + checkTooltip("Cell description item 1, Text"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check button description + cell_1_1 = table.getCell(1, 1); + cell_1_1.showTooltip(); + checkTooltip("Cell description item 1, Component"); + + // move somewhere without a description + new Actions(getDriver()).moveToElement(checkboxes.get(2)).perform(); + sleep(1000); + checkTooltipNotPresent(); + + // check textfield's description + cell_1_2 = table.getCell(1, 2); + cell_1_2.showTooltip(); + checkTooltip("Cell description item 1, Generated component"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + // uncheck cell tooltips + checkboxes.get(1).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = table.getCell(1, 0); + cell_1_0.showTooltip(); + checkTooltip("Row description item 1"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check button description + cell_1_1 = table.getCell(1, 1); + cell_1_1.showTooltip(); + checkTooltip("Button 1 description"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check textfield's description + cell_1_2 = table.getCell(1, 2); + cell_1_2.showTooltip(); + checkTooltip("Textfield's own description"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // uncheck component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = table.getCell(1, 0); + cell_1_0.showTooltip(); + checkTooltip("Row description item 1"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check button description + cell_1_1 = table.getCell(1, 1); + cell_1_1.showTooltip(); + checkTooltip("Row description item 1"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check textfield's description + cell_1_2 = table.getCell(1, 2); + cell_1_2.showTooltip(); + checkTooltip("Row description item 1"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + } + + @Test + public void testPosition() throws Exception { + openTestURL(); + + TableElement table = $(TableElement.class).first(); + List<CheckBoxElement> checkboxes = $(CheckBoxElement.class).all(); + assertEquals(3, checkboxes.size()); + + TestBenchElement cell_3_0 = table.getCell(3, 0); + + // move to the center of the cell + new Actions(getDriver()).moveToElement(cell_3_0).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Cell description item 3, Text"); + clearTooltip(); + + // move outside the cell + new Actions(getDriver()).moveToElement(checkboxes.get(2)).perform(); + + // move to the corner of the cell + new Actions(getDriver()).moveToElement(cell_3_0, 0, 0).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Cell description item 3, Text"); + clearTooltip(); + + // uncheck cell tooltips + checkboxes.get(1).findElement(By.tagName("input")).click(); + + TestBenchElement cell_1_1 = table.getCell(1, 1); + + // move to the center of the cell + new Actions(getDriver()).moveToElement(cell_1_1).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Button 1 description"); + clearTooltip(); + + // move to the corner of the element, outside of the button + new Actions(getDriver()).moveToElement(cell_1_1, 0, 0).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Row description item 1"); + clearTooltip(); + + // check cell tooltips + checkboxes.get(1).findElement(By.tagName("input")).click(); + + TestBenchElement cell_4_2 = table.getCell(4, 2); + + // move to the center of the cell + new Actions(getDriver()).moveToElement(cell_4_2).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Textfield's own description"); + clearTooltip(); + + // move to the corner of the element, outside of the textfield + new Actions(getDriver()).moveToElement(cell_4_2, 0, 0).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Cell description item 4, Generated component"); + clearTooltip(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableMultiSelectSimple-chameleon.html b/uitest/src/com/vaadin/tests/components/table/TableMultiSelectSimple-chameleon.html index f13bd22e84..aa9bfd5391 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableMultiSelectSimple-chameleon.html +++ b/uitest/src/com/vaadin/tests/components/table/TableMultiSelectSimple-chameleon.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.table.TableMultiSelectSimple?restartApplication&theme=chameleon</td> + <td>/run/com.vaadin.tests.components.table.TableMultiSelectSimple?restartApplication&theme=chameleon</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.html b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.html deleted file mode 100644 index a440ff84fb..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.html +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>TableRowHeight2</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TableRowHeight2</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.TableRowHeight2</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>1</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTableRowHeight2::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[1]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTableRowHeight2::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[1]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>1</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.java b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.java index 0011fdca18..5c733b9e24 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.java +++ b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.java @@ -1,16 +1,19 @@ package com.vaadin.tests.components.table; +import com.vaadin.annotations.Theme; import com.vaadin.data.Item; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Table; import com.vaadin.ui.themes.BaseTheme; -public class TableRowHeight2 extends TestBase { +@Theme("tests-tickets") +public class TableRowHeight2 extends AbstractTestUI { @Override - protected String getDescription() { + protected String getTestDescription() { return "The table contains 2 rows, which both should be shown completely as the table height is undefined."; } @@ -19,9 +22,9 @@ public class TableRowHeight2 extends TestBase { return 2747; } + @SuppressWarnings("unchecked") @Override - protected void setup() { - setTheme("tests-tickets"); + protected void setup(VaadinRequest request) { HorizontalLayout vl = new HorizontalLayout(); vl.setSizeFull(); diff --git a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2Test.java b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2Test.java new file mode 100644 index 0000000000..7074225311 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2Test.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.table; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that rows are completely visible and clicking buttons doesn't change + * anything. + * + * @author Vaadin Ltd + */ +public class TableRowHeight2Test extends MultiBrowserTest { + + @Test + public void testRowHeights() throws IOException { + openTestURL(); + + compareScreen("initial"); + + TableElement table = $(TableElement.class).first(); + List<WebElement> rows = table.findElement(By.className("v-table-body")) + .findElements(By.tagName("tr")); + + rows.get(0).findElements(By.className("v-button")).get(1).click(); + rows.get(1).findElements(By.className("v-button")).get(1).click(); + + compareScreen("after"); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRow.java b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRow.java new file mode 100644 index 0000000000..d1d6edaa67 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRow.java @@ -0,0 +1,167 @@ +/* + * 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; + +/** + * + * @author Vaadin Ltd + */ +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Label; +import com.vaadin.ui.NativeButton; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; + +/* + * 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. + */ + +/** + * + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class TableScrollAfterAddRow extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.UI#init(com.vaadin.server.VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + + final int totalRows = 100; + + final VerticalLayout layout = new VerticalLayout(); + + final IndexedContainer datasource = new IndexedContainer(); + + datasource.addContainerProperty("value", Integer.class, -1); + for (int i = 0; i < totalRows; i++) { + addRow(datasource); + } + + final Table table = new Table(); + table.setContainerDataSource(datasource); + layout.addComponent(table); + addComponent(layout); + + final Label label = new Label(""); + layout.addComponent(label); + + NativeButton addRowButton = new NativeButton("Add row", + new NativeButton.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + addRow(datasource); + } + }); + + NativeButton jumpToLastRowButton = new NativeButton("Jump to last row", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + jumpToLastRow(table); + } + }); + NativeButton jumpTo15thRowButton = new NativeButton("Jump to 15th row", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + jumpToFifteenthRow(table); + } + }); + NativeButton jumpToFirstRowButton = new NativeButton( + "Jump to first row", new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + jumpToFirstRow(table); + } + }); + + NativeButton updateLabelButton = new NativeButton("UpdateLabel", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + label.setValue(Integer.toString(table + .getCurrentPageFirstItemIndex())); + } + }); + layout.addComponent(addRowButton); + layout.addComponent(jumpToLastRowButton); + layout.addComponent(jumpTo15thRowButton); + layout.addComponent(jumpToFirstRowButton); + layout.addComponent(updateLabelButton); + } + + private void jumpToFifteenthRow(Table table) { + table.setCurrentPageFirstItemIndex(14); + } + + private void jumpToLastRow(Table table) { + int visibleRows = table.getContainerDataSource().size(); + table.setCurrentPageFirstItemIndex(visibleRows - 1); + } + + private void jumpToFirstRow(Table table) { + table.setCurrentPageFirstItemIndex(0); + } + + private void addRow(IndexedContainer datasource) { + int rowNumber = datasource.size(); + Item row = datasource.addItem(rowNumber); + row.getItemProperty("value").setValue(rowNumber); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return ""; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 14147; + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java new file mode 100644 index 0000000000..9242bae3d8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java @@ -0,0 +1,105 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import static org.junit.Assert.assertEquals; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.commands.TestBenchCommandExecutor; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.screenshot.ImageComparison; +import com.vaadin.testbench.screenshot.ReferenceNameGenerator; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * + * @author Vaadin Ltd + */ +public class TableScrollAfterAddRowTest extends MultiBrowserTest { + + @Before + public void init() { + openTestURL(); + } + + @Test + public void testJumpToFirstRow() throws InterruptedException { + jumpToFifteenthRow(); + jumpToFirstRow(); + assertEquals("0", getCurrentPageFirstItemIndex()); + } + + @Test + public void testAddRowAfterJumpToLastRow() throws InterruptedException { + jumpToLastRow(); + addRow(); + sleep(200); + assertEquals("85", getCurrentPageFirstItemIndex()); + } + + @Test + public void testAddRowAfterJumpingToLastRowAndScrollingUp() + throws InterruptedException { + jumpToLastRow(); + scrollUp(); + addRow(); + sleep(200); + Assert.assertNotEquals("86", getCurrentPageFirstItemIndex()); + } + + private void scrollUp() { + WebElement actualElement = getDriver().findElement( + By.className("v-table-body-wrapper")); + JavascriptExecutor js = new TestBenchCommandExecutor(getDriver(), + new ImageComparison(), new ReferenceNameGenerator()); + js.executeScript("arguments[0].scrollTop = " + 30, actualElement); + } + + private String getCurrentPageFirstItemIndex() throws InterruptedException { + ButtonElement updateLabelButton = $(ButtonElement.class).get(4); + LabelElement label = $(LabelElement.class).get(1); + updateLabelButton.click(); + sleep(200); + return label.getText(); + } + + private void addRow() { + ButtonElement button = $(ButtonElement.class).get(0); + button.click(); + } + + private void jumpToFirstRow() { + ButtonElement button = $(ButtonElement.class).get(3); + button.click(); + } + + private void jumpToFifteenthRow() { + ButtonElement button = $(ButtonElement.class).get(2); + button.click(); + } + + private void jumpToLastRow() { + ButtonElement button = $(ButtonElement.class).get(1); + button.click(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableTooltips.html b/uitest/src/com/vaadin/tests/components/table/TableTooltips.html deleted file mode 100644 index 13ceea935f..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TableTooltips.html +++ /dev/null @@ -1,91 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.TableItemDescriptionGeneratorTest?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseMove</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[0]/domChild[0]</td> - <td>57,5</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 3,Text</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[0]</td> - <td>810,153</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>355,350</td> -</tr> -<tr> - <td>drag</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>822,249</td> -</tr> -<tr> - <td>drop</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]</td> - <td>90,12</td> -</tr> -<tr> - <td>mouseMove</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]</td> - <td>57,12</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[0]</td> - <td>1011,283</td> -</tr> -<tr> - <td>mouseMove</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[4]/VTextField[0]</td> - <td>58,10</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.html b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.html deleted file mode 100644 index caaa15fa1c..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.html +++ /dev/null @@ -1,47 +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>TextFieldValueGoesMissing</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TextFieldValueGoesMissing</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.TextFieldValueGoesMissing?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> - <td>73,10</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> - <td>test</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>contextmenu</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> - <td></td> -</tr> -<tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> - <td>test</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.java b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.java index 9ffad7f1e4..89c9050361 100644 --- a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.java +++ b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.java @@ -1,6 +1,7 @@ package com.vaadin.tests.components.table; -import com.vaadin.tests.components.TestBase; +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.Label; @@ -8,17 +9,18 @@ import com.vaadin.ui.Table; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; -public class TextFieldValueGoesMissing extends TestBase { +public class TextFieldValueGoesMissing extends AbstractTestUI { + @SuppressWarnings("unchecked") @Override - protected void setup() { + protected void setup(VaadinRequest request) { final VerticalLayout verticalLayout = new VerticalLayout(); final Label label1 = new Label("1"); final Label label2 = new Label("2"); Button button = new Button("Replace label"); - button.addListener(new Button.ClickListener() { + button.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { @@ -45,7 +47,7 @@ public class TextFieldValueGoesMissing extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Enter a text in the TextField in the table and press the 'Replace label' button. This replaces the label which is in the same layout as the table but should not cause the TextField in the table to lose its contents"; } diff --git a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissingTest.java b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissingTest.java new file mode 100644 index 0000000000..387882b6ca --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissingTest.java @@ -0,0 +1,53 @@ +/* + * 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 org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that a text field's value isn't cleared after a label in the same + * layout is changed. + * + * @since 7.3 + * @author Vaadin Ltd + */ +public class TextFieldValueGoesMissingTest extends MultiBrowserTest { + + /* This test was rewritten from a TB2 test. */ + @Test + public void valueMissingTest() throws Exception { + openTestURL(); + + waitForElementVisible(By.className("v-textfield")); + + TextFieldElement textfield = $(TextFieldElement.class).first(); + textfield.focus(); + textfield.sendKeys("test"); + + $(ButtonElement.class).first().click(); + + new Actions(getDriver()).contextClick(textfield).perform(); + + Assert.assertEquals("test", textfield.getValue()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResetted.java b/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResetted.java new file mode 100644 index 0000000000..b2607050a4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResetted.java @@ -0,0 +1,111 @@ +/* + * 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.textarea; + +import com.vaadin.event.UIEvents; +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.Component; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.TextField; + +/** + * Ticket #14080 + * + * - The bug happen on push event.<br/> + * - The changes in the DOM are css related.<br/> + * - It seems like when the class attribute is set on push, the textarea revert + * to the height defined by the rows attribute.<br/> + * - The size is reseted on onStateChange where the size is set to the one from + * the state. And it's because, when the user changes the text, at the next poll + * the state will confirm the change of the text, but the width and height + * didn't change in the state either client or server before the fix. + * + * @since + * @author Vaadin Ltd + */ +public class TextAreaSizeResetted extends AbstractTestUI { + + public static final int TEXTAREAHEIGHT = 200; + public static final int TEXTAREAWIDTH = 200; + + CssLayout layout = new CssLayout() { + @Override + protected String getCss(Component c) { + if (c instanceof TextArea) { + return "resize:both"; + } + + return super.getCss(c); + } + }; + + @Override + protected void setup(VaadinRequest request) { + setPollInterval(500); // Short polling like 100ms jams up the TestBench + // waitForVaadin -functionality. + + final Label pollIndicator = new Label(); + pollIndicator.setId("pollIndicator"); + + final TextField textField = new TextField("height"); + + final TextArea textArea = new TextArea(); + textArea.setHeight(TEXTAREAHEIGHT + "px"); + textArea.setWidth(TEXTAREAWIDTH + "px"); + textArea.setValue("This is a text."); + + Button button = new Button("Change Height", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + + textArea.setHeight(textField.getValue()); + } + }); + + addComponent(layout); + + layout.addComponent(textArea); + layout.addComponent(textField); + layout.addComponent(button); + layout.addComponent(pollIndicator); + + addPollListener(new UIEvents.PollListener() { + @Override + public void poll(UIEvents.PollEvent event) { + pollIndicator.setValue(String.valueOf(System + .currentTimeMillis())); + } + }); + } + + @Override + protected String getTestDescription() { + return "TextArea width/height change when user resize it, change the text then a poll come."; + } + + @Override + protected Integer getTicketNumber() { + return 14080; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResettedTest.java b/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResettedTest.java new file mode 100644 index 0000000000..6365d00735 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResettedTest.java @@ -0,0 +1,127 @@ +package com.vaadin.tests.components.textarea; + +import static com.vaadin.tests.components.textarea.TextAreaSizeResetted.TEXTAREAHEIGHT; +import static com.vaadin.tests.components.textarea.TextAreaSizeResetted.TEXTAREAWIDTH; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.TextAreaElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class TextAreaSizeResettedTest extends MultiBrowserTest { + + private final int OFFSET = 100; + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + } + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return getBrowsersExcludingIE(); // IE8-11 don't support CSS resize. + } + + @Test + public void textAreaIsNotResizedOnBlur() { + + resizeAndAssertTextAreaTo(TEXTAREAHEIGHT, OFFSET); + + getTextArea().sendKeys("foo"); + + moveFocusOutsideTextArea(); + + // We can't use a waitUntil to check the text area size here, because it + // won't release the focus from + // the text area, so we need to do use something else. This workaround + // uses a label which is updated to indicate + // polling, which should trigger a resize. + waitUntilPollingOccurs(); + + assertThat(getTextAreaHeight(), is(TEXTAREAHEIGHT + OFFSET)); + assertThat(getTextAreaWidth(), is(TEXTAREAWIDTH + OFFSET)); + + waitUntilPollingOccurs(); + } + + private void moveFocusOutsideTextArea() { + $(TextFieldElement.class).first().focus(); + } + + private void resizeAndAssertTextAreaTo(int size, int offset) { + // Sanity check + assertThat(getTextAreaHeight(), is(size)); + resizeTextAreaBy(offset); + + assertThat(getTextAreaHeight(), is(size + offset)); + } + + private void resizeTextAreaBy(int offset) { + int resizeHandlerOffset = 10; + new Actions(getDriver()) + .moveToElement(getTextArea(), + TEXTAREAWIDTH - resizeHandlerOffset, + TEXTAREAHEIGHT - resizeHandlerOffset).clickAndHold() + .moveByOffset(offset, offset).release().build().perform(); + } + + @Test + public void textAreaWidthIsPresevedOnHeightResize() { + resizeAndAssertTextAreaTo(TEXTAREAHEIGHT, OFFSET); + + changeHeightTo(TEXTAREAHEIGHT + OFFSET + OFFSET); + + assertThat(getTextAreaWidth(), is(TEXTAREAWIDTH + OFFSET)); + assertThat(getTextAreaHeight(), is(TEXTAREAHEIGHT + OFFSET + OFFSET)); + } + + private void changeHeightTo(int offset) { + $(TextFieldElement.class).first().sendKeys(String.valueOf(offset)); + $(ButtonElement.class).first().click(); + } + + private void waitUntilPollingOccurs() { + final String timestamp = getPollTimestamp(); + + waitUntil(new ExpectedCondition<Boolean>() { + @Override + public Boolean apply(WebDriver input) { + return !timestamp.equals(getPollTimestamp()); + } + }); + } + + private String getPollTimestamp() { + return $(LabelElement.class).id("pollIndicator").getText(); + } + + private int getTextAreaHeight() { + return getTextAreaSize().getHeight(); + } + + private int getTextAreaWidth() { + return getTextAreaSize().getWidth(); + } + + private Dimension getTextAreaSize() { + return getTextArea().getSize(); + } + + private TextAreaElement getTextArea() { + return $(TextAreaElement.class).first(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.html b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.html deleted file mode 100644 index 1a20b798ec..0000000000 --- a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.html +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>DisappearingComponents</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">DisappearingComponents</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.treetable.DisappearingComponents?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableDisappearingComponents::/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td> - <td>12,7</td> -</tr> -<tr> - <td>verifyElementPresent</td> - <td>vaadin=runcomvaadintestscomponentstreetableDisappearingComponents::/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[2]/VLink[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.java b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.java index aaa7496616..ee64007234 100644 --- a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.java +++ b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.java @@ -1,16 +1,15 @@ package com.vaadin.tests.components.treetable; import com.vaadin.server.ExternalResource; -import com.vaadin.tests.components.AbstractTestCase; -import com.vaadin.ui.LegacyWindow; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Link; import com.vaadin.ui.TreeTable; -public class DisappearingComponents extends AbstractTestCase { +public class DisappearingComponents extends AbstractTestUI { @Override - public void init() { - LegacyWindow mainWindow = new LegacyWindow("Application"); + public void setup(VaadinRequest request) { final TreeTable tt = new TreeTable(); tt.setSizeUndefined(); tt.setWidth("100%"); @@ -33,13 +32,11 @@ public class DisappearingComponents extends AbstractTestCase { tt.setChildrenAllowed(items[2], false); tt.setParent(items[2], items[1]); - mainWindow.addComponent(tt); - - setMainWindow(mainWindow); + addComponent(tt); } @Override - protected String getDescription() { + protected String getTestDescription() { return "TreeTable column component empty after expand+collapse when pageLength is set to zero"; } diff --git a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponentsTest.java b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponentsTest.java new file mode 100644 index 0000000000..e4d97b9de1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponentsTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.treetable; + +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.TreeTableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that expanded cells with component contents aren't empty. + * + * @author Vaadin Ltd + */ +public class DisappearingComponentsTest extends MultiBrowserTest { + + @Test + public void testNotification() throws InterruptedException { + openTestURL(); + + TreeTableElement treeTable = $(TreeTableElement.class).first(); + treeTable.getCell(1, 0) + .findElement(By.className("v-treetable-treespacer")).click(); + sleep(100); + + WebElement link = treeTable.getCell(2, 1).findElement( + By.className("v-link")); + assertEquals("3", link.getText()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.html b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.html deleted file mode 100644 index 7f2f61bfc3..0000000000 --- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.html +++ /dev/null @@ -1,357 +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://arturwin.office.itmill.com: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/TreeTableItemDescriptionGeneratorTest?restartApplication</td> - <td></td> -</tr> -<!--All on--> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Text</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Button 1 description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Cell and row tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>12,6</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Text</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Component</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Generated component</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Row and Component tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>7,8</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VCheckBox[0]/domChild[0]</td> - <td>7,5</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Button 1 description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Row tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>7,8</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUI.java index 2864156b03..ba057f4c41 100644 --- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.java +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUI.java @@ -15,14 +15,16 @@ */ package com.vaadin.tests.components.treetable; -import com.vaadin.tests.components.table.TableItemDescriptionGeneratorTest; +import com.vaadin.tests.components.table.TableItemDescriptionGeneratorUI; import com.vaadin.ui.Table; import com.vaadin.ui.TreeTable; -public class TreeTableItemDescriptionGeneratorTest extends - TableItemDescriptionGeneratorTest { +public class TreeTableItemDescriptionGeneratorUI extends + TableItemDescriptionGeneratorUI { + @Override protected Table createTable() { return new TreeTable(); } + } diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUITest.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUITest.java new file mode 100644 index 0000000000..849d19cafa --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUITest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.treetable; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.CheckBoxElement; +import com.vaadin.testbench.elements.TreeTableElement; +import com.vaadin.tests.tb3.TooltipTest; + +/** + * Tests TreeTable tooltips with various settings. + * + * @author Vaadin Ltd + */ +public class TreeTableItemDescriptionGeneratorUITest extends TooltipTest { + + @Test + public void testDescriptions() throws Exception { + openTestURL(); + + checkTooltipNotPresent(); + + TreeTableElement treeTable = $(TreeTableElement.class).first(); + List<CheckBoxElement> checkboxes = $(CheckBoxElement.class).all(); + assertEquals(3, checkboxes.size()); + + // check text description + TestBenchElement cell_1_0 = treeTable.getCell(1, 0); + checkTooltip(cell_1_0, "Cell description item 1, Text"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check button description + TestBenchElement cell_1_1 = treeTable.getCell(1, 1); + checkTooltip(cell_1_1, "Button 1 description"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check textfield's description + TestBenchElement cell_1_2 = treeTable.getCell(1, 2); + checkTooltip(cell_1_2, "Textfield's own description"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // uncheck component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = treeTable.getCell(1, 0); + checkTooltip(cell_1_0, "Cell description item 1, Text"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check button description + cell_1_1 = treeTable.getCell(1, 1); + checkTooltip(cell_1_1, "Cell description item 1, Component"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check textfield's description + cell_1_2 = treeTable.getCell(1, 2); + checkTooltip(cell_1_2, "Cell description item 1, Generated component"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + // uncheck cell tooltips + checkboxes.get(1).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = treeTable.getCell(1, 0); + checkTooltip(cell_1_0, "Row description item 1"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check button description + cell_1_1 = treeTable.getCell(1, 1); + checkTooltip(cell_1_1, "Button 1 description"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check textfield's description + cell_1_2 = treeTable.getCell(1, 2); + checkTooltip(cell_1_2, "Textfield's own description"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // uncheck component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = treeTable.getCell(1, 0); + checkTooltip(cell_1_0, "Row description item 1"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check button description + cell_1_1 = treeTable.getCell(1, 1); + checkTooltip(cell_1_1, "Row description item 1"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check textfield's description + cell_1_2 = treeTable.getCell(1, 2); + checkTooltip(cell_1_2, "Row description item 1"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.html b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.html deleted file mode 100644 index b8d6cdb22e..0000000000 --- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.html +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>TreeTableOutOfSync</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TreeTableOutOfSync</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.treetable.TreeTableOutOfSync?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableOutOfSync::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> - <td>10,7</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableOutOfSync::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[2]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>verifyTextNotPresent</td> - <td>Something has caused us to be out of sync with the server.<br />Take note of any unsaved data, and click here to re-sync.</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.java index 7f4aa7f671..b8a0ac61c2 100644 --- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.java +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.java @@ -15,16 +15,18 @@ */ package com.vaadin.tests.components.treetable; -import com.vaadin.tests.components.TestBase; +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.Notification; import com.vaadin.ui.Table; import com.vaadin.ui.TreeTable; -public class TreeTableOutOfSync extends TestBase { +public class TreeTableOutOfSync extends AbstractTestUI { @Override - protected void setup() { + protected void setup(VaadinRequest request) { TreeTable tt = new TreeTable(); tt.addContainerProperty("i", Integer.class, null); tt.addGeneratedColumn("text", new Table.ColumnGenerator() { @@ -35,10 +37,10 @@ public class TreeTableOutOfSync extends TestBase { Button button = new Button("text " + source.getContainerDataSource().getItem(itemId) .getItemProperty("i").getValue()); - button.addListener(new Button.ClickListener() { + button.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { - getMainWindow().showNotification("click"); + Notification.show("click"); } }); return button; @@ -56,7 +58,7 @@ public class TreeTableOutOfSync extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "When a root node is expanded, components created by a column generator go out of sync"; } diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSyncTest.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSyncTest.java new file mode 100644 index 0000000000..0831232df7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSyncTest.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.treetable; + +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.TreeTableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that opening the root node and clicking a generated component doesn't + * cause out of sync (or any other system notifications). + * + * @author Vaadin Ltd + */ +public class TreeTableOutOfSyncTest extends MultiBrowserTest { + + @Test + public void testNotification() throws InterruptedException { + openTestURL(); + + TreeTableElement treeTable = $(TreeTableElement.class).first(); + List<WebElement> rows = treeTable.findElement( + By.className("v-table-body")).findElements(By.tagName("tr")); + + WebElement treeSpacer = rows.get(0).findElement( + By.className("v-treetable-treespacer")); + treeSpacer.click(); + + sleep(100); + + rows = treeTable.findElement(By.className("v-table-body")) + .findElements(By.tagName("tr")); + WebElement button = rows.get(2).findElement(By.className("v-button")); + button.click(); + + List<WebElement> notifications = findElements(By + .className("v-Notification-system")); + assertTrue(notifications.isEmpty()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemText.java b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemText.java new file mode 100644 index 0000000000..d4599fc1a3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemText.java @@ -0,0 +1,43 @@ +package com.vaadin.tests.components.ui; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Label; + +public class ComboboxSelectedItemText extends AbstractTestUIWithLog { + @Override + protected void setup(VaadinRequest request) { + getLayout() + .addComponent( + new Label( + "Select first ANTIGUA AND BARBUDA from the first combobox. Then select ANTIGUA AND BARBUDA from the second combobox. Finally, click the popup button on the first combobox. Before fix you would see UA AND BAR in the field.")); + + ComboBox combobox = new ComboBox("Text input enabled:"); + combobox.setWidth("100px"); + + combobox.addItem("AMERICAN SAMOA"); + combobox.addItem("ANTIGUA AND BARBUDA"); + + ComboBox combobox2 = new ComboBox("Text input disabled:"); + combobox2.setWidth("100px"); + combobox2.setTextInputAllowed(false); + + combobox2.addItem("AMERICAN SAMOA"); + combobox2.addItem("ANTIGUA AND BARBUDA"); + + getLayout().addComponent(combobox); + getLayout().addComponent(combobox2); + } + + @Override + protected String getTestDescription() { + return "Tests selected item is displayed from the beginning"; + } + + @Override + protected Integer getTicketNumber() { + return 13477; + } + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java new file mode 100644 index 0000000000..f826654022 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2013 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.ui; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test class for issue #13477, where selecting a combobox item that is too long + * would render the ending of an item instead of the beginning, which was + * considered less than informative. + * + * @author Vaadin Ltd + */ + +public class ComboboxSelectedItemTextTest extends MultiBrowserTest { + + public final String SCREENSHOT_NAME_EDITABLE = "LongComboboxItemSelectedEditable"; + public final String SCREENSHOT_NAME_NON_EDITABLE = "LongComboboxItemSelectedNonEditable"; + public final int INDEX_EDITABLE_COMBOBOX = 1; + public final int INDEX_NON_EDITABLE_COMBOBOX = 2; + + @Test + public void testCombobox() throws IOException { + testCombobox(INDEX_EDITABLE_COMBOBOX, INDEX_NON_EDITABLE_COMBOBOX, + SCREENSHOT_NAME_EDITABLE); + } + + @Test + public void testComboboxNonEditable() throws IOException { + testCombobox(INDEX_NON_EDITABLE_COMBOBOX, INDEX_EDITABLE_COMBOBOX, + SCREENSHOT_NAME_NON_EDITABLE); + } + + private void testCombobox(int indexToTest, int indexToFocus, + String screenshotIdentifier) throws IOException { + openTestURL(); + + WebElement comboBox = vaadinElement("/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[" + + indexToTest + "]/VFilterSelect[0]"); + WebElement comboBoxFocus = vaadinElement("/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[" + + indexToFocus + "]/VFilterSelect[0]"); + + // Select an element from the first (editable) combobox. + + comboBox.findElement(By.className("v-filterselect-button")).click(); + WebElement comboBoxPopup = vaadinElement("/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[" + + indexToTest + "]/VFilterSelect[0]#popup"); + comboBoxPopup.findElements(By.tagName("td")).get(2).click(); + + // Select an element from the second (non-editable combobox) to remove + // focus from the first combobox + + comboBoxFocus.findElement(By.className("v-filterselect-button")) + .click(); + comboBoxPopup = vaadinElement("/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[" + + indexToFocus + "]/VFilterSelect[0]#popup"); + comboBoxPopup.findElements(By.tagName("td")).get(2).click(); + + // click the popup on the first combobox. This would reveal the unwanted + // behaviour. + + comboBox.findElement(By.className("v-filterselect-button")).click(); + + // sadly, screenshot comparison is the only reasonable way to test a + // rendering issue. + + compareScreen(screenshotIdentifier); + + } + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUp.java b/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUp.java new file mode 100644 index 0000000000..2c5e415408 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUp.java @@ -0,0 +1,103 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.window; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Panel; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; + +/** + * Reproducing bug #12943 where an action on a Button or ComboBox placed at the + * bottom of a window in a scroll panel, will scroll up the parent panel. + * + * This was due to the fact that with the state confirmation notification from + * the server, the window.setVisible would be call again, and the hack that + * solved the scrollbars in a window (#11994) would cause the our bug. + * + * @since + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class BottomComponentScrollsUp extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Button b = new Button("Open window"); + addComponent(b); + b.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + openWindow(); + } + + }); + + openWindow(); + } + + private void openWindow() { + Window w = new Window(); + w.setWidth("300px"); + w.setHeight("300px"); + w.center(); + + Panel p = createPanel(); + p.setSizeFull(); + + w.setContent(p); + + addWindow(w); + } + + private Panel createPanel() { + Panel p = new Panel(); + + VerticalLayout content = new VerticalLayout(); + p.setContent(content); + content.setHeight("500px"); + + List<String> items = new ArrayList<String>(); + items.add("1"); + items.add("2"); + items.add("3"); + + Button button = new Button("Press me"); + content.addComponent(button); + content.setComponentAlignment(button, Alignment.BOTTOM_CENTER); + return p; + } + + @Override + protected String getTestDescription() { + return "Interacting with a component at the bottom of scrollable panel within a subwindow scrolls up"; + } + + @Override + protected Integer getTicketNumber() { + return 12943; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUpTest.java b/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUpTest.java new file mode 100644 index 0000000000..3d0da2677b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUpTest.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.window; + +import java.io.IOException; + +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.testbench.TestBenchElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Automatic test for fix for #12943. + * + * While testing without the fix, the test failed on both Chrome and PhantomJS. + * + * @since + * @author Vaadin Ltd + */ +public class BottomComponentScrollsUpTest extends MultiBrowserTest { + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + } + + @Test + public void windowScrollTest() throws IOException, InterruptedException { + TestBenchElement panelScrollable = (TestBenchElement) getDriver() + .findElement(By.className("v-panel-content")); + Dimension panelScrollableSize = panelScrollable.getSize(); + + WebElement verticalLayout = panelScrollable.findElement(By + .className("v-verticallayout")); + Dimension verticalLayoutSize = verticalLayout.getSize(); + + panelScrollable.scroll(verticalLayoutSize.height); + + WebElement button = verticalLayout + .findElement(By.className("v-button")); + + button.click(); + + // Loose the focus from the button. + new Actions(getDriver()) + .moveToElement(panelScrollable, panelScrollableSize.width / 2, + panelScrollableSize.height / 2).click().build() + .perform(); + + compareScreen("window"); + } +} diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java b/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java deleted file mode 100644 index 412fd3049d..0000000000 --- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.components.window; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.interactions.HasInputDevices; -import org.openqa.selenium.interactions.Mouse; -import org.openqa.selenium.interactions.internal.Coordinates; -import org.openqa.selenium.internal.Locatable; - -import com.vaadin.testbench.By; -import com.vaadin.tests.tb3.MultiBrowserTest; - -/** - * - * @since - * @author Vaadin Ltd - */ -public class TooltipInWindowTest extends MultiBrowserTest { - - @Test - public void testTooltipsInSubWindow() throws InterruptedException { - openTestURL(); - - WebElement textfield = vaadinElementById("tf1"); - Coordinates textfieldCoordinates = ((Locatable) textfield) - .getCoordinates(); - - Mouse mouse = ((HasInputDevices) getDriver()).getMouse(); - - // Show tooltip - mouse.mouseMove(textfieldCoordinates, 10, 10); - - sleep(100); - ensureVisibleTooltipPositionedCorrectly(); - assertEquals("My tooltip", getTooltipElement().getText()); - - // Hide tooltip - mouse.mouseMove(textfieldCoordinates, -100, -100); - sleep(2000); - - ensureHiddenTooltipPositionedCorrectly(); - assertEquals("", getTooltipElement().getText()); - - // Show tooltip again - mouse.mouseMove(textfieldCoordinates, 10, 10); - - sleep(100); - ensureVisibleTooltipPositionedCorrectly(); - assertEquals("My tooltip", getTooltipElement().getText()); - - // Hide tooltip - mouse.mouseMove(textfieldCoordinates, -100, -100); - sleep(2000); - - ensureHiddenTooltipPositionedCorrectly(); - assertEquals("", getTooltipElement().getText()); - - } - - private WebElement getTooltipContainerElement() { - return getDriver().findElement(By.className("v-tooltip")); - } - - private void ensureVisibleTooltipPositionedCorrectly() { - WebElement textfield = vaadinElementById("tf1"); - int tooltipX = getTooltipContainerElement().getLocation().getX(); - int textfieldX = textfield.getLocation().getX(); - assertGreaterOrEqual("Tooltip should be positioned on the textfield (" - + tooltipX + " < " + textfieldX + ")", tooltipX, textfieldX); - } - - private void ensureHiddenTooltipPositionedCorrectly() { - int tooltipX = getTooltipContainerElement().getLocation().getX(); - assertLessThanOrEqual( - "Tooltip should be positioned outside of viewport (was at " - + tooltipX + ")", tooltipX, -1000); - } -} diff --git a/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java b/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java index e067ada818..8d74e3a259 100644 --- a/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java +++ b/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java @@ -43,12 +43,13 @@ public class WindowMoveListenerTest extends MultiBrowserTest { waitUntilWindowHasReseted(window, winPos); } - private void waitUntilWindowHasReseted(final WebElement window, final Point winPos) { + private void waitUntilWindowHasReseted(final WebElement window, + final Point winPos) { waitUntil(new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver input) { - return winPos.x == window.getLocation().x && - winPos.y == window.getLocation().y; + return winPos.x == window.getLocation().x + && winPos.y == window.getLocation().y; } }, 5); } diff --git a/uitest/src/com/vaadin/tests/layouts/gridlayout/GridLayoutWidthChangeTest.java b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridLayoutWidthChangeTest.java index 52ea5f4f8e..ba3d0f06f1 100644 --- a/uitest/src/com/vaadin/tests/layouts/gridlayout/GridLayoutWidthChangeTest.java +++ b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridLayoutWidthChangeTest.java @@ -17,7 +17,8 @@ public class GridLayoutWidthChangeTest extends MultiBrowserTest { compareScreen("initial"); - $(ButtonElement.class).caption("Reduce GridLayout parent width").first().click(); + $(ButtonElement.class).caption("Reduce GridLayout parent width") + .first().click(); compareScreen("buttonMoved"); } diff --git a/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumns.java b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumns.java new file mode 100644 index 0000000000..fc37455752 --- /dev/null +++ b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumns.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.layouts.gridlayout; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.Label; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class GridSpanEmptyColumns extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + GridLayout gridLayout = new GridLayout(3, 1); + gridLayout.setWidth("1000px"); + + Label bigCell = new Label("big cell"); + bigCell.setId("bigCell"); + Label smallCell = new Label("small cell"); + smallCell.setId("smallCell"); + gridLayout.addComponent(bigCell, 0, 0, 1, 0); // spans first two columns + gridLayout.addComponent(smallCell, 2, 0, 2, 0); // last column only + + addComponent(gridLayout); + } + + @Override + protected String getTestDescription() { + return "A 3x1 grid has a spanned component on the first two cells and a component on the last cell. The two components should occupy 2/3 and 1/3 of the available space respectively, instead of 1/2 each."; + } + + @Override + protected Integer getTicketNumber() { + return 14335; + } +} diff --git a/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumnsTest.java b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumnsTest.java new file mode 100644 index 0000000000..f2b86fb69b --- /dev/null +++ b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumnsTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.layouts.gridlayout; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that GridLayout handles elements spanning otherwise empty columns + * correctly (#14335) + * + * @since 7.2.5 + * @author markus + */ +public class GridSpanEmptyColumnsTest extends MultiBrowserTest { + + @Test + public void componentsShouldMoveRight() throws IOException { + openTestURL(); + + LabelElement bigCell = $(LabelElement.class).id("bigCell"); + LabelElement smallCell = $(LabelElement.class).id("smallCell"); + + // Width is 1000px. Big cell should take up 2/3, small cell should take + // up 1/3. + assertEquals(667, bigCell.getSize().width); + assertEquals(333, smallCell.getSize().width); + + } + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/GridLayout/GridAddReplaceMove.java b/uitest/src/com/vaadin/tests/layouts/layouttester/GridLayout/GridAddReplaceMove.java index 2771af01c6..84254b4935 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/GridLayout/GridAddReplaceMove.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/GridLayout/GridAddReplaceMove.java @@ -36,7 +36,7 @@ public class GridAddReplaceMove extends GridBaseLayoutTestUI { /* * (non-Javadoc) - * + * * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. * VaadinRequest) */ diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HAddReplaceMove.java b/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HAddReplaceMove.java index 1c0e992a86..c4787045fc 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HAddReplaceMove.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HAddReplaceMove.java @@ -19,7 +19,6 @@ import com.vaadin.annotations.Theme; import com.vaadin.tests.layouts.layouttester.BaseAddReplaceMove; import com.vaadin.ui.HorizontalLayout; - public class HAddReplaceMove extends BaseAddReplaceMove { /** diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HCaption.java b/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HCaption.java index bb974a8c68..3088a00c39 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HCaption.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HCaption.java @@ -19,7 +19,6 @@ import com.vaadin.annotations.Theme; import com.vaadin.tests.layouts.layouttester.BaseCaption; import com.vaadin.ui.HorizontalLayout; - public class HCaption extends BaseCaption { /** diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutExpandTest.java b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutExpandTest.java index 57bb134be7..152e3f0b86 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutExpandTest.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutExpandTest.java @@ -17,7 +17,6 @@ package com.vaadin.tests.layouts.layouttester.VLayout; import com.vaadin.tests.layouts.layouttester.BaseLayoutExpandTest; - /** * * @since diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutRegErrorTest.java b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutRegErrorTest.java index e3e5914e3a..7f803781fb 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutRegErrorTest.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutRegErrorTest.java @@ -17,7 +17,6 @@ package com.vaadin.tests.layouts.layouttester.VLayout; import com.vaadin.tests.layouts.layouttester.BaseLayoutRegErrorTest; - /** * * @since diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutSizingTest.java b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutSizingTest.java index 372eb9cba4..519f8113f8 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutSizingTest.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutSizingTest.java @@ -17,7 +17,6 @@ package com.vaadin.tests.layouts.layouttester.VLayout; import com.vaadin.tests.layouts.layouttester.BaseLayoutSizingTest; - /** * * @since diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java index 06ddc07abb..5dc15f8fc6 100644 --- a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java @@ -36,7 +36,7 @@ public abstract class ExtremelyLongPushTimeTest extends MultiBrowserTest { testBench(driver).disableWaitForVaadin(); // Wait for startButton to be present - waitForElementToBePresent(vaadinLocatorById("startButton")); + waitForElementVisible(vaadinLocatorById("startButton")); String logRow0Id = "Log_row_0"; By logRow0 = vaadinLocatorById(logRow0Id); diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java index f2207ccba7..a04d569e05 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java @@ -37,7 +37,8 @@ public class PushConfigurationLongPollingTest extends PushConfigurationTest { clearDebugMessages(); new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC"); - waitForDebugMessage("Push connection established using long-polling", 10); + waitForDebugMessage("Push connection established using long-polling", + 10); waitForServerCounterToUpdate(); } diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java index 00ee6bae25..e37bd32832 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java @@ -42,7 +42,7 @@ public class PushLargeDataLongPollingTest extends MultiBrowserTest { private void push() throws InterruptedException { // Wait for startButton to be present - waitForElementToBePresent(vaadinLocatorById("startButton")); + waitForElementVisible(vaadinLocatorById("startButton")); String logRow0Id = "Log_row_0"; By logRow0 = vaadinLocatorById(logRow0Id); diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java index 26fa512ab2..058ac6cc92 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java @@ -42,7 +42,7 @@ public class PushLargeDataStreamingTest extends MultiBrowserTest { private void push() throws InterruptedException { // Wait for startButton to be present - waitForElementToBePresent(vaadinLocatorById("startButton")); + waitForElementVisible(vaadinLocatorById("startButton")); String logRow0Id = "Log_row_0"; By logRow0 = vaadinLocatorById(logRow0Id); diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java index 57fb8c33b0..da4999799d 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java @@ -40,7 +40,7 @@ public class PushLargeDataWebsocketTest extends WebsocketTest { private void push() throws Exception { // Wait for startButton to be present - waitForElementToBePresent(vaadinLocatorById("startButton")); + waitForElementVisible(vaadinLocatorById("startButton")); String logRow0Id = "Log_row_0"; By logRow0 = vaadinLocatorById(logRow0Id); diff --git a/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java b/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java index 8a4593d70d..28ef30a04a 100644 --- a/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java +++ b/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.push; - public class ReconnectLongPollingTest extends ReconnectTest { @Override diff --git a/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java b/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java index fe63764e78..0a0275c4d0 100755 --- a/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java +++ b/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.push; - public class ReconnectStreamingTest extends ReconnectTest { @Override diff --git a/uitest/src/com/vaadin/tests/push/RefreshCloseConnection.java b/uitest/src/com/vaadin/tests/push/RefreshCloseConnection.java new file mode 100644 index 0000000000..4d02c4e62e --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/RefreshCloseConnection.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.push; + +import com.vaadin.annotations.PreserveOnRefresh; +import com.vaadin.annotations.Push; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; + +@Push +@PreserveOnRefresh +public class RefreshCloseConnection extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + log("Init"); + } + + @Override + protected void refresh(VaadinRequest request) { + if (getPushConnection().isConnected()) { + log("Still connected"); + } + log("Refresh"); + new Thread() { + @Override + public void run() { + accessSynchronously(new Runnable() { + @Override + public void run() { + log("Push"); + } + }); + } + }.start(); + } + + @Override + protected String getTestDescription() { + return "A log row should get pushed after reloading the page"; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(14251); + } + +} diff --git a/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java b/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java new file mode 100644 index 0000000000..c5c6064555 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.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.push; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.WebsocketTest; + +public class RefreshCloseConnectionTest extends MultiBrowserTest { + @Test + public void testSessionRefresh() { + openTestURL(); + + Assert.assertEquals("1. Init", getLogRow(0)); + + openTestURL(); + + Assert.assertEquals("2. Refresh", getLogRow(1)); + Assert.assertEquals("3. Push", getLogRow(0)); + } + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return WebsocketTest.getWebsocketBrowsers(); + } +} diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index 8dd10216d2..1c5fb380ab 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -16,6 +16,8 @@ package com.vaadin.tests.tb3; +import static com.vaadin.tests.tb3.TB3Runner.localWebDriverIsUsed; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -24,11 +26,15 @@ import java.net.URL; import java.util.Collections; import java.util.List; -import com.vaadin.testbench.TestBenchElement; import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; -import org.openqa.selenium.*; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.Platform; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.interactions.HasInputDevices; import org.openqa.selenium.interactions.Keyboard; import org.openqa.selenium.interactions.Mouse; @@ -45,13 +51,12 @@ import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium; import com.vaadin.server.LegacyApplication; import com.vaadin.server.UIProvider; import com.vaadin.testbench.TestBench; +import com.vaadin.testbench.TestBenchElement; import com.vaadin.testbench.TestBenchTestCase; import com.vaadin.tests.components.AbstractTestUIWithLog; import com.vaadin.tests.tb3.MultiBrowserTest.Browser; import com.vaadin.ui.UI; -import static com.vaadin.tests.tb3.TB3Runner.localWebDriverIsUsed; - /** * Base class for TestBench 3+ tests. All TB3+ tests in the project should * extend this class. @@ -85,6 +90,8 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { */ private static final int BROWSER_TIMEOUT_IN_MS = 30 * 1000; + private static final int BROWSER_INIT_ATTEMPTS = 5; + private DesiredCapabilities desiredCapabilities; private boolean debug = false; @@ -134,9 +141,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { if (localWebDriverIsUsed()) { setupLocalDriver(capabilities); } else { - WebDriver dr = TestBench.createDriver(new RemoteWebDriver( - new URL(getHubURL()), capabilities)); - setDriver(dr); + setupRemoteDriver(capabilities); } } @@ -166,7 +171,8 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } protected WebElement getTooltipElement() { - return getDriver().findElement(com.vaadin.testbench.By.className("v-tooltip-text")); + return getDriver().findElement( + com.vaadin.testbench.By.className("v-tooltip-text")); } protected Coordinates getCoordinates(TestBenchElement element) { @@ -218,12 +224,53 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { DesiredCapabilities desiredCapabilities); /** + * Creates a {@link WebDriver} instance used for running the test remotely. + * + * @since + * @param capabilities + * the type of browser needed + * @throws Exception + */ + private void setupRemoteDriver(DesiredCapabilities capabilities) + throws Exception { + for (int i = 1; i <= BROWSER_INIT_ATTEMPTS; i++) { + try { + WebDriver dr = TestBench.createDriver(new RemoteWebDriver( + new URL(getHubURL()), capabilities)); + setDriver(dr); + } catch (Exception e) { + System.err.println("Browser startup for " + capabilities + + " failed on attempt " + i + ": " + e.getMessage()); + if (i == BROWSER_INIT_ATTEMPTS) { + throw e; + } + } + } + + } + + /** * Opens the given test (defined by {@link #getTestUrl()}, optionally with * debug window and/or push (depending on {@link #isDebug()} and * {@link #isPush()}. */ protected void openTestURL() { - driver.get(getTestUrl()); + openTestURL(""); + } + + /** + * Opens the given test (defined by {@link #getTestUrl()}, optionally with + * debug window and/or push (depending on {@link #isDebug()} and + * {@link #isPush()}. + */ + protected void openTestURL(String extraParameters) { + String url = getTestUrl(); + if (url.contains("?")) { + url = url + "&" + extraParameters; + } else { + url = url + "?" + extraParameters; + } + driver.get(url); } /** @@ -341,8 +388,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @return Focused element or null */ protected WebElement getFocusedElement() { - Object focusedElement = ((JavascriptExecutor) getDriver()) - .executeScript("return document.activeElement"); + Object focusedElement = executeScript("return document.activeElement"); if (null != focusedElement) { return (WebElement) focusedElement; } else { @@ -351,6 +397,19 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } /** + * Executes the given Javascript + * + * @param script + * the script to execute + * @return whatever + * {@link org.openqa.selenium.JavascriptExecutor#executeScript(String, Object...)} + * returns + */ + protected Object executeScript(String script) { + return ((JavascriptExecutor) getDriver()).executeScript(script); + } + + /** * Find a Vaadin element based on its id given using Component.setId * * @param id @@ -396,7 +455,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @param condition * the condition to wait for to become true */ - protected void waitUntil(ExpectedCondition<Boolean> condition) { + protected <T> void waitUntil(ExpectedCondition<T> condition) { waitUntil(condition, 10); } @@ -408,7 +467,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @param condition * the condition to wait for to become true */ - protected void waitUntil(ExpectedCondition<Boolean> condition, + protected <T> void waitUntil(ExpectedCondition<T> condition, long timeoutInSeconds) { new WebDriverWait(driver, timeoutInSeconds).until(condition); } @@ -421,7 +480,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @param condition * the condition to wait for to become false */ - protected void waitUntilNot(ExpectedCondition<Boolean> condition) { + protected <T> void waitUntilNot(ExpectedCondition<T> condition) { waitUntilNot(condition, 10); } @@ -433,14 +492,42 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @param condition * the condition to wait for to become false */ - protected void waitUntilNot(ExpectedCondition<Boolean> condition, + protected <T> void waitUntilNot(ExpectedCondition<T> condition, long timeoutInSeconds) { waitUntil(ExpectedConditions.not(condition), timeoutInSeconds); } - protected void waitForElementToBePresent(By by) { - waitUntil(ExpectedConditions.not(ExpectedConditions - .invisibilityOfElementLocated(by))); + protected void waitForElementPresent(final By by) { + waitUntil(ExpectedConditions.presenceOfElementLocated(by)); + } + + protected void waitForElementVisible(final By by) { + waitUntil(ExpectedConditions.visibilityOfElementLocated(by)); + } + + /** + * Checks if the given element has the given class name. + * + * Matches only full class names, i.e. has ("foo") does not match + * class="foobar" + * + * @param element + * @param className + * @return + */ + protected boolean hasCssClass(WebElement element, String className) { + String classes = element.getAttribute("class"); + if (classes == null || classes.isEmpty()) { + return (className == null || className.isEmpty()); + } + + for (String cls : classes.split(" ")) { + if (className.equals(cls)) { + return true; + } + } + + return false; } /** @@ -817,6 +904,8 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { public static DesiredCapabilities ie(int version) { DesiredCapabilities c = DesiredCapabilities.internetExplorer(); c.setVersion("" + version); + c.setCapability(InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION, + true); return c; } diff --git a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java index 15ca97f701..ff824ad98a 100644 --- a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java +++ b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2013 Vaadind 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 @@ -28,6 +28,7 @@ import java.util.Properties; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.firefox.FirefoxBinary; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.phantomjs.PhantomJSDriver; @@ -41,7 +42,7 @@ import com.vaadin.tests.tb3.MultiBrowserTest.Browser; * Provides values for parameters which depend on where the test is run. * Parameters should be configured in work/eclipse-run-selected-test.properties. * A template is available in uitest/. - * + * * @author Vaadin Ltd */ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { @@ -105,7 +106,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { /** * Gets the hostname that tests are configured to use. - * + * * @return the host name configuration value */ public static String getConfiguredDeploymentHostname() { @@ -125,7 +126,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { /** * Gets the port that tests are configured to use. - * + * * @return the port configuration value */ public static int getConfiguredDeploymentPort() { @@ -142,7 +143,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { /** * Tries to automatically determine the IP address of the machine the test * is running on. - * + * * @return An IP address of one of the network interfaces in the machine. * @throws RuntimeException * if there was an error or no IP was found @@ -179,7 +180,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { /* * (non-Javadoc) - * + * * @see com.vaadin.tests.tb3.AbstractTB3Test#setupLocalDriver() */ @Override @@ -209,7 +210,13 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { + " containing the path of your local ChromeDriver installation."); } System.setProperty("webdriver.chrome.driver", chromeDriverPath); - driver = new ChromeDriver(); + + // Tells chrome not to show warning + // "You are using an unsupported command-line flag: --ignore-certifcate-errors". + // #14319 + ChromeOptions options = new ChromeOptions(); + options.addArguments("--test-type "); + driver = new ChromeDriver(options); } else if (BrowserUtil.isSafari(desiredCapabilities)) { driver = new SafariDriver(); } else if (BrowserUtil.isPhantomJS(desiredCapabilities)) { diff --git a/uitest/src/com/vaadin/tests/tb3/TB3Runner.java b/uitest/src/com/vaadin/tests/tb3/TB3Runner.java index 5b5a6dcf39..0d540644bf 100644 --- a/uitest/src/com/vaadin/tests/tb3/TB3Runner.java +++ b/uitest/src/com/vaadin/tests/tb3/TB3Runner.java @@ -17,8 +17,10 @@ package com.vaadin.tests.tb3; import java.lang.annotation.Annotation; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; @@ -26,6 +28,8 @@ import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; import org.junit.Ignore; import org.junit.Test; import org.junit.runners.BlockJUnit4ClassRunner; @@ -34,6 +38,8 @@ import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.remote.HttpCommandExecutor; +import org.openqa.selenium.remote.internal.HttpClientFactory; import com.vaadin.tests.annotations.TestCategory; import com.vaadin.tests.tb3.AbstractTB3Test.BrowserUtil; @@ -50,6 +56,13 @@ import com.vaadin.tests.tb3.MultiBrowserTest.Browser; public class TB3Runner extends BlockJUnit4ClassRunner { /** + * Socket timeout for HTTP connections to the grid hub. The connection is + * closed after 30 minutes of inactivity to avoid builds hanging for up to + * three hours per connection if the test client crashes/hangs. + */ + private static final int SOCKET_TIMEOUT = 30 * 60 * 1000; + + /** * This is the total limit of actual JUnit test instances run in parallel */ private static final int MAX_CONCURRENT_TESTS; @@ -67,12 +80,34 @@ public class TB3Runner extends BlockJUnit4ClassRunner { MAX_CONCURRENT_TESTS = 50; } service = Executors.newFixedThreadPool(MAX_CONCURRENT_TESTS); + + // reduce socket timeout to avoid tests hanging for three hours + try { + Field field = HttpCommandExecutor.class + .getDeclaredField("httpClientFactory"); + assert (Modifier.isStatic(field.getModifiers())); + field.setAccessible(true); + field.set(null, new HttpClientFactory() { + @Override + public HttpParams getHttpParams() { + HttpParams params = super.getHttpParams(); + // fifteen minute timeout + HttpConnectionParams.setSoTimeout(params, SOCKET_TIMEOUT); + return params; + } + }); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException( + "Changing socket timeout for TestBench failed", e); + } } protected static boolean localWebDriverIsUsed() { String useLocalWebDriver = System.getProperty("useLocalWebDriver"); - return useLocalWebDriver != null && useLocalWebDriver.toLowerCase().equals("true"); + return useLocalWebDriver != null + && useLocalWebDriver.toLowerCase().equals("true"); } public TB3Runner(Class<?> klass) throws InitializationError { diff --git a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFly.java b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFly.java new file mode 100644 index 0000000000..ec22edd205 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFly.java @@ -0,0 +1,109 @@ +/* + * Copyright 2000-2013 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.themes; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.ThemeResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.tests.util.PersonContainer; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Image; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; + +@Theme("reindeer") +public class ThemeChangeOnTheFly extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + Button inject = new Button("Inject blue background"); + inject.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + getPage().getStyles().add( + ".v-app { background: blue !important;}"); + + } + }); + addComponent(inject); + + GridLayout gl = new GridLayout(2, 4); + gl.setCaption("Change theme by clicking a button"); + for (final String theme : new String[] { "reindeer", "runo", + "chameleon", "base", null }) { + Button b = new Button(theme); + b.setId(theme + ""); + b.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + getUI().setTheme(theme); + } + }); + gl.addComponent(b); + } + + Table t = new Table(); + PersonContainer pc = PersonContainer.createWithTestData(); + pc.addNestedContainerBean("address"); + t.setContainerDataSource(pc); + gl.addComponent(t, 0, 3, 1, 3); + gl.setRowExpandRatio(3, 1); + + gl.setWidth("500px"); + gl.setHeight("800px"); + + HorizontalLayout images = new HorizontalLayout(); + images.setSpacing(true); + + Label l = new Label("Chameleon theme image in caption"); + l.setIcon(new ThemeResource("img/magnifier.png")); + images.addComponent(l); + Image image = new Image("Runo theme image", new ThemeResource( + "icons/64/ok.png")); + images.addComponent(image); + image = new Image("Reindeer theme image", new ThemeResource( + "button/img/left-focus.png")); + images.addComponent(image); + addComponent(images); + addComponent(gl); + + getLayout().setSpacing(true); + + Window w = new Window(); + w.setContent(new VerticalLayout(new Button("Button in window"))); + addWindow(w); + } + + @Override + protected String getTestDescription() { + return "Test that you can change theme on the fly"; + } + + @Override + protected Integer getTicketNumber() { + return 2874; + } + +} diff --git a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java new file mode 100644 index 0000000000..eb010e82ee --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java @@ -0,0 +1,121 @@ +/* + * Copyright 2000-2013 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.themes; + +import java.io.IOException; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ThemeChangeOnTheFlyTest extends MultiBrowserTest { + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + // Seems like stylesheet onload is not fired on PhantomJS + // https://github.com/ariya/phantomjs/issues/12332 + List<DesiredCapabilities> l = super.getBrowsersToTest(); + l.remove(Browser.PHANTOMJS.getDesiredCapabilities()); + return l; + } + + @Test + public void injectedStyleAndThemeChange() throws IOException { + openTestURL(); + $(ButtonElement.class).caption("Inject blue background").first() + .click(); + changeTheme("runo"); + compareScreen("runo-blue-background"); + } + + @Test + public void reindeerToOthers() throws IOException { + openTestURL(); + compareScreen("reindeer"); + + changeThemeAndCompare("runo"); + changeThemeAndCompare("chameleon"); + changeThemeAndCompare("base"); + + } + + @Test + public void runoToReindeer() throws IOException { + openTestURL("theme=runo"); + compareScreen("runo"); + changeThemeAndCompare("reindeer"); + } + + @Test + public void reindeerToNullToReindeer() throws IOException { + openTestURL(); + + changeThemeAndCompare("null"); + changeThemeAndCompare("reindeer"); + } + + private void changeThemeAndCompare(String theme) throws IOException { + changeTheme(theme); + compareScreen(theme); + } + + private void changeTheme(String theme) { + $(ButtonElement.class).id(theme).click(); + if (theme.equals("null")) { + waitForThemeToChange(""); + assertOverlayTheme(""); + } else { + waitForThemeToChange(theme); + assertOverlayTheme(theme); + } + } + + private void waitForThemeToChange(final String theme) { + + final WebElement rootDiv = findElement(By + .xpath("//div[contains(@class,'v-app')]")); + waitUntil(new ExpectedCondition<Boolean>() { + + @Override + public Boolean apply(WebDriver input) { + String rootClass = rootDiv.getAttribute("class").trim(); + String expected = "v-app " + theme; + expected = expected.trim(); + return rootClass.equals(expected); + } + }, 30); + } + + private void assertOverlayTheme(String theme) { + final WebElement overlayContainerDiv = findElement(By + .xpath("//div[contains(@class,'v-overlay-container')]")); + String expected = "v-app v-overlay-container " + theme; + expected = expected.trim(); + + String overlayClass = overlayContainerDiv.getAttribute("class").trim(); + + Assert.assertEquals(expected, overlayClass); + } + +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/Accordions.java b/uitest/src/com/vaadin/tests/themes/valo/Accordions.java index b401451271..c32be01d8d 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Accordions.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Accordions.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2013 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 @@ -44,6 +44,7 @@ public class Accordions extends VerticalLayout implements View { } Accordion getAccordion(String caption) { + TestIcon testIcon = new TestIcon(0); Accordion ac = new Accordion(); ac.setCaption(caption); ac.addTab(new VerticalLayout() { @@ -52,28 +53,28 @@ public class Accordions extends VerticalLayout implements View { addComponent(new Label( "Fabio vel iudice vincam, sunt in culpa qui officia. Ut enim ad minim veniam, quis nostrud exercitation.")); } - }, "First Caption", TestIcon.get()); + }, "First Caption", testIcon.get()); ac.addTab(new VerticalLayout() { { setMargin(true); addComponent(new Label( "Gallia est omnis divisa in partes tres, quarum.")); } - }, "Second Caption", TestIcon.get()); + }, "Second Caption", testIcon.get()); ac.addTab(new VerticalLayout() { { setMargin(true); addComponent(new Label( "Nihil hic munitissimus habendi senatus locus, nihil horum? Sed haec quis possit intrepidus aestimare tellus.")); } - }, "Third Caption", TestIcon.get()); + }, "Third Caption", testIcon.get()); ac.addTab(new VerticalLayout() { { setMargin(true); addComponent(new Label( "Inmensae subtilitatis, obscuris et malesuada fames. Quisque ut dolor gravida, placerat libero vel, euismod.")); } - }, "Custom Caption Style", TestIcon.get()).setStyleName("color1"); + }, "Custom Caption Style", testIcon.get()).setStyleName("color1"); return ac; } diff --git a/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java b/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java index ce08d9ba08..758d2de200 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java @@ -66,61 +66,62 @@ public class ButtonsAndLinks extends VerticalLayout implements View { button.addStyleName("danger"); row.addComponent(button); + TestIcon testIcon = new TestIcon(10); button = new Button("Small"); button.addStyleName("small"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); row.addComponent(button); button = new Button("Large"); button.addStyleName("large"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); row.addComponent(button); button = new Button("Top"); button.addStyleName("icon-align-top"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); row.addComponent(button); button = new Button("Image icon"); - button.setIcon(TestIcon.get(true, 16)); + button.setIcon(testIcon.get(true, 16)); row.addComponent(button); button = new Button("Image icon"); button.addStyleName("icon-align-right"); - button.setIcon(TestIcon.get(true)); + button.setIcon(testIcon.get(true)); row.addComponent(button); button = new Button("Photos"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); row.addComponent(button); button = new Button(); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("icon-only"); row.addComponent(button); button = new Button("Borderless"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("borderless"); row.addComponent(button); button = new Button("Borderless, colored"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("borderless-colored"); row.addComponent(button); button = new Button("Quiet"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("quiet"); row.addComponent(button); button = new Button("Link style"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("link"); row.addComponent(button); button = new Button("Icon on right"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("icon-align-right"); row.addComponent(button); @@ -154,7 +155,7 @@ public class ButtonsAndLinks extends VerticalLayout implements View { link = new Link("Link with icon", new ExternalResource( "https://vaadin.com")); link.addStyleName("color3"); - link.setIcon(TestIcon.get()); + link.setIcon(testIcon.get()); row.addComponent(link); link = new Link("Small", new ExternalResource("https://vaadin.com")); @@ -166,7 +167,7 @@ public class ButtonsAndLinks extends VerticalLayout implements View { row.addComponent(link); link = new Link(null, new ExternalResource("https://vaadin.com")); - link.setIcon(TestIcon.get()); + link.setIcon(testIcon.get()); link.addStyleName("large"); row.addComponent(link); } diff --git a/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java b/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java index a2daeff2f8..c7a2610a21 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java +++ b/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java @@ -57,17 +57,18 @@ public class CheckBoxes extends VerticalLayout implements View { check.addStyleName("color1"); row.addComponent(check); + TestIcon testIcon = new TestIcon(30); check = new CheckBox("Custom color", true); check.addStyleName("color2"); - check.setIcon(TestIcon.get()); + check.setIcon(testIcon.get()); row.addComponent(check); check = new CheckBox("With Icon", true); - check.setIcon(TestIcon.get()); + check.setIcon(testIcon.get()); row.addComponent(check); check = new CheckBox(); - check.setIcon(TestIcon.get(true)); + check.setIcon(testIcon.get(true)); row.addComponent(check); check = new CheckBox("Small", true); @@ -94,9 +95,9 @@ public class CheckBoxes extends VerticalLayout implements View { .addItem("Option Two, with a longer caption that should wrap when the components width is explicitly set."); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon(two, TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get(true)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon(two, testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose many, explicit width"); @@ -107,9 +108,9 @@ public class CheckBoxes extends VerticalLayout implements View { .addItem("Option Two, with a longer caption that should wrap when the components width is explicitly set."); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon(two, TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get(true)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon(two, testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose one, small"); @@ -119,9 +120,9 @@ public class CheckBoxes extends VerticalLayout implements View { 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)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon("Option Two", testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose many, small"); @@ -131,9 +132,9 @@ public class CheckBoxes extends VerticalLayout implements View { 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)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon("Option Two", testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose one, large"); @@ -143,9 +144,9 @@ public class CheckBoxes extends VerticalLayout implements View { 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)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon("Option Two", testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose many, large"); @@ -155,9 +156,9 @@ public class CheckBoxes extends VerticalLayout implements View { 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)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon("Option Two", testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Horizontal items"); @@ -166,9 +167,9 @@ public class CheckBoxes extends VerticalLayout implements View { two = options.addItem("Option Two, with a longer caption"); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon(two, TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get()); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon(two, testIcon.get()); + options.setItemIcon("Option Three", testIcon.get()); row.addComponent(options); options = new OptionGroup("Horizontal items, explicit width"); @@ -179,9 +180,9 @@ public class CheckBoxes extends VerticalLayout implements View { two = options.addItem("Option Two, with a longer caption"); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon(two, TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get()); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon(two, testIcon.get()); + options.setItemIcon("Option Three", testIcon.get()); row.addComponent(options); } diff --git a/uitest/src/com/vaadin/tests/themes/valo/ColorPickers.java b/uitest/src/com/vaadin/tests/themes/valo/ColorPickers.java index b841b0b116..a7fd60ea51 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ColorPickers.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ColorPickers.java @@ -37,9 +37,11 @@ public class ColorPickers extends VerticalLayout implements View { row.setSpacing(true); addComponent(row); + TestIcon testIcon = new TestIcon(40); + ColorPicker cp = new ColorPicker(); cp.setDefaultCaptionEnabled(true); - cp.setIcon(TestIcon.get()); + cp.setIcon(testIcon.get()); cp.setColor(new Color(138, 73, 115)); row.addComponent(cp); diff --git a/uitest/src/com/vaadin/tests/themes/valo/ComboBoxes.java b/uitest/src/com/vaadin/tests/themes/valo/ComboBoxes.java index cafdfe37e0..1b8b290d91 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ComboBoxes.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ComboBoxes.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.themes.valo; -import com.vaadin.data.Container; import com.vaadin.navigator.View; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.server.ThemeResource; @@ -40,15 +39,13 @@ public class ComboBoxes extends VerticalLayout implements View { row.setSpacing(true); addComponent(row); - Container generatedContainer = ValoThemeTest.generateContainer(200, - false); ComboBox combo = new ComboBox("Normal"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); combo.setNullSelectionAllowed(false); - combo.select(generatedContainer.getItemIds().iterator().next()); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.select(combo.getItemIds().iterator().next()); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.setItemIcon(combo.getItemIds().iterator().next(), new ThemeResource("../runo/icons/16/document.png")); row.addComponent(combo); @@ -60,11 +57,11 @@ public class ComboBoxes extends VerticalLayout implements View { combo = new ComboBox(); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); combo.setNullSelectionAllowed(false); - combo.select(generatedContainer.getItemIds().iterator().next()); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.select(combo.getItemIds().iterator().next()); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.setWidth("240px"); group.addComponent(combo); Button today = new Button("Do It"); @@ -120,41 +117,41 @@ public class ComboBoxes extends VerticalLayout implements View { combo = new ComboBox("Custom color"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("color1"); row.addComponent(combo); combo = new ComboBox("Custom color"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("color2"); row.addComponent(combo); combo = new ComboBox("Custom color"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("color3"); row.addComponent(combo); combo = new ComboBox("Small"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("small"); row.addComponent(combo); combo = new ComboBox("Large"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("large"); row.addComponent(combo); diff --git a/uitest/src/com/vaadin/tests/themes/valo/Forms.java b/uitest/src/com/vaadin/tests/themes/valo/Forms.java index 9451b5c5d3..6f1b8bbf7a 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Forms.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Forms.java @@ -60,10 +60,10 @@ public class Forms extends VerticalLayout implements View { Label section = new Label("Personal Info"); section.addStyleName("h2"); form.addComponent(section); + StringGenerator sg = new StringGenerator(); TextField name = new TextField("Name"); - name.setValue(ValoThemeTest.nextString(true) + " " - + ValoThemeTest.nextString(true)); + name.setValue(sg.nextString(true) + " " + sg.nextString(true)); name.setWidth("50%"); form.addComponent(name); @@ -72,8 +72,7 @@ public class Forms extends VerticalLayout implements View { form.addComponent(birthday); TextField username = new TextField("Username"); - username.setValue(ValoThemeTest.nextString(false) - + ValoThemeTest.nextString(false)); + username.setValue(sg.nextString(false) + sg.nextString(false)); username.setRequired(true); form.addComponent(username); @@ -89,15 +88,14 @@ public class Forms extends VerticalLayout implements View { form.addComponent(section); TextField email = new TextField("Email"); - email.setValue(ValoThemeTest.nextString(false) + "@" - + ValoThemeTest.nextString(false) + ".com"); + email.setValue(sg.nextString(false) + "@" + sg.nextString(false) + + ".com"); email.setWidth("50%"); email.setRequired(true); form.addComponent(email); TextField location = new TextField("Location"); - location.setValue(ValoThemeTest.nextString(true) + ", " - + ValoThemeTest.nextString(true)); + location.setValue(sg.nextString(true) + ", " + sg.nextString(true)); location.setWidth("50%"); location.setComponentError(new UserError("This address doesn't exist")); form.addComponent(location); diff --git a/uitest/src/com/vaadin/tests/themes/valo/ImmediateUpload.java b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUpload.java new file mode 100644 index 0000000000..87f24d98d4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUpload.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.themes.valo; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Upload; + +/** + * + * @since + * @author Vaadin Ltd + */ +@Theme("valo") +public class ImmediateUpload extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + + Upload upload = new Upload(); + upload.setId("upload"); + upload.setImmediate(false); + addComponent(upload); + + Upload immediateUpload = new Upload(); + immediateUpload.setId("immediateupload"); + immediateUpload.setImmediate(true); + addComponent(immediateUpload); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Immediate upload should hide the button"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(14238); + } + +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java new file mode 100644 index 0000000000..044f76e335 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java @@ -0,0 +1,73 @@ +/* + * 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.themes.valo; + +import static org.hamcrest.Matchers.equalToIgnoringCase; +import static org.junit.Assert.assertThat; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.testbench.elements.UploadElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test to see if upload immediate mode hides the native file input. + * + * @author Vaadin Ltd + */ +public class ImmediateUploadTest extends MultiBrowserTest { + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return getAllBrowsers(); + } + + @Test + public void fileInputShouldNotBeVisibleInImmediate() + throws InterruptedException { + openTestURL(); + + UploadElement normalUpload = $(UploadElement.class).id("upload"); + UploadElement immediateUpload = $(UploadElement.class).id( + "immediateupload"); + + WebElement normalUploadInput = normalUpload.findElement(By + .cssSelector("input[type='file']")); + WebElement immediateUploadInput = immediateUpload.findElement(By + .cssSelector("input[type='file']")); + + WebElement normalUploadButton = normalUpload.findElement(By + .tagName("div")); + WebElement immediateUploadButton = immediateUpload.findElement(By + .tagName("div")); + + assertThat(normalUploadButton.getCssValue("display"), + equalToIgnoringCase("block")); + assertThat(immediateUploadButton.getCssValue("display"), + equalToIgnoringCase("block")); + + assertThat(normalUploadInput.getCssValue("position"), + equalToIgnoringCase("static")); + assertThat(immediateUploadInput.getCssValue("position"), + equalToIgnoringCase("absolute")); + + } +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/MenuBars.java b/uitest/src/com/vaadin/tests/themes/valo/MenuBars.java index f15f43254a..88eea73513 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/MenuBars.java +++ b/uitest/src/com/vaadin/tests/themes/valo/MenuBars.java @@ -120,14 +120,16 @@ public class MenuBars extends VerticalLayout implements View { view.addItem("Zoom In", click); view.addItem("Zoom Out", click); + TestIcon testIcon = new TestIcon(50); + MenuItem fav = menubar.addItem("", check); - fav.setIcon(TestIcon.get()); + fav.setIcon(testIcon.get()); fav.setStyleName("icon-only"); fav.setCheckable(true); fav.setChecked(true); fav = menubar.addItem("", check); - fav.setIcon(TestIcon.get()); + fav.setIcon(testIcon.get()); fav.setStyleName("icon-only"); fav.setCheckable(true); fav.setCheckable(true); diff --git a/uitest/src/com/vaadin/tests/themes/valo/Panels.java b/uitest/src/com/vaadin/tests/themes/valo/Panels.java index 74baef066b..8a17244693 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Panels.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Panels.java @@ -40,45 +40,46 @@ public class Panels extends VerticalLayout implements View { row.addStyleName("wrapping"); row.setSpacing(true); addComponent(row); + TestIcon testIcon = new TestIcon(60); Panel panel = new Panel("Normal"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Sized"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.setWidth("10em"); panel.setHeight("250px"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Custom Caption"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("color1"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Custom Caption"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("color2"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Custom Caption"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("color3"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Borderless style"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("borderless"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Borderless + scroll divider"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("borderless"); panel.addStyleName("scroll-divider"); panel.setContent(panelContentScroll()); @@ -86,13 +87,13 @@ public class Panels extends VerticalLayout implements View { row.addComponent(panel); panel = new Panel("Well style"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("well"); panel.setContent(panelContent()); row.addComponent(panel); CssLayout layout = new CssLayout(); - layout.setIcon(TestIcon.get()); + layout.setIcon(testIcon.get()); layout.setCaption("Panel style layout"); layout.addStyleName("card"); layout.addComponent(panelContent()); @@ -131,7 +132,7 @@ public class Panels extends VerticalLayout implements View { layout.setWidth("14em"); layout = new CssLayout(); - layout.setIcon(TestIcon.get()); + layout.setIcon(testIcon.get()); layout.setCaption("Well style layout"); layout.addStyleName("well"); layout.addComponent(panelContent()); diff --git a/uitest/src/com/vaadin/tests/themes/valo/StringGenerator.java b/uitest/src/com/vaadin/tests/themes/valo/StringGenerator.java new file mode 100644 index 0000000000..7e5cc0f691 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/StringGenerator.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.themes.valo; + +public class StringGenerator { + static String[] strings = new String[] { "lorem", "ipsum", "dolor", "sit", + "amet", "consectetur", "quid", "securi", "etiam", "tamquam", "eu", + "fugiat", "nulla", "pariatur" }; + int stringCount = -1; + + String nextString(boolean capitalize) { + if (++stringCount >= strings.length) { + stringCount = 0; + } + return capitalize ? strings[stringCount].substring(0, 1).toUpperCase() + + strings[stringCount].substring(1) : strings[stringCount]; + } + +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/Tables.java b/uitest/src/com/vaadin/tests/themes/valo/Tables.java index 6aa02a7f74..442e3e509a 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Tables.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Tables.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -40,10 +40,9 @@ import com.vaadin.ui.VerticalLayout; public class Tables extends VerticalLayout implements View { - static final Container normalContainer = ValoThemeTest.generateContainer( - 200, false); - static final Container hierarchicalContainer = ValoThemeTest - .generateContainer(200, true); + final Container normalContainer = ValoThemeUI.generateContainer(200, false); + final Container hierarchicalContainer = ValoThemeUI.generateContainer(200, + true); CheckBox hierarchical = new CheckBox("Hierarchical"); CheckBox footer = new CheckBox("Footer", true); @@ -140,7 +139,7 @@ public class Tables extends VerticalLayout implements View { table.setColumnCollapsingAllowed(true); table.setColumnReorderingAllowed(true); table.setPageLength(6); - table.addActionHandler(ValoThemeTest.getActionHandler()); + table.addActionHandler(ValoThemeUI.getActionHandler()); table.setDragMode(TableDragMode.MULTIROW); table.setDropHandler(new DropHandler() { @Override @@ -153,9 +152,8 @@ public class Tables extends VerticalLayout implements View { Notification.show(event.getTransferable().toString()); } }); - table.setColumnAlignment(ValoThemeTest.DESCRIPTION_PROPERTY, - Align.RIGHT); - table.setColumnAlignment(ValoThemeTest.INDEX_PROPERTY, Align.CENTER); + table.setColumnAlignment(ValoThemeUI.DESCRIPTION_PROPERTY, Align.RIGHT); + table.setColumnAlignment(ValoThemeUI.INDEX_PROPERTY, Align.CENTER); table.removeContainerProperty("textfield"); table.addContainerProperty("textfield", TextField.class, null); @@ -186,11 +184,11 @@ public class Tables extends VerticalLayout implements View { table.setFooterVisible(footer); if (footer) { - table.setColumnFooter(ValoThemeTest.CAPTION_PROPERTY, "caption"); - table.setColumnFooter(ValoThemeTest.DESCRIPTION_PROPERTY, + table.setColumnFooter(ValoThemeUI.CAPTION_PROPERTY, "caption"); + table.setColumnFooter(ValoThemeUI.DESCRIPTION_PROPERTY, "description"); - table.setColumnFooter(ValoThemeTest.ICON_PROPERTY, "icon"); - table.setColumnFooter(ValoThemeTest.INDEX_PROPERTY, "index"); + table.setColumnFooter(ValoThemeUI.ICON_PROPERTY, "icon"); + table.setColumnFooter(ValoThemeUI.INDEX_PROPERTY, "index"); } if (sized) { @@ -205,9 +203,9 @@ public class Tables extends VerticalLayout implements View { table.setWidth("100%"); } } - table.setColumnExpandRatio(ValoThemeTest.CAPTION_PROPERTY, + table.setColumnExpandRatio(ValoThemeUI.CAPTION_PROPERTY, expandRatios ? 1.0f : 0); - table.setColumnExpandRatio(ValoThemeTest.DESCRIPTION_PROPERTY, + table.setColumnExpandRatio(ValoThemeUI.DESCRIPTION_PROPERTY, expandRatios ? 1.0f : 0); if (!stripes) { @@ -262,14 +260,14 @@ public class Tables extends VerticalLayout implements View { if (rowCaption) { table.setRowHeaderMode(RowHeaderMode.PROPERTY); - table.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); + table.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); } else { table.setItemCaptionPropertyId(null); } if (rowIcon) { table.setRowHeaderMode(RowHeaderMode.ICON_ONLY); - table.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + table.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); } else { table.setItemIconPropertyId(null); } diff --git a/uitest/src/com/vaadin/tests/themes/valo/Tabsheets.java b/uitest/src/com/vaadin/tests/themes/valo/Tabsheets.java index 24a249d90e..5e77292471 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Tabsheets.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Tabsheets.java @@ -149,12 +149,15 @@ public class Tabsheets extends VerticalLayout implements View { static TabSheet getTabSheet(boolean caption, String style, boolean closable, boolean scrolling, boolean icon, boolean disable) { + TestIcon testIcon = new TestIcon(60); + TabSheet ts = new TabSheet(); ts.addStyleName(style); + StringGenerator sg = new StringGenerator(); for (int i = 1; i <= (scrolling ? 10 : 3); i++) { - String tabcaption = caption ? ValoThemeTest.nextString(true) + " " - + ValoThemeTest.nextString(false) : null; + String tabcaption = caption ? sg.nextString(true) + " " + + sg.nextString(false) : null; VerticalLayout content = new VerticalLayout(); content.setMargin(true); @@ -174,7 +177,7 @@ public class Tabsheets extends VerticalLayout implements View { } if (icon) { - t.setIcon(TestIcon.get(false)); + t.setIcon(testIcon.get(false)); } } diff --git a/uitest/src/com/vaadin/tests/themes/valo/TestIcon.java b/uitest/src/com/vaadin/tests/themes/valo/TestIcon.java index 18b834f1bf..469f6bc31d 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/TestIcon.java +++ b/uitest/src/com/vaadin/tests/themes/valo/TestIcon.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2013 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 @@ -24,21 +24,27 @@ import com.vaadin.server.Resource; import com.vaadin.server.ThemeResource; /** - * + * * @since * @author Vaadin Ltd */ public class TestIcon { - public static Resource get() { + int iconCount = 0; + + public TestIcon(int startIndex) { + iconCount = startIndex; + } + + public Resource get() { return get(false, 32); } - public static Resource get(boolean isImage) { + public Resource get(boolean isImage) { return get(isImage, 32); } - public static Resource get(boolean isImage, int imageSize) { + public Resource get(boolean isImage, int imageSize) { if (!isImage) { if (++iconCount >= ICONS.size()) { iconCount = 0; @@ -51,5 +57,4 @@ public class TestIcon { static List<FontAwesome> ICONS = Collections.unmodifiableList(Arrays .asList(FontAwesome.values())); - static int iconCount = 0; } diff --git a/uitest/src/com/vaadin/tests/themes/valo/TextFields.java b/uitest/src/com/vaadin/tests/themes/valo/TextFields.java index cbe7a8a0b3..f8606bb7c9 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/TextFields.java +++ b/uitest/src/com/vaadin/tests/themes/valo/TextFields.java @@ -30,6 +30,8 @@ import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; public class TextFields extends VerticalLayout implements View { + private TestIcon testIcon = new TestIcon(140); + public TextFields() { setMargin(true); @@ -44,7 +46,7 @@ public class TextFields extends VerticalLayout implements View { TextField tf = new TextField("Normal"); tf.setInputPrompt("First name"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("Custom color"); @@ -87,45 +89,45 @@ public class TextFields extends VerticalLayout implements View { tf = new TextField("Large"); tf.setValue("Field value"); tf.addStyleName("large"); - tf.setIcon(TestIcon.get(true)); + tf.setIcon(testIcon.get(true)); row.addComponent(tf); tf = new TextField("Icon inside"); tf.setInputPrompt("Ooh, an icon"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("Large, Icon inside"); tf.setInputPrompt("Ooh, an icon"); tf.addStyleName("large"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("Small, Icon inside"); tf.setInputPrompt("Ooh, an icon"); tf.addStyleName("small"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("16px supported by default"); tf.setInputPrompt("Image icon"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get(true, 16)); + tf.setIcon(testIcon.get(true, 16)); row.addComponent(tf); tf = new TextField(); tf.setValue("Font, no caption"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField(); tf.setValue("Image, no caption"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get(true, 16)); + tf.setIcon(testIcon.get(true, 16)); row.addComponent(tf); CssLayout group = new CssLayout(); @@ -135,7 +137,7 @@ public class TextFields extends VerticalLayout implements View { tf = new TextField(); tf.setInputPrompt("Grouped with a button"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); tf.setWidth("260px"); group.addComponent(tf); @@ -147,7 +149,7 @@ public class TextFields extends VerticalLayout implements View { tf.setInputPrompt("Write hereā¦"); tf.addStyleName("inline-icon"); tf.addStyleName("borderless"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("Right-aligned"); @@ -196,7 +198,7 @@ public class TextFields extends VerticalLayout implements View { ta = new TextArea("Inline icon"); ta.setInputPrompt("Inline icon not really working"); ta.addStyleName("inline-icon"); - ta.setIcon(TestIcon.get()); + ta.setIcon(testIcon.get()); row.addComponent(ta); ta = new TextArea("Custom color"); diff --git a/uitest/src/com/vaadin/tests/themes/valo/Trees.java b/uitest/src/com/vaadin/tests/themes/valo/Trees.java index bb406e4f39..cb5657660a 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Trees.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Trees.java @@ -45,12 +45,12 @@ public class Trees extends VerticalLayout implements View { Tree tree = new Tree(); tree.setSelectable(true); tree.setMultiSelect(true); - Container generateContainer = ValoThemeTest.generateContainer(10, true); + Container generateContainer = ValoThemeUI.generateContainer(10, true); tree.setContainerDataSource(generateContainer); tree.setDragMode(TreeDragMode.NODE); row.addComponent(tree); - tree.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - tree.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + tree.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + tree.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); tree.expandItem(generateContainer.getItemIds().iterator().next()); tree.setDropHandler(new DropHandler() { @@ -66,7 +66,7 @@ public class Trees extends VerticalLayout implements View { }); // Add actions (context menu) - tree.addActionHandler(ValoThemeTest.getActionHandler()); + tree.addActionHandler(ValoThemeUI.getActionHandler()); } @Override diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoMiscTests.java b/uitest/src/com/vaadin/tests/themes/valo/ValoMiscTests.java index 222dd90e49..1676d121af 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ValoMiscTests.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoMiscTests.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -70,7 +70,7 @@ public class ValoMiscTests extends UI { TreeTable table = new TreeTable(); table.setWidth("100%"); - table.setContainerDataSource(Tables.hierarchicalContainer); + table.setContainerDataSource(ValoThemeUI.generateContainer(200, true)); Tables.configure(table, true, false, false, true, true, true, false, true, false, false, false, false, false); layout.addComponent(table); diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeTest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java index 014b1acac8..27a256665e 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeTest.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -50,13 +50,26 @@ import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.MenuBar; import com.vaadin.ui.MenuBar.MenuItem; +import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Notification; import com.vaadin.ui.UI; @Theme("tests-valo") @Title("Valo Theme Test") @PreserveOnRefresh -public class ValoThemeTest extends UI { +public class ValoThemeUI extends UI { + + private static LinkedHashMap<String, String> themeVariants = new LinkedHashMap<String, String>(); + static { + themeVariants.put("tests-valo", "Default"); + themeVariants.put("tests-valo-blueprint", "Blueprint"); + themeVariants.put("tests-valo-dark", "Dark"); + themeVariants.put("tests-valo-facebook", "Facebook"); + themeVariants.put("tests-valo-flatdark", "Flat dark"); + themeVariants.put("tests-valo-flat", "Flat"); + themeVariants.put("tests-valo-metro", "Metro"); + } + private TestIcon testIcon = new TestIcon(100); ValoMenuLayout root = new ValoMenuLayout(); ComponentContainer viewDisplay = root.getContentContainer(); @@ -201,6 +214,7 @@ public class ValoThemeTest extends UI { top.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT); top.addStyleName("valo-menu-title"); menu.addComponent(top); + menu.addComponent(createThemeSelect()); Label title = new Label("Vaadin<br><strong>Valo Theme Styles</strong>", ContentMode.HTML); @@ -271,7 +285,7 @@ public class ValoThemeTest extends UI { } b.setHtmlContentAllowed(true); b.setPrimaryStyleName("valo-menu-item"); - b.setIcon(TestIcon.get()); + b.setIcon(testIcon.get()); menu.addComponent(b); count++; } @@ -281,17 +295,25 @@ public class ValoThemeTest extends UI { return menu; } - static String[] strings = new String[] { "lorem", "ipsum", "dolor", "sit", - "amet", "consectetur", "quid", "securi", "etiam", "tamquam", "eu", - "fugiat", "nulla", "pariatur" }; - static int stringCount = -1; - - static String nextString(boolean capitalize) { - if (++stringCount >= strings.length) { - stringCount = 0; + private Component createThemeSelect() { + final NativeSelect ns = new NativeSelect(); + ns.setNullSelectionAllowed(false); + ns.setId("themeSelect"); + ns.addContainerProperty("caption", String.class, ""); + ns.setItemCaptionPropertyId("caption"); + for (String identifier : themeVariants.keySet()) { + ns.addItem(identifier).getItemProperty("caption") + .setValue(themeVariants.get(identifier)); } - return capitalize ? strings[stringCount].substring(0, 1).toUpperCase() - + strings[stringCount].substring(1) : strings[stringCount]; + + ns.setValue("tests-valo"); + ns.addValueChangeListener(new ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + setTheme((String) ns.getValue()); + } + }); + return ns; } static Handler actionHandler = new Handler() { @@ -324,9 +346,10 @@ public class ValoThemeTest extends UI { @SuppressWarnings("unchecked") static Container generateContainer(final int size, final boolean hierarchical) { + TestIcon testIcon = new TestIcon(90); IndexedContainer container = hierarchical ? new HierarchicalContainer() : new IndexedContainer(); - + StringGenerator sg = new StringGenerator(); container.addContainerProperty(CAPTION_PROPERTY, String.class, null); container.addContainerProperty(ICON_PROPERTY, Resource.class, null); container.addContainerProperty(INDEX_PROPERTY, Integer.class, null); @@ -335,15 +358,15 @@ public class ValoThemeTest extends UI { for (int i = 1; i < size + 1; i++) { Item item = container.addItem(i); item.getItemProperty(CAPTION_PROPERTY).setValue( - nextString(true) + " " + nextString(false)); + sg.nextString(true) + " " + sg.nextString(false)); item.getItemProperty(INDEX_PROPERTY).setValue(i); item.getItemProperty(DESCRIPTION_PROPERTY).setValue( - nextString(true) + " " + nextString(false) + " " - + nextString(false)); - item.getItemProperty(ICON_PROPERTY).setValue(TestIcon.get()); + sg.nextString(true) + " " + sg.nextString(false) + " " + + sg.nextString(false)); + item.getItemProperty(ICON_PROPERTY).setValue(testIcon.get()); } container.getItem(container.getIdByIndex(0)) - .getItemProperty(ICON_PROPERTY).setValue(TestIcon.get()); + .getItemProperty(ICON_PROPERTY).setValue(testIcon.get()); if (hierarchical) { for (int i = 1; i < size + 1; i++) { @@ -351,9 +374,9 @@ public class ValoThemeTest extends UI { String id = i + " -> " + j; Item child = container.addItem(id); child.getItemProperty(CAPTION_PROPERTY).setValue( - nextString(true) + " " + nextString(false)); + sg.nextString(true) + " " + sg.nextString(false)); child.getItemProperty(ICON_PROPERTY).setValue( - TestIcon.get()); + testIcon.get()); ((Hierarchical) container).setChildrenAllowed(id, false); ((Hierarchical) container).setParent(id, i); } diff --git a/uitest/src/com/vaadin/tests/tooltip/AdjacentElementsWithTooltipsTest.java b/uitest/src/com/vaadin/tests/tooltip/AdjacentElementsWithTooltipsTest.java index b9fc788008..af7a303629 100644 --- a/uitest/src/com/vaadin/tests/tooltip/AdjacentElementsWithTooltipsTest.java +++ b/uitest/src/com/vaadin/tests/tooltip/AdjacentElementsWithTooltipsTest.java @@ -69,7 +69,6 @@ public class AdjacentElementsWithTooltipsTest extends MultiBrowserTest { } private ButtonElement getButton(String caption) { - return $(ButtonElement.class) - .caption(caption).first(); + return $(ButtonElement.class).caption(caption).first(); } } diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java b/uitest/src/com/vaadin/tests/tooltip/TooltipInWindow.java index cd2cc7d060..690b65432a 100644 --- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java +++ b/uitest/src/com/vaadin/tests/tooltip/TooltipInWindow.java @@ -1,12 +1,12 @@ -/* +/* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -14,7 +14,7 @@ * the License. */ -package com.vaadin.tests.components.window; +package com.vaadin.tests.tooltip; import com.vaadin.server.VaadinRequest; import com.vaadin.tests.components.AbstractTestUI; @@ -41,9 +41,6 @@ public class TooltipInWindow extends AbstractTestUI { TextField tf = new TextField("TextField with a tooltip"); tf.setDescription("My tooltip"); tf.setId(id); - getTooltipConfiguration().setOpenDelay(0); - getTooltipConfiguration().setQuickOpenDelay(0); - getTooltipConfiguration().setCloseTimeout(1000); return tf; } @@ -54,7 +51,7 @@ public class TooltipInWindow extends AbstractTestUI { @Override protected Integer getTicketNumber() { - return Integer.valueOf(9172); + return 9172; } } diff --git a/uitest/src/com/vaadin/tests/tooltip/TooltipInWindowTest.java b/uitest/src/com/vaadin/tests/tooltip/TooltipInWindowTest.java new file mode 100644 index 0000000000..1c50bf5486 --- /dev/null +++ b/uitest/src/com/vaadin/tests/tooltip/TooltipInWindowTest.java @@ -0,0 +1,66 @@ +/* + * 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.tooltip; + +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.TooltipTest; + +/** + * Test if tooltips in subwindows behave correctly + * + * @author Vaadin Ltd + */ +public class TooltipInWindowTest extends TooltipTest { + + @Test + public void testTooltipsInSubWindow() throws Exception { + openTestURL(); + + WebElement textfield = vaadinElementById("tf1"); + + checkTooltip(textfield, "My tooltip"); + + ensureVisibleTooltipPositionedCorrectly(textfield); + + clearTooltip(); + + checkTooltip(textfield, "My tooltip"); + + clearTooltip(); + } + + private WebElement getTooltipContainerElement() { + return getDriver().findElement(By.className("v-tooltip")); + } + + private void ensureVisibleTooltipPositionedCorrectly(WebElement textfield) + throws InterruptedException { + int tooltipX = getTooltip().getLocation().getX(); + int textfieldX = textfield.getLocation().getX(); + assertGreaterOrEqual("Tooltip should be positioned on the textfield (" + + tooltipX + " < " + textfieldX + ")", tooltipX, textfieldX); + } + + private void ensureHiddenTooltipPositionedCorrectly() { + int tooltipX = getTooltipContainerElement().getLocation().getX(); + assertLessThanOrEqual( + "Tooltip should be positioned outside of viewport (was at " + + tooltipX + ")", tooltipX, -1000); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaConnector.java new file mode 100644 index 0000000000..b9037208f9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaConnector.java @@ -0,0 +1,15 @@ +package com.vaadin.tests.widgetset.client.superText; + +import com.vaadin.client.ui.textarea.TextAreaConnector; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.ExtraSuperTextArea; + +@Connect(ExtraSuperTextArea.class) +public class ExtraSuperTextAreaConnector extends TextAreaConnector { + + // @DelegateToWidget will not work with overridden state + @Override + public ExtraSuperTextAreaState getState() { + return (ExtraSuperTextAreaState) super.getState(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaState.java b/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaState.java new file mode 100644 index 0000000000..44456b27ba --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaState.java @@ -0,0 +1,7 @@ +package com.vaadin.tests.widgetset.client.superText; + +import com.vaadin.shared.ui.textarea.TextAreaState; + +public class ExtraSuperTextAreaState extends TextAreaState { + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaConnector.java new file mode 100644 index 0000000000..fda1fc6f0a --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaConnector.java @@ -0,0 +1,19 @@ +package com.vaadin.tests.widgetset.client.superText; + +import com.vaadin.client.ui.textarea.TextAreaConnector; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.SuperTextArea; + +/** + * @author artamonov + * @version $Id$ + */ +@Connect(SuperTextArea.class) +public class SuperTextAreaConnector extends TextAreaConnector { + + // @DelegateToWidget will not work with overridden state + @Override + public SuperTextAreaState getState() { + return (SuperTextAreaState) super.getState(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaState.java b/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaState.java new file mode 100644 index 0000000000..005075429c --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaState.java @@ -0,0 +1,11 @@ +package com.vaadin.tests.widgetset.client.superText; + +import com.vaadin.shared.ui.textarea.TextAreaState; + +/** + * @author artamonov + * @version $Id$ + */ +public class SuperTextAreaState extends TextAreaState { + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/server/ExtraSuperTextArea.java b/uitest/src/com/vaadin/tests/widgetset/server/ExtraSuperTextArea.java new file mode 100644 index 0000000000..b741c099b5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/ExtraSuperTextArea.java @@ -0,0 +1,16 @@ +package com.vaadin.tests.widgetset.server; + +import com.vaadin.tests.widgetset.client.superText.SuperTextAreaState; +import com.vaadin.ui.TextArea; + +/** + * @author artamonov + * @version $Id$ + */ +public class ExtraSuperTextArea extends TextArea { + + @Override + public SuperTextAreaState getState() { + return (SuperTextAreaState) super.getState(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendants.java b/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendants.java new file mode 100644 index 0000000000..aadabb3fcc --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendants.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.server; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.ui.TextArea; + +/** + * UI for testing that @DelegateToWidget works on derived widget states. + * + * @since + * @author Vaadin Ltd + */ +@Widgetset(TestingWidgetSet.NAME) +public class OverriddenDecendants extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + + TextArea normalTextArea = new TextArea(); + normalTextArea.setRows(10); + normalTextArea.setWordwrap(true); + + getLayout().addComponent(normalTextArea); + + // @DelegateToWidget will not work with overridden state in connector + SuperTextArea superTextArea = new SuperTextArea(); + superTextArea.setRows(10); + superTextArea.setWordwrap(true); + + getLayout().addComponent(superTextArea); + + // @DelegateToWidget will not work with overridden state in connector + ExtraSuperTextArea extraSuperTextArea = new ExtraSuperTextArea(); + extraSuperTextArea.setRows(10); + extraSuperTextArea.setWordwrap(true); + + getLayout().addComponent(extraSuperTextArea); + } + + @Override + protected String getTestDescription() { + return "@DelegateToWidget does not work for widget descendants with overridden getState"; + } + + @Override + protected Integer getTicketNumber() { + return 14059; + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendantsTest.java b/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendantsTest.java new file mode 100644 index 0000000000..aa29284010 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendantsTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.server; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import com.vaadin.testbench.elements.TextAreaElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Class for unit testing that @DelegateToWidget works on derived widget states. + * + * @since + * @author Vaadin Ltd + */ +public class OverriddenDecendantsTest extends MultiBrowserTest { + + @Test + public void allExtendingFieldsShouldGetRowsFromTextAreaStateAnnotation() + throws InterruptedException { + openTestURL(); + + List<TextAreaElement> textAreas = $(TextAreaElement.class).all(); + + assertEquals("Did not contain all 3 text areas", 3, textAreas.size()); + + for (TextAreaElement area : textAreas) { + assertEquals("Text area was missing rows", "10", + area.getAttribute("rows")); + } + + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/SuperTextArea.java b/uitest/src/com/vaadin/tests/widgetset/server/SuperTextArea.java new file mode 100644 index 0000000000..6e73915e44 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/SuperTextArea.java @@ -0,0 +1,16 @@ +package com.vaadin.tests.widgetset.server; + +import com.vaadin.tests.widgetset.client.superText.SuperTextAreaState; +import com.vaadin.ui.TextArea; + +/** + * @author artamonov + * @version $Id$ + */ +public class SuperTextArea extends TextArea { + + @Override + public SuperTextAreaState getState() { + return (SuperTextAreaState) super.getState(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java index d27884a13a..76d884d2c7 100644 --- a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java +++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java @@ -36,7 +36,7 @@ public class GwtRpcTest extends MultiBrowserTest { By label = By.id(GwtRpcButtonConnector.SUCCESS_LABEL_ID); - waitForElementToBePresent(label); + waitForElementVisible(label); getDriver().findElement(label); } |