Bug 7275 - window.getSelection() doesn't work in textareas
Summary: window.getSelection() doesn't work in textareas
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: DOM (show other bugs)
Version: 420+
Hardware: Macintosh OS X 10.4
: P2 Major
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-02-15 08:40 PST by Steven Tamm
Modified: 2011-06-01 04:46 PDT (History)
7 users (show)

See Also:


Attachments
test case (same as is pasted as text in comments below) (1.38 KB, text/html)
2008-04-15 15:16 PDT, Eric Seidel (no email)
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Steven Tamm 2006-02-15 08:40:34 PST
window.getSelection() returns null when the selection is in a text area.  This behavior makes it very difficult when there are two text areas on the page.  Since the selection for a text area remains when you leave it, you have no idea which one of the text areas is the current (or last one) selected.

In the latest nightly build, when I try the page below, if you select the "Random Text" and then click dump range, you will get a real range object.  If you select the "My text" inside the text area, you get null for a range object.  You can fake it using getSelectionRange, but that doesn't work.  

1.  Select "text" inside the text area
2.  Select "random" 
3.  Click "Copy TextArea Sel".  This contains the last selection.  Even though random was selected.

If I would add another text area, I would have no idea what the user has selected

<html>
<head>
<meta http-equiv="Content-type" content="text/html" />
<title>Simple Selection Test</title>
<script>
function dumpO(o) {
  var msg = "";
  var i = 0;
  for (var f in o) {
    try {
      msg += f + " = " + o[f] + "\n";
    } catch (e) {}
    if (i++ == 10) {
       i=0;
       alert(msg);
       msg = "";
    }
  }
  if (msg) alert(msg);
}
function getSelectionRange(o) {
  var start = o.selectionStart;
  var end = o.selectionEnd;
  return o.value.substring(start,end);
}

</script>
</head>
<body>
<button onclick="document.getElementById('r').innerHTML =
	  window.getSelection();"><u>Copy Window Sel</u></button><br>
<button onclick="document.getElementById('r').innerHTML =
		 getSelectionRange(document.getElementById('text'));"><u>Copy
		 TextArea Sel</u></button><br>
<button onclick="dumpO(window.getSelection());"><u>Dump Selection</u></button><br>
<button onclick="dumpO(window.getSelection().getRangeAt(0));"><u>Dump Range</u></button><br>
<button onclick="document.getElementById('r').innerHTML = window.getSelection().getRangeAt(0);"><u>Copy Range</u></button><br>
<button onclick="dumpO(document.getElementById('text'));"><u>Dump TextArea</u></button><br>
<button onclick="dumpO(window);"><u>Dump Window</u></button><br>
<textarea id="text" name="text" rows="20" cols="80"/>
My text</textarea>
<div id="r">divMe</div>
Random Text
</body>
</html>
Comment 1 Alexey Proskuryakov 2006-02-15 12:17:40 PST
Confirming as a difference between Firefox and WebKit, but I am not sure what the correct approach would be.

In Firefox, window.getSelection() returns a collapsed range positioned before the TEXTAREA (HTMLBodyElement, offset 22 in your example). This doesn't look right to me - that is an entirely different position, and the insertion point can easily be moved there in contenteditable mode.

TEXTAREA has a child text node - perhaps it would be more appropriate to make window.getSelection() return the actual range within this text node?

BTW, you can probably use onfocus/onblur handlers to track the last focused textarea.
Comment 2 Steven Tamm 2006-06-30 12:11:16 PDT
> BTW, you can probably use onfocus/onblur handlers to track the last focused
textarea.

This didn't work with 418 because onblur didn't get called appropriately when you click on a button
Comment 3 David Gatwood 2007-05-25 16:21:23 PDT
This fails similarly for anything set to contentEditable, too.  I've been smashing my head against a wall over this bug off and on for months.

Comment 4 Alexey Proskuryakov 2007-12-29 13:26:35 PST
(In reply to comment #3)
> This fails similarly for anything set to contentEditable, too. 

Could you please provide a test case (preferably, in a new bug, to keep this one focused on textareas)? This seems to work correctly to me.
Comment 5 Eric Seidel (no email) 2008-04-15 15:16:02 PDT
Created attachment 20565 [details]
test case (same as is pasted as text in comments below)
Comment 6 Xan Lopez 2011-06-01 04:46:48 PDT
FWIW, I recently stumbled upon this bug and I think nowadays we do what comment #1 (from 2006!) says Firefox used to do back then. The thing that makes this fail is DOMSelection.cpp:getRangeAt, which has a chunk like:


    if (Node* shadowAncestor = selectionShadowAncestor(m_frame)) {
        ContainerNode* container = shadowAncestor->parentNodeGuaranteedHostFree();
        int offset = shadowAncestor->nodeIndex();
        return Range::create(shadowAncestor->document(), container, offset, container, offset);
    }

triggered inside text areas (and that makes us return a 0-0 bogus range). If I just *remove* that code, my simple tests seem to work OK, but I'm sure that breaks something else somewhere.

Opinions?