Bug 635618 part 5. Pass an optional argument to GetPriorNode and GetNextNode to limit the search. r=ehsan

This commit is contained in:
Boris Zbarsky 2011-11-28 07:54:32 -05:00
Родитель 44edffd080
Коммит b4f48cf241
3 изменённых файлов: 92 добавлений и 38 удалений

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

@ -3150,7 +3150,8 @@ nsEditor::GetPriorNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing)
bool bNoBlockCrossing,
nsIContent *aActiveEditorRoot)
{
// just another version of GetPriorNode that takes a {parent, offset}
// instead of a node
@ -3165,13 +3166,15 @@ nsEditor::GetPriorNode(nsIDOMNode *aParentNode,
// if we aren't allowed to cross blocks, don't look before this block
return NS_OK;
}
return GetPriorNode(aParentNode, aEditableNode, aResultNode, bNoBlockCrossing);
return GetPriorNode(aParentNode, aEditableNode, aResultNode,
bNoBlockCrossing, aActiveEditorRoot);
}
// else look before the child at 'aOffset'
nsCOMPtr<nsIDOMNode> child = GetChildAt(aParentNode, aOffset);
if (child)
return GetPriorNode(child, aEditableNode, aResultNode, bNoBlockCrossing);
return GetPriorNode(child, aEditableNode, aResultNode, bNoBlockCrossing,
aActiveEditorRoot);
// unless there isn't one, in which case we are at the end of the node
// and want the deep-right child.
@ -3180,17 +3183,19 @@ nsEditor::GetPriorNode(nsIDOMNode *aParentNode,
return NS_OK;
// restart the search from the non-editable node we just found
nsCOMPtr<nsIDOMNode> notEditableNode = do_QueryInterface(*aResultNode);
return GetPriorNode(notEditableNode, aEditableNode, aResultNode, bNoBlockCrossing);
nsCOMPtr<nsIDOMNode> notEditableNode = *aResultNode;
return GetPriorNode(notEditableNode, aEditableNode, aResultNode,
bNoBlockCrossing, aActiveEditorRoot);
}
nsresult
nsEditor::GetNextNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing)
PRInt32 aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing,
nsIContent *aActiveEditorRoot)
{
// just another version of GetNextNode that takes a {parent, offset}
// instead of a node
@ -3232,7 +3237,8 @@ nsEditor::GetNextNode(nsIDOMNode *aParentNode,
// restart the search from the non-editable node we just found
nsCOMPtr<nsIDOMNode> notEditableNode = do_QueryInterface(*aResultNode);
return GetNextNode(notEditableNode, aEditableNode, aResultNode, bNoBlockCrossing);
return GetNextNode(notEditableNode, aEditableNode, aResultNode,
bNoBlockCrossing, aActiveEditorRoot);
}
// unless there isn't one, in which case we are at the end of the node
@ -3242,7 +3248,8 @@ nsEditor::GetNextNode(nsIDOMNode *aParentNode,
// don't cross out of parent block
return NS_OK;
}
return GetNextNode(aParentNode, aEditableNode, aResultNode, bNoBlockCrossing);
return GetNextNode(aParentNode, aEditableNode, aResultNode, bNoBlockCrossing,
aActiveEditorRoot);
}
@ -3250,23 +3257,38 @@ nsresult
nsEditor::GetPriorNode(nsIDOMNode *aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing)
bool bNoBlockCrossing,
nsIContent *aActiveEditorRoot)
{
if (!aCurrentNode || !aResultNode) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsINode> currentNode = do_QueryInterface(aCurrentNode);
if (!IsDescendantOfBody(currentNode) ||
(aActiveEditorRoot &&
!nsContentUtils::ContentIsDescendantOf(currentNode,
aActiveEditorRoot))) {
*aResultNode = nsnull;
return NS_OK;
}
*aResultNode =
do_QueryInterface(FindNode(currentNode, false, aEditableNode, bNoBlockCrossing));
do_QueryInterface(FindNode(currentNode, false, aEditableNode,
bNoBlockCrossing, aActiveEditorRoot));
return NS_OK;
}
nsIContent*
nsEditor::FindNextLeafNode(nsINode *aCurrentNode,
bool aGoForward,
bool bNoBlockCrossing)
bool bNoBlockCrossing,
nsIContent *aActiveEditorRoot)
{
// called only by GetPriorNode so we don't need to check params.
NS_PRECONDITION(IsDescendantOfBody(aCurrentNode) && !IsRootNode(aCurrentNode),
NS_PRECONDITION(IsDescendantOfBody(aCurrentNode) && !IsRootNode(aCurrentNode) &&
(!aActiveEditorRoot ||
nsContentUtils::ContentIsDescendantOf(aCurrentNode,
aActiveEditorRoot)),
"Bogus arguments");
nsINode* cur = aCurrentNode;
@ -3300,7 +3322,8 @@ nsEditor::FindNextLeafNode(nsINode *aCurrentNode,
"if we ever hit the root, so we better have a descendant of "
"root now!");
if (IsRootNode(parent) ||
(bNoBlockCrossing && IsBlockNode(parent))) {
(bNoBlockCrossing && IsBlockNode(parent)) ||
parent == aActiveEditorRoot) {
return nsnull;
}
@ -3315,13 +3338,23 @@ nsresult
nsEditor::GetNextNode(nsIDOMNode *aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing)
bool bNoBlockCrossing,
nsIContent *aActiveEditorRoot)
{
if (!aCurrentNode || !aResultNode) { return NS_ERROR_NULL_POINTER; }
nsCOMPtr<nsINode> currentNode = do_QueryInterface(aCurrentNode);
if (!IsDescendantOfBody(currentNode) ||
(aActiveEditorRoot &&
!nsContentUtils::ContentIsDescendantOf(currentNode,
aActiveEditorRoot))) {
*aResultNode = nsnull;
return NS_OK;
}
*aResultNode =
do_QueryInterface(FindNode(currentNode, true, aEditableNode, bNoBlockCrossing));
do_QueryInterface(FindNode(currentNode, true, aEditableNode,
bNoBlockCrossing, aActiveEditorRoot));
return NS_OK;
}
@ -3329,9 +3362,10 @@ nsIContent*
nsEditor::FindNode(nsINode *aCurrentNode,
bool aGoForward,
bool aEditableNode,
bool bNoBlockCrossing)
bool bNoBlockCrossing,
nsIContent *aActiveEditorRoot)
{
if (IsRootNode(aCurrentNode))
if (IsRootNode(aCurrentNode) || aCurrentNode == aActiveEditorRoot)
{
// Don't allow traversal above the root node! This helps
// prevent us from accidentally editing browser content
@ -3341,7 +3375,8 @@ nsEditor::FindNode(nsINode *aCurrentNode,
}
nsIContent* candidate =
FindNextLeafNode(aCurrentNode, aGoForward, bNoBlockCrossing);
FindNextLeafNode(aCurrentNode, aGoForward, bNoBlockCrossing,
aActiveEditorRoot);
if (!candidate) {
return nsnull;
@ -3351,7 +3386,8 @@ nsEditor::FindNode(nsINode *aCurrentNode,
return candidate;
}
return FindNode(candidate, aGoForward, aEditableNode, bNoBlockCrossing);
return FindNode(candidate, aGoForward, aEditableNode, bNoBlockCrossing,
aActiveEditorRoot);
}
already_AddRefed<nsIDOMNode>

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

@ -373,7 +373,8 @@ protected:
// helper for GetPriorNode and GetNextNode
nsIContent* FindNextLeafNode(nsINode *aCurrentNode,
bool aGoForward,
bool bNoBlockCrossing);
bool bNoBlockCrossing,
nsIContent *aActiveEditorRoot);
// Get nsIWidget interface
nsresult GetWidget(nsIWidget **aWidget);
@ -474,18 +475,22 @@ public:
* @param aResultNode [OUT] the node that occurs before aCurrentNode in the tree,
* skipping non-editable nodes if aEditableNode is true.
* If there is no prior node, aResultNode will be nsnull.
* @param bNoBlockCrossing If true, don't move across "block" nodes, whatever that means.
* @param aActiveEditorRoot If non-null, only return descendants of aActiveEditorRoot.
*/
nsresult GetPriorNode(nsIDOMNode *aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing = false);
bool bNoBlockCrossing = false,
nsIContent *aActiveEditorRoot = nsnull);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetPriorNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing = false);
bool bNoBlockCrossing = false,
nsIContent *aActiveEditorRoot = nsnull);
/** get the node immediately after to aCurrentNode
* @param aCurrentNode the node from which we start the search
@ -497,20 +502,23 @@ public:
nsresult GetNextNode(nsIDOMNode *aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing = false);
bool bNoBlockCrossing = false,
nsIContent *aActiveEditorRoot = nsnull);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetNextNode(nsIDOMNode *aParentNode,
PRInt32 aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing = false);
bool bNoBlockCrossing = false,
nsIContent *aActiveEditorRoot = nsnull);
// Helper for GetNextNode and GetPriorNode
nsIContent* FindNode(nsINode *aCurrentNode,
bool aGoForward,
bool aEditableNode,
bool bNoBlockCrossing);
bool bNoBlockCrossing,
nsIContent *aActiveEditorRoot);
/**
* Get the rightmost child of aCurrentNode;
* return nsnull if aCurrentNode has no children.

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

@ -4706,13 +4706,18 @@ nsresult
nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing)
{
NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
nsresult res = GetPriorNode(inNode, true, address_of(*outNode), bNoBlockCrossing);
nsIContent* activeEditingHost = GetActiveEditingHost();
if (!activeEditingHost) {
*outNode = nsnull;
return NS_OK;
}
nsresult res = GetPriorNode(inNode, true, address_of(*outNode), bNoBlockCrossing, activeEditingHost);
NS_ENSURE_SUCCESS(res, res);
// if it's not in the body, then zero it out
if (*outNode && !IsNodeInActiveEditor(*outNode)) {
*outNode = nsnull;
}
NS_ASSERTION(!*outNode || IsNodeInActiveEditor(*outNode),
"GetPriorNode screwed up");
return res;
}
@ -4724,13 +4729,18 @@ nsresult
nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing)
{
NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
nsresult res = GetPriorNode(inParent, inOffset, true, address_of(*outNode), bNoBlockCrossing);
nsIContent* activeEditingHost = GetActiveEditingHost();
if (!activeEditingHost) {
*outNode = nsnull;
return NS_OK;
}
nsresult res = GetPriorNode(inParent, inOffset, true, address_of(*outNode), bNoBlockCrossing, activeEditingHost);
NS_ENSURE_SUCCESS(res, res);
// if it's not in the body, then zero it out
if (*outNode && !IsNodeInActiveEditor(*outNode)) {
*outNode = nsnull;
}
NS_ASSERTION(!*outNode || IsNodeInActiveEditor(*outNode),
"GetPriorNode screwed up");
return res;
}