diff options
author | Leif Åstrand <leif@vaadin.com> | 2013-03-12 18:34:18 +0200 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2013-03-20 09:43:35 +0000 |
commit | 5ea677d377c96c60fbc546eb2381bb88f2d4b478 (patch) | |
tree | 36b3fefd6b1481c4f39f182f09e88b00d77d5818 /client | |
parent | 17f64543bcc74f74017a3d1c13e5db83c7a4ec41 (diff) | |
download | vaadin-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.java | 114 | ||||
-rw-r--r-- | client/src/com/vaadin/client/ui/VTextField.java | 4 |
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); + } } |