Open Bug 552695 Opened 11 years ago Updated 2 years ago

DOM Range getClientRects returns questionable position inside wrapped text

Categories

(Core :: DOM: Core & HTML, defect, P5)

x86
Windows 7
defect

Tracking

()

UNCONFIRMED

People

(Reporter: wiredearp, Unassigned)

Details

Attachments

(1 file, 1 obsolete file)

4.69 KB, application/xhtml+xml
Details
User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.3 Safari/533.2
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.3a2pre) Gecko/20100228

ClientRect objects extracted from an editor with white-space:pre-wrap reports positions that are misaligned with the perceived position of the caret when the caret is placed immediately after the soft break that causes the line to wrap. This happens only when the selection is collapsed.

Reproducible: Always

Steps to Reproduce:
1. Create a contenteditable DIV with CSS white-space:pre-wrap.
2. Move the caret to the left side of the DIV - just next to the soft wrap.
3. Check out the clientrects associated to the current selection range.
Actual Results:  
Clientrect positions are misaligned with the carets perceived position on screen.

Expected Results:  
Clientrect objects should be tracking the visual position of the caret; even when the caret is positioned at this twisted bend in the document.

This may not technically be a bug, but the behaviour spoils the usefulness of this otherwise elegant API and it is certainly not easy to come up with a workaround.
Attached file Testcase XHTML (obsolete) —
For some reason your testcase doesn't show the marker on my trunk build...

Is the marker appearing at the end of the line instead of the beginning?

Part of the problem is that the text offset for the end of the line is the same text offset as the start of the next line, so a DOM Range isn't quite enough information to identify the caret position.
That is unfortunate. Testcase was created on a 1.9.3a1 XULRunner build and verified operational on a Firefox preview called Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.3a1) Gecko/20100208 MozillaDeveloperPreview/3.7a1

One positions the cursor in the contenteditable element. The marker appears to the left of the editable box at the vertical position of the line segment in which the caret is positioned. It is pointing to the current line in a "highlight active line" fashion. This works as expected for all positions of the caret, except when positioned at the beginning of a line segment (so that Arrow-Left will move it to the end of the previous segment). In this case, the marker points to the line ABOVE the blinking cursor.

> Part of the problem is that the text offset for the end of the line 
> is the same text offset as the start of the next line, so a DOM Range 
> isn't quite enough information to identify the caret position.

That is essentially the substance of the "bug". I wish for this feature to inform me about the caret position at all times. At first I figured it was doable by cross-referencing focusOffset with the index of the ghostly entities that wrap the lines (entities and indexes that are unknown to Javascript) and simply increment the clientrect position by current lineheight. But I see your point, this place is a singularity. So maybe you can dig into the gizmokeeper in charge of painting the cursor :) In any case, any semi-hacked adjustment to the clientrect position may be justified by the oddness of current behaviour. Incoming attachment will debug clientrect position values in addition to positioning the marker.
Attached file Testcase XHTML updated
Adding textual output of clientrect position.
Attachment #432838 - Attachment is obsolete: true
Anne, see comments #2 and #3.

I think we need new API here, but I'm not sure if it belongs to CSSOM Views. Anne, there's no caret-position API hiding anywhere else, is there?

I almost wonder if we should add something to DOM Range here. Internally we have "before" and "after" hints to disambiguate situations where the caret positions differently depending on whether it's "before" or "after" a given text offset. Maybe DOM Range needs something like that. caretRangeFromPoint needs to return that information.
To get the current caret-position you can use the Selection interface defined by HTML5. DOM Range is in need of a rewrite (also to document some proprietary extensions everyone has), but nobody has volunteered so far.
The Selection object doesn't have any coordinate APIs, so it's not what we want here.

It sounds like this disambiguation problem simply hasn't been addressed yet. I think it should probably be "before or after" attribute on DOM Range. That would immediately solve the use-case in this bug and similar cases for Selection at the same time.
Component: DOM: Traversal-Range → DOM: Core & HTML
https://bugzilla.mozilla.org/show_bug.cgi?id=1472046

Move all DOM bugs that haven’t been updated in more than 3 years and has no one currently assigned to P5.

If you have questions, please contact :mdaly.
Priority: -- → P5
You need to log in before you can comment on or make changes to this bug.