diff options
author | Anna Koskinen <Ansku@users.noreply.github.com> | 2020-04-29 10:33:54 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-29 10:33:54 +0300 |
commit | 4c9a5405a555785dc2b38e82b3d1cda0336491e0 (patch) | |
tree | 75ba4ed2247f48255f6a51ba076c5f702487f2dd | |
parent | 599387b330f66f0dbe6087d2fe829bc251fef6c1 (diff) | |
download | vaadin-framework-4c9a5405a555785dc2b38e82b3d1cda0336491e0.tar.gz vaadin-framework-4c9a5405a555785dc2b38e82b3d1cda0336491e0.zip |
Fix the column width calculations for full width cell contents. (#11974)
Fixes #11973
3 files changed, 180 insertions, 0 deletions
diff --git a/client/src/main/java/com/vaadin/client/widgets/Escalator.java b/client/src/main/java/com/vaadin/client/widgets/Escalator.java index c2e70eeb96..b4427b2df1 100644 --- a/client/src/main/java/com/vaadin/client/widgets/Escalator.java +++ b/client/src/main/java/com/vaadin/client/widgets/Escalator.java @@ -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(); @@ -2260,6 +2265,41 @@ public class Escalator extends Widget } /** + * 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. * * @param colIndex 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 index 0000000000..233a260984 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridWithFullWidthComponents.java @@ -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 index 0000000000..21285f3ed0 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/GridWithFullWidthComponentsTest.java @@ -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")); + } +} |