From ffb33be8a15f3e82ca095901ca4fd2713eb229e6 Mon Sep 17 00:00:00 2001 From: Juho Nurminen Date: Tue, 1 Oct 2013 15:14:28 +0300 Subject: Update slider client-side state object on value change (#12676) Change-Id: Ief93d845e5498388072e05a0faff7ef2d29f1c77 --- .../vaadin/client/ui/slider/SliderConnector.java | 1 + .../tests/components/slider/SliderDisable.java | 81 ++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/components/slider/SliderDisable.java diff --git a/client/src/com/vaadin/client/ui/slider/SliderConnector.java b/client/src/com/vaadin/client/ui/slider/SliderConnector.java index e6e3e0467d..71462d69f0 100644 --- a/client/src/com/vaadin/client/ui/slider/SliderConnector.java +++ b/client/src/com/vaadin/client/ui/slider/SliderConnector.java @@ -52,6 +52,7 @@ public class SliderConnector extends AbstractFieldConnector implements @Override public void onValueChange(ValueChangeEvent event) { + getState().value = event.getValue(); rpc.valueChanged(event.getValue()); } diff --git a/uitest/src/com/vaadin/tests/components/slider/SliderDisable.java b/uitest/src/com/vaadin/tests/components/slider/SliderDisable.java new file mode 100644 index 0000000000..ea29a1657c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/slider/SliderDisable.java @@ -0,0 +1,81 @@ +/* + * 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.slider; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Slider; +import com.vaadin.ui.VerticalLayout; + +public class SliderDisable extends AbstractTestUI { + + public static class SliderDisableTest extends MultiBrowserTest { + @Test + public void disableSlider() throws IOException { + openTestURL(); + WebElement element = vaadinElement("/VVerticalLayout[0]/Slot[0]/VSlider[0]/domChild[2]/domChild[0]"); + new Actions(driver).dragAndDropBy(element, 112, 0).perform(); + compareScreen("enabled"); + vaadinElementById("disableButton").click(); + compareScreen("disabled"); + } + } + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout content = new VerticalLayout(); + content.setMargin(true); + content.setSpacing(true); + + final Slider slider = new Slider(0, 5); + slider.setWidth(200, Unit.PIXELS); + slider.setValue(1.0D); + + Button disableButton = new Button("Disable slider"); + disableButton.setId("disableButton"); + disableButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + slider.setEnabled(false); + } + }); + + content.addComponent(slider); + content.addComponent(disableButton); + setContent(content); + } + + @Override + protected String getTestDescription() { + return "The apparent value of the slider should not change when the slider is disabled"; + } + + @Override + protected Integer getTicketNumber() { + return 12676; + } + +} -- cgit v1.2.3 From b8828e7270122930d21d9b561cde73a652d62f7a Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Wed, 2 Oct 2013 09:39:34 +0300 Subject: Only publish files actually produced by this test/browser Change-Id: If4f66157791d642801c0100bb4bc0f293efe76cc --- uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java b/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java index 565d04fdb9..7f19a76ed6 100644 --- a/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java @@ -73,8 +73,8 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test { // Notify Teamcity of failed test System.out.print("##teamcity[publishArtifacts '"); - System.out.println(getScreenshotErrorDirectory() + "/" - + getScreenshotBaseName() + "* => screenshot-errors']"); + System.out.println(getScreenshotErrorBaseName() + + "* => screenshot-errors']"); } }; -- cgit v1.2.3 From 5966f01b9f804621ac123792850b43e86399ec60 Mon Sep 17 00:00:00 2001 From: Fabian Lange Date: Thu, 12 Sep 2013 16:20:17 +0200 Subject: reduce reflow and calculation in VOverlay (#12566) the actual position of VOverlay is only required when a shim or shadow is used. Otherwise the calculation of its position causes unnecessary reflows. Change-Id: Id3915fe55c6b477f5d3ff01ee3a505014303d6d6 --- client/src/com/vaadin/client/ui/VOverlay.java | 71 ++++++++++++++------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java index ced476f9dd..0e031e3d0d 100644 --- a/client/src/com/vaadin/client/ui/VOverlay.java +++ b/client/src/com/vaadin/client/ui/VOverlay.java @@ -248,10 +248,6 @@ public class VOverlay extends PopupPanel implements CloseHandler { return isShadowEnabled() && shadow.getParentElement() != null; } - private boolean isShimElementAttached() { - return shimElement != null && shimElement.hasParentElement(); - } - private void adjustZIndex() { setZIndex(Z_INDEX); } @@ -469,36 +465,51 @@ public class VOverlay extends PopupPanel implements CloseHandler { getOffsetWidth(); } - PositionAndSize positionAndSize = new PositionAndSize(getActualLeft(), - getActualTop(), getOffsetWidth(), getOffsetHeight()); + if (isShadowEnabled() || needsShimElement()) { + + PositionAndSize positionAndSize = new PositionAndSize( + getActualLeft(), getActualTop(), getOffsetWidth(), + getOffsetHeight()); + + // Animate the size + positionAndSize.setAnimationFromCenterProgress(progress); + + Element container = getElement().getParentElement().cast(); - // Animate the size - positionAndSize.setAnimationFromCenterProgress(progress); + if (isShadowEnabled()) { + updateShadowPosition(progress, zIndex, positionAndSize); + if (shadow.getParentElement() == null) { + container.insertBefore(shadow, getElement()); + sinkShadowEvents(); + } + } + + if (needsShimElement()) { + updateShimPosition(positionAndSize); + if (shimElement.getParentElement() == null) { + container.insertBefore(shimElement, getElement()); + } + } + } + } + private void updateShadowPosition(final double progress, String zIndex, + PositionAndSize positionAndSize) { // Opera needs some shaking to get parts of the shadow showing - // properly - // (ticket #2704) - if (BrowserInfo.get().isOpera() && isShadowEnabled()) { + // properly (ticket #2704) + if (BrowserInfo.get().isOpera()) { // Clear the height of all middle elements DOM.getChild(shadow, 3).getStyle().setProperty("height", "auto"); DOM.getChild(shadow, 4).getStyle().setProperty("height", "auto"); DOM.getChild(shadow, 5).getStyle().setProperty("height", "auto"); } - // Update correct values - if (isShadowEnabled()) { - updatePositionAndSize(shadow, positionAndSize); - DOM.setStyleAttribute(shadow, "zIndex", zIndex); - DOM.setStyleAttribute(shadow, "display", progress < 0.9 ? "none" - : ""); - } - if (needsShimElement()) { - updatePositionAndSize((Element) Element.as(getShimElement()), - positionAndSize); - } + updatePositionAndSize(shadow, positionAndSize); + DOM.setStyleAttribute(shadow, "zIndex", zIndex); + DOM.setStyleAttribute(shadow, "display", progress < 0.9 ? "none" : ""); // Opera fix, part 2 (ticket #2704) - if (BrowserInfo.get().isOpera() && isShadowEnabled()) { + if (BrowserInfo.get().isOpera()) { // We'll fix the height of all the middle elements DOM.getChild(shadow, 3) .getStyle() @@ -513,17 +524,11 @@ public class VOverlay extends PopupPanel implements CloseHandler { .setPropertyPx("height", DOM.getChild(shadow, 5).getOffsetHeight()); } + } - Element container = getElement().getParentElement().cast(); - // Attach to dom if not there already - if (isShadowEnabled() && !isShadowAttached()) { - container.insertBefore(shadow, getElement()); - sinkShadowEvents(); - } - if (needsShimElement() && !isShimElementAttached()) { - container.insertBefore(getShimElement(), getElement()); - } - + private void updateShimPosition(PositionAndSize positionAndSize) { + updatePositionAndSize((Element) Element.as(getShimElement()), + positionAndSize); } /** -- cgit v1.2.3 From 600f5f3238ecca22a8e7890d0656b0a23bd7dbba Mon Sep 17 00:00:00 2001 From: Yuriy Artamonov Date: Thu, 26 Sep 2013 11:37:42 +0400 Subject: Do not try to focus invisible components which not present in UIDL #12654 Change-Id: I365940e72d97426eceb408878bc8b24d7655de7c --- client/src/com/vaadin/client/ui/ui/UIConnector.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index c6d2e1436b..46b5f63180 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -319,6 +319,11 @@ public class UIConnector extends AbstractSingleComponentContainerConnector ComponentConnector paintable = (ComponentConnector) uidl .getPaintableAttribute("focused", getConnection()); + if (paintable == null) { + // Do not try to focus invisible components which not present in UIDL + return; + } + final Widget toBeFocused = paintable.getWidget(); /* * Two types of Widgets can be focused, either implementing -- cgit v1.2.3 From d0e604f6b509767c46ffe0fd6765cf23535f593e Mon Sep 17 00:00:00 2001 From: John Ahlroos Date: Mon, 30 Sep 2013 14:45:43 +0300 Subject: Only print testbench failure TeamCity messages when running in TC Change-Id: Ifa04ce512743bc8ccddea0bdca7b82cceaff150e --- uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java | 8 +++++--- uitest/tb3test.xml | 9 +++++++++ uitest/test.xml | 12 +++++++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java b/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java index 7f19a76ed6..94bcebde84 100644 --- a/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java @@ -72,9 +72,11 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test { protected void failed(Throwable e, Description description) { // Notify Teamcity of failed test - System.out.print("##teamcity[publishArtifacts '"); - System.out.println(getScreenshotErrorBaseName() - + "* => screenshot-errors']"); + if (!System.getProperty("teamcity.version", "").equals("")) { + System.out.print("##teamcity[publishArtifacts '"); + System.out.println(getScreenshotErrorBaseName() + + "* => screenshot-errors']"); + } } }; diff --git a/uitest/tb3test.xml b/uitest/tb3test.xml index 92008ff9f3..de69e0ebe6 100644 --- a/uitest/tb3test.xml +++ b/uitest/tb3test.xml @@ -19,12 +19,21 @@ + + + + + + + + + diff --git a/uitest/test.xml b/uitest/test.xml index 88b5238c09..c534d676b9 100644 --- a/uitest/test.xml +++ b/uitest/test.xml @@ -134,12 +134,18 @@ - - - ##teamcity[publishArtifacts '${com.vaadin.testbench.screenshot.directory}/errors/${basename}* => screenshot-errors'] + + + + + + + ##teamcity[publishArtifacts '${com.vaadin.testbench.screenshot.directory}/errors/${basename}* => screenshot-errors'] + + -- cgit v1.2.3 From 0e9ff32598ed86d5f24a8bce5c5c898d81dc2c84 Mon Sep 17 00:00:00 2001 From: John Ahlroos Date: Wed, 2 Oct 2013 16:33:41 +0300 Subject: Ported regression fixes in 6.8 for #12407 to 7.1 branch Change-Id: Ie46ab97fc1ff89dd241eec9182ed0f92164b754d --- client/src/com/vaadin/client/ui/VScrollTable.java | 32 ++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index 492730259a..6e9e28ff25 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -1113,14 +1113,16 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private ScheduledCommand lazyScroller = new ScheduledCommand() { @Override public void execute() { - if (firstvisibleOnLastPage > -1) { - scrollBodyPanel - .setScrollPosition(measureRowHeightOffset(firstvisibleOnLastPage)); - } else { - scrollBodyPanel - .setScrollPosition(measureRowHeightOffset(firstvisible)); + if (firstvisible > 0) { + firstRowInViewPort = firstvisible; + if (firstvisibleOnLastPage > -1) { + scrollBodyPanel + .setScrollPosition(measureRowHeightOffset(firstvisibleOnLastPage)); + } else { + scrollBodyPanel + .setScrollPosition(measureRowHeightOffset(firstvisible)); + } } - firstRowInViewPort = firstvisible; } }; @@ -1131,17 +1133,15 @@ public class VScrollTable extends FlowPanel implements HasWidgets, firstvisibleOnLastPage = uidl.hasVariable("firstvisibleonlastpage") ? uidl .getIntVariable("firstvisibleonlastpage") : -1; if (firstvisible != lastRequestedFirstvisible && scrollBody != null) { - // received 'surprising' firstvisible from server: scroll there - firstRowInViewPort = firstvisible; + // Update lastRequestedFirstvisible right away here // (don't rely on update in the timer which could be cancelled). lastRequestedFirstvisible = firstRowInViewPort; - /* - * Schedule the scrolling to be executed last so no updates to the - * rows affect scrolling measurements. - */ - Scheduler.get().scheduleFinally(lazyScroller); + // Only scroll if the first visible changes from the server side. + // Else we might unintentionally scroll even when the scroll + // position has not changed. + Scheduler.get().scheduleDeferred(lazyScroller); } } @@ -2160,7 +2160,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets, isNewBody = false; - Scheduler.get().scheduleFinally(lazyScroller); + if (firstvisible > 0) { + Scheduler.get().scheduleDeferred(lazyScroller); + } if (enabled) { // Do we need cache rows -- cgit v1.2.3 From 267a4cae6de31d143c3d8d1d8dd79d4616896603 Mon Sep 17 00:00:00 2001 From: Artem Godin Date: Wed, 2 Oct 2013 17:07:14 +0300 Subject: Fix OptionGroup elements losing focus on value change (#10451) The misbehavior was caused by VOptionGroup.buildOptions recreating associated panel on every change by removing and adding new elements. With this fix applied it tries to update existing elements, distinguishing them by assigned keys. It will recreate panel though if elements are reordered or new elements were added/removed. Change-Id: I1245b2ff30ce1932614c1eac37bd0131cbd29dd7 --- client/src/com/vaadin/client/ui/VOptionGroup.java | 67 +++++++++++++++------ .../OptionGroupRetainFocusKeyboardValueChange.html | 54 +++++++++++++++++ .../OptionGroupRetainFocusKeyboardValueChange.java | 70 ++++++++++++++++++++++ 3 files changed, 174 insertions(+), 17 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.html create mode 100644 uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.java diff --git a/client/src/com/vaadin/client/ui/VOptionGroup.java b/client/src/com/vaadin/client/ui/VOptionGroup.java index a4c8b6733c..455c7669f5 100644 --- a/client/src/com/vaadin/client/ui/VOptionGroup.java +++ b/client/src/com/vaadin/client/ui/VOptionGroup.java @@ -95,11 +95,29 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler, } /* - * Return true if no elements were changed, false otherwise. + * Try to update content of existing elements, rebuild panel entirely + * otherwise */ @Override public void buildOptions(UIDL uidl) { - panel.clear(); + /* + * In order to retain focus, we need to update values rather than + * recreate panel from scratch (#10451). However, the panel will be + * rebuilt (losing focus) if number of elements or their order is + * changed. + */ + HashMap keysToOptions = new HashMap(); + for (Map.Entry entry : optionsToKeys.entrySet()) { + keysToOptions.put(entry.getValue(), entry.getKey()); + } + ArrayList existingwidgets = new ArrayList(); + ArrayList newwidgets = new ArrayList(); + + // Get current order of elements + for (Widget wid : panel) { + existingwidgets.add(wid); + } + optionsEnabled.clear(); if (isMultiselect()) { @@ -110,7 +128,6 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler, for (final Iterator it = uidl.getChildIterator(); it.hasNext();) { final UIDL opUidl = (UIDL) it.next(); - CheckBox op; String itemHtml = opUidl.getStringAttribute("caption"); if (!htmlContentAllowed) { @@ -124,32 +141,48 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler, + Icon.CLASSNAME + "\" alt=\"\" />" + itemHtml; } - if (isMultiselect()) { - op = new VCheckBox(); - op.setHTML(itemHtml); - } else { - op = new RadioButton(paintableId, itemHtml, true); - op.setStyleName("v-radiobutton"); - } + String key = opUidl.getStringAttribute("key"); + CheckBox op = keysToOptions.get(key); + if (op == null) { + // Create a new element + if (isMultiselect()) { + op = new VCheckBox(); + } else { + op = new RadioButton(paintableId); + op.setStyleName("v-radiobutton"); + } + if (icon != null && icon.length() != 0) { + Util.sinkOnloadForImages(op.getElement()); + op.addHandler(iconLoadHandler, LoadEvent.getType()); + } - if (icon != null && icon.length() != 0) { - Util.sinkOnloadForImages(op.getElement()); - op.addHandler(iconLoadHandler, LoadEvent.getType()); + op.addStyleName(CLASSNAME_OPTION); + op.addClickHandler(this); + + optionsToKeys.put(op, key); } - op.addStyleName(CLASSNAME_OPTION); + op.setHTML(itemHtml); op.setValue(opUidl.getBooleanAttribute("selected")); boolean optionEnabled = !opUidl .getBooleanAttribute(OptionGroupConstants.ATTRIBUTE_OPTION_DISABLED); boolean enabled = optionEnabled && !isReadonly() && isEnabled(); op.setEnabled(enabled); optionsEnabled.add(optionEnabled); + setStyleName(op.getElement(), ApplicationConnection.DISABLED_CLASSNAME, !(optionEnabled && isEnabled())); - op.addClickHandler(this); - optionsToKeys.put(op, opUidl.getStringAttribute("key")); - panel.add(op); + + newwidgets.add(op); + } + + if (!newwidgets.equals(existingwidgets)) { + // Rebuild the panel, losing focus + panel.clear(); + for (Widget wid : newwidgets) { + panel.add(wid); + } } } diff --git a/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.html b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.html new file mode 100644 index 0000000000..046cac0e30 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.html @@ -0,0 +1,54 @@ + + + + + + +OptionGroupRetainFocusKeyboardValueChange + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionGroupRetainFocusKeyboardValueChange
open/run/OptionGroupRetainFocusKeyboardValueChange?restartApplication
pressSpecialKeyvaadin=runOptionGroupRetainFocusKeyboardValueChange::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VOptionGroup[0]/domChild[0]/domChild[0]space
screenCapture
pressSpecialKeyvaadin=runOptionGroupRetainFocusKeyboardValueChange::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VOptionGroup[0]/domChild[0]/domChild[0]down
screenCapture
pressSpecialKeyvaadin=runOptionGroupRetainFocusKeyboardValueChange::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VOptionGroup[0]/domChild[1]/domChild[0]down
screenCapture
+ + diff --git a/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.java b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.java new file mode 100644 index 0000000000..570a300cb3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupRetainFocusKeyboardValueChange.java @@ -0,0 +1,70 @@ +/* + * 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.optiongroup; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.OptionGroup; + +/** + * Testcase for #10451 + * + * @author Vaadin Ltd + */ +public class OptionGroupRetainFocusKeyboardValueChange extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final OptionGroup optiongroup = new OptionGroup(); + optiongroup.addItem(1); + optiongroup.addItem(2); + optiongroup.addItem(3); + optiongroup.setItemCaption(1, "A"); + optiongroup.setItemCaption(2, "B"); + optiongroup.setItemCaption(3, "C"); + optiongroup.setImmediate(true); + + optiongroup.addValueChangeListener(new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + if (optiongroup.isSelected(2)) { + optiongroup.setItemCaption(1, "A+"); + } else if (optiongroup.isSelected(3)) { + optiongroup.removeItem(2); + optiongroup.addItem(2); + optiongroup.setItemCaption(2, "B"); + } + } + }); + + addComponent(optiongroup); + + optiongroup.focus(); + } + + @Override + protected String getTestDescription() { + return "OptionGroup should retain focus after it's value being changed with keyboard"; + } + + @Override + protected Integer getTicketNumber() { + return 10451; + } +} -- cgit v1.2.3 From 07ca622a6b2edcf7a253762cf222155bdf460a88 Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Fri, 27 Sep 2013 19:00:53 +0300 Subject: Fixes #12564 (HorizontalLayout breaks w/ alignment & error indicator) Removed some obsolete (hopefully!?) code doing some odd things with caption height calculation and some refactoring to make that part of code slightly more readable. Change-Id: I960e4a9eba0388281868f18a182c8788cedf08f9 --- .../AbstractOrderedLayoutConnector.java | 32 ++++---- ...orizontalLayoutFullsizeContentWithErrorMsg.java | 96 ++++++++++++++++++++++ 2 files changed, 111 insertions(+), 17 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsg.java diff --git a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java index e0dc0d51df..ec4307e50b 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java @@ -19,6 +19,7 @@ import java.util.List; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorHierarchyChangeEvent; @@ -611,13 +612,14 @@ public abstract class AbstractOrderedLayoutConnector extends LayoutManager layoutManager = getLayoutManager(); for (ComponentConnector child : getChildComponents()) { - Slot slot = getWidget().getSlot(child.getWidget()); + Widget childWidget = child.getWidget(); + Slot slot = getWidget().getSlot(childWidget); Element captionElement = slot.getCaptionElement(); - CaptionPosition pos = slot.getCaptionPosition(); + CaptionPosition captionPosition = slot.getCaptionPosition(); - Element childElement = child.getWidget().getElement(); - int h = layoutManager.getOuterHeight(childElement); - if (h == -1) { + int pixelHeight = layoutManager.getOuterHeight(childWidget + .getElement()); + if (pixelHeight == -1) { // Height has not yet been measured -> postpone actions that // depend on the max height return -1; @@ -625,14 +627,10 @@ public abstract class AbstractOrderedLayoutConnector extends boolean hasRelativeHeight = slot.hasRelativeHeight(); + boolean captionSizeShouldBeAddedtoComponentHeight = captionPosition == CaptionPosition.TOP + || captionPosition == CaptionPosition.BOTTOM; boolean includeCaptionHeight = captionElement != null - && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM); - if (!hasRelativeHeight && !includeCaptionHeight - && captionElement != null) { - String sHeight = childElement.getStyle().getHeight(); - includeCaptionHeight = (sHeight == null || !sHeight - .endsWith("%")); - } + && captionSizeShouldBeAddedtoComponentHeight; if (includeCaptionHeight) { int captionHeight = layoutManager @@ -643,16 +641,16 @@ public abstract class AbstractOrderedLayoutConnector extends // depend on the max height return -1; } - h += captionHeight; + pixelHeight += captionHeight; } if (!hasRelativeHeight) { - if (h > highestNonRelative) { - highestNonRelative = h; + if (pixelHeight > highestNonRelative) { + highestNonRelative = pixelHeight; } } else { - if (h > highestRelative) { - highestRelative = h; + if (pixelHeight > highestRelative) { + highestRelative = pixelHeight; } } } diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsg.java b/uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsg.java new file mode 100644 index 0000000000..25675e07c5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/HorizontalLayoutFullsizeContentWithErrorMsg.java @@ -0,0 +1,96 @@ +package com.vaadin.tests.components.orderedlayout; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; + +import com.vaadin.server.UserError; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.tb3.MultiBrowserTest; +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.HorizontalLayout; +import com.vaadin.ui.TextField; + +public class HorizontalLayoutFullsizeContentWithErrorMsg extends AbstractTestUI { + + private static final String FIELD_ID = "f"; + private static final String BUTTON_ID = "b"; + private TextField tf; + + @Override + protected Integer getTicketNumber() { + return 12564; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + HorizontalLayout hl = new HorizontalLayout(); + hl.setWidth("500px"); + + tf = new TextField(); + tf.setId(FIELD_ID); + tf.setWidth("100%"); + hl.addComponent(tf); + hl.setExpandRatio(tf, 1); + hl.setComponentAlignment(tf, Alignment.MIDDLE_CENTER); + + Button toggleError = new Button("Toggle error"); + toggleError.setId(BUTTON_ID); + toggleError.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + tf.setComponentError(tf.getComponentError() == null ? new UserError( + "foo") : null); + } + }); + hl.addComponent(toggleError); + + addComponent(hl); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "TextField should remain at same level vertically, horizontally width should adjust to fit error indicator."; + } + + public static class TbTest extends MultiBrowserTest { + + @Test + public void test() { + openTestURL(); + WebElement element = getDriver().findElement(By.id(FIELD_ID)); + Point location = element.getLocation(); + + WebElement errorToggleButton = getDriver().findElement( + By.id(BUTTON_ID)); + + errorToggleButton.click(); + + Assert.assertEquals(location, element.getLocation()); + + errorToggleButton.click(); + + Assert.assertEquals(location, element.getLocation()); + + } + + } + +} -- cgit v1.2.3