From 7fa43952ca1b1e26afe79f5c0a75f9e735431be0 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Fri, 20 Mar 2015 16:51:45 +0200 Subject: Use special logic for allocating selection col widths (#17091) Change-Id: I2d0a80a26e8211d6f5e9110e1476f857803b4d3f --- client/src/com/vaadin/client/widgets/Grid.java | 5 ++-- .../grid/GridColumnWidthsWithoutData.java | 21 +++++++++++++ .../grid/GridColumnWidthsWithoutDataTest.java | 34 +++++++++++++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index cb9e9c55d1..f4a5b0961c 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -2528,7 +2528,7 @@ public class Grid extends ResizeComposite implements final double widthFixed = Math.max(widthAsIs, column.getMinimumWidth()); defaultExpandRatios = defaultExpandRatios - && column.getExpandRatio() == -1; + && (column.getExpandRatio() == -1 || column == selectionColumn); if (isFixedWidth) { columnSizes.put(indexOfColumn(column), widthFixed); @@ -2546,7 +2546,8 @@ public class Grid extends ResizeComposite implements .getExpandRatio()); final double newWidth = column.getWidthActual(); final double maxWidth = getMaxWidth(column); - boolean shouldExpand = newWidth < maxWidth && expandRatio > 0; + boolean shouldExpand = newWidth < maxWidth && expandRatio > 0 + && column != selectionColumn; if (shouldExpand) { totalRatios += expandRatio; columnsToExpand.add(column); diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthsWithoutData.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthsWithoutData.java index 1dfc7bcf11..b04745f17a 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthsWithoutData.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthsWithoutData.java @@ -15,21 +15,41 @@ */ package com.vaadin.tests.components.grid; +import java.util.EnumSet; + +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.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.NativeSelect; import com.vaadin.ui.VerticalLayout; public class GridColumnWidthsWithoutData extends AbstractTestUI { + private SelectionMode selectionMode = SelectionMode.NONE; private Grid grid = createGrid(true); @Override protected void setup(VaadinRequest request) { addComponent(grid); + NativeSelect selectionModeSelector = new NativeSelect("Selection mode", + EnumSet.allOf(SelectionMode.class)); + selectionModeSelector.setValue(selectionMode); + selectionModeSelector.setNullSelectionAllowed(false); + selectionModeSelector.addValueChangeListener(new ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + selectionMode = (SelectionMode) event.getProperty().getValue(); + grid.setSelectionMode(selectionMode); + } + }); + addComponent(selectionModeSelector); + addComponent(new Button("Recreate without data", new Button.ClickListener() { @Override @@ -72,6 +92,7 @@ public class GridColumnWidthsWithoutData extends AbstractTestUI { grid.addColumn("foo"); grid.addColumn("bar"); grid.setWidth("300px"); + grid.setSelectionMode(selectionMode); if (withData) { addDataToGrid(grid); diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthsWithoutDataTest.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthsWithoutDataTest.java index dd63d6abc9..c215fa0a59 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthsWithoutDataTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthsWithoutDataTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.NativeSelectElement; import com.vaadin.testbench.elements.NotificationElement; import com.vaadin.tests.tb3.SingleBrowserTest; @@ -49,7 +50,7 @@ public class GridColumnWidthsWithoutDataTest extends SingleBrowserTest { } @Test - public void restWidthsWhenInitiallyEmpty() { + public void testWidthsWhenInitiallyEmpty() { setDebug(true); openTestURL(); $(ButtonElement.class).caption("Recreate without data").first().click(); @@ -74,6 +75,37 @@ public class GridColumnWidthsWithoutDataTest extends SingleBrowserTest { isElementPresent(NotificationElement.class)); } + @Test + public void testMultiSelectWidths() { + setDebug(true); + openTestURL(); + $(NativeSelectElement.class).caption("Selection mode").first() + .selectByText("Multi"); + + GridElement grid = $(GridElement.class).first(); + + int sum = sumUsedWidths(grid); + + // 295 instead of 300 to avoid rounding issues + Assert.assertTrue("Only " + sum + " out of 300px was used", sum > 295); + + $(ButtonElement.class).caption("Recreate without data").first().click(); + + grid = $(GridElement.class).first(); + sum = sumUsedWidths(grid); + + // 295 instead of 300 to avoid rounding issues + Assert.assertTrue("Only " + sum + " out of 300px was used", sum > 295); + } + + private int sumUsedWidths(GridElement grid) { + int sum = 0; + for (int i : getColWidths(grid)) { + sum += i; + } + return sum; + } + private static void assertSameWidths(int[] expected, int[] actual) { Assert.assertEquals("Arrays have differing lengths", expected.length, actual.length); -- cgit v1.2.3 From 4f3397df74dc737a9c5592d5418e741433e20dee Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 23 Mar 2015 22:15:51 +0200 Subject: Expect Chrome 41 Change-Id: I64c8788c0ae6160c565dfc0cfb4a87a7ed86bc81 --- .../src/com/vaadin/tests/VerifyBrowserVersionTest.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java b/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java index 5b4f4df788..8d0530204a 100644 --- a/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java +++ b/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java @@ -33,9 +33,20 @@ public class VerifyBrowserVersionTest extends MultiBrowserTest { DesiredCapabilities desiredCapabilities = getDesiredCapabilities(); - assertThat(vaadinElementById("userAgent").getText(), - containsString(getExpectedUserAgentString(desiredCapabilities) - + desiredCapabilities.getVersion())); + String userAgent = vaadinElementById("userAgent").getText(); + String browserIdentifier; + + if (BrowserUtil.isChrome(getDesiredCapabilities())) { + // Chrome version does not necessarily match the desired version + // because of auto updates... + browserIdentifier = getExpectedUserAgentString(getDesiredCapabilities()) + + "41"; + } else { + browserIdentifier = getExpectedUserAgentString(desiredCapabilities) + + desiredCapabilities.getVersion(); + } + + assertThat(userAgent, containsString(browserIdentifier)); assertThat(vaadinElementById("touchDevice").getText(), is("Touch device? No")); -- cgit v1.2.3 From 2a671f2810dfb409cc4d30a1606868282d0925d3 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Mon, 23 Mar 2015 12:10:07 +0200 Subject: Fix declarative support for CustomLayout (#17210) CustomLayout now has a public default constructor. If a template is not set using one of the setters, a warning message is displayed like in the case where the template file is specified but not found. Change-Id: I5d56f24fafc5c82e6ab76dec393a0c25bd78aae5 --- .../ui/customlayout/CustomLayoutConnector.java | 22 ++--- server/src/com/vaadin/ui/CustomLayout.java | 36 +++++++- .../customlayout/CustomLayoutDeclarativeTest.java | 96 ++++++++++++++++++++++ .../customlayout/CustomLayoutWithNullTemplate.java | 44 ++++++++++ .../CustomLayoutWithNullTemplateTest.java | 43 ++++++++++ 5 files changed, 229 insertions(+), 12 deletions(-) create mode 100644 server/tests/src/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java create mode 100644 uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithNullTemplate.java create mode 100644 uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithNullTemplateTest.java diff --git a/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java b/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java index 80979587b9..cde1f1af0f 100644 --- a/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/customlayout/CustomLayoutConnector.java @@ -77,22 +77,24 @@ public class CustomLayoutConnector extends AbstractLayoutConnector implements // (even though both can never be given at the same time) templateContents = getConnection().getResource( "layouts/" + templateName + ".html"); - if (templateContents == null) { - // Template missing -> show debug notice and render components - // in order. - getWidget() - .getElement() - .setInnerHTML( - "Layout file layouts/" - + templateName - + ".html is missing. Components will be drawn for debug purposes."); - } } if (templateContents != null) { // Template ok -> initialize. getWidget().initializeHTML(templateContents, getConnection().getThemeUri()); + } else { + // Template missing -> show debug notice and render components in + // order. + String warning = templateName != null ? "Layout file layouts/" + + templateName + ".html is missing." + : "Layout file not specified."; + getWidget() + .getElement() + .setInnerHTML( + "" + + warning + + " Components will be drawn for debug purposes."); } templateUpdated = true; } diff --git a/server/src/com/vaadin/ui/CustomLayout.java b/server/src/com/vaadin/ui/CustomLayout.java index a9c266b0b9..ceb47e1e7a 100644 --- a/server/src/com/vaadin/ui/CustomLayout.java +++ b/server/src/com/vaadin/ui/CustomLayout.java @@ -23,12 +23,16 @@ import java.io.InputStreamReader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import org.jsoup.nodes.Element; + import com.vaadin.server.JsonPaintTarget; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.shared.ui.customlayout.CustomLayoutState; +import com.vaadin.ui.declarative.DesignContext; /** *

@@ -71,8 +75,8 @@ public class CustomLayout extends AbstractLayout implements LegacyComponent { * {@link #setTemplateName(String)}, that makes layout fetch the template * from theme, or {@link #setTemplateContents(String)}. */ - protected CustomLayout() { - setWidth(100, UNITS_PERCENTAGE); + public CustomLayout() { + setWidth(100, Unit.PERCENTAGE); } /** @@ -305,4 +309,32 @@ public class CustomLayout extends AbstractLayout implements LegacyComponent { } } + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + for (Element child : design.children()) { + + Component childComponent = designContext.readDesign(child); + + if (child.hasAttr(":location")) { + addComponent(childComponent, child.attr(":location")); + } else { + addComponent(childComponent); + } + } + } + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + + for (Entry slot : slots.entrySet()) { + Element child = designContext.createElement(slot.getValue()); + if (slots.size() > 1 || !"".equals(slot.getKey())) { + child.attr(":location", slot.getKey()); + } + design.appendChild(child); + } + } } diff --git a/server/tests/src/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java new file mode 100644 index 0000000000..44261a61dc --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/customlayout/CustomLayoutDeclarativeTest.java @@ -0,0 +1,96 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.customlayout; + +import org.junit.Test; + +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.CustomLayout; +import com.vaadin.ui.Label; + +/** + * Tests declarative support for {@link CustomLayout}. + * + * @since + * @author Vaadin Ltd + */ +public class CustomLayoutDeclarativeTest extends + DeclarativeTestBase { + + @Test + public void testEmpty() { + String design = ""; + CustomLayout expected = new CustomLayout(); + test(design, expected); + } + + @Test + public void testWithChildren() { + String design = "" + // + "" + // + "" + // + ""; + + CustomLayout expected = new CustomLayout(); + expected.addComponent(new Button(), "b"); + expected.addComponent(new Label(), "l"); + + test(design, expected); + } + + @Test + public void testWithOneChild() { + String design = ""; + + CustomLayout expected = new CustomLayout(); + expected.addComponent(new Button()); + + test(design, expected); + } + + @Test + public void testWithTemplate() { + String design = ""; + CustomLayout expected = new CustomLayout("template.html"); + test(design, expected); + } + + @Test + public void testWithDuplicateLocations() { + String design = "" + // + "" + // + "" + // + ""; + + CustomLayout expected = new CustomLayout(); + expected.addComponent(new Button(), "foo"); + expected.addComponent(new Label(), "foo"); + + testRead(design, expected); + + String written = "" + // + "" + // + ""; + + testWrite(written, expected); + } + + protected void test(String design, CustomLayout expected) { + testRead(design, expected); + testWrite(design, expected); + } +} diff --git a/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithNullTemplate.java b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithNullTemplate.java new file mode 100644 index 0000000000..de1caf86df --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithNullTemplate.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.customlayout; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.CustomLayout; +import com.vaadin.ui.Label; + +public class CustomLayoutWithNullTemplate extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + CustomLayout cl = new CustomLayout(); + cl.addComponent(new Label("This Label should be visible."), "foo"); + cl.addComponent(new Button("This Button too."), "bar"); + + addComponent(cl); + } + + @Override + protected String getTestDescription() { + return "Verify that a default-constructed CustomLayout renders child components"; + } + + @Override + protected Integer getTicketNumber() { + return 17210; + } +} diff --git a/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithNullTemplateTest.java b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithNullTemplateTest.java new file mode 100644 index 0000000000..668d43f18f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/customlayout/CustomLayoutWithNullTemplateTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.customlayout; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.ElementQuery; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.CustomLayoutElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class CustomLayoutWithNullTemplateTest extends SingleBrowserTest { + + @Test + public void testChildComponents() { + openTestURL(); + + ElementQuery customLayout = $(CustomLayoutElement.class); + + // Verify the Button and Label are rendered inside the CustomLayout. + assertTrue("Button was not rendered.", + customLayout.$(ButtonElement.class).exists()); + assertTrue("Label was not rendered.", customLayout + .$(LabelElement.class).exists()); + } + +} -- cgit v1.2.3 From f18a9642b7ad5831719b2c15c1b4adb788b386e8 Mon Sep 17 00:00:00 2001 From: Anna Miroshnik Date: Fri, 6 Mar 2015 16:05:09 +0300 Subject: Fix Table column header sorting on Chrome (#14796) This fix is similar to the fix that has been made for other similar cases (i.e. #13381). Couldn't find a reliable way to reproduce the problem. Hopefully this will fix the issue. Was reproduced (before fix) on Google Chrome 40.0.2214.115 m on TableSortingStopsWorkingOnChrome test one time (but then suddenly it started to work again). Was reproduced (before fix) on Project TableSorting once, as described in the ticket. That project has been attached to the ticket. Change-Id: Id901c9ce4a0a7c369572bf4374223851658aa703 --- client/src/com/vaadin/client/ui/VScrollTable.java | 88 +++++++----- .../vaadin/client/ui/dd/VDragAndDropManager.java | 12 +- .../table/TableSortingStopsWorkingOnChrome.java | 150 +++++++++++++++++++++ 3 files changed, 210 insertions(+), 40 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/table/TableSortingStopsWorkingOnChrome.java diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index 12de2724fc..13561dcd0f 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -2774,7 +2774,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private boolean sortable = false; private final String cid; + private boolean dragging; + private Integer currentDragX = null; // is used to resolve #14796 private int dragStartX; private int colIndex; @@ -3146,6 +3148,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, event.stopPropagation(); } dragging = true; + currentDragX = WidgetUtil.getTouchOrMouseClientX(event); moved = false; colIndex = getColIndexByKey(cid); DOM.setCapture(getElement()); @@ -3160,6 +3163,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, if (columnReordering && WidgetUtil.isTouchEventOrLeftMouseButton(event)) { dragging = false; + currentDragX = null; DOM.releaseCapture(getElement()); if (WidgetUtil.isTouchEvent(event)) { @@ -3227,47 +3231,57 @@ public class VScrollTable extends FlowPanel implements HasWidgets, break; case Event.ONTOUCHMOVE: case Event.ONMOUSEMOVE: - if (dragging && WidgetUtil.isTouchEventOrLeftMouseButton(event)) { - if (event.getTypeInt() == Event.ONTOUCHMOVE) { - /* - * prevent using this event in e.g. scrolling - */ - event.stopPropagation(); - } - if (!moved) { - createFloatingCopy(); - moved = true; - } + // only start the drag if the mouse / touch has moved a minimum + // distance in x-axis (the same idea as in #13381) + int currentX = WidgetUtil.getTouchOrMouseClientX(event); - final int clientX = WidgetUtil - .getTouchOrMouseClientX(event); - final int x = clientX + tHead.hTableWrapper.getScrollLeft(); - int slotX = headerX; - closestSlot = colIndex; - int closestDistance = -1; - int start = 0; - if (showRowHeaders) { - start++; - } - final int visibleCellCount = tHead.getVisibleCellCount(); - for (int i = start; i <= visibleCellCount; i++) { - if (i > 0) { - final String colKey = getColKeyByIndex(i - 1); - // getColWidth only returns the internal width - // without padding, not the offset width of the - // whole td (#10890) - slotX += getColWidth(colKey) - + scrollBody.getCellExtraWidth(); + if (currentDragX == null + || Math.abs(currentDragX - currentX) > VDragAndDropManager.MINIMUM_DISTANCE_TO_START_DRAG) { + if (dragging + && WidgetUtil.isTouchEventOrLeftMouseButton(event)) { + if (event.getTypeInt() == Event.ONTOUCHMOVE) { + /* + * prevent using this event in e.g. scrolling + */ + event.stopPropagation(); } - final int dist = Math.abs(x - slotX); - if (closestDistance == -1 || dist < closestDistance) { - closestDistance = dist; - closestSlot = i; + if (!moved) { + createFloatingCopy(); + moved = true; } - } - tHead.focusSlot(closestSlot); - updateFloatingCopysPosition(clientX, -1); + final int clientX = WidgetUtil + .getTouchOrMouseClientX(event); + final int x = clientX + + tHead.hTableWrapper.getScrollLeft(); + int slotX = headerX; + closestSlot = colIndex; + int closestDistance = -1; + int start = 0; + if (showRowHeaders) { + start++; + } + final int visibleCellCount = tHead + .getVisibleCellCount(); + for (int i = start; i <= visibleCellCount; i++) { + if (i > 0) { + final String colKey = getColKeyByIndex(i - 1); + // getColWidth only returns the internal width + // without padding, not the offset width of the + // whole td (#10890) + slotX += getColWidth(colKey) + + scrollBody.getCellExtraWidth(); + } + final int dist = Math.abs(x - slotX); + if (closestDistance == -1 || dist < closestDistance) { + closestDistance = dist; + closestSlot = i; + } + } + tHead.focusSlot(closestSlot); + + updateFloatingCopysPosition(clientX, -1); + } } break; default: diff --git a/client/src/com/vaadin/client/ui/dd/VDragAndDropManager.java b/client/src/com/vaadin/client/ui/dd/VDragAndDropManager.java index 844f4c1b9c..3a0b52b6af 100644 --- a/client/src/com/vaadin/client/ui/dd/VDragAndDropManager.java +++ b/client/src/com/vaadin/client/ui/dd/VDragAndDropManager.java @@ -38,9 +38,9 @@ import com.vaadin.client.ComponentConnector; import com.vaadin.client.MouseEventDetailsBuilder; import com.vaadin.client.Profiler; import com.vaadin.client.UIDL; -import com.vaadin.client.WidgetUtil; import com.vaadin.client.VConsole; import com.vaadin.client.ValueMap; +import com.vaadin.client.WidgetUtil; import com.vaadin.client.ui.VOverlay; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.MouseEventDetails; @@ -240,6 +240,12 @@ public class VDragAndDropManager { } + /* + * #13381, #14796. The drag only actually starts when the mouse move or + * touch move event is more than 3 pixel away. + */ + public static final int MINIMUM_DISTANCE_TO_START_DRAG = 3; + private static VDragAndDropManager instance; private HandlerRegistration handlerRegistration; private VDragEvent currentDrag; @@ -425,8 +431,8 @@ public class VDragAndDropManager { int currentY = WidgetUtil .getTouchOrMouseClientY(event .getNativeEvent()); - if (Math.abs(startX - currentX) > 3 - || Math.abs(startY - currentY) > 3) { + if (Math.abs(startX - currentX) > MINIMUM_DISTANCE_TO_START_DRAG + || Math.abs(startY - currentY) > MINIMUM_DISTANCE_TO_START_DRAG) { if (deferredStartRegistration != null) { deferredStartRegistration .removeHandler(); diff --git a/uitest/src/com/vaadin/tests/components/table/TableSortingStopsWorkingOnChrome.java b/uitest/src/com/vaadin/tests/components/table/TableSortingStopsWorkingOnChrome.java new file mode 100644 index 0000000000..23d0581e5a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableSortingStopsWorkingOnChrome.java @@ -0,0 +1,150 @@ +package com.vaadin.tests.components.table; + +import java.io.Serializable; + +import com.vaadin.annotations.Theme; +import com.vaadin.data.util.BeanItemContainer; +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptAll; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.ColumnReorderEvent; +import com.vaadin.ui.Table.ColumnReorderListener; +import com.vaadin.ui.Table.HeaderClickEvent; +import com.vaadin.ui.Table.HeaderClickListener; +import com.vaadin.ui.VerticalLayout; + +@Theme("valo") +@SuppressWarnings("serial") +public class TableSortingStopsWorkingOnChrome extends AbstractTestUI { + + protected static final int ROW_COUNT = 100; + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout layout = new VerticalLayout(); + layout.setSizeFull(); + + final Table table = new Table(); + table.setColumnReorderingAllowed(true); + table.setSizeFull(); + + BeanItemContainer cont = new BeanItemContainer( + TestItem.class); + + for (int i = 0; i < ROW_COUNT; i++) { + TestItem ti = new TestItem(); + ti.setValue1("Value1_" + i); + ti.setValue2("Value2_" + (ROW_COUNT - i)); + ti.setValue3("Value3_" + i); + ti.setValue4("Value4_" + (ROW_COUNT - i)); + ti.setValue5("Value5_" + i); + cont.addBean(ti); + } + + table.setContainerDataSource(cont); + table.setImmediate(true); + table.setSelectable(true); + table.setMultiSelect(false); + + table.setPageLength(10); + table.setDragMode(Table.TableDragMode.ROW); + + table.setDropHandler(new DropHandler() { + @Override + public void drop(DragAndDropEvent dragAndDropEvent) { + + } + + @Override + public AcceptCriterion getAcceptCriterion() { + return AcceptAll.get(); + } + }); + + table.addColumnReorderListener(new ColumnReorderListener() { + + @Override + public void columnReorder(ColumnReorderEvent event) { + System.out.println("columnReorder"); + } + }); + + table.addHeaderClickListener(new HeaderClickListener() { + + @Override + public void headerClick(HeaderClickEvent event) { + System.out.println("Header was clicked"); + } + }); + + layout.addComponent(table); + + addComponent(layout); + } + + public class TestItem implements Serializable { + private static final long serialVersionUID = -745849615488792221L; + + private String value1; + private String value2; + private String value3; + private String value4; + private String value5; + + public String getValue1() { + return value1; + } + + public void setValue1(String value1) { + this.value1 = value1; + } + + public String getValue2() { + return value2; + } + + public void setValue2(String value2) { + this.value2 = value2; + } + + public String getValue3() { + return value3; + } + + public void setValue3(String value3) { + this.value3 = value3; + } + + public String getValue4() { + return value4; + } + + public void setValue4(String value4) { + this.value4 = value4; + } + + public String getValue5() { + return value5; + } + + public void setValue5(String value5) { + this.value5 = value5; + } + + } + + @Override + protected String getTestDescription() { + return "After an indeterminate period of time sorting tables via clicking on the column header should not stop working on Chrome"; + } + + @Override + protected Integer getTicketNumber() { + return 14796; + } + +} -- cgit v1.2.3 From e3bf98708cb02e0772a46496ef8720657253e1ce Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Wed, 18 Mar 2015 15:42:48 +0200 Subject: Fix Declarative support for Slider (#17196) Change-Id: I5cc390566af38115939416591a549f06e39d3153 --- server/src/com/vaadin/ui/Slider.java | 38 +++++++++++++ .../component/slider/SliderDeclarativeTest.java | 66 ++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 server/tests/src/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/com/vaadin/ui/Slider.java index 99e1e8d5e9..40a4047d53 100644 --- a/server/src/com/vaadin/ui/Slider.java +++ b/server/src/com/vaadin/ui/Slider.java @@ -16,9 +16,16 @@ package com.vaadin.ui; +import java.util.Collection; + +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; + import com.vaadin.shared.ui.slider.SliderOrientation; import com.vaadin.shared.ui.slider.SliderServerRpc; import com.vaadin.shared.ui.slider.SliderState; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * A component for selecting a numerical value within a range. @@ -353,4 +360,35 @@ public class Slider extends AbstractField { // Slider is never really "empty" return false; } + + @Override + public void readDesign(Element design, DesignContext context) { + super.readDesign(design, context); + Attributes attr = design.attributes(); + if (attr.hasKey("vertical")) { + setOrientation(SliderOrientation.VERTICAL); + } + if (!attr.get("value").isEmpty()) { + setValue(DesignAttributeHandler.readAttribute("value", attr, + Double.class)); + } + } + + @Override + public void writeDesign(Element design, DesignContext context) { + super.writeDesign(design, context); + if (getOrientation() == SliderOrientation.VERTICAL) { + design.attr("vertical", ""); + } + Slider defaultSlider = context.getDefaultInstance(this); + DesignAttributeHandler.writeAttribute(this, "value", + design.attributes(), defaultSlider); + } + + @Override + protected Collection getCustomAttributes() { + Collection result = super.getCustomAttributes(); + result.add("orientation"); + return result; + } } diff --git a/server/tests/src/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.java new file mode 100644 index 0000000000..9ef28afb82 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/slider/SliderDeclarativeTest.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.server.component.slider; + +import org.junit.Test; + +import com.vaadin.shared.ui.slider.SliderOrientation; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Slider; + +/** + * Tests declarative support for implementations of {@link Slider}. + * + * @since + * @author Vaadin Ltd + */ +public class SliderDeclarativeTest extends DeclarativeTestBase { + + @Test + public void testDefault() { + String design = ""; + + Slider expected = new Slider(); + + testRead(design, expected); + testWrite(design, expected); + } + + @Test + public void testHorizontal() { + String design = ""; + + Slider expected = new Slider(); + expected.setMin(10.0); + expected.setMax(20.0); + expected.setResolution(1); + expected.setValue(12.3); + + testRead(design, expected); + testWrite(design, expected); + } + + @Test + public void testVertical() { + String design = ""; + + Slider expected = new Slider(); + expected.setOrientation(SliderOrientation.VERTICAL); + + testRead(design, expected); + testWrite(design, expected); + } +} -- cgit v1.2.3 From 1c569304b3f10960854c2045030d907408978d05 Mon Sep 17 00:00:00 2001 From: Johannes Tuikkala Date: Thu, 5 Mar 2015 13:32:33 +0200 Subject: Fixed scroll jump by using native focusing in IE (#15294) Change-Id: I412ba219f31567ebba019b7d6ce4db4af9be9363 --- .../TableInIframeRowClickScrollJumpTest.html | 12 ++ .../com/vaadin/client/ui/FocusableScrollPanel.java | 8 ++ .../tests/components/table/TableBlurFocus.java | 153 +++++++++++++++++++++ .../tests/components/table/TableBlurFocusTest.java | 64 +++++++++ .../table/TableInIframeRowClickScrollJumpTest.java | 127 +++++++++++++++++ 5 files changed, 364 insertions(+) create mode 100644 WebContent/statictestfiles/TableInIframeRowClickScrollJumpTest.html create mode 100644 uitest/src/com/vaadin/tests/components/table/TableBlurFocus.java create mode 100644 uitest/src/com/vaadin/tests/components/table/TableBlurFocusTest.java create mode 100644 uitest/src/com/vaadin/tests/components/table/TableInIframeRowClickScrollJumpTest.java diff --git a/WebContent/statictestfiles/TableInIframeRowClickScrollJumpTest.html b/WebContent/statictestfiles/TableInIframeRowClickScrollJumpTest.html new file mode 100644 index 0000000000..dfddbdb7e5 --- /dev/null +++ b/WebContent/statictestfiles/TableInIframeRowClickScrollJumpTest.html @@ -0,0 +1,12 @@ + + +IEJumpTest + + + +

test div
+ + + + \ No newline at end of file diff --git a/client/src/com/vaadin/client/ui/FocusableScrollPanel.java b/client/src/com/vaadin/client/ui/FocusableScrollPanel.java index 475c8f8074..9dd9c17675 100644 --- a/client/src/com/vaadin/client/ui/FocusableScrollPanel.java +++ b/client/src/com/vaadin/client/ui/FocusableScrollPanel.java @@ -48,9 +48,11 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements Style style = getElement().getStyle(); style.setProperty("zoom", "1"); style.setPosition(Position.RELATIVE); + browserInfo = BrowserInfo.get(); } private DivElement focusElement; + private BrowserInfo browserInfo; public FocusableScrollPanel(boolean useFakeFocusElement) { this(); @@ -72,6 +74,12 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements style.setPosition(Position.FIXED); style.setTop(0, Unit.PX); style.setLeft(0, Unit.PX); + if (browserInfo.isIE()) { + // for #15294: artificially hide little bit more the + // focusElement, otherwise IE will make the window to scroll + // into it when focused + style.setLeft(-999, Unit.PX); + } getElement().appendChild(focusElement); /* Sink from focusElemet too as focusa and blur don't bubble */ DOM.sinkEvents(focusElement, Event.FOCUSEVENTS); diff --git a/uitest/src/com/vaadin/tests/components/table/TableBlurFocus.java b/uitest/src/com/vaadin/tests/components/table/TableBlurFocus.java new file mode 100644 index 0000000000..d95b406c1a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableBlurFocus.java @@ -0,0 +1,153 @@ +/* + * 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.util.Map; + +import com.vaadin.event.FieldEvents.BlurEvent; +import com.vaadin.event.FieldEvents.BlurListener; +import com.vaadin.event.FieldEvents.FocusEvent; +import com.vaadin.event.FieldEvents.FocusListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Table; + +/** + * Tests that previously focused component's blur event happens before any + * variable changes in the focused Table. + * + * @author Vaadin Ltd + */ +public class TableBlurFocus extends AbstractTestUIWithLog { + + enum Columns { + COLUMN1, COLUMN2, COLUMN3, COLUMN4, COLUMN5 + } + + private int count = 0; + private Button focusButton; + + @Override + protected void setup(VaadinRequest request) { + System.out + .println("TableBlurFocus/TableInIframeRowClickScrollJumpTest"); + Button button = new Button("click to focus"); + button.addFocusListener(new FocusListener() { + + @Override + public void focus(FocusEvent event) { + log("focus"); + } + }); + button.addBlurListener(new BlurListener() { + + @Override + public void blur(BlurEvent event) { + log("blur"); + } + }); + final Button scrollButton = new Button( + "focus lowest button to scroll down"); + scrollButton.setId("scroll-button"); + scrollButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + focusButton.focus(); + } + }); + + Label spacerLabel = new Label("spacer"); + spacerLabel.setHeight("300px"); + + addComponent(button); + addComponent(scrollButton); + addComponent(createTable()); + addComponent(spacerLabel); + addComponent(focusButton = new Button("for focus")); + focusButton.setId("focus-button"); + focusButton.addFocusListener(new FocusListener() { + @Override + public void focus(FocusEvent event) { + focusButton.setCaption("focused"); + } + }); + } + + private Table createTable() { + Table table = new Table() { + @Override + public void changeVariables(Object source, + Map variables) { + log("variable change"); + super.changeVariables(source, variables); + } + }; + table.setSelectable(true); + table.setImmediate(true); + + table.addContainerProperty(Columns.COLUMN1, String.class, " "); + table.addContainerProperty(Columns.COLUMN2, Label.class, null); + table.addContainerProperty(Columns.COLUMN3, Button.class, null); + table.addContainerProperty(Columns.COLUMN4, String.class, " "); + table.setColumnCollapsingAllowed(true); + table.setColumnCollapsible(Columns.COLUMN4, true); + table.setColumnCollapsed(Columns.COLUMN4, true); + table.setSortEnabled(true); + table.setFooterVisible(true); + table.setPageLength(14); + table.addGeneratedColumn(Columns.COLUMN5, new Table.ColumnGenerator() { + + @Override + public Object generateCell(Table source, Object itemId, + Object columnId) { + return "Generated"; + } + }); + + table.setColumnHeader(Columns.COLUMN1, "Column"); + for (int x = 0; x < 120; x++) { + final Label buttonLabel = new Label("Not clicked"); + Button button = new Button("Click me?", new Button.ClickListener() { + + @Override + public void buttonClick(Button.ClickEvent event) { + ++count; + buttonLabel.setValue("Clicked " + count + " times"); + Notification.show("Clicked!"); + } + }); + table.addItem(new Object[] { "entryString" + x, buttonLabel, + button, " " }, "entryID" + x); + } + return table; + } + + @Override + protected String getTestDescription() { + return "Click button to focus, then click Table header. Blur event should arrive before the next variable change."; + } + + @Override + protected Integer getTicketNumber() { + return 15294; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableBlurFocusTest.java b/uitest/src/com/vaadin/tests/components/table/TableBlurFocusTest.java new file mode 100644 index 0000000000..e5d07abc22 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableBlurFocusTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class TableBlurFocusTest extends MultiBrowserTest { + + @Test + public void testBlurAndFocus() throws InterruptedException { + openTestURL(); + waitForElementPresent(By.className("v-button")); + + assertAnyLogText("1. variable change"); + assertEquals("Unexpected column header,", "COLUMN2", + $(TableElement.class).first().getHeaderCell(1).getCaption()); + assertEquals("Unexpected button caption,", "click to focus", + $(ButtonElement.class).first().getCaption()); + + $(ButtonElement.class).first().click(); + assertAnyLogText("2. focus", "3. focus"); + + $(TableElement.class).first().getHeaderCell(1).click(); + assertAnyLogText("3. blur", "4. blur"); + } + + private void assertAnyLogText(String... texts) { + assertThat(String.format( + "Correct log text was not found, expected any of %s", + Arrays.asList(texts)), logContainsAnyText(texts)); + } + + private boolean logContainsAnyText(String... texts) { + for (String text : texts) { + if (logContainsText(text)) { + return true; + } + } + return false; + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableInIframeRowClickScrollJumpTest.java b/uitest/src/com/vaadin/tests/components/table/TableInIframeRowClickScrollJumpTest.java new file mode 100644 index 0000000000..074958d671 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableInIframeRowClickScrollJumpTest.java @@ -0,0 +1,127 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * For testing that UI scroll does not jump back to up when: 1. UI is in iframe + * 2. the window scrolled down 3. and table is clicked + * + * @since + * @author Vaadin Ltd + */ +public class TableInIframeRowClickScrollJumpTest extends MultiBrowserTest { + + private static final String TEST_URL = "statictestfiles/TableInIframeRowClickScrollJumpTest.html"; + + @Test + public void testRowClicking_WhenScrolledDown_shouldMaintainScrollPosition() + throws InterruptedException { + System.out.println(">>>" + getBaseURL() + TEST_URL); + + driver.get(getUrl()); + + // using non-standard way because of iframe + sleep(4000); + + // make sure we are in the "main content" + driver.switchTo().defaultContent(); + sleep(2000); + switchIntoIframe(); + + // using non-standard way because of iframe + waitForElementVisible(By.id("scroll-button")); + + ButtonElement scrollbutton = $(ButtonElement.class).id("scroll-button"); + scrollbutton.click(); + + // using non-standard way because of iframe + sleep(1000); + + Long scrollPosition = getWindowsScrollPosition(); + + assertThat("Scroll position should be greater than 100 (it was " + + scrollPosition + ")", scrollPosition > 100); + + TableElement table = $(TableElement.class).first(); + table.getRow(13).getCell(0).click(); + + // using non-standard way because of iframe + sleep(1000); + + Long scrollPosition2 = getWindowsScrollPosition(); + + assertThat("Scroll position should stay about the same. Old was " + + scrollPosition + " and new one " + scrollPosition2, + Math.abs(scrollPosition - scrollPosition2) < 10); + } + + private String getUrl() { + String url; + // using non-standard way because of iframe + if (getBaseURL().charAt(getBaseURL().length() - 1) == '/') { + url = getBaseURL() + TEST_URL; + } else { + // this one is for gerrit's teamcity :( + url = getBaseURL() + '/' + TEST_URL; + } + return url; + } + + public void switchIntoIframe() { + List frames = driver.findElements(By.tagName("iframe")); + assertThat("No frames was found", frames.size() > 0); + driver.switchTo().frame(frames.get(0)); + } + + private Long getWindowsScrollPosition() { + // measure scroll pos in the main window + driver.switchTo().defaultContent(); + + JavascriptExecutor executor = (JavascriptExecutor) driver; + Long value = (Long) executor + .executeScript("if (window.pageYOffset) return window.pageYOffset;else if (window.document.documentElement.scrollTop) return window.document.documentElement.scrollTop;else return window.document.body.scrollTop;"); + + // back to the iframe + switchIntoIframe(); + + return value; + } + + @Override + // using non-standard way because of iframe + protected void closeApplication() { + if (driver != null) { + try { + driver.get(getUrl() + "?closeApplication"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} -- cgit v1.2.3 From 140844eaff3de1b926460081405eb7d53ec811f8 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 19 Mar 2015 09:49:32 +0000 Subject: Revert "Make push path configurable (#14432)." Breaks long polling fallback when implemented this way This reverts commit 735f0748344d7ee594c4e52a715d867dfdb23cb1. Conflicts: push/build.xml push/ivy.xml server/src/com/vaadin/server/Constants.java uitest/src/com/vaadin/tests/push/PushPathTest.java Change-Id: I07f6fedafc648b0ee403865ccb322017d2a8d571 --- WebContent/WEB-INF/web.xml | 22 +------ .../communication/AtmospherePushConnection.java | 15 ++--- server/src/com/vaadin/server/Constants.java | 3 +- .../server/DefaultDeploymentConfiguration.java | 19 ------ .../com/vaadin/server/DeploymentConfiguration.java | 10 +-- .../com/vaadin/server/ServletPortletHelper.java | 3 +- .../vaadin/server/communication/UIInitHandler.java | 5 +- server/src/com/vaadin/ui/PushConfiguration.java | 47 +------------ .../AbstractDeploymentConfigurationTest.java | 4 -- .../tests/util/MockDeploymentConfiguration.java | 6 -- .../com/vaadin/shared/ApplicationConstants.java | 12 ++-- shared/src/com/vaadin/shared/ui/ui/UIState.java | 1 - .../vaadin/launcher/ApplicationRunnerServlet.java | 9 +-- uitest/src/com/vaadin/tests/push/PushPath.java | 77 ---------------------- uitest/src/com/vaadin/tests/push/PushPathTest.java | 39 ----------- 15 files changed, 24 insertions(+), 248 deletions(-) delete mode 100644 uitest/src/com/vaadin/tests/push/PushPath.java delete mode 100644 uitest/src/com/vaadin/tests/push/PushPathTest.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index c1102f4682..ef60364202 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -87,9 +87,9 @@ - + VaadinApplicationRunnerWithTimeoutRedirect com.vaadin.launcher.ApplicationRunnerServlet @@ -115,17 +115,6 @@ true - - - VaadinApplicationRunnerWithPushPathTest - com.vaadin.launcher.ApplicationRunnerServlet - - pushPath - ws - - true - - Embed App 1 /embed1/* @@ -159,11 +148,6 @@ /run-push/* - - VaadinApplicationRunnerWithPushPathTest - /run-pushpath/* - - IntegrationTest /integration/* diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java index 787da9bc6f..e544c91d0f 100644 --- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java +++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java @@ -43,7 +43,7 @@ import elemental.json.JsonObject; /** * The default {@link PushConnection} implementation that uses Atmosphere for * handling the communication channel. - * + * * @author Vaadin Ltd * @since 7.1 */ @@ -135,8 +135,6 @@ public class AtmospherePushConnection implements PushConnection { */ private Command pendingDisconnectCommand; - private String pushPath; - public AtmospherePushConnection() { } @@ -183,9 +181,6 @@ public class AtmospherePushConnection implements PushConnection { pushConfiguration.parameters.get(param)); } - pushPath = pushConfiguration.pushPath; - assert pushPath != null; - runWhenAtmosphereLoaded(new Command() { @Override public void execute() { @@ -202,7 +197,7 @@ public class AtmospherePushConnection implements PushConnection { private void connect() { String baseUrl = connection .translateVaadinUri(ApplicationConstants.APP_PROTOCOL_PREFIX - + pushPath + '/'); + + ApplicationConstants.PUSH_PATH + '/'); String extraParams = UIConstants.UI_ID_PARAMETER + "=" + connection.getConfiguration().getUIId(); @@ -277,9 +272,9 @@ public class AtmospherePushConnection implements PushConnection { /** * Called whenever a server push connection is established (or * re-established). - * + * * @param response - * + * * @since 7.2 */ protected void onConnect(AtmosphereResponse response) { @@ -360,7 +355,7 @@ public class AtmospherePushConnection implements PushConnection { /** * Called if the push connection fails. Atmosphere will automatically retry * the connection until successful. - * + * */ protected void onError(AtmosphereResponse response) { state = State.DISCONNECTED; diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java index b7c2a1ff3e..f3cdd48d58 100644 --- a/server/src/com/vaadin/server/Constants.java +++ b/server/src/com/vaadin/server/Constants.java @@ -132,12 +132,11 @@ public interface Constants { static final String SERVLET_PARAMETER_RESOURCE_CACHE_TIME = "resourceCacheTime"; static final String SERVLET_PARAMETER_HEARTBEAT_INTERVAL = "heartbeatInterval"; static final String SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS = "closeIdleSessions"; + static final String SERVLET_PARAMETER_PUSH_MODE = "pushMode"; static final String SERVLET_PARAMETER_UI_PROVIDER = "UIProvider"; static final String SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING = "legacyPropertyToString"; static final String SERVLET_PARAMETER_SYNC_ID_CHECK = "syncIdCheck"; static final String SERVLET_PARAMETER_SENDURLSASPARAMETERS = "sendUrlsAsParameters"; - static final String SERVLET_PARAMETER_PUSH_MODE = "pushMode"; - static final String SERVLET_PARAMETER_PUSH_PATH = "pushPath"; // Configurable parameter names static final String PARAMETER_VAADIN_RESOURCES = "Resources"; diff --git a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java index 5402979be8..b26e048431 100644 --- a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java +++ b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java @@ -61,13 +61,6 @@ public class DefaultDeploymentConfiguration extends public static final boolean DEFAULT_SEND_URLS_AS_PARAMETERS = true; - /** - * Default value for {@link #getPushPath()} = {@value} . - * - * @since 7.4.1 - */ - public static final String DEFAULT_PUSH_PATH = "PUSH"; - private final Properties initParameters; private boolean productionMode; private boolean xsrfProtectionEnabled; @@ -291,18 +284,6 @@ public class DefaultDeploymentConfiguration extends return initParameters; } - /** - * {@inheritDoc} - *

- * The default path {@link DEFAULT_PUSH_PATH} can be changed by using init - * parameter {@link Constants.SERVLET_PARAMETER_PUSH_PATH}. - */ - @Override - public String getPushPath() { - return getApplicationOrSystemProperty( - Constants.SERVLET_PARAMETER_PUSH_PATH, DEFAULT_PUSH_PATH); - } - /** * Log a warning if Vaadin is not running in production mode. */ diff --git a/server/src/com/vaadin/server/DeploymentConfiguration.java b/server/src/com/vaadin/server/DeploymentConfiguration.java index 06556e28a7..968ec7c0c3 100644 --- a/server/src/com/vaadin/server/DeploymentConfiguration.java +++ b/server/src/com/vaadin/server/DeploymentConfiguration.java @@ -195,7 +195,7 @@ public interface DeploymentConfiguration extends Serializable { * * @since 7.4 * - * @return the name of the widgetset + * @return UI class name */ public String getWidgetset(String defaultValue); @@ -213,14 +213,6 @@ public interface DeploymentConfiguration extends Serializable { */ public String getClassLoaderName(); - /** - * Returns the push path configuration option value. Should never be null. - * - * @since 7.4.1 - * @return the path used with server push - */ - public String getPushPath(); - /** * Returns to legacy Property.toString() mode used. See * {@link AbstractProperty#isLegacyToStringEnabled()} for more information. diff --git a/server/src/com/vaadin/server/ServletPortletHelper.java b/server/src/com/vaadin/server/ServletPortletHelper.java index 1f0c7f02b9..197d9fe416 100644 --- a/server/src/com/vaadin/server/ServletPortletHelper.java +++ b/server/src/com/vaadin/server/ServletPortletHelper.java @@ -124,8 +124,7 @@ public class ServletPortletHelper implements Serializable { } public static boolean isPushRequest(VaadinRequest request) { - return hasPathPrefix(request, request.getService() - .getDeploymentConfiguration().getPushPath() + '/'); + return hasPathPrefix(request, ApplicationConstants.PUSH_PATH + '/'); } public static void initDefaultUIProvider(VaadinSession session, diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java index 02b4e64159..3a6dc1e55f 100644 --- a/server/src/com/vaadin/server/communication/UIInitHandler.java +++ b/server/src/com/vaadin/server/communication/UIInitHandler.java @@ -198,11 +198,10 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { PushMode pushMode = provider.getPushMode(event); if (pushMode == null) { - pushMode = session.getConfiguration().getPushMode(); + pushMode = session.getService().getDeploymentConfiguration() + .getPushMode(); } ui.getPushConfiguration().setPushMode(pushMode); - ui.getPushConfiguration().setPushPath( - session.getConfiguration().getPushPath()); Transport transport = provider.getPushTransport(event); if (transport != null) { diff --git a/server/src/com/vaadin/ui/PushConfiguration.java b/server/src/com/vaadin/ui/PushConfiguration.java index d5e89b4b14..90ad28542c 100644 --- a/server/src/com/vaadin/ui/PushConfiguration.java +++ b/server/src/com/vaadin/ui/PushConfiguration.java @@ -104,26 +104,6 @@ public interface PushConfiguration extends Serializable { */ public void setFallbackTransport(Transport fallbackTransport); - /** - * Sets the path that is used with push. - * - * @since 7.4.1 - * @param pushPath - * The path to be used with push - * - * @throws IllegalArgumentException - * if the argument is null or empty. - */ - public void setPushPath(String pushPath); - - /** - * Returns the path used with push. - * - * @since 7.4.1 - * @return The path that is used with push - */ - public String getPushPath(); - /** * Returns the given parameter, if set. *

@@ -275,32 +255,6 @@ class PushConfigurationImpl implements PushConfiguration { fallbackTransport.getIdentifier()); } - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.PushConfiguration#setPushPath(java.lang.String) - */ - @Override - public void setPushPath(String pushPath) { - if (pushPath != null && !pushPath.isEmpty()) { - getState().pushPath = pushPath; - } else { - throw new IllegalArgumentException( - "Push path can't be empty or null"); - } - - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.PushConfiguration#getPushPath() - */ - @Override - public String getPushPath() { - return getState(false).pushPath; - } - /* * (non-Javadoc) * @@ -336,4 +290,5 @@ class PushConfigurationImpl implements PushConfiguration { return Collections.unmodifiableCollection(getState(false).parameters .keySet()); } + } diff --git a/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java b/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java index ccdbfea150..0518bea650 100644 --- a/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java +++ b/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java @@ -158,9 +158,5 @@ public class AbstractDeploymentConfigurationTest { return DefaultDeploymentConfiguration.DEFAULT_SEND_URLS_AS_PARAMETERS; } - @Override - public String getPushPath() { - return null; - } } } diff --git a/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java b/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java index 175dcb2b94..ddee23a9ec 100644 --- a/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java +++ b/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java @@ -22,7 +22,6 @@ public class MockDeploymentConfiguration extends private LegacyProperyToStringMode legacyPropertyToStringMode = LegacyProperyToStringMode.DISABLED; private boolean syncIdCheckEnabled = true; private boolean sendUrlsAsParameters = true; - private String pushPath = "PUSH"; @Override public boolean isProductionMode() { @@ -126,9 +125,4 @@ public class MockDeploymentConfiguration extends return sendUrlsAsParameters; } - @Override - public String getPushPath() { - return pushPath; - } - } diff --git a/shared/src/com/vaadin/shared/ApplicationConstants.java b/shared/src/com/vaadin/shared/ApplicationConstants.java index 990564a6b8..d7aaee6267 100644 --- a/shared/src/com/vaadin/shared/ApplicationConstants.java +++ b/shared/src/com/vaadin/shared/ApplicationConstants.java @@ -28,6 +28,8 @@ public class ApplicationConstants implements Serializable { public static final String HEARTBEAT_PATH = "HEARTBEAT"; + public static final String PUSH_PATH = "PUSH"; + public static final String PUBLISHED_FILE_PATH = APP_PATH + '/' + "PUBLISHED"; @@ -74,7 +76,7 @@ public class ApplicationConstants implements Serializable { /** * 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"; @@ -88,7 +90,7 @@ public class ApplicationConstants implements Serializable { /** * The name of the debug version of the javascript containing push support. * The file is located in the VAADIN directory. - * + * * @since 7.1.6 */ public static final String VAADIN_PUSH_DEBUG_JS = "vaadinPush.debug.js"; @@ -100,14 +102,14 @@ public class ApplicationConstants implements Serializable { /** * The name of the parameter used to transmit RPC invocations - * + * * @since 7.2 */ public static final String RPC_INVOCATIONS = "rpc"; /** * The name of the parameter used to transmit the CSRF token - * + * * @since 7.2 */ public static final String CSRF_TOKEN = "csrfToken"; @@ -116,7 +118,7 @@ public class ApplicationConstants implements Serializable { * The name of the parameter used to transmit the sync id. The value can be * set to -1 e.g. when testing with pre-recorded requests to make the * framework ignore the sync id. - * + * * @see com.vaadin.ui.ConnectorTracker#getCurrentSyncId() * @since 7.2 */ diff --git a/shared/src/com/vaadin/shared/ui/ui/UIState.java b/shared/src/com/vaadin/shared/ui/ui/UIState.java index 04e182c5d4..2f51fef6ee 100644 --- a/shared/src/com/vaadin/shared/ui/ui/UIState.java +++ b/shared/src/com/vaadin/shared/ui/ui/UIState.java @@ -110,7 +110,6 @@ public class UIState extends TabIndexState { public static final String FALLBACK_TRANSPORT_PARAM = "fallbackTransport"; public PushMode mode = PushMode.DISABLED; - public String pushPath; public Map parameters = new HashMap(); { parameters diff --git a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java index 5c2e58d3a2..e2b93ab7d2 100644 --- a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java +++ b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java @@ -402,12 +402,9 @@ public class ApplicationRunnerServlet extends LegacyVaadinServlet { try { VaadinServletService service = (VaadinServletService) VaadinService .getCurrent(); - if (service != null) { - session = service - .findVaadinSession(new VaadinServletRequest( - currentRequest, service)); - } - + session = service + .findVaadinSession(new VaadinServletRequest( + currentRequest, service)); } finally { /* * Clear some state set by findVaadinSession to diff --git a/uitest/src/com/vaadin/tests/push/PushPath.java b/uitest/src/com/vaadin/tests/push/PushPath.java deleted file mode 100644 index 20771bd84f..0000000000 --- a/uitest/src/com/vaadin/tests/push/PushPath.java +++ /dev/null @@ -1,77 +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.push; - -import com.vaadin.annotations.Push; -import com.vaadin.server.VaadinRequest; -import com.vaadin.shared.ui.ui.Transport; -import com.vaadin.tests.components.AbstractTestUI; -import com.vaadin.ui.Label; - -@Push(transport = Transport.WEBSOCKET) -public class PushPath extends AbstractTestUI { - - public static final String PUSH_PATH_LABEL_ID = "push-path-label-id"; - public static final String PUSH_PATH_LABEL_TEXT = "Label by push"; - - @Override - protected void setup(VaadinRequest request) { - // use only websockets - getPushConfiguration().setFallbackTransport(Transport.WEBSOCKET); - - String pushPath = request.getService().getDeploymentConfiguration() - .getPushPath(); - String transport = getPushConfiguration().getTransport().name(); - Label pushPathLabel = new Label(String.format( - "Waiting for push from path '%s' using %s in 3 seconds.", - pushPath, transport)); - addComponent(pushPathLabel); - - new PushThread().start(); - } - - public class PushThread extends Thread { - - @Override - public void run() { - try { - Thread.sleep(3000); - } catch (InterruptedException e) { - } - access(new Runnable() { - - @Override - public void run() { - Label pushLabel = new Label(PUSH_PATH_LABEL_TEXT); - pushLabel.setId(PUSH_PATH_LABEL_ID); - addComponent(pushLabel); - } - }); - - } - } - - @Override - public Integer getTicketNumber() { - return 14432; - } - - @Override - public String getDescription() { - return "Push path should be configurable since some servers can't serve both websockets and long polling from same URL."; - } - -} diff --git a/uitest/src/com/vaadin/tests/push/PushPathTest.java b/uitest/src/com/vaadin/tests/push/PushPathTest.java deleted file mode 100644 index 0af9c8d3a7..0000000000 --- a/uitest/src/com/vaadin/tests/push/PushPathTest.java +++ /dev/null @@ -1,39 +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.push; - -import org.junit.Assert; -import org.junit.Test; - -import com.vaadin.tests.tb3.WebsocketTest; - -public class PushPathTest extends WebsocketTest { - - private static final int TEN_SECONDS_IN_MS = 10 * 1000; - - @Test - public void testCustomPushPath() throws InterruptedException { - openTestURL(); - sleep(TEN_SECONDS_IN_MS); - Assert.assertEquals(vaadinElementById(PushPath.PUSH_PATH_LABEL_ID) - .getText(), PushPath.PUSH_PATH_LABEL_TEXT); - } - - @Override - protected String getDeploymentPath(Class uiClass) { - return "/run-pushpath/" + uiClass.getCanonicalName(); - } -} -- cgit v1.2.3 From f665aed236f64da849862d4e463d80deecc33d9a Mon Sep 17 00:00:00 2001 From: Alexey Fansky Date: Mon, 23 Mar 2015 11:55:55 -0700 Subject: Disables selection when Grid's editor is open (#17132). Change-Id: Ibbbffbfe2e8bcb763031ac277c2c36ce4eb4e3fc --- .../grid/selection/MultiSelectionRenderer.java | 1 + client/src/com/vaadin/client/widgets/Grid.java | 13 +++++ .../components/grid/GridEditorMultiselect.java | 35 ++++++++++++++ .../components/grid/GridEditorMultiselectTest.java | 55 ++++++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/components/grid/GridEditorMultiselect.java create mode 100644 uitest/src/com/vaadin/tests/components/grid/GridEditorMultiselectTest.java diff --git a/client/src/com/vaadin/client/widget/grid/selection/MultiSelectionRenderer.java b/client/src/com/vaadin/client/widget/grid/selection/MultiSelectionRenderer.java index 5024c8bffa..ddbf690970 100644 --- a/client/src/com/vaadin/client/widget/grid/selection/MultiSelectionRenderer.java +++ b/client/src/com/vaadin/client/widget/grid/selection/MultiSelectionRenderer.java @@ -569,6 +569,7 @@ public class MultiSelectionRenderer extends ComplexRenderer { InputElement checkbox = InputElement.as(cell.getElement() .getFirstChildElement()); checkbox.setChecked(data.booleanValue()); + checkbox.setDisabled(grid.isEditorActive()); checkbox.setPropertyInt(LOGICAL_ROW_PROPERTY_INT, cell.getRowIndex()); } diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index f4a5b0961c..d9845bcdc8 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -1157,6 +1157,7 @@ public class Grid extends ResizeComposite implements + "Grid editor"); grid.getEscalator().setScrollLocked(Direction.VERTICAL, false); + updateSelectionCheckboxesAsNeeded(true); } } }; @@ -1256,6 +1257,16 @@ public class Grid extends ResizeComposite implements null); handler.cancel(request); state = State.INACTIVE; + updateSelectionCheckboxesAsNeeded(true); + } + + private void updateSelectionCheckboxesAsNeeded(boolean isEnabled) { + if (grid.getSelectionModel() instanceof Multi) { + grid.refreshBody(); + CheckBox checkBox = (CheckBox) grid.getDefaultHeaderRow() + .getCell(grid.selectionColumn).getWidget(); + checkBox.setEnabled(isEnabled); + } } /** @@ -1282,6 +1293,7 @@ public class Grid extends ResizeComposite implements EditorRequest request = new EditorRequestImpl(grid, rowIndex, saveRequestCallback); handler.save(request); + updateSelectionCheckboxesAsNeeded(true); } /** @@ -1346,6 +1358,7 @@ public class Grid extends ResizeComposite implements rowIndex, bindRequestCallback); handler.bind(request); grid.getEscalator().setScrollLocked(Direction.VERTICAL, true); + updateSelectionCheckboxesAsNeeded(false); } } diff --git a/uitest/src/com/vaadin/tests/components/grid/GridEditorMultiselect.java b/uitest/src/com/vaadin/tests/components/grid/GridEditorMultiselect.java new file mode 100644 index 0000000000..b80a9d1153 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridEditorMultiselect.java @@ -0,0 +1,35 @@ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; + +public class GridEditorMultiselect extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Grid grid = new Grid(); + + grid.addColumn("name"); + grid.addColumn("age", Integer.class); + + for (int i = 0; i < 30; i++) { + grid.addRow("name " + i, i); + } + + grid.setEditorEnabled(true); + grid.setSelectionMode(Grid.SelectionMode.MULTI); + + addComponent(grid); + } + + @Override + protected Integer getTicketNumber() { + return 17132; + } + + @Override + public String getDescription() { + return "Grid Multiselect: Edit mode allows invalid selection"; + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridEditorMultiselectTest.java b/uitest/src/com/vaadin/tests/components/grid/GridEditorMultiselectTest.java new file mode 100644 index 0000000000..ba689fb5e1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridEditorMultiselectTest.java @@ -0,0 +1,55 @@ +package com.vaadin.tests.components.grid; + +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.GridElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridEditorMultiselectTest extends MultiBrowserTest { + + @Test + public void testSelectCheckboxesDisabled() { + openTestURL(); + GridElement grid = openEditor(); + assertCheckboxesEnabled(grid, false); + } + + @Test + public void testSelectCheckboxesEnabledBackOnSave() { + openTestURL(); + GridElement grid = openEditor(); + grid.getEditor().save(); + assertCheckboxesEnabled(grid, true); + } + + @Test + public void testSelectCheckboxesEnabledBackOnCancel() { + openTestURL(); + GridElement grid = openEditor(); + grid.getEditor().cancel(); + assertCheckboxesEnabled(grid, true); + } + + private GridElement openEditor() { + GridElement grid = $(GridElement.class).first(); + grid.getRow(0).doubleClick(); + Assert.assertTrue("Grid editor should be displayed.", grid.getEditor() + .isDisplayed()); + return grid; + } + + private void assertCheckboxesEnabled(GridElement grid, boolean isEnabled) { + List checkboxes = grid.findElements(By + .xpath("//input[@type='checkbox']")); + for (WebElement checkbox : checkboxes) { + Assert.assertEquals("Select checkboxes should be " + + (isEnabled ? "enabled" : "disabled"), isEnabled, + checkbox.isEnabled()); + } + } +} -- cgit v1.2.3 From f38697786931944177c86498939d6b5993b1588d Mon Sep 17 00:00:00 2001 From: Miki Date: Fri, 6 Feb 2015 15:27:59 +0200 Subject: Fix declarative support for DragAndDropWrapper (#16324) Change-Id: I132e37fe54fb5949748c0e0ec265bd411ff91ce3 --- server/src/com/vaadin/ui/DragAndDropWrapper.java | 37 +++++++++++- .../DragAndDropWrapperDeclarativeTest.java | 66 ++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 server/tests/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java diff --git a/server/src/com/vaadin/ui/DragAndDropWrapper.java b/server/src/com/vaadin/ui/DragAndDropWrapper.java index 6e4ec903d2..b813973861 100644 --- a/server/src/com/vaadin/ui/DragAndDropWrapper.java +++ b/server/src/com/vaadin/ui/DragAndDropWrapper.java @@ -24,6 +24,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import org.jsoup.nodes.Element; + import com.vaadin.event.Transferable; import com.vaadin.event.TransferableImpl; import com.vaadin.event.dd.DragSource; @@ -38,6 +40,7 @@ import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.ui.dd.HorizontalDropLocation; import com.vaadin.shared.ui.dd.VerticalDropLocation; import com.vaadin.shared.ui.draganddropwrapper.DragAndDropWrapperConstants; +import com.vaadin.ui.declarative.DesignContext; @SuppressWarnings("serial") public class DragAndDropWrapper extends CustomComponent implements DropTarget, @@ -185,7 +188,12 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, private Set sentIds = new HashSet(); - private DragAndDropWrapper() { + /** + * This is an internal constructor. Use + * {@link DragAndDropWrapper#DragAndDropWrapper(Component)} instead. + */ + @Deprecated + public DragAndDropWrapper() { super(); } @@ -458,4 +466,31 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, } + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + for (Element child : design.children()) { + Component component = designContext.readDesign(child); + if (getDragStartMode() == DragStartMode.COMPONENT_OTHER + && child.hasAttr(":drag-image")) { + setDragImageComponent(component); + } else if (getCompositionRoot() == null) { + setCompositionRoot(component); + } + } + } + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + + design.appendChild(designContext.createElement(getCompositionRoot())); + if (getDragStartMode() == DragStartMode.COMPONENT_OTHER) { + Element child = designContext + .createElement(getDragImageComponent()); + child.attr(":drag-image", ""); + design.appendChild(child); + } + } } diff --git a/server/tests/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java b/server/tests/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.java new file mode 100644 index 0000000000..735216c474 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperDeclarativeTest.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.draganddropwrapper; + +import org.junit.Test; + +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.DragStartMode; +import com.vaadin.ui.declarative.DesignContext; + +public class DragAndDropWrapperDeclarativeTest extends + DeclarativeTestBase { + + @Test + public void testDefaultDnDWrapper() { + Button okButton = new Button("OK"); + String input = "" + + new DesignContext().createElement(okButton) + + ""; + DragAndDropWrapper wrapper = new DragAndDropWrapper(okButton); + testWrite(input, wrapper); + testRead(input, wrapper); + } + + @Test + public void testNoDragImage() { + Button okButton = new Button("OK"); + String input = "" + + new DesignContext().createElement(okButton) + + ""; + DragAndDropWrapper wrapper = new DragAndDropWrapper(okButton); + wrapper.setDragStartMode(DragStartMode.WRAPPER); + testWrite(input, wrapper); + testRead(input, wrapper); + } + + @Test + public void testWithDragImage() { + Button dragImage = new Button("Cancel"); + Button okButton = new Button("OK"); + String input = "" + + new DesignContext().createElement(okButton) + + new DesignContext().createElement(dragImage).attr( + ":drag-image", "") + ""; + DragAndDropWrapper wrapper = new DragAndDropWrapper(okButton); + wrapper.setDragStartMode(DragStartMode.COMPONENT_OTHER); + wrapper.setDragImageComponent(dragImage); + testWrite(input, wrapper); + testRead(input, wrapper); + } +} -- cgit v1.2.3 From 640ac265babd0c31c3572e8080dff4f9a9be2ab6 Mon Sep 17 00:00:00 2001 From: Henri Sara Date: Thu, 19 Mar 2015 15:36:36 +0200 Subject: Build Maven BOM for Vaadin (#17025) Change-Id: I842a5f1551012744354371e1c099f6ca2360029c --- all/ivy.xml | 1 + bom/build.xml | 46 ++++++++++++++++++++++++ bom/ivy.xml | 18 ++++++++++ bom/vaadin-bom.pom | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++ build.xml | 2 ++ common.xml | 2 +- ivysettings.xml | 2 ++ 7 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 bom/build.xml create mode 100644 bom/ivy.xml create mode 100644 bom/vaadin-bom.pom diff --git a/all/ivy.xml b/all/ivy.xml index 156588485f..cea833731a 100644 --- a/all/ivy.xml +++ b/all/ivy.xml @@ -32,6 +32,7 @@ rev="${vaadin.version}" /> + diff --git a/bom/build.xml b/bom/build.xml new file mode 100644 index 0000000000..42d7303b7b --- /dev/null +++ b/bom/build.xml @@ -0,0 +1,46 @@ + + + + + Compiles a BOM (Bill of Materials) Maven artifact + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bom/ivy.xml b/bom/ivy.xml new file mode 100644 index 0000000000..39abb30d80 --- /dev/null +++ b/bom/ivy.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/bom/vaadin-bom.pom b/bom/vaadin-bom.pom new file mode 100644 index 0000000000..f2b482ad9b --- /dev/null +++ b/bom/vaadin-bom.pom @@ -0,0 +1,103 @@ + + 4.0.0 + + com.vaadin + vaadin-parent + 1.0.0 + + com.vaadin + vaadin-bom + @vaadin.version@ + pom + Vaadin Framework (Bill of Materials) + Vaadin Framework (Bill of Materials) + + Vaadin Ltd + http://vaadin.com + + http://vaadin.com + + + Apache License Version 2.0 + repo + http://www.apache.org/licenses/LICENSE-2.0 + + + + scm:https:https://github.com/vaadin/vaadin.git + scm:https:https://github.com/vaadin/vaadin.git + https://github.com/vaadin/vaadin + + + + artur + Artur Signell + artur.signell@vaadin.com + http://vaadin.com/web/artur + Vaadin Ltd + http://vaadin.com/ + + architect + developer + team manager + + 2 + + + hesara + Henri Sara + hesara@vaadin.com + Vaadin Ltd + http://vaadin.com/ + + developer + + 2 + + + + + + com.vaadin + vaadin-shared + @vaadin.version@ + + + com.vaadin + vaadin-server + @vaadin.version@ + + + com.vaadin + vaadin-push + @vaadin.version@ + + + com.vaadin + vaadin-widgets + @vaadin.version@ + + + com.vaadin + vaadin-client + @vaadin.version@ + + + com.vaadin + vaadin-client-compiler + @vaadin.version@ + + + com.vaadin + vaadin-client-compiled + @vaadin.version@ + + + com.vaadin + vaadin-themes + @vaadin.version@ + + + + diff --git a/build.xml b/build.xml index ee24c61529..a88892772e 100644 --- a/build.xml +++ b/build.xml @@ -21,11 +21,13 @@ + + diff --git a/common.xml b/common.xml index 9487560051..feb3381607 100644 --- a/common.xml +++ b/common.xml @@ -9,7 +9,7 @@ - + diff --git a/ivysettings.xml b/ivysettings.xml index f1fc4d1c63..c97b6a3bfb 100644 --- a/ivysettings.xml +++ b/ivysettings.xml @@ -49,6 +49,8 @@ resolver="build-temp" /> + -- cgit v1.2.3 From f7f581d57a8bfa42428c0751454aa8dccb00ec49 Mon Sep 17 00:00:00 2001 From: Juho Nurminen Date: Thu, 26 Mar 2015 10:23:14 +0200 Subject: Use native scrolling in IE on touch devices (#14864) Change-Id: I8c652944b917d6392e2d02052b00ddb119ec242c --- client/src/com/vaadin/client/BrowserInfo.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/src/com/vaadin/client/BrowserInfo.java b/client/src/com/vaadin/client/BrowserInfo.java index 5ca79cb121..3bc75a9a9b 100644 --- a/client/src/com/vaadin/client/BrowserInfo.java +++ b/client/src/com/vaadin/client/BrowserInfo.java @@ -411,6 +411,11 @@ public class BrowserInfo { if (isIOS() && isWebkit() && getOperatingSystemMajorVersion() >= 6) { return false; } + + if (isIE()) { + return false; + } + return true; } -- cgit v1.2.3 From 6e208eb77a248c5f5b1baa055ded94a43b0c96ed Mon Sep 17 00:00:00 2001 From: wodencafe Date: Wed, 4 Feb 2015 11:28:51 -0600 Subject: SplitPanel should have an event for the splitter being moved (#3855) Change-Id: I473e5a0f8420c95971af52ef230849f468ebbbad --- server/src/com/vaadin/ui/AbstractSplitPanel.java | 77 +++++++++++++++++++ .../vaadin/ui/SplitPositionChangeListenerTest.java | 44 +++++++++++ .../components/splitpanel/SplitPositionChange.java | 87 ++++++++++++++++++++++ .../splitpanel/SplitPositionChangeTest.java | 82 ++++++++++++++++++++ 4 files changed, 290 insertions(+) create mode 100644 server/tests/src/com/vaadin/ui/SplitPositionChangeListenerTest.java create mode 100644 uitest/src/com/vaadin/tests/components/splitpanel/SplitPositionChange.java create mode 100644 uitest/src/com/vaadin/tests/components/splitpanel/SplitPositionChangeTest.java diff --git a/server/src/com/vaadin/ui/AbstractSplitPanel.java b/server/src/com/vaadin/ui/AbstractSplitPanel.java index af73fca6a8..8a7b9086c2 100644 --- a/server/src/com/vaadin/ui/AbstractSplitPanel.java +++ b/server/src/com/vaadin/ui/AbstractSplitPanel.java @@ -64,6 +64,8 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { @Override public void setSplitterPosition(float position) { getSplitterState().position = position; + fireEvent(new SplitPositionChangeEvent(AbstractSplitPanel.this, + position, getSplitPositionUnit())); } }; @@ -331,6 +333,8 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { splitterState.positionUnit = unit.getSymbol(); splitterState.positionReversed = reverse; posUnit = unit; + fireEvent(new SplitPositionChangeEvent(AbstractSplitPanel.this, pos, + posUnit)); } /** @@ -520,6 +524,54 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { } + /** + * Interface for listening for {@link SplitPositionChangeEvent}s fired by a + * SplitPanel. + * + * @since + */ + public interface SplitPositionChangeListener extends ConnectorEventListener { + + public static final Method moveMethod = ReflectTools.findMethod( + SplitPositionChangeListener.class, "onSplitPositionChanged", + SplitPositionChangeEvent.class); + + /** + * SplitPanel splitter position has been changed. + * + * @param event + * SplitPositionChangeEvent event. + */ + public void onSplitPositionChanged(SplitPositionChangeEvent event); + } + + /** + * Event that indicates a change in SplitPanel's splitter position. + * + * @since + */ + public static class SplitPositionChangeEvent extends Component.Event { + + private final float position; + private final Unit unit; + + public SplitPositionChangeEvent(final Component source, + final float position, final Unit unit) { + super(source); + this.position = position; + this.unit = unit; + } + + public float getSplitPosition() { + return position; + } + + public Unit getSplitPositionUnit() { + return unit; + } + + } + public void addSplitterClickListener(SplitterClickListener listener) { addListener(EventId.CLICK_EVENT_IDENTIFIER, SplitterClickEvent.class, listener, SplitterClickListener.clickMethod); @@ -548,6 +600,31 @@ public abstract class AbstractSplitPanel extends AbstractComponentContainer { removeSplitterClickListener(listener); } + /** + * Register a listener to handle {@link SplitPositionChangeEvent}s. + * + * @since + * @param listener + * {@link SplitPositionChangeListener} to be registered. + */ + public void addSplitPositionChangeListener( + SplitPositionChangeListener listener) { + addListener(SplitPositionChangeEvent.class, listener, + SplitPositionChangeListener.moveMethod); + } + + /** + * Removes a {@link SplitPositionChangeListener}. + * + * @since + * @param listener + * SplitPositionChangeListener to be removed. + */ + public void removeSplitPositionChangeListener( + SplitPositionChangeListener listener) { + removeListener(SplitPositionChangeEvent.class, listener); + } + @Override protected AbstractSplitPanelState getState() { return (AbstractSplitPanelState) super.getState(); diff --git a/server/tests/src/com/vaadin/ui/SplitPositionChangeListenerTest.java b/server/tests/src/com/vaadin/ui/SplitPositionChangeListenerTest.java new file mode 100644 index 0000000000..02dc412cd9 --- /dev/null +++ b/server/tests/src/com/vaadin/ui/SplitPositionChangeListenerTest.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.ui; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.Test; + +import com.vaadin.server.Sizeable.Unit; +import com.vaadin.ui.AbstractSplitPanel.SplitPositionChangeEvent; +import com.vaadin.ui.AbstractSplitPanel.SplitPositionChangeListener; + +/** + * Test for {@link SplitPositionChangeListener} + * + * @author Vaadin Ltd + */ +public class SplitPositionChangeListenerTest { + + @Test + public void testSplitPositionListenerIsTriggered() throws Exception { + final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel(); + SplitPositionChangeListener splitPositionChangeListener = mock(SplitPositionChangeListener.class); + splitPanel.addSplitPositionChangeListener(splitPositionChangeListener); + splitPanel.setSplitPosition(50, Unit.PERCENTAGE); + verify(splitPositionChangeListener).onSplitPositionChanged( + any(SplitPositionChangeEvent.class)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/splitpanel/SplitPositionChange.java b/uitest/src/com/vaadin/tests/components/splitpanel/SplitPositionChange.java new file mode 100644 index 0000000000..81c449731c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/splitpanel/SplitPositionChange.java @@ -0,0 +1,87 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.splitpanel; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.AbstractSplitPanel; +import com.vaadin.ui.HorizontalSplitPanel; +import com.vaadin.ui.Label; +import com.vaadin.ui.Panel; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.VerticalSplitPanel; + +/** + * Test for {@link SplitPositionChangeListeners}. + * + * @author Vaadin Ltd + */ +public class SplitPositionChange extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + addSplitPanel(true, "Left", "Right"); + addSplitPanel(false, "Top", "Bottom"); + } + + private void addSplitPanel(final boolean horizontal, String firstCaption, + String secondCaption) { + AbstractSplitPanel splitPanel; + if (horizontal) { + splitPanel = new HorizontalSplitPanel(); + } else { + splitPanel = new VerticalSplitPanel(); + } + splitPanel.setWidth("200px"); + splitPanel.setHeight("200px"); + splitPanel.addComponent(buildPanel(firstCaption)); + splitPanel.addComponent(buildPanel(secondCaption)); + splitPanel + .addSplitPositionChangeListener(new AbstractSplitPanel.SplitPositionChangeListener() { + + @Override + public void onSplitPositionChanged( + AbstractSplitPanel.SplitPositionChangeEvent event) { + log(String.format( + "Split position changed: %s, position: %s %s", + (horizontal ? "horizontal" : "vertical"), + event.getSplitPosition(), + event.getSplitPositionUnit())); + } + }); + addComponent(splitPanel); + } + + private Panel buildPanel(String caption) { + VerticalLayout pl = new VerticalLayout(); + pl.setMargin(true); + pl.addComponent(new Label("content")); + Panel panel = new Panel(caption, pl); + panel.setSizeFull(); + return panel; + } + + @Override + protected String getTestDescription() { + return "SplitPanel should have an event for the splitter being moved"; + } + + @Override + protected Integer getTicketNumber() { + return 3855; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/splitpanel/SplitPositionChangeTest.java b/uitest/src/com/vaadin/tests/components/splitpanel/SplitPositionChangeTest.java new file mode 100644 index 0000000000..43edb56f3a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/splitpanel/SplitPositionChangeTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.splitpanel; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.HorizontalSplitPanelElement; +import com.vaadin.testbench.elements.VerticalSplitPanelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for {@link SplitPositionChangeListeners}. + * + * @author Vaadin Ltd + */ +public class SplitPositionChangeTest extends MultiBrowserTest { + + @Override + public void setup() throws Exception { + super.setup(); + openTestURL(); + waitForElementPresent(By.className("v-splitpanel-horizontal")); + } + + @Test + public void testHorizontalSplit() { + HorizontalSplitPanelElement split = $(HorizontalSplitPanelElement.class) + .first(); + WebElement splitter = split.findElement(By + .className("v-splitpanel-hsplitter")); + int position = splitter.getLocation().getX(); + Actions actions = new Actions(driver); + actions.clickAndHold(splitter).moveByOffset(50, 0).release().perform(); + assertPosition(position, splitter.getLocation().getX()); + assertLogText(true); + } + + @Test + public void testVerticalSplit() { + VerticalSplitPanelElement split = $(VerticalSplitPanelElement.class) + .first(); + WebElement splitter = split.findElement(By + .className("v-splitpanel-vsplitter")); + int position = splitter.getLocation().getY(); + Actions actions = new Actions(driver); + actions.clickAndHold(splitter).moveByOffset(0, 50).release().perform(); + assertPosition(position, splitter.getLocation().getY()); + assertLogText(false); + } + + private void assertPosition(int original, int current) { + Assert.assertFalse("Position didn't change", original == current); + } + + private void assertLogText(boolean horizontal) { + String expected = String.format( + "1. Split position changed: %s, position: .*", + horizontal ? "horizontal" : "vertical"); + String actual = getLogRow(0); + Assert.assertTrue( + String.format( + "Log content didn't match the expected format.\nexpected: '%s'\nwas: '%s'", + expected, actual), actual.matches(expected)); + } +} -- cgit v1.2.3 From b826bb17ee3349bbaa4ac67526315427a716a62d Mon Sep 17 00:00:00 2001 From: Henri Sara Date: Thu, 26 Mar 2015 13:25:57 +0200 Subject: Fix build scripts for BOM (#17025) Change-Id: Ia59a2423d8e22e15a978dd73baf08b5fa6388ea6 --- all/build.xml | 4 ++-- all/ivy.xml | 1 - common.xml | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/all/build.xml b/all/build.xml index 37f728e529..c3672fc828 100644 --- a/all/build.xml +++ b/all/build.xml @@ -50,7 +50,7 @@ - @@ -88,7 +88,7 @@ - diff --git a/all/ivy.xml b/all/ivy.xml index cea833731a..156588485f 100644 --- a/all/ivy.xml +++ b/all/ivy.xml @@ -32,7 +32,6 @@ rev="${vaadin.version}" /> - diff --git a/common.xml b/common.xml index feb3381607..075044bb5b 100644 --- a/common.xml +++ b/common.xml @@ -9,7 +9,8 @@ - + + -- cgit v1.2.3 From bacb87d5e42d6b52bf59f2f6781cca9b3cdc903a Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Tue, 24 Mar 2015 10:08:58 +0200 Subject: Fix Calendar declarative support (#16595) Change-Id: Ib9a33d6d0fe48e63e5043a84a47375f123eccb58 --- server/src/com/vaadin/ui/Calendar.java | 71 +++++++++++++++++++++- .../calendar/CalendarDeclarativeTest.java | 61 +++++++++++++++++++ 2 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 server/tests/src/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java diff --git a/server/src/com/vaadin/ui/Calendar.java b/server/src/com/vaadin/ui/Calendar.java index 48c024026e..acddbe308b 100644 --- a/server/src/com/vaadin/ui/Calendar.java +++ b/server/src/com/vaadin/ui/Calendar.java @@ -22,6 +22,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.EventListener; import java.util.GregorianCalendar; @@ -37,6 +38,9 @@ import java.util.TimeZone; import java.util.logging.Level; import java.util.logging.Logger; +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; + import com.vaadin.data.Container; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.event.Action; @@ -84,6 +88,8 @@ import com.vaadin.ui.components.calendar.handler.BasicEventMoveHandler; import com.vaadin.ui.components.calendar.handler.BasicEventResizeHandler; import com.vaadin.ui.components.calendar.handler.BasicForwardHandler; import com.vaadin.ui.components.calendar.handler.BasicWeekClickHandler; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** *

@@ -334,6 +340,10 @@ public class Calendar extends AbstractComponent implements */ public Date getStartDate() { if (startDate == null) { + currentCalendar.set(java.util.Calendar.MILLISECOND, 0); + currentCalendar.set(java.util.Calendar.SECOND, 0); + currentCalendar.set(java.util.Calendar.MINUTE, 0); + currentCalendar.set(java.util.Calendar.HOUR_OF_DAY, 0); currentCalendar.set(java.util.Calendar.DAY_OF_WEEK, currentCalendar.getFirstDayOfWeek()); return currentCalendar.getTime(); @@ -363,6 +373,10 @@ public class Calendar extends AbstractComponent implements */ public Date getEndDate() { if (endDate == null) { + currentCalendar.set(java.util.Calendar.MILLISECOND, 0); + currentCalendar.set(java.util.Calendar.SECOND, 59); + currentCalendar.set(java.util.Calendar.MINUTE, 59); + currentCalendar.set(java.util.Calendar.HOUR_OF_DAY, 23); currentCalendar.set(java.util.Calendar.DAY_OF_WEEK, currentCalendar.getFirstDayOfWeek() + 6); return currentCalendar.getTime(); @@ -655,8 +669,14 @@ public class Calendar extends AbstractComponent implements */ public TimeFormat getTimeFormat() { if (currentTimeFormat == null) { - SimpleDateFormat f = (SimpleDateFormat) SimpleDateFormat - .getTimeInstance(SimpleDateFormat.SHORT, getLocale()); + SimpleDateFormat f; + if (getLocale() == null) { + f = (SimpleDateFormat) SimpleDateFormat + .getTimeInstance(SimpleDateFormat.SHORT); + } else { + f = (SimpleDateFormat) SimpleDateFormat.getTimeInstance( + SimpleDateFormat.SHORT, getLocale()); + } String p = f.toPattern(); if (p.indexOf("HH") != -1 || p.indexOf("H") != -1) { return TimeFormat.Format24H; @@ -1925,4 +1945,51 @@ public class Calendar extends AbstractComponent implements return getState(false).eventCaptionAsHtml; } + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + Attributes attr = design.attributes(); + if (design.hasAttr("time-format")) { + setTimeFormat(TimeFormat.valueOf("Format" + + design.attr("time-format").toUpperCase())); + } + + if (design.hasAttr("start-date")) { + setStartDate(DesignAttributeHandler.readAttribute("start-date", + attr, Date.class)); + } + if (design.hasAttr("end-date")) { + setEndDate(DesignAttributeHandler.readAttribute("end-date", attr, + Date.class)); + } + }; + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + + if (currentTimeFormat != null) { + design.attr("time-format", + (currentTimeFormat == TimeFormat.Format12H ? "12h" : "24h")); + } + if (startDate != null) { + design.attr("start-date", df_date.format(getStartDate())); + } + if (endDate != null) { + design.attr("end-date", df_date.format(getEndDate())); + } + if (!getTimeZone().equals(TimeZone.getDefault())) { + design.attr("time-zone", getTimeZone().getID()); + } + } + + @Override + protected Collection getCustomAttributes() { + Collection customAttributes = super.getCustomAttributes(); + customAttributes.add("time-format"); + customAttributes.add("start-date"); + customAttributes.add("end-date"); + return customAttributes; + } } diff --git a/server/tests/src/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.java new file mode 100644 index 0000000000..d866878fc7 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/calendar/CalendarDeclarativeTest.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.server.component.calendar; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +import org.junit.Test; + +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Calendar; +import com.vaadin.ui.Calendar.TimeFormat; + +public class CalendarDeclarativeTest extends DeclarativeTestBase { + + @Test + public void testEmpty() { + verifyDeclarativeDesign("", new Calendar()); + } + + @Test + public void testCalendarAllFeatures() throws ParseException { + String design = ""; + + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Calendar calendar = new Calendar(); + calendar.setStartDate(format.parse("2014-11-17")); + calendar.setEndDate(format.parse("2014-11-23")); + calendar.setFirstVisibleDayOfWeek(2); + calendar.setLastVisibleDayOfWeek(5); + calendar.setTimeZone(TimeZone.getTimeZone("EST")); + calendar.setTimeFormat(TimeFormat.Format12H); + calendar.setFirstVisibleHourOfDay(8); + calendar.setLastVisibleHourOfDay(18); + calendar.setWeeklyCaptionFormat("mmm MM/dd"); + verifyDeclarativeDesign(design, calendar); + } + + protected void verifyDeclarativeDesign(String design, Calendar expected) { + testRead(design, expected); + testWrite(design, expected); + } +} -- cgit v1.2.3 From ebcf64b94911597a123a599cd758e36b4abfe8bf Mon Sep 17 00:00:00 2001 From: Miki Date: Tue, 10 Feb 2015 15:04:27 +0200 Subject: Fix declarative support for MenuBar (#16328) Change-Id: Icd70a02aa8ffef9d1aca4b833ac23aeff5813771 --- server/src/com/vaadin/ui/MenuBar.java | 153 ++++++++++++++++++++- .../ui/declarative/DesignAttributeHandler.java | 5 +- .../components/menubar/MenuBarDeclarativeTest.java | 139 +++++++++++++++++++ 3 files changed, 293 insertions(+), 4 deletions(-) create mode 100644 server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java diff --git a/server/src/com/vaadin/ui/MenuBar.java b/server/src/com/vaadin/ui/MenuBar.java index 6b6555c0a2..747ce42727 100644 --- a/server/src/com/vaadin/ui/MenuBar.java +++ b/server/src/com/vaadin/ui/MenuBar.java @@ -17,17 +17,25 @@ package com.vaadin.ui; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Stack; +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; +import org.jsoup.nodes.Node; +import org.jsoup.parser.Tag; + import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.Resource; import com.vaadin.shared.ui.menubar.MenuBarConstants; import com.vaadin.shared.ui.menubar.MenuBarState; import com.vaadin.ui.Component.Focusable; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** *

@@ -932,7 +940,150 @@ public class MenuBar extends AbstractComponent implements LegacyComponent, this.checked = checked; markAsDirty(); } - }// class MenuItem + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + for (MenuItem item : getItems()) { + design.appendChild(createMenuElement(item)); + } + + // in many cases there seems to be an empty more menu item + if (getMoreMenuItem() != null && !getMoreMenuItem().getText().isEmpty()) { + Element moreMenu = createMenuElement(getMoreMenuItem()); + moreMenu.attr("more", ""); + design.appendChild(moreMenu); + } + + if (!htmlContentAllowed) { + design.attr(DESIGN_ATTR_PLAIN_TEXT, ""); + } + } + + protected Element createMenuElement(MenuItem item) { + Element menuElement = new Element(Tag.valueOf("menu"), ""); + // Defaults + MenuItem def = new MenuItem("", null, null); + + Attributes attr = menuElement.attributes(); + DesignAttributeHandler.writeAttribute("icon", attr, item.getIcon(), + def.getIcon(), Resource.class); + DesignAttributeHandler.writeAttribute("disabled", attr, + !item.isEnabled(), !def.isEnabled(), boolean.class); + DesignAttributeHandler.writeAttribute("visible", attr, + item.isVisible(), def.isVisible(), boolean.class); + DesignAttributeHandler.writeAttribute("separator", attr, + item.isSeparator(), def.isSeparator(), boolean.class); + DesignAttributeHandler.writeAttribute("checkable", attr, + item.isCheckable(), def.isCheckable(), boolean.class); + DesignAttributeHandler.writeAttribute("checked", attr, + item.isChecked(), def.isChecked(), boolean.class); + DesignAttributeHandler.writeAttribute("description", attr, + item.getDescription(), def.getDescription(), String.class); + DesignAttributeHandler.writeAttribute("style-name", attr, + item.getStyleName(), def.getStyleName(), String.class); + + menuElement.append(item.getText()); + + if (item.hasChildren()) { + for (MenuItem subMenu : item.getChildren()) { + menuElement.appendChild(createMenuElement(subMenu)); + } + } + + return menuElement; + } + + protected MenuItem readMenuElement(Element menuElement) { + Resource icon = null; + if (menuElement.hasAttr("icon")) { + icon = DesignAttributeHandler.getFormatter().parse( + menuElement.attr("icon"), Resource.class); + } + + String caption = ""; + List subMenus = new ArrayList(); + for (Node node : menuElement.childNodes()) { + if (node instanceof Element + && ((Element) node).tagName().equals("menu")) { + subMenus.add((Element) node); + } + caption += node.toString(); + } + MenuItem menu = new MenuItem(caption.trim(), icon, null); + + Attributes attr = menuElement.attributes(); + if (menuElement.hasAttr("icon")) { + menu.setIcon(DesignAttributeHandler.readAttribute("icon", attr, + Resource.class)); + } + if (menuElement.hasAttr("disabled")) { + menu.setEnabled(!DesignAttributeHandler.readAttribute("disabled", + attr, boolean.class)); + } + if (menuElement.hasAttr("visible")) { + menu.setVisible(DesignAttributeHandler.readAttribute("visible", + attr, boolean.class)); + } + if (menuElement.hasAttr("separator")) { + menu.setSeparator(DesignAttributeHandler.readAttribute("separator", + attr, boolean.class)); + } + if (menuElement.hasAttr("checkable")) { + menu.setCheckable(DesignAttributeHandler.readAttribute("checkable", + attr, boolean.class)); + } + if (menuElement.hasAttr("checked")) { + menu.setChecked(DesignAttributeHandler.readAttribute("checked", + attr, boolean.class)); + } + if (menuElement.hasAttr("description")) { + menu.setDescription(DesignAttributeHandler.readAttribute( + "description", attr, String.class)); + } + if (menuElement.hasAttr("style-name")) { + menu.setStyleName(DesignAttributeHandler.readAttribute( + "style-name", attr, String.class)); + } + + if (!subMenus.isEmpty()) { + menu.itsChildren = new ArrayList(); + } + + for (Element subMenu : subMenus) { + MenuItem newItem = readMenuElement(subMenu); + + newItem.setParent(menu); + menu.itsChildren.add(newItem); + } + + return menu; + } + + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + for (Element itemElement : design.children()) { + if (itemElement.tagName().equals("menu")) { + MenuItem menuItem = readMenuElement(itemElement); + if (itemElement.hasAttr("more")) { + setMoreMenuItem(menuItem); + } else { + menuItems.add(menuItem); + } + } + } + + setHtmlContentAllowed(!design.hasAttr(DESIGN_ATTR_PLAIN_TEXT)); + } + + @Override + protected Collection getCustomAttributes() { + Collection result = super.getCustomAttributes(); + result.add(DESIGN_ATTR_PLAIN_TEXT); + result.add("html-content-allowed"); + return result; + } }// class MenuBar diff --git a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java index 215afd5041..2b446bda0e 100644 --- a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java +++ b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java @@ -38,7 +38,6 @@ import org.jsoup.nodes.Node; import com.vaadin.data.util.converter.Converter; import com.vaadin.shared.util.SharedUtil; -import com.vaadin.ui.Component; /** * Default attribute handler implementation used when parsing designs to @@ -192,8 +191,8 @@ public class DesignAttributeHandler implements Serializable { * @param defaultInstance * the default instance for comparing default values */ - public static void writeAttribute(Component component, String attribute, - Attributes attr, Component defaultInstance) { + public static void writeAttribute(Object component, String attribute, + Attributes attr, Object defaultInstance) { Method getter = findGetterForAttribute(component.getClass(), attribute); if (getter == null) { getLogger().warning( diff --git a/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java b/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java new file mode 100644 index 0000000000..e6dee44812 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java @@ -0,0 +1,139 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.menubar; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.server.ExternalResource; +import com.vaadin.server.ThemeResource; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.MenuBar.MenuItem; + +/** + * Tests declarative support for menu bars. + * + * @since 7.4 + * @author Vaadin Ltd + */ +public class MenuBarDeclarativeTest extends DeclarativeTestBase { + + @Test + // #16328 + public void testReadWrite() throws IOException { + String design = "" + + "

Save" + + "Open" + + "Close" + + "Help" + + "About" + + "SubItem" + + "WTF?!" + ""; + MenuBar bar = new MenuBar(); + bar.setAutoOpen(true); + bar.setHtmlContentAllowed(true); + bar.setTabIndex(5); + + bar.addItem("Save", null).setCheckable(true); + bar.addItem("Open", null).setDescription("Open a file"); + bar.addItem("Close", null).setEnabled(false); + bar.addItem("Help", null).setIcon( + new ExternalResource("http://foo.bar/ico.png")); + bar.addItem("About", null).setVisible(false); + + bar.addItem("Sub", null).addItem("Item", null); + + bar.setMoreMenuItem(bar.new MenuItem("WTF?!", null, null)); + + testWrite(design, bar); + testRead(design, bar); + } + + @Test + // #16328 + public void testTicketSpec1() throws IOException { + String design = " " + + "File" + + "Save" + + "Open" + + "" + + "Exit" + + "Not for everybody" + + "" + + "Other" + + "Sub" + + "Option 1 - no html" + + "Option 2" + + "Option 3" // + + "" // + + "" // + + "foo" + + ""; + // for one reason or another, no component has a correct .equals + // implementation, which makes tests a bit annoying + MenuBar menuBar = new MenuBar(); + menuBar.setHtmlContentAllowed(false); + menuBar.setTabIndex(5); + menuBar.setAutoOpen(true); + // File menu + MenuItem fileMenu = menuBar.addItem("File", null); + fileMenu.addItem("Save", null); + fileMenu.addItem("Open", new ThemeResource( + "../runo/icons/16/folder.png"), null); + fileMenu.addSeparator(); + fileMenu.addItem("Exit", null).setEnabled(false); + fileMenu.addItem("Not for everybody", null).setVisible(false); + MenuItem otherMenu = menuBar.addItem("Other", null); + otherMenu.setDescription("This contains many items in sub menus"); + MenuItem subMenu = otherMenu.addItem("Sub", null); + subMenu.setStyleName("fancy"); + MenuItem option1 = subMenu.addItem("Option 1 - no html", null); + option1.setCheckable(true); + option1.setChecked(true); + subMenu.addItem("Option 2", null).setCheckable(true); + subMenu.addItem("Option 3", null).setCheckable(true); + menuBar.setMoreMenuItem(null); + MenuItem moreMenu = menuBar.getMoreMenuItem(); + moreMenu.setIcon(new ThemeResource("icon.png")); + moreMenu.setText("foo"); + testRead(design, menuBar); + testWrite(design, menuBar); + } + + @Test + // #16328 + public void testTicketSpec2() throws IOException { + String design = "" + + "File" + + "Save" + + "Open" + + "" + + "Exit" // + + ""; + MenuBar menuBar = new MenuBar(); + menuBar.setHtmlContentAllowed(true); + MenuItem fileMenu = menuBar.addItem("File", null); + fileMenu.addItem("Save", null); + fileMenu.addItem("Open", new ThemeResource( + "../runo/icons/16/folder.png"), null); + fileMenu.addSeparator(); + fileMenu.addItem("Exit", null).setEnabled(false); + testRead(design, menuBar); + testWrite(design, menuBar); + } +} \ No newline at end of file -- cgit v1.2.3 From b96861c1809d12f2d1339fd64f825a3c513977d2 Mon Sep 17 00:00:00 2001 From: Miki Date: Fri, 6 Feb 2015 14:49:03 +0200 Subject: Fix declarative support for AbstractMedia (#16330 #16331 #16332) Also fixes HTTPS resource handling (#17267) Contains tests for both Audio and Video. Change-Id: Id4a7325f0d29f6857ff2236757b28b9eb911e39a --- server/src/com/vaadin/server/ExternalResource.java | 1 - server/src/com/vaadin/server/FileResource.java | 1 - server/src/com/vaadin/ui/AbstractMedia.java | 52 ++++++++++++++++++ server/src/com/vaadin/ui/Video.java | 39 ++++++++++++++ .../converters/DesignResourceConverter.java | 3 +- .../component/audio/AudioDeclarativeTest.java | 63 ++++++++++++++++++++++ .../component/audio/VideoDeclarativeTest.java | 59 ++++++++++++++++++++ 7 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 server/tests/src/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java create mode 100644 server/tests/src/com/vaadin/tests/server/component/audio/VideoDeclarativeTest.java diff --git a/server/src/com/vaadin/server/ExternalResource.java b/server/src/com/vaadin/server/ExternalResource.java index 0c724ae19f..e3b026dde8 100644 --- a/server/src/com/vaadin/server/ExternalResource.java +++ b/server/src/com/vaadin/server/ExternalResource.java @@ -124,5 +124,4 @@ public class ExternalResource implements Resource, Serializable { public void setMIMEType(String mimeType) { this.mimeType = mimeType; } - } diff --git a/server/src/com/vaadin/server/FileResource.java b/server/src/com/vaadin/server/FileResource.java index b32905f972..28de124fe9 100644 --- a/server/src/com/vaadin/server/FileResource.java +++ b/server/src/com/vaadin/server/FileResource.java @@ -156,5 +156,4 @@ public class FileResource implements ConnectorResource { public void setBufferSize(int bufferSize) { this.bufferSize = bufferSize; } - } diff --git a/server/src/com/vaadin/ui/AbstractMedia.java b/server/src/com/vaadin/ui/AbstractMedia.java index 0bd8c3ea77..a0344624d7 100644 --- a/server/src/com/vaadin/ui/AbstractMedia.java +++ b/server/src/com/vaadin/ui/AbstractMedia.java @@ -18,12 +18,17 @@ package com.vaadin.ui; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; +import org.jsoup.nodes.Node; + import com.vaadin.server.ConnectorResource; import com.vaadin.server.DownloadStream; import com.vaadin.server.Resource; @@ -34,6 +39,8 @@ import com.vaadin.server.VaadinSession; import com.vaadin.shared.communication.URLReference; import com.vaadin.shared.ui.AbstractMediaState; import com.vaadin.shared.ui.MediaControl; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * Abstract base class for the HTML5 media components. @@ -256,4 +263,49 @@ public abstract class AbstractMedia extends AbstractComponent { getRpcProxy(MediaControl.class).play(); } + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + + String altText = getAltText(); + if (altText != null && !altText.isEmpty()) { + design.append(altText); + } + + for (Resource r : getSources()) { + Attributes attr = design.appendElement("source").attributes(); + DesignAttributeHandler.writeAttribute("href", attr, r, null, + Resource.class); + } + } + + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + String altText = ""; + for (Node child : design.childNodes()) { + if (child instanceof Element + && ((Element) child).tagName().equals("source") + && child.hasAttr("href")) { + addSource(DesignAttributeHandler.readAttribute("href", + child.attributes(), Resource.class)); + } else { + altText += child.toString(); + } + } + + altText = altText.trim(); + if (!altText.isEmpty()) { + setAltText(altText); + } + } + + @Override + protected Collection getCustomAttributes() { + Collection result = super.getCustomAttributes(); + result.add("alt-text"); + return result; + } + } diff --git a/server/src/com/vaadin/ui/Video.java b/server/src/com/vaadin/ui/Video.java index e690218e6f..46a4293b36 100644 --- a/server/src/com/vaadin/ui/Video.java +++ b/server/src/com/vaadin/ui/Video.java @@ -16,9 +16,17 @@ package com.vaadin.ui; +import java.util.Collection; + +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + import com.vaadin.server.Resource; import com.vaadin.shared.ui.video.VideoConstants; import com.vaadin.shared.ui.video.VideoState; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * The Video component translates into an HTML5 <video> element and as @@ -89,4 +97,35 @@ public class Video extends AbstractMedia { return getResource(VideoConstants.POSTER_RESOURCE); } + @Override + public void readDesign(Element design, DesignContext designContext) { + Elements elems = design.getElementsByTag("poster"); + for (Element poster : elems) { + if (getPoster() == null && poster.hasAttr("href")) { + setPoster(DesignAttributeHandler.readAttribute("href", + poster.attributes(), Resource.class)); + } + poster.remove(); + } + + // Poster is extracted so AbstractMedia does not include it in alt text + super.readDesign(design, designContext); + } + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + if (getPoster() != null) { + Attributes attr = design.appendElement("poster").attributes(); + DesignAttributeHandler.writeAttribute("href", attr, getPoster(), + null, Resource.class); + } + } + + @Override + protected Collection getCustomAttributes() { + Collection result = super.getCustomAttributes(); + result.add("poster"); + return result; + } } diff --git a/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java b/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java index 70e46b8e7f..21f20e6403 100644 --- a/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java +++ b/server/src/com/vaadin/ui/declarative/converters/DesignResourceConverter.java @@ -39,7 +39,8 @@ public class DesignResourceConverter implements Converter { public Resource convertToModel(String value, Class targetType, Locale locale) throws Converter.ConversionException { - if (value.startsWith("http://")) { + if (value.startsWith("http://") || value.startsWith("https://") + || value.startsWith("ftp://") || value.startsWith("ftps://")) { return new ExternalResource(value); } else if (value.startsWith("theme://")) { return new ThemeResource(value.substring(8)); diff --git a/server/tests/src/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java new file mode 100644 index 0000000000..4390499c4e --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/audio/AudioDeclarativeTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.audio; + +import java.io.File; + +import org.junit.Test; + +import com.vaadin.server.ExternalResource; +import com.vaadin.server.FileResource; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Audio; + +/** + * Tests specs of declarative support for abstract media and its + * implementations. + * + * @since 7.4 + * @author Vaadin Ltd + */ +public class AudioDeclarativeTest extends DeclarativeTestBase