Currently, Gecko is the only browser engine which supports multiple selection ranges.
When user makes a non-collapsed selection range by dragging a mouse or "Select All", Gecko splits the range to multiple ones to exclude non-selectable elements. E.g., if you do "Select All" in a bug page, over 30 selection ranges will be created even if there is only comment#0.
However, some web apps do not handle multiple ranges correctly.
They assume that they need to handle only one range which is
returned by `getSelection().getRangeAt(0)`. When the
apps use `::before`/`::after`
pseudo-elements and/or `user-select:none`, only the
first range before such non-selectable content will be handled and
the latter content will be ignored.
To improve the compatibility around this, Gecko will stop
splitting the user's selection range automatically. Instead, the
layout module stops painting non-selectable content as selected by
itself. And non-selectable elements won't be contained in the
clipboard data when you copy the range containing them nor in the
result of `getSelection().toString()`. However, the
result of `getSelection().getRangeAt(0).toString()`
will start containing the non-selectable content.
Gecko has already stopped doing this when the web apps use Selection API. Therefore, the painting result after selecting non-selectable elements with Selection API may be changing. However, the painting results become consistent with the source of selection and more compatible with Chrome.
Note that this change does not mean Gecko stops
supporting multiple selection ranges. Can be create multiple
selection ranges with selecting content with Ctrl or Command key
press or `getSelection().addRange()` without `getSelection().removeAllRanges()`.
Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1998858
Specification: N/A
Platform coverage: All platforms
Preference: dom.selection.exclude_non_selectable_nodes
DevTools bug: N/A
Other browsers: Do not support multiple selection ranges so that they won't split user's selection range
web-platform-tests: N/A (there are tons of incompatibility at edge cases, but testing with a lot of mochitests)
-- Masayuki Nakano <masa...@d-toybox.com> Working on DOM, Events, editor and IME handling for Gecko
Instead, the layout module stops painting non-selectable content as selected by itself.
Oh, I forgot to ask a11y team, sorry.
On Fri, Nov 21, 2025 at 12:39 PM Masayuki Nakano <masa...@d-toybox.com> wrote:
Instead, the layout module stops painting non-selectable content as selected by itself.
Does this include content marked with CSS user-select: none?
When accessibility clients (like screen readers) select a range of text, they don't necessarily know that there is non-selectable content in the middle, so they just select the entire range. Because of this, we apparently have a bug in Firefox where if you select a range of text with VoiceOver and that range contains non-selectable content, the visually painted selection includes the non-selectable content, even though it isn't copied to the clipboard. I'm wondering whether this change will "fix" this bug.
Oh, sounds nice. That should be fixed by the patches in the next Nightly build.
--
You received this message because you are subscribed to the Google Groups "dev-pl...@mozilla.org" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dev-platform...@mozilla.org.
To view this discussion visit https://groups.google.com/a/mozilla.org/d/msgid/dev-platform/8e324215-bbea-4a77-9016-f4bf0c286d01%40d-toybox.com.
I don't know if this is reasonable, but I see some interesting compatibility challenges here.
Take:
That selects over a pilcrow that is in a <span> marked with `user-select: none`. Edge presently returns '7841.¶\n\nInformation' when asking for the selection. That seems consistent with your `getSelection().getRangeAt(0).toString()` variant. Firefox does not include the pilcrow OR the line feed characters. Firefox presently returns '7841.Information'. What do you expect to happen with the change? (There's a long-standing open bug on not including the line feed characters when copying content like this that I'd love to see fixed, FWIW. https://bugzilla.mozilla.org/show_bug.cgi?id=1832443)
Well, the serialization is managed by the serializer module which is currently maintained by Edgar. According to his comment in the review, we ignore "user-select:none" contents. I don't know whether this is reasonable or not. From point of view of the rendering result, not containing them is reasonable because they are painted as not selected. From point of view of the some users, they may want the non-selectable content in the clipboard data since they selected across the non-selectable nodes.
On the other hand, the range across the boundaries of the paragraphs. Then, I think it should be reasonable to contain the line break before "Information". And with the fix, the line break is also copied into the clipboard.
When Gecko splits a user selected range to multiple ranges, Gecko started 2nd or latter range from following leaf content. I guess that that the cause of not copying the line break caused by the new paragraph. Gecko will ignore non-selectable nodes at serialization so that the block boundaries won't be lost.