Closed Bug 1475232 Opened 5 years ago Closed 1 year ago

Up/Down causes cursor jump inside "contenteditable=true" with "display: flex" or "display: grid"


(Core :: DOM: Editor, defect, P3)

61 Branch



103 Branch
Tracking Status
firefox63 --- wontfix
firefox103 --- fixed


(Reporter: kevin, Assigned: martinh, NeedInfo)


(Blocks 1 open bug)


(Whiteboard: [h2review-noted])


(1 file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.1 Safari/605.1.15

Steps to reproduce:

See basic reproduction case here:

1. Create a `<div contenteditable="true" id="main"></div>` element
2. Apply flex styles to the div: `#main {display: flex; flex-direction: column}`
3. Add `<p>` child elements with text
4. Place the cursor in the contenteditable region
5. Use Up/Down arrow keys to move the cursor

Note that the following styling also demonstrates the problem: `#main {display: flex; flex-direction: row; flex-wrap: wrap}`

Actual results:

When the cursor reaches the edge of a child element the cursor jumps to the beginning or end (depending whether Up or Down key was pressed) of the whole contenteditable element.

Expected results:

The cursor moves naturally to the next vertical element. Chrome/Safari behave as expected.
Component: Untriaged → Editor
Ever confirmed: true
Priority: -- → P3
Product: Firefox → Core
See Also: → 1216483
The same thing happens for CSS Grid, too, FWIW:

Kinda good news: in both cases, the right/left-arrow keys *do* seem to move between sections naturally (to the next vertical element when pressed at the beginning/end of a section).  It's just the up/down-arrow keys that do a confusing thing.  So we've got the internal "previous/next" mapping correct, but our up/down logic just doesn't understand what is up/down.
Summary: Up/Down causes cursor jump inside "contenteditable=true" with "display: flex" → Up/Down causes cursor jump inside "contenteditable=true" with "display: flex" or "display: grid"
nsIFrame::PeekOffset with eSelectLine cannot found better frame (nsFrame::GetLineNumber cannot return better frame, or nsFrame::GetNextPrevLineFromeBlockFrame doesn't return NS_OK...). I suspect GetNextPrevLineFromeBlockFrame, but I don't know root cause.
Whiteboard: [h2review-noted]

If this occurs with non-editable elements in the caret browning mode, this should be moved to DOM: Selection component.

Also bug 1216483

The problem was that GetNextPrevLineFromeBlockFrame correctly identified the target frame but in case it was a flex/grid container, PeekOffsetForLine didn't accept it as a valid result due to a missing line iterator.

There was an existing case which handled this similarly for a table target, drilling into a first child with line iterator, but it was also incomplete.

Extended the drill condition for flex/grid and made the drilling algorithm more robust to be able to also crawl siblings and skip non-selectable elements (e.g. :before pseudoelement)

Assignee: nobody → martinh
Flags: needinfo?(martinh)
Pushed by
When next line selection moves to a valid frame without line iterator, drill down to a first selectable child with line iterator r=emilio
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 103 Branch
You need to log in before you can comment on or make changes to this bug.