Open Bug 1527627 Opened 5 years ago Updated 4 months ago

window.getSelection() and document.getSelection() do not work with selected text in an <input> element

Categories

(Core :: DOM: Selection, defect, P3)

65 Branch
defect

Tracking

()

UNCONFIRMED
Webcompat Priority P2

People

(Reporter: daniel.lee1ibm, Unassigned)

References

()

Details

(Keywords: parity-chrome, testcase)

Attachments

(1 file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36

Steps to reproduce:

https://jsbin.com/hixutufomu/edit?html,console,output

selected text in <input type=text /> and then asked for window.getSelection() or document.getSelection()

steps to reproduce:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<input type="text" id="one" />
<button onclick="getMySelection()">click for selection</button>
<script>
function getMySelection(){
var inputs= document.getElementById('one')
inputs.focus()
inputs.select()
console.log('document selection',document.getSelection().toString())
console.log('window selection',document.getSelection().toString())
console.log('active element selection',document.activeElement.value.substring(inputs.selectionStart,inputs.selectionEnd))
}
</script>
</body>
</html>

enter some text in the input and click on the button, the three console logs should be the same

tested on mac and windows, same results.
Other browsers perform normally (all three console.log's are the same)

Actual results:

results returned nothing

Expected results:

the selected text should have been printed in the console.log(window.getSelection().toString())

Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0
20190211233335

(In reply to daniel.lee1ibm from comment #0)

  console.log('active element selection',document.activeElement.value.substring(inputs.selectionStart,inputs.selectionEnd))

Actual results:

results returned nothing

This should almost certainly be marked as a duplicate of bug 85686. I refrained from doing so because the third method works for me, while you say it returned nothing.

Component: Untriaged → DOM: Core & HTML
Product: Firefox → Core
Summary: window.getSelection() and document.getSelection() do no work → window.getSelection() and document.getSelection() do not work with selected text in an <input> element

@Gingerbread Man,

Sorry for any confusion, let me be clear that the third method is the only one returning results, it is the work around I am forced to use.
console.log('active element selection',document.activeElement.value.substring(inputs.selectionStart,inputs.selectionEnd))

I was also tempted to not open this because of that bug however, 85686 specifically states that this is only an issue inside form fields while I am saying that this is an issue.....getSelection() does not work 100% of the time no matter where or when you call it.

(In reply to daniel.lee1ibm from comment #2)

getSelection() does not work 100% of the time no matter where or when you call it.

You used an input in your testcase, which is a form element. If I replace it with a p then it works for me. Also note that you used document.getSelection() twice where you apparently meant window.getSelection()

I rushed the code to open an issue, admittedly I made some mistakes, thanks for correcting them ^_^
With regards to the semantics of defining the element
"The input element represents a typed data field, usually with a form control to allow the user to edit the data"
(https://html.spec.whatwg.org/multipage/input.html#the-input-element)
in this case, there is no form control - simply a data field.

If you would like to close this bug as a duplicate of an 18 year old issue that has not been addressed, please feel free to do what you feel is best. Personally I don't mind, as long as one or the other is taken care of in the next 18 years.

But seriously, mdn says firefox supports getSelection (https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection)
It doesn't say, it's supported except for input elements, or partially, or unknown. At the very least, can we update that to reflect the reality of the past 2 decades?

I vote fix, but minimum should be to update the online documentation :) I also vote to close this as a duplicate, maybe it is better to show that this has been an ongoing issue since the Bill Clinton was president (but I still think it's a little different than what is described in 85686)

:masayuki would you be the right person to ask about this? I don't think the lack of form element is a relevant distinction from bug 85686.

:cmills any input on the aforementioned MDN article at comment 4?

Flags: needinfo?(masayuki)
Flags: needinfo?(cmills)

(In reply to Gingerbread Man from comment #5)

:masayuki would you be the right person to ask about this? I don't think the lack of form element is a relevant distinction from bug 85686.

I think that this is dup of it.

On the other hand, from point of view of Selection API, working on other browsers is really odd to me because Selection API cannot represent selection in <input>/<textarea> with DOM Range. So, we might need to treat Selection.toString() as special case.

IIRC, Boris was discussing selectionchange event on <input>/<textarea> because of not changing Range of Selection actually. So, he might know something more.

Flags: needinfo?(masayuki) → needinfo?(bzbarsky)

I think perhaps we do need to say something on the relevant MDN pages. We do say

"HTML inputs provide simpler helper APIs for working with selection (see HTMLInputElement.setSelectionRange())."

But perhaps we should say something like

"HTML inputs provide simpler helper APIs for working with selection (see HTMLInputElement.setSelectionRange()). In fact, the Selection API was not designed for selecting text inside input elements; trying to do so will not work reliably across browsers."

?

I am not 100% sure. Thoughts welcome.

Flags: needinfo?(cmills)

(In reply to Chris Mills (Mozilla, MDN editor) [:cmills] from comment #7)

"HTML inputs provide simpler helper APIs for working with selection (see HTMLInputElement.setSelectionRange()). In fact, the Selection API was not designed for selecting text inside input elements; trying to do so will not work reliably across browsers."

HTMLInputElement.select()
https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select

according to
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea%2Finput-select

will trigger HTMLInputElement.setSelectionRange(); which is, in fact, how I got to this issue.
I am setting text in an input, firing .select() which in turn fires the .setSelectionRange() and then asking the window or document to return the getSelection() but I am receiving nothing.

However on the input's .selectionStart and .selectionEnd I can see there is a value set. These facts seem to contradict each other. How can window.getSelection === document.getSelection() while at the same time input.selectionStart have a value?

input.select() is triggering the input.setSelectionRange, so why is getSelection not getting a value?

Per: https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selection
"The user agent should allow the user to change the active document's selection. If the user makes any modification to a selection, the user agent must create a new range with suitable start and end and associate the selection with this new range (not modify the existing range)."

I would think that making a "modification to a selection" vis input.select() would, in turn, "create a new range with a suitable start and end and associate the selection with this new range". I am getting the start and end, but not the associated selection.

From the docs I would infer that inputs may very well have a simpler API but the Selection API was designed to select text inside of input elements and allow the user to know what was selected on the window, document and document.activeElement objects.

I don't really have strong opinions here. We could in fact special-case Selection.toString for the case when the selected thing for the global selection is a single input element, and return the contents of the inputs internal selection instead... Is that something that we could get standardized?

Flags: needinfo?(bzbarsky)

(In reply to Boris Zbarsky [:bzbarsky, bz on IRC] from comment #9)

I don't really have strong opinions here. We could in fact special-case Selection.toString for the case when the selected thing for the global selection is a single input element, and return the contents of the inputs internal selection instead... Is that something that we could get standardized?

Looks like not standardized yet. Selection API is referred by WHATWG and it declares toString() as stringifier but there is no detail and there is a lik to a spec bug.

(In reply to Masayuki Nakano [:masayuki] (JST, +0900)(PTO: 2/13 and 2/14) from comment #10)

(In reply to Boris Zbarsky [:bzbarsky, bz on IRC] from comment #9)

I don't really have strong opinions here. We could in fact special-case Selection.toString for the case when the selected thing for the global selection is a single input element, and return the contents of the inputs internal selection instead... Is that something that we could get standardized?

Looks like not standardized yet. Selection API is referred by WHATWG and it declares toString() as stringifier but there is no detail and there is a lik to a spec bug.

Standardizing would be nice, but defacto behavior parity is also a worthwhile consideration. I think I'll update the relevant pages to say that this currently doesn;t work in Firefox, and HTMLInputElement.setSelectionRange() could be used as a workaround.

(In reply to Chris Mills (Mozilla, MDN editor) [:cmills] from comment #11)

Standardizing would be nice, but defacto behavior parity is also a worthwhile consideration. I think I'll update the relevant pages to say that this currently doesn;t work in Firefox, and HTMLInputElement.setSelectionRange() could be used as a workaround.

I was hoping to clarify something on this point - the selection is being set when using the standard HTMLInputElement.select().

The issue is not with that method, it's with the result of it the window/document.getSelection().
The work around that I found is to use the

document.activeElement.value.substring(document.activeElement.selectionStart,document.activeElement.selectionEnd))

This method would not work if the selection range was not already set.

Priority: -- → P3
See Also: → 85686
Webcompat Priority: --- → ?
Component: DOM: Core & HTML → DOM: Selection

This can break a lot of sites, but we don't have known reported massive breakages about this. Maybe people just don't understand how this is broken when it is happening.

Webcompat Priority: ? → P2
Severity: normal → S3

https://w3c.github.io/selection-api/#dom-selection-stringifier says

If the selection is within a textarea or input element, it must return the selected substring in its value.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: