Intent to change: Stop splitting user selected range to multiple ones for excluding non-selectable nodes

81 views
Skip to first unread message

Masayuki Nakano

unread,
Nov 20, 2025, 9:39:21 PM (2 days ago) Nov 20
to dev-pl...@mozilla.org

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

James Teh

unread,
Nov 20, 2025, 9:59:01 PM (2 days ago) Nov 20
to Masayuki Nakano, dev-pl...@mozilla.org
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.
Jamie

Masayuki Nakano

unread,
Nov 20, 2025, 10:09:02 PM (2 days ago) Nov 20
to James Teh, dev-pl...@mozilla.org

Oh, I forgot to ask a11y team, sorry.

On 11/21/2025 11:58 AM, 'James Teh' via dev-pl...@mozilla.org wrote:
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?
Yes, it does. Previously, they were not contained into the selection ranges by a user's operation, but were contained into them if the range is added by JS. Previously, the layout module does not consider whether painting selection highlight by itself. However, now, each frame checks whether the frame is selectable or not to stop painting as selected.
 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.

Martin Thomson

unread,
Nov 20, 2025, 11:26:56 PM (2 days ago) Nov 20
to Masayuki Nakano, dev-pl...@mozilla.org
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)


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

Masayuki Nakano

unread,
Nov 20, 2025, 11:42:29 PM (2 days ago) Nov 20
to Martin Thomson, dev-pl...@mozilla.org, Edgar Chen
On 11/21/2025 1:26 PM, Martin Thomson wrote:
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.

Reply all
Reply to author
Forward
0 new messages