fix for 21412 - backspace wouldn't remove list items in html editor.

In addition some improvements were made to the adjustment of selection after an edit action (example: backspacing through a list item now pops you up to the previous item)


git-svn-id: svn://10.0.0.236/trunk@58013 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
jfrancis%netscape.com 2000-01-17 12:41:34 +00:00
parent aaed41e784
commit de4c509f39
8 changed files with 280 additions and 106 deletions

View File

@ -791,7 +791,17 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection,
{
nsCOMPtr<nsIDOMNode> nodeToDelete;
if (aAction == nsIEditor::ePrevious)
// first note that the right node to delete might be the one we
// are in. For example, if a list item is deleted one character at a time,
// eventually it will be empty (except for a moz-br). If the user hits
// backspace again, they expect the item itself to go away. Check to
// see if we are in an "empty" node.
// Note: do NOT delete table elements this way.
PRBool bIsEmptyNode;
res = IsEmptyNode(node, &bIsEmptyNode, PR_TRUE, PR_FALSE);
if (bIsEmptyNode && !mEditor->IsTableElement(node))
nodeToDelete = node;
else if (aAction == nsIEditor::ePrevious)
res = GetPriorHTMLNode(node, offset, &nodeToDelete);
else if (aAction == nsIEditor::eNext)
res = GetNextHTMLNode(node, offset, &nodeToDelete);
@ -1839,6 +1849,24 @@ nsHTMLEditRules::IsAnchor(nsIDOMNode *node)
}
///////////////////////////////////////////////////////////////////////////
// IsImage: true if node an html image node
//
PRBool
nsHTMLEditRules::IsImage(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsHTMLEditRules::IsImage");
nsAutoString tag;
nsEditor::GetTagString(node,tag);
tag.ToLowerCase();
if (tag == "img")
{
return PR_TRUE;
}
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// IsDiv: true if node an html div node
//
@ -3640,69 +3668,77 @@ nsHTMLEditRules::AdjustSelection(nsIDOMSelection *aSelection, nsIEditor::EDirect
}
}
// we aren't in a textnode: look for a nearby text node.
// we aren't in a textnode: are we adjacent to a break or an image?
res = GetPriorHTMLSibling(selNode, selOffset, &nearNode);
if (NS_FAILED(res)) return res;
if (nearNode && (IsBreak(nearNode) || IsImage(nearNode)))
return NS_OK; // this is a good place for the caret to be
res = GetNextHTMLSibling(selNode, selOffset, &nearNode);
if (NS_FAILED(res)) return res;
if (nearNode && (IsBreak(nearNode) || IsImage(nearNode)))
return NS_OK; // this is a good place for the caret to be
// look for a nearby text node.
// prefer the correct direction.
res = FindNearTextNode(selNode, selOffset, aAction, &nearNode);
res = FindNearSelectableNode(selNode, selOffset, aAction, &nearNode);
if (NS_FAILED(res)) return res;
// did we suceed in getting back a node?
nsIEditor::EDirection dir;
if (!nearNode)
{
// if not try again in other direction
dir = nsIEditor::eNext;
if (aAction == nsIEditor::eNext) dir = nsIEditor::ePrevious;
res = FindNearTextNode(selNode, selOffset, dir, &nearNode);
if (NS_FAILED(res)) return res;
}
else
{
dir = aAction;
}
// is the nearnode a text node?
if (!nearNode) return NS_OK; // couldn't find a near text node
// is the nearnode a text node?
textNode = do_QueryInterface(nearNode);
if (!textNode) return NS_ERROR_UNEXPECTED;
PRInt32 offset = 0;
// put selection in right place:
if (dir == nsIEditor::ePrevious)
textNode->GetLength((PRUint32*)&offset);
res = aSelection->Collapse(nearNode,offset);
if (NS_FAILED(res)) return res;
if (textNode)
{
PRInt32 offset = 0;
// put selection in right place:
if (aAction == nsIEditor::ePrevious)
textNode->GetLength((PRUint32*)&offset);
res = aSelection->Collapse(nearNode,offset);
}
else // must be break or image
{
res = nsEditor::GetNodeLocation(nearNode, &selNode, &selOffset);
if (NS_FAILED(res)) return res;
if (aAction == nsIEditor::ePrevious) selOffset++; // want to be beyond it if we backed up to it
res = aSelection->Collapse(selNode, selOffset);
}
return res;
}
nsresult
nsHTMLEditRules::FindNearTextNode(nsIDOMNode *aSelNode,
PRInt32 aSelOffset,
nsIEditor::EDirection aDirection,
nsCOMPtr<nsIDOMNode> *outTextNode)
nsHTMLEditRules::FindNearSelectableNode(nsIDOMNode *aSelNode,
PRInt32 aSelOffset,
nsIEditor::EDirection aDirection,
nsCOMPtr<nsIDOMNode> *outSelectableNode)
{
if (!aSelNode || !outTextNode) return NS_ERROR_NULL_POINTER;
*outTextNode = nsnull;
if (!aSelNode || !outSelectableNode) return NS_ERROR_NULL_POINTER;
*outSelectableNode = nsnull;
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> nearNode;
nsCOMPtr<nsIDOMNode> nearNode, curNode;
if (aDirection == nsIEditor::ePrevious)
res = GetPriorHTMLNode(aSelNode, aSelOffset, &nearNode);
else
res = GetNextHTMLNode(aSelNode, aSelOffset, &nearNode);
if (NS_FAILED(res)) return res;
// if there is no node then punt
if (!nearNode) return NS_OK;
// is nearNode also a descendant of same block?
nsCOMPtr<nsIDOMNode> block, nearBlock;
if (mEditor->IsBlockNode(aSelNode)) block = aSelNode;
else block = mEditor->GetBlockNodeParent(aSelNode);
if (mEditor->IsBlockNode(nearNode)) nearBlock = nearNode;
else nearBlock = mEditor->GetBlockNodeParent(nearNode);
if (block != nearBlock) return NS_OK; // punt - we dont want to jump across a block
// is the nearnode a text node?
nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(nearNode);
if (textNode) *outTextNode = nearNode;
// scan in the right direction until we find an eligible text node,
// but dont cross any breaks, images, or table elements.
while (nearNode && !(mEditor->IsTextNode(nearNode) || IsBreak(nearNode) || IsImage(nearNode)))
{
// dont cross any table elements
if (mEditor->IsTableElement(nearNode))
return NS_OK;
curNode = nearNode;
if (aDirection == nsIEditor::ePrevious)
res = GetPriorHTMLNode(curNode, &nearNode);
else
res = GetNextHTMLNode(curNode, &nearNode);
if (NS_FAILED(res)) return res;
}
if (nearNode) *outSelectableNode = do_QueryInterface(nearNode);
return res;
}

View File

@ -91,6 +91,7 @@ protected:
static PRBool IsOrderedList(nsIDOMNode *aNode);
static PRBool IsBlockquote(nsIDOMNode *aNode);
static PRBool IsAnchor(nsIDOMNode *aNode);
static PRBool IsImage(nsIDOMNode *aNode);
static PRBool IsDiv(nsIDOMNode *aNode);
static PRBool IsNormalDiv(nsIDOMNode *aNode);
static PRBool IsMozDiv(nsIDOMNode *aNode);
@ -143,10 +144,10 @@ protected:
nsresult AdjustSpecialBreaks();
nsresult AdjustWhitespace(nsIDOMSelection *aSelection);
nsresult AdjustSelection(nsIDOMSelection *aSelection, nsIEditor::EDirection aAction);
nsresult FindNearTextNode(nsIDOMNode *aSelNode,
PRInt32 aSelOffset,
nsIEditor::EDirection aDirection,
nsCOMPtr<nsIDOMNode> *outTextNode);
nsresult FindNearSelectableNode(nsIDOMNode *aSelNode,
PRInt32 aSelOffset,
nsIEditor::EDirection aDirection,
nsCOMPtr<nsIDOMNode> *outSelectableNode);
nsresult RemoveEmptyNodes();
nsresult DoTextNodeWhitespace(nsIDOMCharacterData *aTextNode, PRInt32 aStart, PRInt32 aEnd);
nsresult UpdateDocChangeRange(nsIDOMRange *aRange);

View File

@ -1579,7 +1579,7 @@ nsTextEditRules::DoTextInsertion(nsIDOMSelection *aSelection,
nsresult
nsTextEditRules::GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode)
{
if (!outNode) return NS_ERROR_NULL_POINTER;
if (!outNode || !inNode) return NS_ERROR_NULL_POINTER;
nsresult res = NS_OK;
*outNode = nsnull;
nsCOMPtr<nsIDOMNode> temp, node = do_QueryInterface(inNode);
@ -1588,7 +1588,7 @@ nsTextEditRules::GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *o
{
res = node->GetPreviousSibling(getter_AddRefs(temp));
if (NS_FAILED(res)) return res;
if (!temp) return NS_ERROR_FAILURE;
if (!temp) return NS_OK; // return null sibling
// if it's editable, we're done
if (mEditor->IsEditable(temp)) break;
// otherwise try again
@ -1600,6 +1600,30 @@ nsTextEditRules::GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *o
///////////////////////////////////////////////////////////////////////////
// GetPriorHTMLSibling: returns the previous editable sibling, if there is
// one within the parent. just like above routine but
// takes a parent/offset instead of a node.
//
nsresult
nsTextEditRules::GetPriorHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode)
{
if (!outNode || !inParent) return NS_ERROR_NULL_POINTER;
nsresult res = NS_OK;
*outNode = nsnull;
if (!inOffset) return NS_OK; // return null sibling if at offset zero
nsCOMPtr<nsIDOMNode> node = nsEditor::GetChildAt(inParent,inOffset-1);
if (mEditor->IsEditable(node))
{
*outNode = node;
return res;
}
// else
return GetPriorHTMLSibling(node, outNode);
}
///////////////////////////////////////////////////////////////////////////
// GetNextHTMLSibling: returns the next editable sibling, if there is
// one within the parent
@ -1628,6 +1652,30 @@ nsTextEditRules::GetNextHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *ou
///////////////////////////////////////////////////////////////////////////
// GetNextHTMLSibling: returns the next editable sibling, if there is
// one within the parent. just like above routine but
// takes a parent/offset instead of a node.
//
nsresult
nsTextEditRules::GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode)
{
if (!outNode || !inParent) return NS_ERROR_NULL_POINTER;
nsresult res = NS_OK;
*outNode = nsnull;
nsCOMPtr<nsIDOMNode> node = nsEditor::GetChildAt(inParent,inOffset);
if (!node) return NS_OK; // return null sibling if no sibling
if (mEditor->IsEditable(node))
{
*outNode = node;
return res;
}
// else
return GetPriorHTMLSibling(node, outNode);
}
///////////////////////////////////////////////////////////////////////////
// GetPriorHTMLNode: returns the previous editable leaf node, if there is
// one within the <body>

View File

@ -206,7 +206,9 @@ protected:
TypeInState aTypeInState);
nsresult GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);

View File

@ -791,7 +791,17 @@ nsHTMLEditRules::WillDeleteSelection(nsIDOMSelection *aSelection,
{
nsCOMPtr<nsIDOMNode> nodeToDelete;
if (aAction == nsIEditor::ePrevious)
// first note that the right node to delete might be the one we
// are in. For example, if a list item is deleted one character at a time,
// eventually it will be empty (except for a moz-br). If the user hits
// backspace again, they expect the item itself to go away. Check to
// see if we are in an "empty" node.
// Note: do NOT delete table elements this way.
PRBool bIsEmptyNode;
res = IsEmptyNode(node, &bIsEmptyNode, PR_TRUE, PR_FALSE);
if (bIsEmptyNode && !mEditor->IsTableElement(node))
nodeToDelete = node;
else if (aAction == nsIEditor::ePrevious)
res = GetPriorHTMLNode(node, offset, &nodeToDelete);
else if (aAction == nsIEditor::eNext)
res = GetNextHTMLNode(node, offset, &nodeToDelete);
@ -1839,6 +1849,24 @@ nsHTMLEditRules::IsAnchor(nsIDOMNode *node)
}
///////////////////////////////////////////////////////////////////////////
// IsImage: true if node an html image node
//
PRBool
nsHTMLEditRules::IsImage(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsHTMLEditRules::IsImage");
nsAutoString tag;
nsEditor::GetTagString(node,tag);
tag.ToLowerCase();
if (tag == "img")
{
return PR_TRUE;
}
return PR_FALSE;
}
///////////////////////////////////////////////////////////////////////////
// IsDiv: true if node an html div node
//
@ -3640,69 +3668,77 @@ nsHTMLEditRules::AdjustSelection(nsIDOMSelection *aSelection, nsIEditor::EDirect
}
}
// we aren't in a textnode: look for a nearby text node.
// we aren't in a textnode: are we adjacent to a break or an image?
res = GetPriorHTMLSibling(selNode, selOffset, &nearNode);
if (NS_FAILED(res)) return res;
if (nearNode && (IsBreak(nearNode) || IsImage(nearNode)))
return NS_OK; // this is a good place for the caret to be
res = GetNextHTMLSibling(selNode, selOffset, &nearNode);
if (NS_FAILED(res)) return res;
if (nearNode && (IsBreak(nearNode) || IsImage(nearNode)))
return NS_OK; // this is a good place for the caret to be
// look for a nearby text node.
// prefer the correct direction.
res = FindNearTextNode(selNode, selOffset, aAction, &nearNode);
res = FindNearSelectableNode(selNode, selOffset, aAction, &nearNode);
if (NS_FAILED(res)) return res;
// did we suceed in getting back a node?
nsIEditor::EDirection dir;
if (!nearNode)
{
// if not try again in other direction
dir = nsIEditor::eNext;
if (aAction == nsIEditor::eNext) dir = nsIEditor::ePrevious;
res = FindNearTextNode(selNode, selOffset, dir, &nearNode);
if (NS_FAILED(res)) return res;
}
else
{
dir = aAction;
}
// is the nearnode a text node?
if (!nearNode) return NS_OK; // couldn't find a near text node
// is the nearnode a text node?
textNode = do_QueryInterface(nearNode);
if (!textNode) return NS_ERROR_UNEXPECTED;
PRInt32 offset = 0;
// put selection in right place:
if (dir == nsIEditor::ePrevious)
textNode->GetLength((PRUint32*)&offset);
res = aSelection->Collapse(nearNode,offset);
if (NS_FAILED(res)) return res;
if (textNode)
{
PRInt32 offset = 0;
// put selection in right place:
if (aAction == nsIEditor::ePrevious)
textNode->GetLength((PRUint32*)&offset);
res = aSelection->Collapse(nearNode,offset);
}
else // must be break or image
{
res = nsEditor::GetNodeLocation(nearNode, &selNode, &selOffset);
if (NS_FAILED(res)) return res;
if (aAction == nsIEditor::ePrevious) selOffset++; // want to be beyond it if we backed up to it
res = aSelection->Collapse(selNode, selOffset);
}
return res;
}
nsresult
nsHTMLEditRules::FindNearTextNode(nsIDOMNode *aSelNode,
PRInt32 aSelOffset,
nsIEditor::EDirection aDirection,
nsCOMPtr<nsIDOMNode> *outTextNode)
nsHTMLEditRules::FindNearSelectableNode(nsIDOMNode *aSelNode,
PRInt32 aSelOffset,
nsIEditor::EDirection aDirection,
nsCOMPtr<nsIDOMNode> *outSelectableNode)
{
if (!aSelNode || !outTextNode) return NS_ERROR_NULL_POINTER;
*outTextNode = nsnull;
if (!aSelNode || !outSelectableNode) return NS_ERROR_NULL_POINTER;
*outSelectableNode = nsnull;
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> nearNode;
nsCOMPtr<nsIDOMNode> nearNode, curNode;
if (aDirection == nsIEditor::ePrevious)
res = GetPriorHTMLNode(aSelNode, aSelOffset, &nearNode);
else
res = GetNextHTMLNode(aSelNode, aSelOffset, &nearNode);
if (NS_FAILED(res)) return res;
// if there is no node then punt
if (!nearNode) return NS_OK;
// is nearNode also a descendant of same block?
nsCOMPtr<nsIDOMNode> block, nearBlock;
if (mEditor->IsBlockNode(aSelNode)) block = aSelNode;
else block = mEditor->GetBlockNodeParent(aSelNode);
if (mEditor->IsBlockNode(nearNode)) nearBlock = nearNode;
else nearBlock = mEditor->GetBlockNodeParent(nearNode);
if (block != nearBlock) return NS_OK; // punt - we dont want to jump across a block
// is the nearnode a text node?
nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(nearNode);
if (textNode) *outTextNode = nearNode;
// scan in the right direction until we find an eligible text node,
// but dont cross any breaks, images, or table elements.
while (nearNode && !(mEditor->IsTextNode(nearNode) || IsBreak(nearNode) || IsImage(nearNode)))
{
// dont cross any table elements
if (mEditor->IsTableElement(nearNode))
return NS_OK;
curNode = nearNode;
if (aDirection == nsIEditor::ePrevious)
res = GetPriorHTMLNode(curNode, &nearNode);
else
res = GetNextHTMLNode(curNode, &nearNode);
if (NS_FAILED(res)) return res;
}
if (nearNode) *outSelectableNode = do_QueryInterface(nearNode);
return res;
}

View File

@ -91,6 +91,7 @@ protected:
static PRBool IsOrderedList(nsIDOMNode *aNode);
static PRBool IsBlockquote(nsIDOMNode *aNode);
static PRBool IsAnchor(nsIDOMNode *aNode);
static PRBool IsImage(nsIDOMNode *aNode);
static PRBool IsDiv(nsIDOMNode *aNode);
static PRBool IsNormalDiv(nsIDOMNode *aNode);
static PRBool IsMozDiv(nsIDOMNode *aNode);
@ -143,10 +144,10 @@ protected:
nsresult AdjustSpecialBreaks();
nsresult AdjustWhitespace(nsIDOMSelection *aSelection);
nsresult AdjustSelection(nsIDOMSelection *aSelection, nsIEditor::EDirection aAction);
nsresult FindNearTextNode(nsIDOMNode *aSelNode,
PRInt32 aSelOffset,
nsIEditor::EDirection aDirection,
nsCOMPtr<nsIDOMNode> *outTextNode);
nsresult FindNearSelectableNode(nsIDOMNode *aSelNode,
PRInt32 aSelOffset,
nsIEditor::EDirection aDirection,
nsCOMPtr<nsIDOMNode> *outSelectableNode);
nsresult RemoveEmptyNodes();
nsresult DoTextNodeWhitespace(nsIDOMCharacterData *aTextNode, PRInt32 aStart, PRInt32 aEnd);
nsresult UpdateDocChangeRange(nsIDOMRange *aRange);

View File

@ -1579,7 +1579,7 @@ nsTextEditRules::DoTextInsertion(nsIDOMSelection *aSelection,
nsresult
nsTextEditRules::GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode)
{
if (!outNode) return NS_ERROR_NULL_POINTER;
if (!outNode || !inNode) return NS_ERROR_NULL_POINTER;
nsresult res = NS_OK;
*outNode = nsnull;
nsCOMPtr<nsIDOMNode> temp, node = do_QueryInterface(inNode);
@ -1588,7 +1588,7 @@ nsTextEditRules::GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *o
{
res = node->GetPreviousSibling(getter_AddRefs(temp));
if (NS_FAILED(res)) return res;
if (!temp) return NS_ERROR_FAILURE;
if (!temp) return NS_OK; // return null sibling
// if it's editable, we're done
if (mEditor->IsEditable(temp)) break;
// otherwise try again
@ -1600,6 +1600,30 @@ nsTextEditRules::GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *o
///////////////////////////////////////////////////////////////////////////
// GetPriorHTMLSibling: returns the previous editable sibling, if there is
// one within the parent. just like above routine but
// takes a parent/offset instead of a node.
//
nsresult
nsTextEditRules::GetPriorHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode)
{
if (!outNode || !inParent) return NS_ERROR_NULL_POINTER;
nsresult res = NS_OK;
*outNode = nsnull;
if (!inOffset) return NS_OK; // return null sibling if at offset zero
nsCOMPtr<nsIDOMNode> node = nsEditor::GetChildAt(inParent,inOffset-1);
if (mEditor->IsEditable(node))
{
*outNode = node;
return res;
}
// else
return GetPriorHTMLSibling(node, outNode);
}
///////////////////////////////////////////////////////////////////////////
// GetNextHTMLSibling: returns the next editable sibling, if there is
// one within the parent
@ -1628,6 +1652,30 @@ nsTextEditRules::GetNextHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *ou
///////////////////////////////////////////////////////////////////////////
// GetNextHTMLSibling: returns the next editable sibling, if there is
// one within the parent. just like above routine but
// takes a parent/offset instead of a node.
//
nsresult
nsTextEditRules::GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode)
{
if (!outNode || !inParent) return NS_ERROR_NULL_POINTER;
nsresult res = NS_OK;
*outNode = nsnull;
nsCOMPtr<nsIDOMNode> node = nsEditor::GetChildAt(inParent,inOffset);
if (!node) return NS_OK; // return null sibling if no sibling
if (mEditor->IsEditable(node))
{
*outNode = node;
return res;
}
// else
return GetPriorHTMLSibling(node, outNode);
}
///////////////////////////////////////////////////////////////////////////
// GetPriorHTMLNode: returns the previous editable leaf node, if there is
// one within the <body>

View File

@ -206,7 +206,9 @@ protected:
TypeInState aTypeInState);
nsresult GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);