summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2013-03-12 18:34:18 +0200
committerVaadin Code Review <review@vaadin.com>2013-03-20 09:43:35 +0000
commit5ea677d377c96c60fbc546eb2381bb88f2d4b478 (patch)
tree36b3fefd6b1481c4f39f182f09e88b00d77d5818 /client
parent17f64543bcc74f74017a3d1c13e5db83c7a4ec41 (diff)
downloadvaadin-framework-5ea677d377c96c60fbc546eb2381bb88f2d4b478.tar.gz
vaadin-framework-5ea677d377c96c60fbc546eb2381bb88f2d4b478.zip
Make TextArea.setCursorPosition work in all browsers (#8769)
svn changeset:25579/svn branch:6.8 Conflicts: client/src/com/vaadin/client/ui/VTextField.java Change-Id: I3b53be8df4ce0564f34d8aa9bc1ce1c34648eadd
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/client/ui/VTextArea.java114
-rw-r--r--client/src/com/vaadin/client/ui/VTextField.java4
2 files changed, 118 insertions, 0 deletions
diff --git a/client/src/com/vaadin/client/ui/VTextArea.java b/client/src/com/vaadin/client/ui/VTextArea.java
index 4a5de23828..45e0532451 100644
--- a/client/src/com/vaadin/client/ui/VTextArea.java
+++ b/client/src/com/vaadin/client/ui/VTextArea.java
@@ -63,6 +63,120 @@ public class VTextArea extends VTextField {
getTextAreaElement().setRows(rows);
}
+ @Override
+ public void setSelectionRange(int pos, int length) {
+ super.setSelectionRange(pos, length);
+ final String value = getValue();
+ /*
+ * Align position to index inside string value
+ */
+ int index = pos;
+ if (index < 0) {
+ index = 0;
+ }
+ if (index > value.length()) {
+ index = value.length();
+ }
+ // Get pixels count required to scroll textarea vertically
+ int scrollTop = getScrollTop(value, index);
+ int scrollLeft = -1;
+ /*
+ * Check if textarea has wrap attribute set to "off". In the latter case
+ * horizontal scroll is also required.
+ */
+ if (!isWordwrap()) {
+ // Get pixels count required to scroll textarea horizontally
+ scrollLeft = getScrollLeft(value, index);
+ }
+ // Set back original text if previous methods calls changed it
+ if (!isWordwrap() || index < value.length()) {
+ setValue(value, false);
+ }
+ /*
+ * Call original method to set cursor position. In most browsers it
+ * doesn't lead to scrolling.
+ */
+ super.setSelectionRange(pos, length);
+ /*
+ * Align vertical scroll to middle of textarea view (height) if
+ * scrolling is reqiured at all.
+ */
+ if (scrollTop > 0) {
+ scrollTop += getElement().getClientHeight() / 2;
+ }
+ /*
+ * Align horizontal scroll to middle of textarea view (widht) if
+ * scrolling is reqiured at all.
+ */
+ if (scrollLeft > 0) {
+ scrollLeft += getElement().getClientWidth() / 2;
+ }
+ /*
+ * Scroll if computed scrollTop is greater than scroll after cursor
+ * setting
+ */
+ if (getElement().getScrollTop() < scrollTop) {
+ getElement().setScrollTop(scrollTop);
+ }
+ /*
+ * Scroll if computed scrollLeft is greater than scroll after cursor
+ * setting
+ */
+ if (getElement().getScrollLeft() < scrollLeft) {
+ getElement().setScrollLeft(scrollLeft);
+ }
+ }
+
+ /*
+ * Get horizontal scroll value required to get position visible. Method is
+ * called only when text wrapping is off. There is need to scroll
+ * horizontally in case words are wrapped.
+ */
+ private int getScrollLeft(String value, int index) {
+ String beginning = value.substring(0, index);
+ // Compute beginning of the current line
+ int begin = beginning.lastIndexOf('\n');
+ String line = value.substring(begin + 1);
+ index = index - begin - 1;
+ if (index < line.length()) {
+ index++;
+ }
+ line = line.substring(0, index);
+ /*
+ * Now <code>line</code> contains current line up to index position
+ */
+ setValue(line.trim(), false); // Set this line to the textarea.
+ /*
+ * Scroll textarea up to the end of the line (maximum possible
+ * horizontal scrolling value). Now the end line becomes visible.
+ */
+ getElement().setScrollLeft(getElement().getScrollWidth());
+ // Return resulting horizontal scrolling value.
+ return getElement().getScrollLeft();
+ }
+
+ /*
+ * Get vertical scroll value required to get position visible
+ */
+ private int getScrollTop(String value, int index) {
+ /*
+ * Trim text after position and set this trimmed text if index is not
+ * very end.
+ */
+ if (index < value.length()) {
+ String beginning = value.substring(0, index);
+ setValue(beginning, false);
+ }
+ /*
+ * Now textarea contains trimmed text and could be scrolled up to the
+ * top. Scroll it to maximum possible value to get end of the text
+ * visible.
+ */
+ getElement().setScrollTop(getElement().getScrollHeight());
+ // Return resulting vertical scrolling value.
+ return getElement().getScrollTop();
+ }
+
private class MaxLengthHandler implements KeyUpHandler, ChangeHandler {
@Override
diff --git a/client/src/com/vaadin/client/ui/VTextField.java b/client/src/com/vaadin/client/ui/VTextField.java
index 0fbed0dd90..da9445c811 100644
--- a/client/src/com/vaadin/client/ui/VTextField.java
+++ b/client/src/com/vaadin/client/ui/VTextField.java
@@ -446,4 +446,8 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler,
this.inputPrompt = inputPrompt;
}
+ protected boolean isWordwrap() {
+ String wrap = getElement().getAttribute("wrap");
+ return !"off".equals(wrap);
+ }
}