]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix the column width calculations for full width cell contents. (#11974)
authorAnna Koskinen <Ansku@users.noreply.github.com>
Wed, 29 Apr 2020 07:33:54 +0000 (10:33 +0300)
committerGitHub <noreply@github.com>
Wed, 29 Apr 2020 07:33:54 +0000 (10:33 +0300)
Fixes #11973

client/src/main/java/com/vaadin/client/widgets/Escalator.java
uitest/src/main/java/com/vaadin/tests/components/grid/GridWithFullWidthComponents.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/grid/GridWithFullWidthComponentsTest.java [new file with mode: 0644]

index c2e70eeb96358b63006f5dd49d8f199a6369a98a..b4427b2df13c2ba584bfa55ffec003955e211898 100644 (file)
@@ -37,6 +37,7 @@ import com.google.gwt.animation.client.AnimationScheduler;
 import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback;
 import com.google.gwt.animation.client.AnimationScheduler.AnimationHandle;
 import com.google.gwt.core.client.Duration;
+import com.google.gwt.core.client.JavaScriptException;
 import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.core.client.JsArray;
 import com.google.gwt.core.client.Scheduler;
@@ -2240,6 +2241,10 @@ public class Escalator extends Widget
 
             TableCellElement cellClone = TableCellElement
                     .as((Element) cell.cloneNode(withContent));
+            if (!withContent || columnConfiguration
+                    .getColumnWidth(cell.getCellIndex()) < 0) {
+                clearRelativeWidthContents(cellClone);
+            }
             cellClone.getStyle().clearHeight();
             cellClone.getStyle().clearWidth();
 
@@ -2259,6 +2264,41 @@ public class Escalator extends Widget
             return requiredWidth;
         }
 
+        /**
+         * Contents of an element that is configured to have relative width
+         * shouldn't be taken into consideration when measuring minimum widths.
+         * Thus any such contents within the element hierarchy need to be
+         * cleared out for accurate results. The element itself should remain,
+         * however, in case it has styles that affect the end results.
+         *
+         * @param elem
+         *            an element that might have unnecessary content that
+         *            interferes with minimum width calculations
+         */
+        private void clearRelativeWidthContents(Element elem) {
+            try {
+                String width = elem.getStyle().getWidth();
+                if (width != null && width.endsWith("%")) {
+                    if (elem.hasChildNodes()) {
+                        elem.removeAllChildren();
+                        // add a fake child so that :empty behavior doesn't
+                        // change
+                        elem.setInnerHTML("<a/>");
+                    } else {
+                        elem.setInnerHTML(null);
+                    }
+                }
+            } catch (JavaScriptException e) {
+                // no width set, move on
+            }
+            for (int i = 0; i < elem.getChildCount(); ++i) {
+                Node node = elem.getChild(i);
+                if (node instanceof Element) {
+                    clearRelativeWidthContents((Element) node);
+                }
+            }
+        }
+
         /**
          * Gets the minimum width needed to display the cell properly.
          *
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridWithFullWidthComponents.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridWithFullWidthComponents.java
new file mode 100644 (file)
index 0000000..233a260
--- /dev/null
@@ -0,0 +1,79 @@
+package com.vaadin.tests.components.grid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.data.provider.DataProvider;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+
+public class GridWithFullWidthComponents extends AbstractTestUI {
+    private String s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
+            + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        getPage().getStyles()
+                .add(".v-grid .v-label, .v-grid .v-csslayout:not(:empty) { "
+                        + "background-color: yellow; min-width: 300px; }");
+
+        List<Integer> content = new ArrayList<>();
+        for (int i = 0; i < 100; ++i) {
+            content.add(i);
+        }
+
+        Grid<Integer> grid = new Grid<>(DataProvider.ofCollection(content));
+        grid.setSizeFull();
+        grid.setSelectionMode(Grid.SelectionMode.NONE);
+        grid.setBodyRowHeight(70);
+        grid.addComponentColumn(this::labelResponse).setCaption("Label");
+        grid.addComponentColumn(this::hLayoutResponse)
+                .setCaption("HorizontalLayout");
+        grid.addComponentColumn(this::cssLayoutResponse)
+                .setCaption("CssLayout");
+
+        addComponent(grid);
+    }
+
+    private Label labelResponse(Integer item) {
+        Label label = new Label(s);
+        label.setWidthFull();
+        return label;
+    }
+
+    private HorizontalLayout hLayoutResponse(Integer ite) {
+        HorizontalLayout layout = new HorizontalLayout();
+        layout.setWidthFull();
+        for (int i = 0; i < 5; ++i) {
+            layout.addComponent(new Button("Button" + i));
+        }
+        return layout;
+    }
+
+    private CssLayout cssLayoutResponse(Integer ite) {
+        CssLayout layout = new CssLayout();
+        layout.setWidthFull();
+        for (int i = 0; i < 5; ++i) {
+            layout.addComponent(new Button("Button" + i));
+        }
+        return layout;
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "All column contents are components with 100% width, "
+                + "in first and third column the contents are styled "
+                + "to have background color and minimum width of 300px. "
+                + "Initial render and browser resize should behave accordingly.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 11973;
+    }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridWithFullWidthComponentsTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridWithFullWidthComponentsTest.java
new file mode 100644 (file)
index 0000000..21285f3
--- /dev/null
@@ -0,0 +1,61 @@
+package com.vaadin.tests.components.grid;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.openqa.selenium.Dimension;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class GridWithFullWidthComponentsTest extends MultiBrowserTest {
+
+    @Test
+    public void testResizeUpAndDown() {
+        openTestURL();
+
+        WebElement hScrollBar = findElement(
+                By.className("v-grid-scroller-horizontal"));
+        assertEquals("Unexpected horizontal scrollbar visibility", "none",
+                hScrollBar.getCssValue("display"));
+
+        // increase the browser size
+        getDriver().manage().window().setSize(new Dimension(2000, 850));
+        sleep(300);
+
+        assertEquals("Unexpected horizontal scrollbar visibility", "none",
+                hScrollBar.getCssValue("display"));
+
+        // scale back again
+        getDriver().manage().window().setSize(new Dimension(1500, 850));
+        sleep(300);
+
+        assertEquals("Unexpected horizontal scrollbar visibility", "none",
+                hScrollBar.getCssValue("display"));
+    }
+
+    @Test
+    public void testResizeDownAndUp() {
+        openTestURL();
+
+        WebElement hScrollBar = findElement(
+                By.className("v-grid-scroller-horizontal"));
+        assertEquals("Unexpected horizontal scrollbar visibility", "none",
+                hScrollBar.getCssValue("display"));
+
+        // decrease the browser size far enough that scrollbars are needed
+        getDriver().manage().window().setSize(new Dimension(800, 850));
+        sleep(300);
+
+        assertEquals("Unexpected horizontal scrollbar visibility", "block",
+                hScrollBar.getCssValue("display"));
+
+        // scale back again
+        getDriver().manage().window().setSize(new Dimension(1500, 850));
+        sleep(300);
+
+        assertEquals("Unexpected horizontal scrollbar visibility", "none",
+                hScrollBar.getCssValue("display"));
+    }
+}