Bug 1411687 - part 1: HTMLEditor::GetBlockNodeParent() and HTMLEditor::GetBlock() should take an ancestor limiter node optionally r?m_kato
Perhaps, most callers don't need parent block outside active editing host.
Therefore, callers of these methods should be able to specify the editing
host for making those methods stop looking for a block ancestor.
Then, callers can avoid using EditorUtils::IsDescendantOf() and
nsContentUtils::IsContentDescendantOf().
MozReview-Commit-ID: 7IK4gAVHY5d
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -743,38 +743,58 @@ HTMLEditor::IsBlockNode(nsINode* aNode)
{
return aNode && NodeIsBlockStatic(aNode);
}
/**
* GetBlockNodeParent returns enclosing block level ancestor, if any.
*/
Element*
-HTMLEditor::GetBlockNodeParent(nsINode* aNode)
+HTMLEditor::GetBlockNodeParent(nsINode* aNode,
+ nsINode* aAncestorLimiter)
{
MOZ_ASSERT(aNode);
+ MOZ_ASSERT(!aAncestorLimiter ||
+ aNode == aAncestorLimiter ||
+ EditorUtils::IsDescendantOf(aNode, aAncestorLimiter),
+ "aNode isn't in aAncestorLimiter");
+
+ // The caller has already reached the limiter.
+ if (aNode == aAncestorLimiter) {
+ return nullptr;
+ }
nsCOMPtr<nsINode> p = aNode->GetParentNode();
while (p) {
if (NodeIsBlockStatic(p)) {
return p->AsElement();
}
+ // Now, we have reached the limiter, there is no block in its ancestors.
+ if (p == aAncestorLimiter) {
+ return nullptr;
+ }
p = p->GetParentNode();
}
return nullptr;
}
/**
* Returns the node if it's a block, otherwise GetBlockNodeParent
*/
Element*
-HTMLEditor::GetBlock(nsINode& aNode)
+HTMLEditor::GetBlock(nsINode& aNode,
+ nsINode* aAncestorLimiter)
{
+ MOZ_ASSERT(!aAncestorLimiter ||
+ &aNode == aAncestorLimiter ||
+ EditorUtils::IsDescendantOf(&aNode, aAncestorLimiter),
+ "aNode isn't in aAncestorLimiter");
+
if (NodeIsBlockStatic(&aNode)) {
return aNode.AsElement();
}
return GetBlockNodeParent(&aNode);
}
/**
* IsNextCharInNodeWhitespace() checks the adjacent content in the same node to
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -180,19 +180,30 @@ public:
/**
* This sets background on the appropriate container element (table, cell,)
* or calls into nsTextEditor to set the page background.
*/
nsresult SetCSSBackgroundColor(const nsAString& aColor);
nsresult SetHTMLBackgroundColor(const nsAString& aColor);
- // Block methods moved from EditorBase
- static Element* GetBlockNodeParent(nsINode* aNode);
- static Element* GetBlock(nsINode& aNode);
+ /**
+ * GetBlockNodeParent() returns parent or nearest ancestor of aNode if
+ * there is a block parent. If aAncestorLimiter is not nullptr,
+ * this stops looking for the result.
+ */
+ static Element* GetBlockNodeParent(nsINode* aNode,
+ nsINode* aAncestorLimiter = nullptr);
+ /**
+ * GetBlock() returns aNode itself, or parent or nearest ancestor of aNode
+ * if there is a block parent. If aAncestorLimiter is not nullptr,
+ * this stops looking for the result.
+ */
+ static Element* GetBlock(nsINode& aNode,
+ nsINode* aAncestorLimiter = nullptr);
void IsNextCharInNodeWhitespace(nsIContent* aContent,
int32_t aOffset,
bool* outIsSpace,
bool* outIsNBSP,
nsIContent** outNode = nullptr,
int32_t* outOffset = 0);
void IsPrevCharInNodeWhitespace(nsIContent* aContent,