Re: [editing] Avoiding selections with no corresponding range, to simplify authoring
On Wed, Jan 11, 2012 at 8:41 AM, Aryeh Gregor a...@aryeh.name wrote: Anne asked me to investigate how exactly Ranges are added to Selections (bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=15470). It turns out browsers mostly don't interoperate. One interesting thing I found out is that in Gecko, if no one calls addRange/removeRange/removeAllRanges, rangeCount is always exactly one. This means getRangeAt(0) will never throw. This is actually great, because it avoids a common authoring bug -- rangeCount is rarely 0 in any browser, so authors often will call getRangeAt(0) unconditionally, which risks throwing IndexSizeError. I plan to change the spec to match Gecko, in requiring that user-created selections always have exactly one range (which is initially collapsed at (document, 0)). Does gecko returns a Range at (document, 0) for getRange(0) in such cases? I'd like to go further, though. addRange() already doesn't allow more than one range per spec -- if there's an existing range, it replaces it. How about removeRange() and removeAllRanges() remove the range and then add a new one collapsed at (document, 0)? The common pattern of remove(All)Range(s) followed by addRange will still work the same, because addRange will replace the dummy range. But now rangeCount will *always* be 1, so getRangeAt(0) will *never* throw. This seems like it would prevent an entire class of authoring bugs (although I'm admittedly not totally sure about compat impact). Also, while I'm at it, how about collapsing at (document.documentElement, 0) instead of (document, 0)? This has the minor added benefit of avoiding Selection boundary points that aren't in an Element or Text node, which again makes things simpler for authors. This would change the behavior of removing ranges in design mode. Removing the range will move the caret to the top of the document. - Ryosuke
Re: [editing] Avoiding selections with no corresponding range, to simplify authoring
On 1/11/12 11:41 AM, Aryeh Gregor wrote: Also, while I'm at it, how about collapsing at (document.documentElement, 0) instead of (document, 0)? Then you have to handle the case when document.documentElement is null. And yes, this has come up before; there are scripts out there that remove documentElements, do some stuff, insert new documentElements, etc. This has the minor added benefit of avoiding Selection boundary points that aren't in an Element or Text node This would happen anyway if you set up a selection inside document.documentElement and someone removes the documentElement; the normal range algorithm will give you endpoints inside the Document. so you really can't enforce this condition. -Boris
Re: [editing] Avoiding selections with no corresponding range, to simplify authoring
On Wed, Jan 11, 2012 at 12:27 PM, Ryosuke Niwa rn...@webkit.org wrote: Does gecko returns a Range at (document, 0) for getRange(0) in such cases? Okay, it looks like my testing before was off. Actually, all browsers have no range in the selection initially. But I was testing in Live DOM Viewer, which didn't fully reset the document state when the source code changed, because not all browsers clear the selection's range on unload. I fixed the spec to require the range to initially be null (like all browsers), and specified that the range has to be reset to null when the document is unloaded (like IE/Opera, not like Gecko/WebKit): http://dvcs.w3.org/hg/editing/rev/6aaa4b8455c9 I also added a test for the latter condition, and filed a Gecko bug (WebKit is also now buggy per spec): http://dvcs.w3.org/hg/editing/raw-file/6aaa4b8455c9/selecttest/unload.html https://bugzilla.mozilla.org/show_bug.cgi?id=717339 Since we seem to have interop on the selection's rangeCount initially being 0, I'm no longer enthusiastic about changing that. I'm fine with leaving the spec as-is now, unless implementers would prefer to change. On Wed, Jan 11, 2012 at 11:54 AM, Boris Zbarsky bzbar...@mit.edu wrote: Then you have to handle the case when document.documentElement is null. And yes, this has come up before; there are scripts out there that remove documentElements, do some stuff, insert new documentElements, etc. . . . This would happen anyway if you set up a selection inside document.documentElement and someone removes the documentElement; the normal range algorithm will give you endpoints inside the Document. so you really can't enforce this condition. Well, yes, and you can also do addRange() with whatever you like. But we can at least try to make the condition rarer, so bugs are less likely to crop up in practice when authors inevitably write incorrect code. Anyway, as noted, I retract my suggestion for other reasons, unless someone else is still interested.