Open Bug 1674359 Opened 4 years ago Updated 1 year ago

Can't move caret cursor focus after `<table>` in `contenteditable` element if `<table>` is the last element (nor before table when it's the first element)

Categories

(Core :: DOM: Editor, defect)

defect

Tracking

()

People

(Reporter: mbrodesser-Igalia, Unassigned)

References

(Blocks 2 open bugs)

Details

(4 keywords, Whiteboard: [enterprise-relevance])

User Story

Testcase (copy this into location bar):

data:text/html,<div contenteditable><table style="border:1px solid green"><tbody><tr><td>C1</td><td>C2</td></tr></tbody></table></div>

Simpler than bug 1247480 and presumably not exactly the same, hence this separate issue.

STR:

  1. Open data:text/html,<div contenteditable><table style="border:1px solid green"><tbody><tr><td>C1</td><td>C2</td></tr></tbody></table></div>
  2. Click at the end of the last table-cell.
  3. Try moving the caret with the arrow-right key or the mouse after the table.

Expected:
6) should succeed.

Actual:
6) doesn't succeed.

Works with Chrome.

Component: DOM: Selection → DOM: Editor
Assignee: nobody → mbrodesser
Severity: -- → S3

In this case, nsFrameSelection::MoveCaret doesn't move the caret.

A possible fix could be inserting an invisible <br>. IIRC, that's done in other cases too. However, unfortunately Gecko's behavior differs here from Chrome's, which is undesirable. Ideally, it seems, we should get rid of internally added invisible <br>s.

Masayuki: what do you think about the proposal? More context about invisible <br>s would be appreciated. I vaguely remember this topic having been mentioned before.

Flags: needinfo?(masayuki)
Assignee: mbrodesser → nobody

Although the caret is positioned at odd coordinates, this should be fixed in nsFrameSelection or layout code because this should occur is the caret browsing mode too and in that case, we cannot insert <br> element (anyway, I don't like to do it in editable element too).

On Chrome, I see caret at right of the table, and typing text is inserted after the table (i.e., appeared in the next new line) without paragraph. Perhaps, this is the only way to guarantee that we allow user to move caret outside the table and showing caret since the parent block of the table may have border or background and caret shouldn't be put outside of it.

Flags: needinfo?(masayuki)

(In reply to Masayuki Nakano [:masayuki] (he/him)(JST, +0900) from comment #2)

Although the caret is positioned at odd coordinates, this should be fixed in nsFrameSelection or layout code because this should occur is the caret browsing mode too and in that case, we cannot insert <br> element (anyway, I don't like to do it in editable element too).

Thanks, Masayuki.

On Chrome, I see caret at right of the table, and typing text is inserted after the table (i.e., appeared in the next new line) without paragraph. Perhaps, this is the only way to guarantee that we allow user to move caret outside the table and showing caret since the parent block of the table may have border or background and caret shouldn't be put outside of it.

:jfkthame: what do you think about the proposal? Moreover, if you support following Chrome's behavior, can you please point to the code areas which need adaptation?

Flags: needinfo?(jfkthame)

I guess Chrome's behavior is as reasonable as we can expect. When the caret appears to the right of the last table cell, it's not very clear to the user (IMO) that content will be inserted after the table rather than appended to the last cell, but there may not be any better way to do this. (On the one hand, it might seem preferable for the caret to appear below the table if the insertion position is outside it, but on the other hand there may not be any space there for a caret to appear.)

I'm not very familiar with all this code, but I think a starting point might be to look into what nsFrameSelection::PeekOffsetForCaretMove does when we're at the end of the table. We'd presumably want it to be able to step "up" the frame tree to return a selection that refers to the parent frame, even though this doesn't represent any change of position in terms of character offset within the document.

There's a similar issue at the beginning of the table, too: in Firefox, I can't move the caret before the table and insert content above it, whereas in Chrome I can.

Flags: needinfo?(jfkthame)

(In reply to Jonathan Kew (:jfkthame) from comment #4)

I guess Chrome's behavior is as reasonable as we can expect. When the caret appears to the right of the last table cell, it's not very clear to the user (IMO) that content will be inserted after the table rather than appended to the last cell, but there may not be any better way to do this. (On the one hand, it might seem preferable for the caret to appear below the table if the insertion position is outside it, but on the other hand there may not be any space there for a caret to appear.)

On Ubuntu, the size of the caret increases in Chrome, when it's outside of the table-cell. That's at least some indication to the user. I'm not sure if this would happen in Gecko too.

I'm not very familiar with all this code, but I think a starting point might be to look into what nsFrameSelection::PeekOffsetForCaretMove does when we're at the end of the table. We'd presumably want it to be able to step "up" the frame tree to return a selection that refers to the parent frame, even though this doesn't represent any change of position in terms of character offset within the document.

Thanks for suggestion. I'll have to develop a clearer understanding of the relation of the frames to the Selection instance, if that needs additional adaptation, or if that'll work automatically.

There's a similar issue at the beginning of the table, too: in Firefox, I can't move the caret before the table and insert content above it, whereas in Chrome I can.

Summary: Can't move focus after `<table>` in `contenteditable` element, when `<table>` is the last element → Can't move caret cursor focus after `<table>` in `contenteditable` element, when `<table>` is the last element (nor before table when it's the first element)
Summary: Can't move caret cursor focus after `<table>` in `contenteditable` element, when `<table>` is the last element (nor before table when it's the first element) → Can't move caret cursor focus after `<table>` in `contenteditable` element if `<table>` is the last element (nor before table when it's the first element)
Blocks: 1525576

Masayuki, I believe this needs pretty much exactly the same awesome behavior which you have implemented for links in
Bug 1357365 (great job!!!) - Cannot exit links in contenteditable elements, i.e. no way to place caret cursor outside <a href> element when there is no editable/navigable content before or after <a href>

Could you try the same approach here?

Thunderbird's message editor is much affected by this, also wrt enterprise use cases where inserting tables can be expected more frequently. As the ongoing duplicates and recent comments on the original bug 535475 (filed 12 years back) show, this continues to annoy users as the workarounds are clumsy. It's quite unexpected that after adding a table at the end of the message, there's no direct way to add more content after that. This implementation-level restriction makes users feel not in control as they have to spend extra time removing the table, adding other content like empty paragraphs, and then inserting the table in between (ux-implementation-level, ux-control, ux-efficiency).

Flags: needinfo?(masayuki)
Whiteboard: [enterprise-relevance]

Here's the link to bug 1357365 where Masayuki fixed the same problem with links (<a href="...">).

Mirko, could you update your testcase in comment 1 with the border style which makes the problem more apparent?

data:text/html,<div contenteditable><table style="border:1px solid green"><tbody><tr><td>C1</td><td>C2</td></tr></tbody></table></div>

User Story: (updated)
Flags: needinfo?(mbrodesser)
See Also: → 1357365

See comment 2 and comment 4. From point of view of editor module, working on this requires layout to allow caret to be right after a <table>. (I'm not familiar with nsFrameSelection::PeekOffsetForCaretMove, and I don't have much time to investigate the new area for me.

Flags: needinfo?(masayuki)

It seems that there is same problem for <hr> too.

Checking briefly:

So, perhaps, adding special case here to make selection being collapsed after <table> allowed. However, I'm not sure it's enough to paint caret because of unsupported position from point of view of caret.

(In reply to Thomas D. (:thomas8) from comment #11)

Here's the link to bug 1357365 where Masayuki fixed the same problem with links (<a href="...">).

Mirko, could you update your testcase in comment 1 with the border style which makes the problem more apparent?

data:text/html,<div contenteditable><table style="border:1px solid green"><tbody><tr><td>C1</td><td>C2</td></tr></tbody></table></div>

Done. Thanks for the updated testcase.

Flags: needinfo?(mbrodesser)

The severity field for this bug is relatively low, S3. However, the bug has 6 duplicates.
:hsinyi, could you consider increasing the bug severity?

For more information, please visit auto_nag documentation.

Flags: needinfo?(htsai)

(In reply to Release mgmt bot [:suhaib / :marco/ :calixte] from comment #18)

The severity field for this bug is relatively low, S3. However, the bug has 6 duplicates.
:hsinyi, could you consider increasing the bug severity?

For more information, please visit auto_nag documentation.

Yup, there are several duplicates (and some are old), however I don't see breakages in the wild for Firefox users from the reports. So it looks sensible for me to keep S3 for now.

Flags: needinfo?(htsai)

(In reply to Hsin-Yi Tsai (Fx104 REO) [:hsinyi] from comment #19)

Yup, there are several duplicates (and some are old), however I don't see breakages in the wild for Firefox users from the reports. So it looks sensible for me to keep S3 for now.

It's been affecting Thunderbird for about 13 years at least (see bug 535475). I'm guessing there might not be too many reports in Firefox because editing HTML with contenteditable isn't used as commonly as it is in Thunderbird, where composing messages is one of the main features.

(In reply to Bruno Harbulot from comment #20)

(In reply to Hsin-Yi Tsai (Fx104 REO) [:hsinyi] from comment #19)

Yup, there are several duplicates (and some are old), however I don't see breakages in the wild for Firefox users from the reports. So it looks sensible for me to keep S3 for now.

It's been affecting Thunderbird for about 13 years at least (see bug 535475). I'm guessing there might not be too many reports in Firefox because editing HTML with contenteditable isn't used as commonly as it is in Thunderbird, where composing messages is one of the main features.

FYI: Thunderbird can avoid this bug with putting <br> element when it (newly) inserts a <table> element.

13 years and still broken. Yes, it's not critical, but it's so frustrating when it happens.

Often you can get around it by manually putting in breaks before pasting in a table.

But I was just going to forward a "message blocked" email, and the last thing in it is a table. If I hit forward, I have no way to pre-fill blank lines, so I can't add any info after the table. I've got to manually copy and paste the email, and then I lose all the forwarded headers.

It just seems incredibly dumb, and surely something that could be fixed by appending a <br> after a table - even if that was a menu option from the table properties popup. Anything!

You need to log in before you can comment on or make changes to this bug.