зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1627175 - part 54: Merge `HTMLEditor::Get(First|Last)EditableLeaf()` into `HTMLEditUtils::Get(First|Last)LeafContent()` r=m_kato
The different points are, whether it checks in a given element or not, and whether it ignores non-editable content. Therefore, this patch adds new `LeafNodeType` and new ancestor limiter argument. The new flag is not handled in the other methods which take `LeafNodeType` because there is no test. Differential Revision: https://phabricator.services.mozilla.com/D115123
This commit is contained in:
Родитель
d6eec3ae11
Коммит
249be2b40e
|
@ -568,12 +568,25 @@ class HTMLEditUtils final {
|
|||
// If there is a non-editable element if and only if scanning from editable
|
||||
// node, return it too.
|
||||
LeafNodeOrNonEditableNode,
|
||||
// Ignore non-editable content at walking the tree.
|
||||
OnlyEditableLeafNode,
|
||||
};
|
||||
using LeafNodeTypes = EnumSet<LeafNodeType>;
|
||||
static nsIContent* GetLastLeafContent(nsINode& aNode,
|
||||
const LeafNodeTypes& aLeafNodeTypes) {
|
||||
for (nsIContent* content = aNode.GetLastChild(); content;
|
||||
content = content->GetLastChild()) {
|
||||
static nsIContent* GetLastLeafContent(
|
||||
nsINode& aNode, const LeafNodeTypes& aLeafNodeTypes,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
MOZ_ASSERT_IF(
|
||||
aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode),
|
||||
!aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode));
|
||||
for (nsIContent* content = aNode.GetLastChild(); content;) {
|
||||
if (aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode) &&
|
||||
!EditorUtils::IsEditableContent(*content,
|
||||
EditorUtils::EditorType::HTML)) {
|
||||
content = HTMLEditUtils::GetPreviousContent(
|
||||
*content, {WalkTreeOption::IgnoreNonEditableNode},
|
||||
aAncestorLimiter);
|
||||
continue;
|
||||
}
|
||||
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrChildBlock) &&
|
||||
HTMLEditUtils::IsBlockElement(*content)) {
|
||||
return content;
|
||||
|
@ -585,6 +598,7 @@ class HTMLEditUtils final {
|
|||
aNode.IsEditable() && !content->IsEditable()) {
|
||||
return content;
|
||||
}
|
||||
content = content->GetLastChild();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -594,10 +608,21 @@ class HTMLEditUtils final {
|
|||
* on aLeafNodeTypes whether this scans into a block child or treat block as a
|
||||
* leaf.
|
||||
*/
|
||||
static nsIContent* GetFirstLeafContent(const nsINode& aNode,
|
||||
const LeafNodeTypes& aLeafNodeTypes) {
|
||||
for (nsIContent* content = aNode.GetFirstChild(); content;
|
||||
content = content->GetFirstChild()) {
|
||||
static nsIContent* GetFirstLeafContent(
|
||||
const nsINode& aNode, const LeafNodeTypes& aLeafNodeTypes,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
MOZ_ASSERT_IF(
|
||||
aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode),
|
||||
!aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode));
|
||||
for (nsIContent* content = aNode.GetFirstChild(); content;) {
|
||||
if (aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode) &&
|
||||
!EditorUtils::IsEditableContent(*content,
|
||||
EditorUtils::EditorType::HTML)) {
|
||||
content = HTMLEditUtils::GetNextContent(
|
||||
*content, {WalkTreeOption::IgnoreNonEditableNode},
|
||||
aAncestorLimiter);
|
||||
continue;
|
||||
}
|
||||
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrChildBlock) &&
|
||||
HTMLEditUtils::IsBlockElement(*content)) {
|
||||
return content;
|
||||
|
@ -609,6 +634,7 @@ class HTMLEditUtils final {
|
|||
aNode.IsEditable() && !content->IsEditable()) {
|
||||
return content;
|
||||
}
|
||||
content = content->GetFirstChild();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -632,6 +658,10 @@ class HTMLEditUtils final {
|
|||
const nsIContent& aStartContent, const nsIContent& aCurrentBlock,
|
||||
const LeafNodeTypes& aLeafNodeTypes,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
MOZ_ASSERT_IF(
|
||||
aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode),
|
||||
!aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode));
|
||||
|
||||
if (&aStartContent == aAncestorLimiter) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -691,6 +721,11 @@ class HTMLEditUtils final {
|
|||
const nsIContent& aCurrentBlock, const LeafNodeTypes& aLeafNodeTypes,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
MOZ_ASSERT(aStartPoint.IsSet());
|
||||
MOZ_ASSERT_IF(
|
||||
aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode),
|
||||
!aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode));
|
||||
NS_ASSERTION(!aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode),
|
||||
"Not implemented yet");
|
||||
|
||||
if (!aStartPoint.IsInContentNode()) {
|
||||
return nullptr;
|
||||
|
@ -759,6 +794,12 @@ class HTMLEditUtils final {
|
|||
const nsIContent& aStartContent, const nsIContent& aCurrentBlock,
|
||||
const LeafNodeTypes& aLeafNodeTypes,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
MOZ_ASSERT_IF(
|
||||
aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode),
|
||||
!aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode));
|
||||
NS_ASSERTION(!aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode),
|
||||
"Not implemented yet");
|
||||
|
||||
if (&aStartContent == aAncestorLimiter) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -818,6 +859,11 @@ class HTMLEditUtils final {
|
|||
const nsIContent& aCurrentBlock, const LeafNodeTypes& aLeafNodeTypes,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
MOZ_ASSERT(aStartPoint.IsSet());
|
||||
MOZ_ASSERT_IF(
|
||||
aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode),
|
||||
!aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode));
|
||||
NS_ASSERTION(!aLeafNodeTypes.contains(LeafNodeType::OnlyEditableLeafNode),
|
||||
"Not implemented yet");
|
||||
|
||||
if (!aStartPoint.IsInContentNode()) {
|
||||
return nullptr;
|
||||
|
|
|
@ -4932,42 +4932,6 @@ nsresult HTMLEditor::DeleteSelectionAndPrepareToCreateNode() {
|
|||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
nsIContent* HTMLEditor::GetFirstEditableLeaf(nsINode& aNode) const {
|
||||
Element* editingHost = GetActiveEditingHost();
|
||||
if (NS_WARN_IF(!editingHost) ||
|
||||
editingHost->IsInclusiveDescendantOf(&aNode)) {
|
||||
return nullptr;
|
||||
}
|
||||
nsIContent* child =
|
||||
HTMLEditUtils::GetFirstLeafContent(aNode, {LeafNodeType::OnlyLeafNode});
|
||||
while (child && (!EditorUtils::IsEditableContent(*child, EditorType::HTML) ||
|
||||
child->HasChildren())) {
|
||||
child = HTMLEditUtils::GetNextContent(
|
||||
*child, {WalkTreeOption::IgnoreNonEditableNode},
|
||||
aNode.IsElement() ? aNode.AsElement() : editingHost);
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
nsIContent* HTMLEditor::GetLastEditableLeaf(nsINode& aNode) const {
|
||||
Element* editingHost = GetActiveEditingHost();
|
||||
if (NS_WARN_IF(!editingHost) ||
|
||||
editingHost->IsInclusiveDescendantOf(&aNode)) {
|
||||
return nullptr;
|
||||
}
|
||||
nsIContent* child =
|
||||
HTMLEditUtils::GetLastLeafContent(aNode, {LeafNodeType::OnlyLeafNode});
|
||||
while (child && (!EditorUtils::IsEditableContent(*child, EditorType::HTML) ||
|
||||
child->HasChildren())) {
|
||||
child = HTMLEditUtils::GetPreviousContent(
|
||||
*child, {WalkTreeOption::IgnoreNonEditableNode},
|
||||
aNode.IsElement() ? aNode.AsElement() : editingHost);
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
bool HTMLEditor::IsEmpty() const {
|
||||
if (mPaddingBRElementForEmptyEditor) {
|
||||
return true;
|
||||
|
|
|
@ -917,9 +917,6 @@ class HTMLEditor final : public TextEditor,
|
|||
SplitAncestorStyledInlineElementsAt(const EditorDOMPoint& aPointToSplit,
|
||||
nsAtom* aProperty, nsAtom* aAttribute);
|
||||
|
||||
nsIContent* GetFirstEditableLeaf(nsINode& aNode) const;
|
||||
nsIContent* GetLastEditableLeaf(nsINode& aNode) const;
|
||||
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetInlinePropertyBase(
|
||||
nsAtom& aHTMLProperty, nsAtom* aAttribute, const nsAString* aValue,
|
||||
bool* aFirst, bool* aAny, bool* aAll, nsAString* outValue) const;
|
||||
|
|
|
@ -82,6 +82,7 @@ class nsISupports;
|
|||
namespace mozilla {
|
||||
|
||||
using namespace dom;
|
||||
using LeafNodeType = HTMLEditUtils::LeafNodeType;
|
||||
|
||||
#define kInsertCookie "_moz_Insert Here_moz_"
|
||||
|
||||
|
@ -353,8 +354,9 @@ HTMLEditor::HTMLWithContextInserter::GetNewCaretPointAfterInsertingHTML(
|
|||
// but don't cross tables
|
||||
nsIContent* containerContent = nullptr;
|
||||
if (!HTMLEditUtils::IsTable(aLastInsertedPoint.GetChild())) {
|
||||
containerContent =
|
||||
mHTMLEditor.GetLastEditableLeaf(*aLastInsertedPoint.GetChild());
|
||||
containerContent = HTMLEditUtils::GetLastLeafContent(
|
||||
*aLastInsertedPoint.GetChild(), {LeafNodeType::OnlyEditableLeafNode},
|
||||
aLastInsertedPoint.GetChild()->GetAsElementOrParentElement());
|
||||
if (containerContent) {
|
||||
Element* mostDistantInclusiveAncestorTableElement = nullptr;
|
||||
for (Element* maybeTableElement =
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace mozilla {
|
|||
using namespace dom;
|
||||
using EmptyCheckOption = HTMLEditUtils::EmptyCheckOption;
|
||||
using InvisibleWhiteSpaces = HTMLEditUtils::InvisibleWhiteSpaces;
|
||||
using LeafNodeType = HTMLEditUtils::LeafNodeType;
|
||||
using StyleDifference = HTMLEditUtils::StyleDifference;
|
||||
using TableBoundary = HTMLEditUtils::TableBoundary;
|
||||
using WalkTreeOption = HTMLEditUtils::WalkTreeOption;
|
||||
|
@ -2434,13 +2435,15 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
|||
|
||||
// First find the adjacent node in the block
|
||||
if (aDirectionAndAmount == nsIEditor::ePrevious) {
|
||||
mLeafContentInOtherBlock =
|
||||
aHTMLEditor.GetLastEditableLeaf(aOtherBlockElement);
|
||||
mLeafContentInOtherBlock = HTMLEditUtils::GetLastLeafContent(
|
||||
aOtherBlockElement, {LeafNodeType::OnlyEditableLeafNode},
|
||||
&aOtherBlockElement);
|
||||
mLeftContent = mLeafContentInOtherBlock;
|
||||
mRightContent = aCaretPoint.GetContainerAsContent();
|
||||
} else {
|
||||
mLeafContentInOtherBlock =
|
||||
aHTMLEditor.GetFirstEditableLeaf(aOtherBlockElement);
|
||||
mLeafContentInOtherBlock = HTMLEditUtils::GetFirstLeafContent(
|
||||
aOtherBlockElement, {LeafNodeType::OnlyEditableLeafNode},
|
||||
&aOtherBlockElement);
|
||||
mLeftContent = aCaretPoint.GetContainerAsContent();
|
||||
mRightContent = mLeafContentInOtherBlock;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче