From fa2dd72cb398dbb312365c11cda6ea36d509122a Mon Sep 17 00:00:00 2001 From: "surkov.alexander%gmail.com" Date: Wed, 5 Sep 2007 08:22:19 +0000 Subject: [PATCH] 390414 - text-changed:delete event details no longer correct effective, r=aaronlev, sr=bz, a=dsicore git-svn-id: svn://10.0.0.236/trunk@233915 18797224-902f-48f8-a5cc-f745e15eee43 --- .../accessible/src/base/nsDocAccessible.cpp | 50 +++++++++++++------ mozilla/accessible/src/base/nsDocAccessible.h | 13 +++-- .../content/base/public/nsIMutationObserver.h | 34 +++++++++++-- .../content/base/src/nsGenericDOMDataNode.cpp | 10 ++++ mozilla/content/base/src/nsNodeUtils.cpp | 9 ++++ mozilla/content/base/src/nsNodeUtils.h | 9 ++++ .../content/events/src/nsXMLEventsManager.cpp | 4 ++ mozilla/content/xbl/src/nsBindingManager.cpp | 9 ++++ mozilla/docshell/shistory/src/nsSHEntry.cpp | 7 +++ mozilla/widget/src/cocoa/nsMenuBarX.mm | 6 +++ 10 files changed, 130 insertions(+), 21 deletions(-) diff --git a/mozilla/accessible/src/base/nsDocAccessible.cpp b/mozilla/accessible/src/base/nsDocAccessible.cpp index 1a02eaaa9b2..7bb9596d0e0 100644 --- a/mozilla/accessible/src/base/nsDocAccessible.cpp +++ b/mozilla/accessible/src/base/nsDocAccessible.cpp @@ -1171,11 +1171,18 @@ void nsDocAccessible::ContentStatesChanged(nsIDocument* aDocument, nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent2); } +void nsDocAccessible::CharacterDataWillChange(nsIDocument *aDocument, + nsIContent* aContent, + CharacterDataChangeInfo* aInfo) +{ + FireTextChangeEventForText(aContent, aInfo, PR_FALSE); +} + void nsDocAccessible::CharacterDataChanged(nsIDocument *aDocument, nsIContent* aContent, CharacterDataChangeInfo* aInfo) { - FireTextChangedEventOnDOMCharacterDataModified(aContent, aInfo); + FireTextChangeEventForText(aContent, aInfo, PR_TRUE); } void @@ -1206,8 +1213,9 @@ nsDocAccessible::ParentChainChanged(nsIContent *aContent) } void -nsDocAccessible::FireTextChangedEventOnDOMCharacterDataModified(nsIContent *aContent, - CharacterDataChangeInfo* aInfo) +nsDocAccessible::FireTextChangeEventForText(nsIContent *aContent, + CharacterDataChangeInfo* aInfo, + PRBool aIsInserted) { if (!mIsContentLoaded || !mDocument) { return; @@ -1229,26 +1237,38 @@ nsDocAccessible::FireTextChangedEventOnDOMCharacterDataModified(nsIContent *aCon return; PRInt32 start = aInfo->mChangeStart; - PRUint32 end = aInfo->mChangeEnd; - PRInt32 length = end - start; - PRUint32 replaceLen = aInfo->mReplaceLength; PRInt32 offset = 0; rv = textAccessible->DOMPointToHypertextOffset(node, start, &offset); if (NS_FAILED(rv)) return; - // Text has been removed. - if (length > 0) { - nsCOMPtr event = - new nsAccTextChangeEvent(accessible, offset, length, PR_FALSE); - textAccessible->FireAccessibleEvent(event); - } + PRInt32 length = aIsInserted ? + aInfo->mReplaceLength; // text has been added + aInfo->mChangeEnd - start : // text has been removed + + if (length > 0) { + nsCOMPtr shell(do_QueryReferent(mWeakShell)); + if (!shell) + return; + + PRUint32 renderedStartOffset, renderedEndOffset; + nsIFrame* frame = shell->GetPrimaryFrameFor(aContent); + + rv = textAccessible->ContentToRenderedOffset(frame, start, + &renderedStartOffset); + if (NS_FAILED(rv)) + return; + + rv = textAccessible->ContentToRenderedOffset(frame, start + length, + &renderedEndOffset); + if (NS_FAILED(rv)) + return; - // Text has been added. - if (replaceLen) { nsCOMPtr event = - new nsAccTextChangeEvent(accessible, offset, replaceLen, PR_TRUE); + new nsAccTextChangeEvent(accessible, offset, + renderedEndOffset - renderedStartOffset, + aIsInserted, PR_FALSE); textAccessible->FireAccessibleEvent(event); } } diff --git a/mozilla/accessible/src/base/nsDocAccessible.h b/mozilla/accessible/src/base/nsDocAccessible.h index d0a0b4d34ec..c02455b123e 100644 --- a/mozilla/accessible/src/base/nsDocAccessible.h +++ b/mozilla/accessible/src/base/nsDocAccessible.h @@ -157,10 +157,17 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap, void ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute); /** - * Fire text changed event for charackter data changed. + * Fire text changed event for character data changed. The method is used + * from nsIMutationObserver methods. + * + * @param aContent the text node holding changed data + * @param aInfo info structure describing how the data was changed + * @param aIsInserted the flag pointed whether removed or inserted + * characters should be cause of event */ - void FireTextChangedEventOnDOMCharacterDataModified(nsIContent *aContent, - CharacterDataChangeInfo* aInfo); + void FireTextChangeEventForText(nsIContent *aContent, + CharacterDataChangeInfo* aInfo, + PRBool aIsInserted); /** * Create a text change event for a changed node diff --git a/mozilla/content/base/public/nsIMutationObserver.h b/mozilla/content/base/public/nsIMutationObserver.h index e60db1d47a0..13333086677 100755 --- a/mozilla/content/base/public/nsIMutationObserver.h +++ b/mozilla/content/base/public/nsIMutationObserver.h @@ -45,8 +45,8 @@ class nsIDocument; class nsINode; #define NS_IMUTATION_OBSERVER_IID \ -{ 0x93542eb8, 0x98e1, 0x46f6, \ - { 0xbb, 0xa2, 0x90, 0x54, 0x05, 0xfe, 0xbe, 0xf9 } } +{ 0x32e68316, 0x67d4, 0x44a5, \ + { 0x8d, 0x35, 0xd, 0x39, 0xf, 0xa9, 0xdf, 0x11 } } /** * Information details about a characterdata change @@ -75,6 +75,22 @@ class nsIMutationObserver : public nsISupports public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMUTATION_OBSERVER_IID) + /** + * Notification that the node value of a data node (text, cdata, pi, comment) + * will be changed. + * + * This notification is not sent when a piece of content is + * added/removed from the document (the other notifications are used + * for that). + * + * @param aDocument The owner-document of aContent. Can be null. + * @param aContent The piece of content that changed. Is never null. + * @param aInfo The structure with information details about the change. + */ + virtual void CharacterDataWillChange(nsIDocument *aDocument, + nsIContent* aContent, + CharacterDataChangeInfo* aInfo) = 0; + /** * Notification that the node value of a data node (text, cdata, pi, comment) * has changed. @@ -85,7 +101,7 @@ public: * * @param aDocument The owner-document of aContent. Can be null. * @param aContent The piece of content that changed. Is never null. - * @param aAppend Whether the change was an append + * @param aInfo The structure with information details about the change. */ virtual void CharacterDataChanged(nsIDocument *aDocument, nsIContent* aContent, @@ -194,6 +210,11 @@ public: NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID) +#define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \ + virtual void CharacterDataWillChange(nsIDocument* aDocument, \ + nsIContent* aContent, \ + CharacterDataChangeInfo* aInfo); + #define NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \ virtual void CharacterDataChanged(nsIDocument* aDocument, \ nsIContent* aContent, \ @@ -231,6 +252,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID) virtual void ParentChainChanged(nsIContent *aContent); #define NS_DECL_NSIMUTATIONOBSERVER \ + NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE \ NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED \ NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \ NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \ @@ -247,6 +269,12 @@ _class::NodeWillBeDestroyed(const nsINode* aNode) #define NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class) \ void \ +_class::CharacterDataWillChange(nsIDocument* aDocument, \ + nsIContent* aContent, \ + CharacterDataChangeInfo* aInfo) \ +{ \ +} \ +void \ _class::CharacterDataChanged(nsIDocument* aDocument, \ nsIContent* aContent, \ CharacterDataChangeInfo* aInfo) \ diff --git a/mozilla/content/base/src/nsGenericDOMDataNode.cpp b/mozilla/content/base/src/nsGenericDOMDataNode.cpp index 5f436eae71b..5c8c04e1a75 100644 --- a/mozilla/content/base/src/nsGenericDOMDataNode.cpp +++ b/mozilla/content/base/src/nsGenericDOMDataNode.cpp @@ -423,6 +423,16 @@ nsGenericDOMDataNode::SetTextInternal(PRUint32 aOffset, PRUint32 aCount, endOffset = textLength; } + if (aNotify) { + CharacterDataChangeInfo info = { + aOffset == textLength, + aOffset, + endOffset, + aLength + }; + nsNodeUtils::CharacterDataWillChange(this, &info); + } + if (aOffset == 0 && endOffset == textLength) { // Replacing whole text or old text was empty mText.SetTo(aBuffer, aLength); diff --git a/mozilla/content/base/src/nsNodeUtils.cpp b/mozilla/content/base/src/nsNodeUtils.cpp index 8d871005287..ec11d40a884 100755 --- a/mozilla/content/base/src/nsNodeUtils.cpp +++ b/mozilla/content/base/src/nsNodeUtils.cpp @@ -79,6 +79,15 @@ PR_END_MACRO +void +nsNodeUtils::CharacterDataWillChange(nsIContent* aContent, + CharacterDataChangeInfo* aInfo) +{ + nsIDocument* doc = aContent->GetOwnerDoc(); + IMPL_MUTATION_NOTIFICATION(CharacterDataWillChange, aContent, + (doc, aContent, aInfo)); +} + void nsNodeUtils::CharacterDataChanged(nsIContent* aContent, CharacterDataChangeInfo* aInfo) diff --git a/mozilla/content/base/src/nsNodeUtils.h b/mozilla/content/base/src/nsNodeUtils.h index e4b0bd82321..4dac9f03f15 100755 --- a/mozilla/content/base/src/nsNodeUtils.h +++ b/mozilla/content/base/src/nsNodeUtils.h @@ -55,6 +55,15 @@ struct CharacterDataChangeInfo; class nsNodeUtils { public: + /** + * Send CharacterDataWillChange notifications to nsIMutationObservers. + * @param aContent Node whose data changed + * @param aInfo Struct with information details about the change + * @see nsIMutationObserver::CharacterDataWillChange + */ + static void CharacterDataWillChange(nsIContent* aContent, + CharacterDataChangeInfo* aInfo); + /** * Send CharacterDataChanged notifications to nsIMutationObservers. * @param aContent Node whose data changed diff --git a/mozilla/content/events/src/nsXMLEventsManager.cpp b/mozilla/content/events/src/nsXMLEventsManager.cpp index 0924f30b2a3..6f2340b5053 100644 --- a/mozilla/content/events/src/nsXMLEventsManager.cpp +++ b/mozilla/content/events/src/nsXMLEventsManager.cpp @@ -347,6 +347,10 @@ nsXMLEventsManager::EndLoad(nsIDocument* aDocument) AddListeners(aDocument); } NS_IMPL_NSIDOCUMENTOBSERVER_STATE_STUB(nsXMLEventsManager) +void +nsXMLEventsManager::CharacterDataWillChange(nsIDocument* aDocument, + nsIContent* aContent, + CharacterDataChangeInfo* aInfo) {} void nsXMLEventsManager::CharacterDataChanged(nsIDocument* aDocument, nsIContent* aContent, diff --git a/mozilla/content/xbl/src/nsBindingManager.cpp b/mozilla/content/xbl/src/nsBindingManager.cpp index eb6cfd18bdd..d76dbb1a2f4 100644 --- a/mozilla/content/xbl/src/nsBindingManager.cpp +++ b/mozilla/content/xbl/src/nsBindingManager.cpp @@ -1181,6 +1181,15 @@ nsBindingManager::RemoveObserver(nsIMutationObserver* aObserver) return mObservers.RemoveObserver(aObserver); } +void +nsBindingManager::CharacterDataWillChange(nsIDocument* aDocument, + nsIContent* aContent, + CharacterDataChangeInfo* aInfo) +{ + NS_BINDINGMANAGER_NOTIFY_OBSERVERS(CharacterDataWillChange, + (aDocument, aContent, aInfo)); +} + void nsBindingManager::CharacterDataChanged(nsIDocument* aDocument, nsIContent* aContent, diff --git a/mozilla/docshell/shistory/src/nsSHEntry.cpp b/mozilla/docshell/shistory/src/nsSHEntry.cpp index 23809399e45..e057c1ff800 100644 --- a/mozilla/docshell/shistory/src/nsSHEntry.cpp +++ b/mozilla/docshell/shistory/src/nsSHEntry.cpp @@ -648,6 +648,13 @@ nsSHEntry::NodeWillBeDestroyed(const nsINode* aNode) NS_NOTREACHED("Document destroyed while we're holding a strong ref to it"); } +void +nsSHEntry::CharacterDataWillChange(nsIDocument* aDocument, + nsIContent* aContent, + CharacterDataChangeInfo* aInfo) +{ +} + void nsSHEntry::CharacterDataChanged(nsIDocument* aDocument, nsIContent* aContent, diff --git a/mozilla/widget/src/cocoa/nsMenuBarX.mm b/mozilla/widget/src/cocoa/nsMenuBarX.mm index e4365935b09..01bd2d7383c 100644 --- a/mozilla/widget/src/cocoa/nsMenuBarX.mm +++ b/mozilla/widget/src/cocoa/nsMenuBarX.mm @@ -846,6 +846,12 @@ NS_IMETHODIMP nsMenuBarX::Paint() // +nsMenuBarX::CharacterDataWillChange(nsIDocument * aDocument, + nsIContent * aContent, + CharacterDataChangeInfo * aInfo) +{ +} + void nsMenuBarX::CharacterDataChanged(nsIDocument * aDocument, nsIContent * aContent,