[whatwg] Request for new DOM property textarea.selectionText

Maciej Stachowiak mjs at apple.com
Sat Apr 28 23:09:38 PDT 2012


Does this work in any non-WebKit browsers? (Asking mainly out of curiosity; I would tend to agree in any case that adding nontrivial editing APIs that are specific to only plaintext editable controls is not a good idea. But it might be nice to specify explicitly whether execCommand works on form controls.)

While I would not go out of my way to praise execCommand, setRangeText is also not a very good API  design:

1) setRangeText is a vague and confusing name. If its only function was replacing the selection, then replaceSelection would be much better, but:
2) The method is overloaded to do a variety of tangentially related things. The overloading makes it hard to give it a good name. If the different operations were different methods, it would be easier to name it well (replaceSelection, replaceRange), but it's hard to describe all four of the selection modes.
3) It's not clear that all of the different selection modes of this function have use cases.

Regards,
Maciej

On Apr 27, 2012, at 9:11 PM, Ryosuke Niwa <rniwa at webkit.org> wrote:

> Why are we adding this new API? WebKit already supports
> 
> document.execCommand('InsertText', false, "new selected text");
> 
> - Ryosuke
> 
> On Fri, Apr 27, 2012 at 9:01 PM, Ian Hickson <ian at hixie.ch> wrote:
> 
>> On Mon, 10 May 2010, Biju wrote:
>>> 
>>> Can we have a new DOM property textarea.selectionText which can be used
>>> to set/get selection text of a TEXTAREA/INPUT type=text.
>> 
>> Gettng the value is relatively easy:
>> 
>> On Mon, 10 May 2010, Biju wrote:
>>> 
>>> Current way in firefox is to
>>> 
>>> 1. OrigStart = textarea.selectionStart
>> 
>> But admittedly setting it is a pain:
>> 
>>> 2.  textarea.value = textarea.value.substr(0, OrigStart)
>>>                          + new_text_to_replace
>>>                          + textarea.value.substr(textarea.selectionEnd);
>>> 3. Now u loose original selection, so
>>> 
>>> 4.  textarea.setSelectionRange(OrigStart,
>> OrigStart+new_text_to_replace.length)
>>> 5.  remember .scrollTop and reapply if needed
>> 
>> I agree that making this easier would be good.
>> 
>> 
>>> On IE even though wierd you can do it simply by
>>>   document.selection.createRange().text = new_text_to_replace;
>>> BTW, you need to make sure the selection is currently on the
>>> textarea/input form control.
>>> IE is also very fast when doing that, when firefox hangs few second
>>> using the other way
>> 
>> IE's version is non-standard and not adopted by other UAs.
>> 
>> 
>> On Mon, 10 May 2010, Ojan Vafai wrote:
>>> 
>>> In addition to selection and scroll issues, needing to replace the
>>> entire textarea value doesn't scale and thus limits what sorts of things
>>> you can do with textareas. A general way to set a sub-part of a
>>> textarea's value seems useful to me. I don't think we should tie that to
>>> setting the selected text though.
>>> 
>>> textarea.setRangeText(start, end, text);
>>> 
>>> It replaces the text between start and end, maintains current scroll
>>> position and preserves the selection.
>> 
>> On Tue, 11 May 2010, Biju wrote:
>>> 
>>> Both have advantages
>>> 
>>> Option 1 (textobj.selectionText) advantages
>>> * No need for web developer to provide selection start/end
>>> * Automatically select the newly inserted text,
>>>   (as most time that is what you want)
>>> * No need for web developer to calculate selection start/end for
>>> setting it after text insert
>>> * preserve scroll
>>> * Has both Getter and Setter
>>> 
>>> Option 2 (textobj.setRangeText(start, end, text)); advantages
>>> * Independent of selection, web developer can change text at any range
>>>   with out affecting selection
>>> * Web developer has more options with it.
>>> * preserve scroll
>>> 
>>> So I want to merge both suggestion, with a new signature,
>>> also trying to reduce coding for web developer "less code less bug"
>>> 
>>> textobj.setRangeText(newtext, start, end, cursorpos)
>>> 
>>> parameters:
>>> newtext
>>> - optional parameter
>>> - new text that will replace existing
>>> - if missing/null/undefined/NaN then default to ""
>>> 
>>> start
>>> - optional parameter
>>> - starting position of the original textobj text that need to be
>> replaced
>>> - if missing/null/undefined/NaN then default to textobj.selectionStart
>>> - negative value make start position from last character in the text
>> content
>>> 
>>> end
>>> - optional parameter
>>> - ending position of the original textobj text that need to be replaced
>>> - if missing/null/undefined/NaN then default to textobj.selectionEnd
>>> - negative value make end position from last character
>>> 
>>> cursorpos
>>> - optional parameter
>>> - if missing/null/undefined/NaN then default to 0
>>> - what should happen to cursor/selection after text insert, its values
>> are
>>> - - 0 - select the newly inserted text
>>> - - 1 - place cursor at beginning of inserted text
>>> - - 2 - place cursor at the end of inserted text
>>> - - 3 - keep selection unaffected
>>> * issue, when value is 3 what should we do when setRangeText is
>> replacing text
>>> which has some parts selected and some other parts unselected
>>> 
>>> 
>>> so if somebody want replace selection text it is just
>>>     textobj.setRangeText(newtext);
>>> which is almost same as my original proposal, and
>>>     textobj.setRangeText();
>>> will blank a selection
>> 
>> That seems a bit overly complicated, but something in that vein seems
>> reasonable.
>> 
>> I've added
>> 
>>  setRangeText(newText); // replace selection with newText
>>  setRangeText(newText, start, end); // replace given range with newText
>>  setRangeText(newText, start, end, action); // see below
>> 
>> ...where action is one of:
>> 
>>  'select': selects the new text
>>  'start': selects empty range at start of new text
>>  'end': selects empty range at end of new text
>>  'preserve': (default) set selection as follows:
>> 
>>   - if selection start was before range, leave as is
>>   - if selection start was after the old range, put it as far from the
>>     end of the new range as it was from the end of the old range
>>   - if selection start was in the old range, move it to the start of the
>>     new range
>> 
>>   - if selection end was before range, leave as is
>>   - if selection end was after the old range, put it as far from the
>>     end of the new range as it was from the end of the old range
>>   - if selection emd was in the old range, move it to the end of the
>>     new range
>> 
>> 
>>> We could also add a getter method, also with optional parameters
>>>     textobj.getRangeText(start, end)
>>> so,
>>> textobj.getRangeText() gives current selection
>>> textobj.getRangeText(0) gives from start of text to current selection end
>>> textobj.getRangeText(null, -1) gives from current selection start to end
>> of text
>> 
>> Getting the text from a range is already rather simple (as demonstrated at
>> the top of this e-mail), so I don't think that's necessary.
>> 
>> --
>> Ian Hickson               U+1047E                )\._.,--....,'``.    fL
>> http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
>> Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
>> 




More information about the whatwg mailing list