]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add browser specific handling in setRows (#12141)
authorTatu Lund <tatu@vaadin.com>
Mon, 19 Apr 2021 07:52:08 +0000 (10:52 +0300)
committerGitHub <noreply@github.com>
Mon, 19 Apr 2021 07:52:08 +0000 (10:52 +0300)
* Add browser specific handling in setRows

Fixes: https://github.com/vaadin/framework/issues/10138
Fixes: https://github.com/vaadin/framework/issues/7878
* Enforced minimum height to 1 rows and added a test.

Co-authored-by: Anna Koskinen <anna@vaadin.com>
client/src/main/java/com/vaadin/client/ui/VTextArea.java
server/src/main/java/com/vaadin/ui/TextArea.java
uitest/src/main/java/com/vaadin/tests/components/textarea/TextAreaSetRows.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/textarea/TextAreaSetRowsTest.java [new file with mode: 0644]

index 769b1ed817a9b61e69dfd0b230dbaec569d06a34..b50bd88a04515290001cfeb8d9614ef8d672d6d9 100644 (file)
@@ -60,6 +60,7 @@ public class VTextArea extends VTextField implements DragImageModifier {
         super(DOM.createTextArea());
         setStyleName(CLASSNAME);
         addKeyDownHandler(enterDownHandler);
+        getElement().getStyle().setOverflowX(Overflow.HIDDEN);
     }
 
     public TextAreaElement getTextAreaElement() {
@@ -76,7 +77,8 @@ public class VTextArea extends VTextField implements DragImageModifier {
         }
         if (wordWrap) {
             getElement().removeAttribute("wrap");
-            getElement().getStyle().clearOverflow();
+            getElement().getStyle().clearOverflowY();
+            getElement().getStyle().setOverflowX(Overflow.HIDDEN);
             getElement().getStyle().clearWhiteSpace();
         } else {
             getElement().setAttribute("wrap", "off");
index 7d19948bb3a8d7ddd60f904f7c1c7f17d17d0ff9..211cc44a2948ba9e67f6b155e62b31baf79f23e6 100644 (file)
@@ -136,13 +136,16 @@ public class TextArea extends AbstractTextField {
 
     /**
      * Sets the number of rows in the text area.
+     * <p>
+     * Note: it's not possible to display less than one row via this height
+     * setting method, so minimum number of rows has been set to 1.
      *
      * @param rows
      *            the number of rows for this text area.
      */
     public void setRows(int rows) {
-        if (rows < 0) {
-            rows = 0;
+        if (rows < 1) {
+            rows = 1;
         }
         getState().rows = rows;
     }
diff --git a/uitest/src/main/java/com/vaadin/tests/components/textarea/TextAreaSetRows.java b/uitest/src/main/java/com/vaadin/tests/components/textarea/TextAreaSetRows.java
new file mode 100644 (file)
index 0000000..393c914
--- /dev/null
@@ -0,0 +1,67 @@
+package com.vaadin.tests.components.textarea;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.util.LoremIpsum;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.TextArea;
+
+public class TextAreaSetRows extends AbstractTestUI {
+
+    protected static final String ROWS_0 = "Set rows to 0";
+    protected static final String ROWS_1 = "Set rows to 1";
+    protected static final String ROWS_2 = "Set rows to 2";
+    protected static final String ROWS_3 = "Set rows to 3";
+    protected static final String ROWS_4 = "Set rows to 4";
+    protected static final String HEIGHT0 = "Set height to 0px";
+    protected static final String HEIGHTR = "Reset height setting";
+    protected static final String WWRAP = "Toggle word wrap";
+    protected static final String LONGS = "Use longer contents (separate)";
+    protected static final String LONGN = "Use longer contents (no breaks)";
+    protected static final String SCROLLB = "Add scrollbar to panel";
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        TextArea ta = new TextArea();
+        String value = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n";
+        ta.setValue(value);
+        addComponent(ta);
+
+        addComponent(new Button(ROWS_0, e -> ta.setRows(0)));
+        addComponent(new Button(ROWS_1, e -> ta.setRows(1)));
+        addComponent(new Button(ROWS_2, e -> ta.setRows(2)));
+        addComponent(new Button(ROWS_3, e -> ta.setRows(3)));
+        addComponent(new Button(ROWS_4, e -> ta.setRows(4)));
+        addComponent(new Button(HEIGHT0, e -> ta.setHeight("0px")));
+        addComponent(new Button(HEIGHTR, e -> ta.setHeight("-1px")));
+        addComponent(new Button(WWRAP, e -> ta.setWordWrap(!ta.isWordWrap())));
+        addComponent(new Button(LONGS,
+                e -> ta.setValue(value + LoremIpsum.get(50))));
+        addComponent(new Button(LONGN,
+                e -> ta.setValue(value + getClass().getName())));
+
+        Panel p = new Panel();
+        CssLayout content = new CssLayout();
+        p.setContent(content);
+        content.setHeight("0px");
+        p.setHeightUndefined();
+        p.setWidth("100px");
+        addComponent(p);
+        addComponent(new Button(SCROLLB, e -> content.setWidth("200px")));
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 10138;
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "Default height: 5 rows. Minimum height: 1 rows. "
+                + "Height should update as expected. Disabling word wrap "
+                + "adds space for a scrollbar whether one is needed or not. "
+                + "Firefox always behaves like word wrap was disabled.";
+    }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/textarea/TextAreaSetRowsTest.java b/uitest/src/test/java/com/vaadin/tests/components/textarea/TextAreaSetRowsTest.java
new file mode 100644 (file)
index 0000000..d2f4f13
--- /dev/null
@@ -0,0 +1,127 @@
+package com.vaadin.tests.components.textarea;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.elements.PanelElement;
+import com.vaadin.testbench.elements.TextAreaElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class TextAreaSetRowsTest extends MultiBrowserTest {
+    private double rowHeight;
+    private int scrollbarHeight;
+    private int bordersAndPadding = 14; // fixed by Valo theme
+
+    @Test
+    public void testSetRows() {
+        openTestURL();
+        waitUntilLoadingIndicatorNotVisible();
+
+        // calculate scrollbar height for comparison
+        PanelElement panel = $(PanelElement.class).first();
+        int panelHeight = panel.getSize().getHeight();
+        // add scrollbar
+        $(ButtonElement.class).caption(TextAreaSetRows.SCROLLB).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        scrollbarHeight = panel.getSize().getHeight() - panelHeight;
+        assertGreater("Unexpected comparison scrollbar height", scrollbarHeight,
+                0);
+
+        TextAreaElement textArea = $(TextAreaElement.class).first();
+        int height5 = textArea.getSize().getHeight();
+        // calculate height of a single row
+        rowHeight = (height5 - bordersAndPadding) / 5d;
+        assertEquals("Unexpected initial height,", getExpected(5), height5, 1);
+
+        $(ButtonElement.class).caption(TextAreaSetRows.ROWS_0).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        int height0 = textArea.getSize().getHeight();
+        assertEquals("Unexpected 0 rows height,", getExpected(0), height0, 1);
+
+        $(ButtonElement.class).caption(TextAreaSetRows.ROWS_4).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        int height4 = textArea.getSize().getHeight();
+        assertEquals("Unexpected 4 rows height,", getExpected(4), height4, 1);
+
+        $(ButtonElement.class).caption(TextAreaSetRows.ROWS_2).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        int height2 = textArea.getSize().getHeight();
+        assertEquals("Unexpected 2 rows height,", getExpected(2), height2, 1);
+
+        $(ButtonElement.class).caption(TextAreaSetRows.ROWS_1).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        int height1 = textArea.getSize().getHeight();
+        assertEquals("Unexpected 1 rows height,", getExpected(1), height1, 1);
+
+        assertEquals("Height mismatch for 0 and 1 rows", height0, height1, 1);
+
+        // set fixed height to 0 (does not affect borders and padding)
+        $(ButtonElement.class).caption(TextAreaSetRows.HEIGHT0).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        int heightFixed = textArea.getSize().getHeight();
+        assertEquals("Unexpected fixed height,", bordersAndPadding, heightFixed,
+                1);
+
+        // remove fixed height, should return to height by rows
+        $(ButtonElement.class).caption(TextAreaSetRows.HEIGHTR).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        int heightReset = textArea.getSize().getHeight();
+        assertEquals("Unexpected 1 rows height,", height1, heightReset, 1);
+
+        $(ButtonElement.class).caption(TextAreaSetRows.ROWS_3).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        int height3 = textArea.getSize().getHeight();
+        assertEquals("Unexpected 3 rows height,", getExpected(3), height3, 1);
+
+        // toggle off word wrap
+        $(ButtonElement.class).caption(TextAreaSetRows.WWRAP).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        int newHeight3 = textArea.getSize().getHeight();
+        // expected height to increase even without a scrollbar
+        assertGreater("Unexpected 3 rows height without word wrap (short),",
+                newHeight3, height3);
+
+        // trigger horizontal scroll bar
+        $(ButtonElement.class).caption(TextAreaSetRows.LONGS).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        // height should not have changed
+        assertEquals("Unexpected 3 rows height without word wrap (long),",
+                newHeight3, textArea.getSize().getHeight(), 1);
+
+        // switch to longer contents with no breaks
+        $(ButtonElement.class).caption(TextAreaSetRows.LONGN).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        // height should not have changed
+        assertEquals(
+                "Unexpected 3 rows height without word wrap (long without breaks),",
+                newHeight3, textArea.getSize().getHeight(), 1);
+
+        // ensure that the height difference to original matches a scrollbar
+        // height, use a Panel's scrollbar as a comparison
+        assertEquals("Unexpected textarea scrollbar height,", scrollbarHeight,
+                newHeight3 - height3, 1);
+
+        // toggle word wrap back on
+        $(ButtonElement.class).caption(TextAreaSetRows.WWRAP).first().click();
+        waitUntilLoadingIndicatorNotVisible();
+        // height should have reverted to what it was before removing wrap
+        assertEquals(
+                "Unexpected 3 rows height with word wrap (long without breaks),",
+                height3, textArea.getSize().getHeight(), 1);
+    }
+
+    /**
+     * Calculates the expected height when horizontal scrollbar isn't possible.
+     *
+     * @param rows
+     *            how many rows are displayed
+     * @return expected text area height
+     */
+    private double getExpected(int rows) {
+        // minimum row count is one
+        return bordersAndPadding + (Math.max(1, rows) * rowHeight);
+    }
+
+}