Bug 1728433 - Make `WSScanResult::AssertIfInvalidData` check the ancestor block element if the reason is `CurrentBlockBoundary` r=m_kato

As the comment in the method, `CurrentBlockBoundary` may be set when `mContent`
is not a block.  However, it's not allowed that there is an editable block
ancestor of `mContent` in same editing host (in this case, `mContent` should be
the block).  Therefore, it should compute ancestor block element and check
whether it's not in same editing host if `mContent` is editable and connected.

Differential Revision: https://phabricator.services.mozilla.com/D190644
This commit is contained in:
Masayuki Nakano 2023-10-13 02:57:08 +00:00
Родитель 0cb91fe33e
Коммит 0b01d23e7a
2 изменённых файлов: 47 добавлений и 7 удалений

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

@ -141,13 +141,34 @@ class MOZ_STACK_CLASS WSScanResult final {
// there is no editable block parent, this is topmost editable inline
// content. Additionally, if there is no editable content, this is the
// container start of scanner and is not editable.
MOZ_ASSERT_IF(
mReason == WSType::CurrentBlockBoundary,
!mContent || !mContent->GetParentElement() ||
HTMLEditUtils::IsBlockElement(*mContent, aBlockInlineCheck) ||
HTMLEditUtils::IsBlockElement(*mContent->GetParentElement(),
aBlockInlineCheck) ||
!mContent->GetParentElement()->IsEditable());
if (mReason == WSType::CurrentBlockBoundary) {
if (!mContent ||
// Although not expected that scanning in orphan document fragment,
// it's okay.
!mContent->IsInComposedDoc() ||
// This is what the most preferred result is mContent itself is a
// block.
HTMLEditUtils::IsBlockElement(*mContent, aBlockInlineCheck) ||
// If mContent is not editable, we cannot check whether there is no
// block ancestor in the limiter which we don't have. Therefore,
// let's skip the ancestor check.
!mContent->IsEditable()) {
return;
}
const DebugOnly<Element*> closestAncestorEditableBlockElement =
HTMLEditUtils::GetAncestorElement(
*mContent, HTMLEditUtils::ClosestEditableBlockElement,
aBlockInlineCheck);
MOZ_ASSERT_IF(
mReason == WSType::CurrentBlockBoundary,
// There is no editable block ancestor, it's fine.
!closestAncestorEditableBlockElement ||
// If we found an editable block, but mContent can be inline if
// it's an editing host (root or its parent is not editable).
!closestAncestorEditableBlockElement->GetParentElement() ||
!closestAncestorEditableBlockElement->GetParentElement()
->IsEditable());
}
#endif // #ifdef DEBUG
}

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

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<script>
addEventListener("load", () => {
const object = document.querySelector("object[contenteditable]");
const mo = object.querySelector("mo");
const range = new Range();
document.replaceChildren();
range.insertNode(object);
object.replaceChild(mo, object.firstChild);
});
</script>
</head>
<object contenteditable>
<mo>
</mo>
</object>
</html>