Caret position confused after backspace delete, leading to erroneous further deletions (part 2)
Categories
(Core :: DOM: Editor, defect)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox-esr115 | --- | unaffected |
| firefox-esr140 | --- | fixed |
| firefox146 | --- | wontfix |
| firefox147 | --- | verified |
| firefox148 | --- | verified |
People
(Reporter: masayuki, Assigned: masayuki)
References
(Regression)
Details
(Keywords: regression)
Attachments
(6 files)
|
48 bytes,
text/x-phabricator-request
|
Details | Review | |
|
48 bytes,
text/x-phabricator-request
|
phab-bot
:
approval-mozilla-beta+
|
Details | Review |
|
48 bytes,
text/x-phabricator-request
|
phab-bot
:
approval-mozilla-esr140+
|
Details | Review |
|
3.68 MB,
video/mp4
|
Details | |
|
1.21 MB,
video/mp4
|
Details | |
|
898.56 KB,
video/mp4
|
Details |
Oddly, we still reproduce the bug in attachment 9532874 [details] even though the similar tests in bug 2005895 pass.
Original report:
This happening in Firefox 140 ESR, but also current Nightly.
STR:
Open the attached HTML document.
Place the cursor into the third empty line.
Press backspace, observe the cursor position, press backspace again.
Actual:
After the first backspace the caret is at the beginning of the second line. (When run in Thunderbird, the cursor disappears completely.)
After the second backspace, the full stop (.) at the end of the second line is deleted.
Variation:
Open the attached HTML document.
Place the cursor into the third empty line.
Press backspace, observe the cursor position, type a letter.
Again, after the first backspace, the cursor location is confused, typing a letter goes back to the third line.
Expected:
After the first backspace, the caret should be at the end of the second line.
Alice, is this a regression? This erroneous behaviour seems new.
| Assignee | ||
Comment 1•2 months ago
|
||
Okay, the remaining issue is the case that a white-space only Text is there between the paragraphs like:
<p>abc<br> </p> <p>{}<br></p>
| Assignee | ||
Comment 2•2 months ago
|
||
The remaining case of bug 2005895 is, there is a invisible Text
between paragraphs like:
<p>abc</p> <p>{}<br></p>
The reason is, HTMLEditUtils::GetPreviousContent is not called with
WalkTreeOption::IgnoreWhiteSpaceOnlyText. Therefore, I tried to
add the option in AutoEmptyBlockAncestorDeleter::GetNewCaretPosition.
However, the handling is odd [1]:
static bool IsContentIgnored(const nsIContent& aContent,
const WalkTreeOptions& aOptions) {
<snip>
if (aOptions.contains(WalkTreeOption::IgnoreWhiteSpaceOnlyText) &&
aContent.IsText() &&
const_cast<Text*>(aContent.AsText())->TextIsOnlyWhitespace()) {
return true;
}
So, whether the Text is actually visible or not is not tested.
Therefore, this does not work with preformatted content. However, I'd
like to uplift this to ESR140 so that it's too risky to change the
extant HTMLEditUtils implementation. Therefore, this patch makes
GetNewCaretPosition ignore invisible Text nodes directly.
| Assignee | ||
Comment 3•2 months ago
•
|
||
FYI: HTMLEditUtils::IsContentIgnored will be removed in bug 1996500.
| Assignee | ||
Comment 6•2 months ago
|
||
FYI: I'll request uplifts tomorrow.
Comment 7•2 months ago
|
||
| bugherder | ||
| Assignee | ||
Comment 8•2 months ago
|
||
| Assignee | ||
Comment 9•2 months ago
|
||
The remaining case of bug 2005895 is, there is a invisible Text
between paragraphs like:
<p>abc</p> <p>{}<br></p>
The reason is, HTMLEditUtils::GetPreviousContent is not called with
WalkTreeOption::IgnoreWhiteSpaceOnlyText. Therefore, I tried to
add the option in AutoEmptyBlockAncestorDeleter::GetNewCaretPosition.
However, the handling is odd [1]:
static bool IsContentIgnored(const nsIContent& aContent,
const WalkTreeOptions& aOptions) {
<snip>
if (aOptions.contains(WalkTreeOption::IgnoreWhiteSpaceOnlyText) &&
aContent.IsText() &&
const_cast<Text*>(aContent.AsText())->TextIsOnlyWhitespace()) {
return true;
}
So, whether the Text is actually visible or not is not tested.
Therefore, this does not work with preformatted content. However, I'd
like to uplift this to ESR140 so that it's too risky to change the
extant HTMLEditUtils implementation. Therefore, this patch makes
GetNewCaretPosition ignore invisible Text nodes directly.
Original Revision: https://phabricator.services.mozilla.com/D277498
Updated•2 months ago
|
Comment 10•2 months ago
|
||
firefox-beta Uplift Approval Request
- User impact if declined: If the initial content of
contenteditableordesignModeis created with source file, paragraphs may be separated with whitespaces like:
<p>
foo
</p>
<p>
<br>
</p>
(the line break after the first </p>). In this case, Backspace from the second paragraph does not work. This may block developers to write tests, etc.
- Code covered by automated testing: yes
- Fix verified in Nightly: yes
- Needs manual QE test: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: low
- Explanation of risk level: This patch just does: when considering the new caret position after deleting empty paragraph, this patch makes the code ignore the invisible
Textnode and look for another leaf node again. - String changes made/needed: no
- Is Android affected?: yes
| Assignee | ||
Comment 11•2 months ago
|
||
The remaining case of bug 2005895 is, there is a invisible Text
between paragraphs like:
<p>abc</p> <p>{}<br></p>
The reason is, HTMLEditUtils::GetPreviousContent is not called with
WalkTreeOption::IgnoreWhiteSpaceOnlyText. Therefore, I tried to
add the option in AutoEmptyBlockAncestorDeleter::GetNewCaretPosition.
However, the handling is odd [1]:
static bool IsContentIgnored(const nsIContent& aContent,
const WalkTreeOptions& aOptions) {
<snip>
if (aOptions.contains(WalkTreeOption::IgnoreWhiteSpaceOnlyText) &&
aContent.IsText() &&
const_cast<Text*>(aContent.AsText())->TextIsOnlyWhitespace()) {
return true;
}
So, whether the Text is actually visible or not is not tested.
Therefore, this does not work with preformatted content. However, I'd
like to uplift this to ESR140 so that it's too risky to change the
extant HTMLEditUtils implementation. Therefore, this patch makes
GetNewCaretPosition ignore invisible Text nodes directly.
Original Revision: https://phabricator.services.mozilla.com/D277498
Updated•2 months ago
|
Comment 12•2 months ago
|
||
firefox-esr140 Uplift Approval Request
- User impact if declined: If the initial content of contenteditable or designMode is created with source file, paragraphs may be separated with whitespaces like:
<p>
foo
</p>
<p>
<br>
</p>
(the line break after the first </p>). In this case, Backspace from the second paragraph does not work. This may block developers to write tests, etc.
NOTE: Unfortunately, the white-space:pre cases do not pass in ESR140. It must have been fixed in 141 or later, but not uplifted. Anyway, the case is not important because of non-realistic case.
- Code covered by automated testing: yes
- Fix verified in Nightly: yes
- Needs manual QE test: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: low
- Explanation of risk level: This patch just does: when considering the new caret position after deleting empty paragraph, this patch makes the code ignore the invisible
Textnode and look for another leaf node again. - String changes made/needed: no
- Is Android affected?: yes
Updated•2 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Updated•2 months ago
|
Comment 14•2 months ago
|
||
| uplift | ||
Comment 15•2 months ago
|
||
| uplift | ||
Comment 16•2 months ago
•
|
||
I've verified on the latest Nightly build (148.0a1 from 2025-12-29) using a Samsung Galaxy S25 Ultra with the following result:
- On both versions of verification, the caret remains on the same third line after the first backspace, but unlike before when on the second backspace it jumped to a line between the third and the second, now after the second backspace, the caret is on the end of the second line.
- In case of the second version, after deleting the letter with the backspace, the next backspace gets the caret to the end of the second line.
Marking the ticket as verified on 148.
Updated•2 months ago
|
Comment 17•2 months ago
|
||
As this fix appeared among the uplifted bugs for Beta 8, I did check the behavior on the latest Beta as well, giving that the uplift appeared 2 days ago, and Beta 8 appeared 10 hours ago. But it seems like the behavior is still the same as before. Should this be checked on Beta 9? Thank you!
| Assignee | ||
Comment 18•2 months ago
|
||
That's wired. I cannot reproduce this bug anymore even on Android within Nightly (with ATOK Pro nor Gboard). If you don't use wrong build to check, I think you find another bug.
Comment 19•2 months ago
|
||
Re-verified on the latest Nightly build (148.0a1 from 2025-12-29) and on the latest Beta (147.0b8) build.
Devices used:
- Samsung Galaxy Note 10 (Android 12);
- OnePlus 13R (Android 15);
- Google Pixel 7 (Android 16).
Marking the ticket as verified on 147 and 148.
Updated•2 months ago
|
Description
•