Open Bug 1514140 Opened 5 years ago Updated 2 years ago

Range.getClientRects returns wrong rect for selections starting at the end of an element

Categories

(Core :: DOM: CSS Object Model, defect, P3)

65 Branch
defect

Tracking

()

People

(Reporter: stef.busking, Unassigned)

References

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.14 Safari/537.36

Steps to reproduce:

See test case at https://codepen.io/Bwrrp/pen/VqeqLL

This is a single text node surrounded by a paragraph, which is surrounded by a div. Click the button to create a range starting directly after the text node and ending directly after the div. This will measure the range's bounds using Range.getClientRects and visualize the first rect using an absolutely positioned element. It will also use Range.toString to show the text within the range.


Actual results:

As demonstrated by the span showing the .toString result, this range contains no text at all. However, Firefox returns a single rect surrounding the entire paragraph.

Range.getBoundingClientRect returns the same rect.


Expected results:

Given that the range is empty, I would have expected either no rects being returned (as happens for a selection starting inside the text node directly after its text and ending after the container div), or possibly some rects near the end of this textnode and/or the container div. As is, the div returned is not a good representation of the range at all, as it gives the impression that the range covers the entire contents of the paragraph.
Reproducible, 

Build ID 	20181218191030
User Agent 	Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0
Status: UNCONFIRMED → NEW
Component: Untriaged → DOM: CSS Object Model
Ever confirmed: true
Product: Firefox → Core
So the spec is:

  https://drafts.csswg.org/cssom-view/#extensions-to-the-range-interface

Which says:

> For each element selected by the range, whose parent is not selected by the range, include the border areas returned by invoking getClientRects() on the element.

So given the range starts inside the element, and ends outside of the <p> element (and thus is selected), but the parent (the <div> element) is not selected by the range, we're adding the <p> element rects.

I guess the difference between Blink / WebKit and us ends up being whether we consider the <p> selected or not.

The concept of "being selected" is nowhere to be defined in the cssom-view spec, but so far what Gecko is doing makes sense to me...
Filed bug https://github.com/w3c/csswg-drafts/issues/3456 to get the "selected" part clarified in the spec, but let me know if I got something wrong.
Priority: -- → P3
I mainly filed this because the rects returned by the method are inconsistent with the area highlighted by the normal selection in this case. If the element would be considered "selected", shouldn't it also be covered by the selection's highlight?

We are using the rects returned by this method as a way to visualize the content covered by a given Range, including as a placeholder for the actual selection in cases where the editor does not have focus. The difference in this case is quite noticeable and confusing.
No, since the selection highlight is only drawn for text, not for arbitrary blocks...


In any case yeah, I see how this behavior is not terribly useful, though given what the spec says I think it's correct.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: