зеркало из https://github.com/mozilla/gecko-dev.git
Bug 635618 part 5. Pass an optional argument to GetPriorNode and GetNextNode to limit the search. r=ehsan
This commit is contained in:
Родитель
44edffd080
Коммит
b4f48cf241
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче