timdown / rangy

A cross-browser JavaScript range and selection library.
MIT License
2.24k stars 368 forks source link

getSelection() Returns inconsistent focusOffset and node across browsers #120

Open timdown opened 10 years ago

timdown commented 10 years ago

From hashm...@gmail.com on June 26, 2012 14:28:46

What steps will reproduce the problem? 1. Set up a key handler tracking left / right key inputs

  1. On each keypress, getSelection() and inspect the contents across browsers
  2. Particularly notice when moving from one node to another (text-caret right at node start) What is the expected output? What do you see instead? It'd be good to get the same data in each. For now:

Firefox : When text-caret as at start of node, returns focusOffset at 0 (this should be what happens), and on right retursn ix = length of text (also good) Webkit: ix = last of previous node - never returns on ix = 0.... but on right returns len of focusNode (not next) IE: On left, returns last of previous. On right, returns ix = 0 for next. What version of the product are you using? On what operating system? 1.2.3 Please provide any additional information below. Not high priority but it'd be better for rangy to adjust it rather than other code to

Original issue: http://code.google.com/p/rangy/issues/detail?id=120

timdown commented 10 years ago

From timd...@gmail.com on June 27, 2012 17:25:16

Well, this is a tricky thing. I've written about the dilemma of what to do about "correcting" selections several times. Here's a couple, and I'll try and find some more on the discussion group:

mightyiam commented 10 years ago

Thanks for excellent, useful software, Tim and everyone involved.

Down at WYMeditor, we're very impacted by this and I can imagine that many users of Rangy are, as well.

Ideally, the selection object should be normalized in Rangy, as much as possible. This is obvious. But I'm not aware of the challenges of doing that.

timdown commented 10 years ago

As noted above, I've written about this a few times and my view on this hasn't changed. I think I need to compile some kind of FAQ page. In the meantime, the most coherent thing I've written on this subject is in issue #3:

https://github.com/timdown/rangy/issues/3#issuecomment-38367900

Reporting ranges different to what the browser provides when querying the selection doesn't seem a viable option for Rangy because the browser's idea about the selection is definitive. For example, imagine trying to place the caret in the location shown by the pipe character below in a WebKit-flavoured browser such as Chrome:

 Here is some <b>|bold text</b>

You create a collapsed range inside the <b> element and add it to the selection. The browser, which has fixed ideas about what positions are allowed for selection boundaries (see WebKit issue 23189), moves your range to be immediately before the <b> element. This has real consequences: when the user next types a character, the character will be placed in the text node preceding <b> element rather than inside it. Obtaining the selection range via the native API or Rangy will reveal what the browser has done and calling code can therefore decide what to do about it; if Rangy reported some other range in the name of normalization then that is less helpful and a deception.

I can see an argument for normalizing the selection in the case of an editor in which all input and DOM manipulation is handled by editor code rather than native browser contenteditable behaviour, but Rangy has to be more general than that.

If you have particular cases in mind then I'm always open to discussing them

mightyiam commented 10 years ago

Thank you for the detailed explanation, Tim.

I still don't understand how the fact that some browsers move selections to other than what they were asked, would prevent Rangy from normalizing the returned selection object.

In order to be clear that we're on the same page here, I would like to point out that when I'm speaking of normalization I'm speaking of not what is described in the selection object but how it is described.

So, I'm talking about the fact that in some browsers the anchorNode and the focusNode are always an element and in other browsers they can be text nodes. This is what I'm talking about.

This is how we currently deal with this in WYMeditor.

Are we one the same page?

mightyiam commented 10 years ago

Also, I'd love to get comments on that piece of code, as it uses Rangy.

timdown commented 10 years ago

Apologies. I've been dealing with a number of Rangy issues and this one had fallen off my radar. I need to get more organized.

I think I understand the distinction you're making: for, say, the caret position <p>|Some text</p>, you'd always want that expressed as position 0 in the "Some text" text node rather than position 0 within the <p> element, since these positions are to all intents and purposes identical. Is that correct?