Bug 1870222 - part 5: Make `HTMLEditor::ClearStyleAt` treat non-editable content as visible r=m_kato

Pasting and inserting HTML clears current style to respect the new style.
Therefore, the old ancestors shouldn't be removed when they have only
non-editable content.

Unfortunately, I have no idea how to test all of the paths which are changed
by this patch. However, I believe the method should always treat non-editable
content as visible.

Differential Revision: https://phabricator.services.mozilla.com/D196817
This commit is contained in:
Masayuki Nakano 2023-12-25 12:54:08 +00:00
Родитель 3a1fc63ab7
Коммит bc25bfb070
2 изменённых файлов: 18 добавлений и 10 удалений

Просмотреть файл

@ -2347,8 +2347,7 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::ClearStyleAt(
*unwrappedSplitNodeResult.GetPreviousContent(), *unwrappedSplitNodeResult.GetPreviousContent(),
{EmptyCheckOption::TreatSingleBRElementAsVisible, {EmptyCheckOption::TreatSingleBRElementAsVisible,
EmptyCheckOption::TreatListItemAsVisible, EmptyCheckOption::TreatListItemAsVisible,
EmptyCheckOption::TreatTableCellAsVisible, EmptyCheckOption::TreatTableCellAsVisible})) {
EmptyCheckOption::TreatNonEditableContentAsInvisible})) {
AutoTrackDOMPoint trackPointToPutCaret(RangeUpdaterRef(), &pointToPutCaret); AutoTrackDOMPoint trackPointToPutCaret(RangeUpdaterRef(), &pointToPutCaret);
// Delete previous node if it's empty. // Delete previous node if it's empty.
// MOZ_KnownLive(unwrappedSplitNodeResult.GetPreviousContent()): // MOZ_KnownLive(unwrappedSplitNodeResult.GetPreviousContent()):
@ -2430,8 +2429,7 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::ClearStyleAt(
if (HTMLEditUtils::IsEmptyNode( if (HTMLEditUtils::IsEmptyNode(
*unwrappedSplitResultAtStartOfNextNode.GetNextContent(), *unwrappedSplitResultAtStartOfNextNode.GetNextContent(),
{EmptyCheckOption::TreatListItemAsVisible, {EmptyCheckOption::TreatListItemAsVisible,
EmptyCheckOption::TreatTableCellAsVisible, EmptyCheckOption::TreatTableCellAsVisible},
EmptyCheckOption::TreatNonEditableContentAsInvisible},
&seenBR)) { &seenBR)) {
if (seenBR && !brElement) { if (seenBR && !brElement) {
brElement = HTMLEditUtils::GetFirstBRElement( brElement = HTMLEditUtils::GetFirstBRElement(
@ -2530,8 +2528,7 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::ClearStyleAt(
*unwrappedSplitResultAtStartOfNextNode.GetNextContent(), *unwrappedSplitResultAtStartOfNextNode.GetNextContent(),
{EmptyCheckOption::TreatSingleBRElementAsVisible, {EmptyCheckOption::TreatSingleBRElementAsVisible,
EmptyCheckOption::TreatListItemAsVisible, EmptyCheckOption::TreatListItemAsVisible,
EmptyCheckOption::TreatTableCellAsVisible, EmptyCheckOption::TreatTableCellAsVisible})) {
EmptyCheckOption::TreatNonEditableContentAsInvisible})) {
// MOZ_KnownLive because the result is grabbed by // MOZ_KnownLive because the result is grabbed by
// unwrappedSplitResultAtStartOfNextNode. // unwrappedSplitResultAtStartOfNextNode.
nsresult rv = DeleteNodeWithTransaction(MOZ_KnownLive( nsresult rv = DeleteNodeWithTransaction(MOZ_KnownLive(
@ -2550,16 +2547,14 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::ClearStyleAt(
else if (HTMLEditUtils::IsEmptyNode( else if (HTMLEditUtils::IsEmptyNode(
*unwrappedSplitResultAtStartOfNextNode.GetNextContent(), *unwrappedSplitResultAtStartOfNextNode.GetNextContent(),
{EmptyCheckOption::TreatListItemAsVisible, {EmptyCheckOption::TreatListItemAsVisible,
EmptyCheckOption::TreatTableCellAsVisible, EmptyCheckOption::TreatTableCellAsVisible})) {
EmptyCheckOption::TreatNonEditableContentAsInvisible})) {
AutoTArray<OwningNonNull<nsIContent>, 4> emptyInlineContainerElements; AutoTArray<OwningNonNull<nsIContent>, 4> emptyInlineContainerElements;
HTMLEditUtils::CollectEmptyInlineContainerDescendants( HTMLEditUtils::CollectEmptyInlineContainerDescendants(
*unwrappedSplitResultAtStartOfNextNode.GetNextContentAs<Element>(), *unwrappedSplitResultAtStartOfNextNode.GetNextContentAs<Element>(),
emptyInlineContainerElements, emptyInlineContainerElements,
{EmptyCheckOption::TreatSingleBRElementAsVisible, {EmptyCheckOption::TreatSingleBRElementAsVisible,
EmptyCheckOption::TreatListItemAsVisible, EmptyCheckOption::TreatListItemAsVisible,
EmptyCheckOption::TreatTableCellAsVisible, EmptyCheckOption::TreatTableCellAsVisible},
EmptyCheckOption::TreatNonEditableContentAsInvisible},
BlockInlineCheck::UseComputedDisplayOutsideStyle); BlockInlineCheck::UseComputedDisplayOutsideStyle);
for (const OwningNonNull<nsIContent>& emptyInlineContainerElement : for (const OwningNonNull<nsIContent>& emptyInlineContainerElement :
emptyInlineContainerElements) { emptyInlineContainerElements) {

Просмотреть файл

@ -590,4 +590,17 @@ var browserTests = [
"<div class=\"d1\"></div><div class=\"d2\"><span class=\"s1\">some text</span><a href=\"foo.html\"></a></div>", "<div class=\"d1\"></div><div class=\"d2\"><span class=\"s1\">some text</span><a href=\"foo.html\"></a></div>",
[true], [true],
{"inserthtml":[false,false,"",false,false,""]}], {"inserthtml":[false,false,"",false,false,""]}],
// Do not delete non-editable when clearing the original style
["<p><b>[X]<span contenteditable=false>abc</span></b><i>def</i></p>",
[["inserthtml","<i>Z</i>"]],
"<p><i>Z</i><b><span contenteditable=\"false\">abc</span></b><i>def</i></p>",
[true],
{}],
["<p><b><span contenteditable=false>abc</span>[Y]</b><i>def</i></p>",
[["inserthtml","<i>Z</i>"]],
["<p><b><span contenteditable=\"false\">abc</span></b><i>Z</i><i>def</i></p>",
"<p><b><span contenteditable=\"false\">abc</span></b><i>Zdef</i></p>"],
[true],
{}],
] ]