зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
eb7921111d
Коммит
9aa7cb1b47
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче