fixes 98543: backspace/delete was crossing table structure boundaries. Also fixed other flavors of this bug that had not been discovered yet.

r=fm; sr=kin
This commit is contained in:
jfrancis%netscape.com 2001-09-09 20:57:46 +00:00
Родитель eb7921111d
Коммит 9aa7cb1b47
2 изменённых файлов: 108 добавлений и 38 удалений

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

@ -1386,7 +1386,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
res = CheckForEmptyBlock(startNode, bodyNode, aSelection, aHandled); res = CheckForEmptyBlock(startNode, bodyNode, aSelection, aHandled);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
if (*aHandled) return NS_OK; if (*aHandled) return NS_OK;
#ifdef IBMBIDI #ifdef IBMBIDI
// Test for distance between caret and text that will be deleted // Test for distance between caret and text that will be deleted
res = CheckBidiLevelForDeletion(startNode, startOffset, aAction, aCancel); res = CheckBidiLevelForDeletion(startNode, startOffset, aAction, aCancel);
@ -1397,11 +1397,27 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
if (!bPlaintext) if (!bPlaintext)
{ {
// Check for needed whitespace adjustments. If we need to delete // Check for needed whitespace adjustments. If we need to delete
// just whitespace, that is handled here. // just whitespace, that is handled here.
res = CheckForWhitespaceDeletion(address_of(startNode), &startOffset, // CheckForWhitespaceDeletion also adjusts it's first two args to
// skip over invisible ws. So we need to check that we didn't cross a table
// element boundary afterwards.
nsCOMPtr<nsIDOMNode> visNode = startNode;
PRInt32 visOffset = startOffset;
res = CheckForWhitespaceDeletion(address_of(visNode), &visOffset,
aAction, aHandled); aAction, aHandled);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
if (*aHandled) return NS_OK; if (*aHandled) return NS_OK;
// dont cross any table elements
PRBool bInDifTblElems;
res = InDifferentTableElements(visNode, startNode, &bInDifTblElems);
if (NS_FAILED(res)) return res;
if (bInDifTblElems)
{
*aCancel = PR_TRUE;
return NS_OK;
}
// else reset startNode/startOffset
startNode = visNode; startOffset = visOffset;
} }
// in a text node: // in a text node:
if (mHTMLEditor->IsTextNode(startNode)) if (mHTMLEditor->IsTextNode(startNode))
@ -1506,7 +1522,18 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
else return NS_OK; // punt to default else return NS_OK; // punt to default
} }
// deleting across blocks // ---- deleting across blocks ---------------------------------------------
// dont cross any table elements
PRBool bInDifTblElems;
res = InDifferentTableElements(startNode, priorNode, &bInDifTblElems);
if (NS_FAILED(res)) return res;
if (bInDifTblElems)
{
*aCancel = PR_TRUE;
return NS_OK;
}
nsCOMPtr<nsIDOMNode> leftParent; nsCOMPtr<nsIDOMNode> leftParent;
nsCOMPtr<nsIDOMNode> rightParent; nsCOMPtr<nsIDOMNode> rightParent;
if (IsBlockNode(priorNode)) if (IsBlockNode(priorNode))
@ -1523,13 +1550,6 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
if (!leftParent || !rightParent) if (!leftParent || !rightParent)
return NS_OK; // bail to default return NS_OK; // bail to default
// do not delete across table structures
if (nsHTMLEditUtils::IsTableElement(leftParent) || nsHTMLEditUtils::IsTableElement(rightParent))
{
*aCancel = PR_TRUE;
return NS_OK;
}
// are the blocks of same type? // are the blocks of same type?
if (mHTMLEditor->NodesSameType(leftParent, rightParent)) if (mHTMLEditor->NodesSameType(leftParent, rightParent))
{ {
@ -1646,7 +1666,18 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
else return NS_OK; // punt to default else return NS_OK; // punt to default
} }
// deleting across blocks // ---- deleting across blocks ---------------------------------------------
// dont cross any table elements
PRBool bInDifTblElems;
res = InDifferentTableElements(startNode, nextNode, &bInDifTblElems);
if (NS_FAILED(res)) return res;
if (bInDifTblElems)
{
*aCancel = PR_TRUE;
return NS_OK;
}
nsCOMPtr<nsIDOMNode> leftParent; nsCOMPtr<nsIDOMNode> leftParent;
nsCOMPtr<nsIDOMNode> rightParent; nsCOMPtr<nsIDOMNode> rightParent;
if (IsBlockNode(startNode)) if (IsBlockNode(startNode))
@ -1663,13 +1694,6 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
if (!leftParent || !rightParent) if (!leftParent || !rightParent)
return NS_OK; // bail to default return NS_OK; // bail to default
// do not delete across table structures
if (nsHTMLEditUtils::IsTableElement(leftParent) || nsHTMLEditUtils::IsTableElement(rightParent))
{
*aCancel = PR_TRUE;
return NS_OK;
}
// are the blocks of same type? // are the blocks of same type?
if (mHTMLEditor->NodesSameType(leftParent, rightParent)) if (mHTMLEditor->NodesSameType(leftParent, rightParent))
{ {
@ -1765,6 +1789,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
return NS_OK; return NS_OK;
} }
// don't delete the root element!
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
if (!nodeToDelete) return NS_ERROR_NULL_POINTER; if (!nodeToDelete) return NS_ERROR_NULL_POINTER;
if (mBody == nodeToDelete) if (mBody == nodeToDelete)
@ -1773,6 +1798,16 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
return res; return res;
} }
// dont cross any table elements
PRBool bInDifTblElems;
res = InDifferentTableElements(startNode, nodeToDelete, &bInDifTblElems);
if (NS_FAILED(res)) return res;
if (bInDifTblElems)
{
*aCancel = PR_TRUE;
return NS_OK;
}
// if this node is text node, adjust selection // if this node is text node, adjust selection
if (nsEditor::IsTextNode(nodeToDelete)) if (nsEditor::IsTextNode(nodeToDelete))
{ {

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

@ -1386,7 +1386,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
res = CheckForEmptyBlock(startNode, bodyNode, aSelection, aHandled); res = CheckForEmptyBlock(startNode, bodyNode, aSelection, aHandled);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
if (*aHandled) return NS_OK; if (*aHandled) return NS_OK;
#ifdef IBMBIDI #ifdef IBMBIDI
// Test for distance between caret and text that will be deleted // Test for distance between caret and text that will be deleted
res = CheckBidiLevelForDeletion(startNode, startOffset, aAction, aCancel); res = CheckBidiLevelForDeletion(startNode, startOffset, aAction, aCancel);
@ -1397,11 +1397,27 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
if (!bPlaintext) if (!bPlaintext)
{ {
// Check for needed whitespace adjustments. If we need to delete // Check for needed whitespace adjustments. If we need to delete
// just whitespace, that is handled here. // just whitespace, that is handled here.
res = CheckForWhitespaceDeletion(address_of(startNode), &startOffset, // CheckForWhitespaceDeletion also adjusts it's first two args to
// skip over invisible ws. So we need to check that we didn't cross a table
// element boundary afterwards.
nsCOMPtr<nsIDOMNode> visNode = startNode;
PRInt32 visOffset = startOffset;
res = CheckForWhitespaceDeletion(address_of(visNode), &visOffset,
aAction, aHandled); aAction, aHandled);
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
if (*aHandled) return NS_OK; if (*aHandled) return NS_OK;
// dont cross any table elements
PRBool bInDifTblElems;
res = InDifferentTableElements(visNode, startNode, &bInDifTblElems);
if (NS_FAILED(res)) return res;
if (bInDifTblElems)
{
*aCancel = PR_TRUE;
return NS_OK;
}
// else reset startNode/startOffset
startNode = visNode; startOffset = visOffset;
} }
// in a text node: // in a text node:
if (mHTMLEditor->IsTextNode(startNode)) if (mHTMLEditor->IsTextNode(startNode))
@ -1506,7 +1522,18 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
else return NS_OK; // punt to default else return NS_OK; // punt to default
} }
// deleting across blocks // ---- deleting across blocks ---------------------------------------------
// dont cross any table elements
PRBool bInDifTblElems;
res = InDifferentTableElements(startNode, priorNode, &bInDifTblElems);
if (NS_FAILED(res)) return res;
if (bInDifTblElems)
{
*aCancel = PR_TRUE;
return NS_OK;
}
nsCOMPtr<nsIDOMNode> leftParent; nsCOMPtr<nsIDOMNode> leftParent;
nsCOMPtr<nsIDOMNode> rightParent; nsCOMPtr<nsIDOMNode> rightParent;
if (IsBlockNode(priorNode)) if (IsBlockNode(priorNode))
@ -1523,13 +1550,6 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
if (!leftParent || !rightParent) if (!leftParent || !rightParent)
return NS_OK; // bail to default return NS_OK; // bail to default
// do not delete across table structures
if (nsHTMLEditUtils::IsTableElement(leftParent) || nsHTMLEditUtils::IsTableElement(rightParent))
{
*aCancel = PR_TRUE;
return NS_OK;
}
// are the blocks of same type? // are the blocks of same type?
if (mHTMLEditor->NodesSameType(leftParent, rightParent)) if (mHTMLEditor->NodesSameType(leftParent, rightParent))
{ {
@ -1646,7 +1666,18 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
else return NS_OK; // punt to default else return NS_OK; // punt to default
} }
// deleting across blocks // ---- deleting across blocks ---------------------------------------------
// dont cross any table elements
PRBool bInDifTblElems;
res = InDifferentTableElements(startNode, nextNode, &bInDifTblElems);
if (NS_FAILED(res)) return res;
if (bInDifTblElems)
{
*aCancel = PR_TRUE;
return NS_OK;
}
nsCOMPtr<nsIDOMNode> leftParent; nsCOMPtr<nsIDOMNode> leftParent;
nsCOMPtr<nsIDOMNode> rightParent; nsCOMPtr<nsIDOMNode> rightParent;
if (IsBlockNode(startNode)) if (IsBlockNode(startNode))
@ -1663,13 +1694,6 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
if (!leftParent || !rightParent) if (!leftParent || !rightParent)
return NS_OK; // bail to default return NS_OK; // bail to default
// do not delete across table structures
if (nsHTMLEditUtils::IsTableElement(leftParent) || nsHTMLEditUtils::IsTableElement(rightParent))
{
*aCancel = PR_TRUE;
return NS_OK;
}
// are the blocks of same type? // are the blocks of same type?
if (mHTMLEditor->NodesSameType(leftParent, rightParent)) if (mHTMLEditor->NodesSameType(leftParent, rightParent))
{ {
@ -1765,6 +1789,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
return NS_OK; return NS_OK;
} }
// don't delete the root element!
if (NS_FAILED(res)) return res; if (NS_FAILED(res)) return res;
if (!nodeToDelete) return NS_ERROR_NULL_POINTER; if (!nodeToDelete) return NS_ERROR_NULL_POINTER;
if (mBody == nodeToDelete) if (mBody == nodeToDelete)
@ -1773,6 +1798,16 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
return res; return res;
} }
// dont cross any table elements
PRBool bInDifTblElems;
res = InDifferentTableElements(startNode, nodeToDelete, &bInDifTblElems);
if (NS_FAILED(res)) return res;
if (bInDifTblElems)
{
*aCancel = PR_TRUE;
return NS_OK;
}
// if this node is text node, adjust selection // if this node is text node, adjust selection
if (nsEditor::IsTextNode(nodeToDelete)) if (nsEditor::IsTextNode(nodeToDelete))
{ {