зеркало из https://github.com/mozilla/pjs.git
Bug 344423. Backspace notifications off by 1
This commit is contained in:
Родитель
82ef28f26d
Коммит
cd9b71c1de
|
@ -1032,6 +1032,7 @@ NS_IMETHODIMP nsHyperTextAccessible::WillInsertNode(nsIDOMNode *aNode, nsIDOMNod
|
|||
NS_IMETHODIMP nsHyperTextAccessible::DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent,
|
||||
PRInt32 aPosition, nsresult aResult)
|
||||
{
|
||||
InvalidateChildren();
|
||||
AtkTextChange textData;
|
||||
|
||||
textData.add = PR_TRUE;
|
||||
|
@ -1067,6 +1068,7 @@ NS_IMETHODIMP nsHyperTextAccessible::WillDeleteNode(nsIDOMNode *aChild)
|
|||
AtkTextChange textData;
|
||||
|
||||
textData.add = PR_FALSE;
|
||||
textData.length = 1;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aChild));
|
||||
if (content && content->IsNodeOfType(nsINode::eTEXT)) {
|
||||
textData.length = content->TextLength();
|
||||
|
@ -1086,7 +1088,13 @@ NS_IMETHODIMP nsHyperTextAccessible::WillDeleteNode(nsIDOMNode *aChild)
|
|||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(DOMPointToOffset(aChild, 0, &textData.start))) {
|
||||
nsCOMPtr<nsIDOMNode> parentNode;
|
||||
aChild->GetParentNode(getter_AddRefs(parentNode));
|
||||
nsCOMPtr<nsIContent> parentContent(do_QueryInterface(parentNode));
|
||||
NS_ENSURE_TRUE(parentContent, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIContent> childContent(do_QueryInterface(aChild));
|
||||
NS_ENSURE_TRUE(childContent, NS_ERROR_FAILURE);
|
||||
if (NS_FAILED(DOMPointToOffset(parentNode, parentContent->IndexOf(childContent), &textData.start))) {
|
||||
return NS_OK;
|
||||
}
|
||||
return FireTextChangeEvent(&textData);
|
||||
|
@ -1094,7 +1102,7 @@ NS_IMETHODIMP nsHyperTextAccessible::WillDeleteNode(nsIDOMNode *aChild)
|
|||
|
||||
NS_IMETHODIMP nsHyperTextAccessible::DidDeleteNode(nsIDOMNode *aChild, nsresult aResult)
|
||||
{
|
||||
return NS_OK;
|
||||
return InvalidateChildren();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHyperTextAccessible::WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset)
|
||||
|
@ -1105,7 +1113,7 @@ NS_IMETHODIMP nsHyperTextAccessible::WillSplitNode(nsIDOMNode *aExistingRightNod
|
|||
NS_IMETHODIMP nsHyperTextAccessible::DidSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset,
|
||||
nsIDOMNode *aNewLeftNode, nsresult aResult)
|
||||
{
|
||||
return NS_OK;
|
||||
return InvalidateChildren();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHyperTextAccessible::WillJoinNodes(nsIDOMNode *aLeftNode,
|
||||
|
@ -1117,7 +1125,7 @@ NS_IMETHODIMP nsHyperTextAccessible::WillJoinNodes(nsIDOMNode *aLeftNode,
|
|||
NS_IMETHODIMP nsHyperTextAccessible::DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode,
|
||||
nsIDOMNode *aParent, nsresult aResult)
|
||||
{
|
||||
return NS_OK;
|
||||
return InvalidateChildren();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHyperTextAccessible::WillInsertText(nsIDOMCharacterData *aTextNode,
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include "nsIDOMTextListener.h"
|
||||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMHTMLBRElement.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsITransactionManager.h"
|
||||
#include "nsIAbsorbingTransaction.h"
|
||||
|
@ -4593,29 +4594,110 @@ nsEditor::DeleteSelectionImpl(nsIEditor::EDirection aAction)
|
|||
if (NS_FAILED(res)) return res;
|
||||
nsAutoRules beginRulesSniffing(this, kOpDeleteSelection, aAction);
|
||||
|
||||
nsCOMPtr<nsIDOMCharacterData> deleteCharData;
|
||||
nsCOMPtr<nsIDOMNode> deleteNode;
|
||||
PRInt32 deleteCharOffset = -1;
|
||||
PRBool isDeletingOneChar = PR_FALSE;
|
||||
|
||||
// Notification uses nsIEditActionListener::[Will|Did]Delete[Text|Node] instead of
|
||||
// nsIEditActionListener::[Will|Did]DeleteSelection when collapsed action is
|
||||
// used to delete one character forward or backwards.
|
||||
// The following code block determines what to call by setting
|
||||
// isDeletingOneChar, deleteNode and deleteCharData
|
||||
if (aAction == ePrevious || aAction == eNext) {
|
||||
#ifdef DEBUG
|
||||
PRUint32 flags;
|
||||
NS_ASSERTION(NS_SUCCEEDED(GetFlags(&flags) &&
|
||||
(flags & nsIPlaintextEditor::eEditorPlaintextMask)),
|
||||
"Should not have reached this point in rich text editor");
|
||||
#endif
|
||||
res = selection->GetIsCollapsed(&isDeletingOneChar);
|
||||
if (isDeletingOneChar) {
|
||||
// XXX After bug 240933 is fixed we will never be deleting a node
|
||||
// a node, there will always be a char data
|
||||
selection->GetFocusNode(getter_AddRefs(deleteNode));
|
||||
deleteCharData = do_QueryInterface(deleteNode);
|
||||
selection->GetFocusOffset(&deleteCharOffset);
|
||||
if (!deleteCharData) {
|
||||
nsCOMPtr<nsINode> parentNode(do_QueryInterface(deleteNode));
|
||||
deleteNode = do_QueryInterface(parentNode->GetChildAt(deleteCharOffset));
|
||||
deleteCharData = do_QueryInterface(deleteNode);
|
||||
deleteCharOffset = 0;
|
||||
}
|
||||
if (aAction == ePrevious && --deleteCharOffset < 0) {
|
||||
// Backspace pressed at beginning of node, so get the previous node
|
||||
nsCOMPtr<nsIDOMNode> previousNode;
|
||||
deleteNode->GetPreviousSibling(getter_AddRefs(previousNode));
|
||||
deleteNode.swap(previousNode);
|
||||
deleteCharData = do_QueryInterface(deleteNode);
|
||||
}
|
||||
PRUint32 deleteDataLength = 1; // Treat deleted node as length of 1
|
||||
if (deleteCharData) {
|
||||
deleteCharData->GetLength(&deleteDataLength);
|
||||
}
|
||||
// Check for valid position for a deletion
|
||||
if (deleteCharOffset < 0) {
|
||||
deleteCharOffset = deleteDataLength - 1;
|
||||
}
|
||||
else if (deleteCharOffset >= NS_STATIC_CAST(PRInt32, deleteDataLength)) {
|
||||
nsCOMPtr<nsIDOMNode> nextNode;
|
||||
deleteNode->GetNextSibling(getter_AddRefs(nextNode));
|
||||
deleteNode.swap(nextNode);
|
||||
deleteCharOffset = 0;
|
||||
}
|
||||
deleteCharData = do_QueryInterface(deleteNode);
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIDOMHTMLBRElement> deleteBR(do_QueryInterface(deleteNode));
|
||||
NS_ASSERTION(!deleteNode || deleteCharData || deleteBR,
|
||||
"Deleting non-BR node in plaintext editor");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32 i;
|
||||
nsIEditActionListener *listener;
|
||||
if (NS_SUCCEEDED(res))
|
||||
{
|
||||
// Notify nsIEditActionListener::WillDelete[Selection|Text|Node]
|
||||
if (mActionListeners)
|
||||
{
|
||||
for (i = 0; i < mActionListeners->Count(); i++)
|
||||
{
|
||||
listener = (nsIEditActionListener *)mActionListeners->ElementAt(i);
|
||||
if (listener)
|
||||
listener->WillDeleteSelection(selection);
|
||||
if (listener) {
|
||||
if (!isDeletingOneChar) {
|
||||
listener->WillDeleteSelection(selection);
|
||||
}
|
||||
else if (deleteCharData) {
|
||||
listener->WillDeleteText(deleteCharData, deleteCharOffset, 1);
|
||||
}
|
||||
else if (deleteNode) {
|
||||
listener->WillDeleteNode(deleteNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the specified amount
|
||||
res = DoTransaction(txn);
|
||||
|
||||
// Notify nsIEditActionListener::DidDelete[Selection|Text|Node]
|
||||
if (mActionListeners)
|
||||
{
|
||||
for (i = 0; i < mActionListeners->Count(); i++)
|
||||
{
|
||||
listener = (nsIEditActionListener *)mActionListeners->ElementAt(i);
|
||||
if (listener)
|
||||
listener->DidDeleteSelection(selection);
|
||||
if (listener) {
|
||||
if (!isDeletingOneChar) {
|
||||
listener->DidDeleteSelection(selection);
|
||||
}
|
||||
else if (deleteCharData) {
|
||||
listener->DidDeleteText(deleteCharData, deleteCharOffset, 1, res);
|
||||
}
|
||||
else if (deleteNode) {
|
||||
listener->DidDeleteNode(deleteNode, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче