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)).

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.

If implementers are okay with this, I'll update the spec.

Reply via email to