diff --git a/mozilla/accessible/public/nsIAccessibilityService.idl b/mozilla/accessible/public/nsIAccessibilityService.idl index f544615e93d..568ec530b30 100644 --- a/mozilla/accessible/public/nsIAccessibilityService.idl +++ b/mozilla/accessible/public/nsIAccessibilityService.idl @@ -98,8 +98,8 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval * EVENT_HIDE (destroy or hide) */ void invalidateSubtreeFor(in nsIPresShell aPresShell, - in nsIContent aChangedContent, - in PRUint32 aEvent); + in nsIContent aChangedContent, + in PRUint32 aEvent); }; diff --git a/mozilla/accessible/public/nsIAccessibleEvent.idl b/mozilla/accessible/public/nsIAccessibleEvent.idl index 15938f4839c..8d7d2129346 100755 --- a/mozilla/accessible/public/nsIAccessibleEvent.idl +++ b/mozilla/accessible/public/nsIAccessibleEvent.idl @@ -553,6 +553,11 @@ interface nsIAccessibleTextChangeEvent : nsIAccessibleEvent * Returns true if text was inserted, otherwise false. */ boolean isInserted(); + + /** + * The inserted or removed text + */ + readonly attribute DOMString modifiedText; }; [scriptable, uuid(b9076dce-4cd3-4e3d-a7f6-7f33a7f40c31)] diff --git a/mozilla/accessible/src/base/nsAccessibilityService.cpp b/mozilla/accessible/src/base/nsAccessibilityService.cpp index cc0050af8a8..2288ff24660 100644 --- a/mozilla/accessible/src/base/nsAccessibilityService.cpp +++ b/mozilla/accessible/src/base/nsAccessibilityService.cpp @@ -1804,11 +1804,14 @@ NS_IMETHODIMP nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell, { NS_ASSERTION(aEvent == nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE || aEvent == nsIAccessibleEvent::EVENT_ASYNCH_SHOW || - aEvent == nsIAccessibleEvent::EVENT_ASYNCH_HIDE, + aEvent == nsIAccessibleEvent::EVENT_ASYNCH_HIDE || + aEvent == nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE || + aEvent == nsIAccessibleEvent::EVENT_DOM_CREATE || + aEvent == nsIAccessibleEvent::EVENT_DOM_DESTROY, "Incorrect aEvent passed in"); + NS_ENSURE_ARG_POINTER(aShell); nsCOMPtr weakShell(do_GetWeakReference(aShell)); - NS_ASSERTION(aShell, "No pres shell in call to InvalidateSubtreeFor"); nsCOMPtr accessibleDoc = nsAccessNode::GetDocAccessibleFor(weakShell); nsCOMPtr privateAccessibleDoc = diff --git a/mozilla/accessible/src/base/nsAccessibleEventData.cpp b/mozilla/accessible/src/base/nsAccessibleEventData.cpp index d14689c5d31..f33e8e72f7c 100755 --- a/mozilla/accessible/src/base/nsAccessibleEventData.cpp +++ b/mozilla/accessible/src/base/nsAccessibleEventData.cpp @@ -394,11 +394,16 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextChangeEvent, nsAccEvent, nsAccTextChangeEvent:: nsAccTextChangeEvent(nsIAccessible *aAccessible, - PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted): + PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted, PRBool aIsAsynch): nsAccEvent(aIsInserted ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : nsIAccessibleEvent::EVENT_TEXT_REMOVED, - aAccessible, nsnull), + aAccessible, nsnull, aIsAsynch), mStart(aStart), mLength(aLength), mIsInserted(aIsInserted) { + nsCOMPtr textAccessible = do_QueryInterface(aAccessible); + NS_ASSERTION(textAccessible, "Should not be firing test change event for non-text accessible!!!"); + if (textAccessible) { + textAccessible->GetText(aStart, aStart + aLength, mModifiedText); + } } NS_IMETHODIMP @@ -422,6 +427,13 @@ nsAccTextChangeEvent::IsInserted(PRBool *aIsInserted) return NS_OK; } +NS_IMETHODIMP +nsAccTextChangeEvent::GetModifiedText(nsAString& aModifiedText) +{ + aModifiedText = mModifiedText; + return NS_OK; +} + // nsAccCaretMoveEvent NS_IMPL_ISUPPORTS_INHERITED1(nsAccCaretMoveEvent, nsAccEvent, nsIAccessibleCaretMoveEvent) diff --git a/mozilla/accessible/src/base/nsAccessibleEventData.h b/mozilla/accessible/src/base/nsAccessibleEventData.h index 4206c61173f..1dc8a8fabc3 100644 --- a/mozilla/accessible/src/base/nsAccessibleEventData.h +++ b/mozilla/accessible/src/base/nsAccessibleEventData.h @@ -46,6 +46,8 @@ #include "nsIAccessible.h" #include "nsIAccessibleDocument.h" #include "nsIDOMNode.h" +#include "nsString.h" + class nsIPresShell; class nsAccEvent: public nsIAccessibleEvent @@ -128,8 +130,8 @@ class nsAccTextChangeEvent: public nsAccEvent, public nsIAccessibleTextChangeEvent { public: - nsAccTextChangeEvent(nsIAccessible *aAccessible, - PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted); + nsAccTextChangeEvent(nsIAccessible *aAccessible, PRInt32 aStart, PRUint32 aLength, + PRBool aIsInserted, PRBool aIsAsynch = PR_FALSE); NS_DECL_ISUPPORTS_INHERITED NS_FORWARD_NSIACCESSIBLEEVENT(nsAccEvent::) @@ -139,6 +141,7 @@ private: PRInt32 mStart; PRUint32 mLength; PRBool mIsInserted; + nsString mModifiedText; }; class nsAccCaretMoveEvent: public nsAccEvent, diff --git a/mozilla/accessible/src/base/nsDocAccessible.cpp b/mozilla/accessible/src/base/nsDocAccessible.cpp index 230f833a3aa..04712371a85 100644 --- a/mozilla/accessible/src/base/nsDocAccessible.cpp +++ b/mozilla/accessible/src/base/nsDocAccessible.cpp @@ -1149,9 +1149,6 @@ void nsDocAccessible::ContentAppended(nsIDocument *aDocument, PRUint32 childCount = aContainer->GetChildCount(); for (PRUint32 index = aNewIndexInContainer; index < childCount; index ++) { nsCOMPtr child(aContainer->GetChildAt(index)); - - FireTextChangedEventOnDOMNodeInserted(child, aContainer, index); - // InvalidateCacheSubtree will not fire the EVENT_SHOW for the new node // unless an accessible can be created for the passed in node, which it // can't do unless the node is visible. The right thing happens there so @@ -1184,8 +1181,6 @@ void nsDocAccessible::ContentInserted(nsIDocument *aDocument, nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer) { - FireTextChangedEventOnDOMNodeInserted(aChild, aContainer, aIndexInContainer); - // InvalidateCacheSubtree will not fire the EVENT_SHOW for the new node // unless an accessible can be created for the passed in node, which it // can't do unless the node is visible. The right thing happens there so @@ -1197,10 +1192,11 @@ void nsDocAccessible::ContentRemoved(nsIDocument *aDocument, nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer) { - FireTextChangedEventOnDOMNodeRemoved(aChild, aContainer, aIndexInContainer); - // Invalidate the subtree of the removed element. - InvalidateCacheSubtree(aChild, nsIAccessibleEvent::EVENT_DOM_DESTROY); + // InvalidateCacheSubtree(aChild, nsIAccessibleEvent::EVENT_DOM_DESTROY); + // This is no longer needed, we get our notifications directly from content + // *before* the frame for the content is destroyed, or any other side effects occur. + // That allows us to correctly calculate the TEXT_REMOVED event if there is one. } void @@ -1256,122 +1252,82 @@ nsDocAccessible::FireTextChangedEventOnDOMCharacterDataModified(nsIContent *aCon } } -void -nsDocAccessible::FireTextChangedEventOnDOMNodeInserted(nsIContent *aChild, - nsIContent *aContainer, - PRInt32 aIndexInContainer) +already_AddRefed +nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible, + nsIDOMNode *aChangeNode, + nsIAccessible *aAccessibleForChangeNode, + PRBool aIsInserting, + PRBool aIsAsynch) { - if (!mIsContentLoaded || !mDocument) { - return; + nsRefPtr textAccessible; + aContainerAccessible->QueryInterface(NS_GET_IID(nsHyperTextAccessible), + getter_AddRefs(textAccessible)); + if (!textAccessible) { + return nsnull; } - nsCOMPtr node(do_QueryInterface(aChild)); - if (!node) - return; + PRInt32 offset; + PRInt32 length = 0; + nsCOMPtr changeAccessible; + nsresult rv = textAccessible->DOMPointToHypertextOffset(aChangeNode, -1, &offset, + getter_AddRefs(changeAccessible)); + NS_ENSURE_SUCCESS(rv, nsnull); - nsCOMPtr accessible; - nsresult rv = GetAccessibleInParentChain(node, getter_AddRefs(accessible)); - if (NS_FAILED(rv) || !accessible) - return; - - nsRefPtr textAccessible; - rv = accessible->QueryInterface(NS_GET_IID(nsHyperTextAccessible), - getter_AddRefs(textAccessible)); - if (NS_FAILED(rv) || !textAccessible) - return; - - PRUint32 length = 1; - if (aChild && aChild->IsNodeOfType(nsINode::eTEXT)) { - length = aChild->TextLength(); - if (!length) - return; - } else { - // Don't fire event for the first html:br in an editor. - nsCOMPtr editor; - textAccessible->GetAssociatedEditor(getter_AddRefs(editor)); - if (editor) { - PRBool isEmpty = PR_FALSE; - editor->GetDocumentIsEmpty(&isEmpty); - if (isEmpty) - return; + if (!aAccessibleForChangeNode) { + // A span-level object or something else without an accessible is being removed, where + // it has no accessible but it has descendant content which is aggregated as text + // into the parent hypertext. + // In this case, accessibleToBeRemoved may just be the first + // accessible that is removed, which affects the text in the hypertext container + if (!changeAccessible) { + return nsnull; // No descendant content that represents any text in the hypertext parent + } + nsCOMPtr child = changeAccessible; + while (PR_TRUE) { + nsCOMPtr childAccessNode = + do_QueryInterface(changeAccessible); + nsCOMPtr childNode; + childAccessNode->GetDOMNode(getter_AddRefs(childNode)); + if (!nsAccUtils::IsAncestorOf(aChangeNode, childNode)) { + break; // We only want accessibles with DOM nodes as children of this node + } + length += TextLength(child); + child->GetNextSibling(getter_AddRefs(changeAccessible)); + if (!changeAccessible) { + break; + } + child.swap(changeAccessible); + } + } + else { + NS_ASSERTION(changeAccessible == aAccessibleForChangeNode, + "Hypertext is reporting a different accessible for this node"); + length = TextLength(aAccessibleForChangeNode); + if (Role(aAccessibleForChangeNode) == nsIAccessibleRole::ROLE_WHITESPACE) { // newline + // Don't fire event for the first html:br in an editor. + nsCOMPtr editor; + textAccessible->GetAssociatedEditor(getter_AddRefs(editor)); + if (editor) { + PRBool isEmpty = PR_FALSE; + editor->GetDocumentIsEmpty(&isEmpty); + if (isEmpty) { + return nsnull; + } + } } } - nsCOMPtr parentNode(do_QueryInterface(aContainer)); - if (!parentNode) - return; - - PRInt32 offset = 0; - rv = textAccessible->DOMPointToHypertextOffset(parentNode, aIndexInContainer, &offset); - if (NS_FAILED(rv)) - return; - - nsCOMPtr event = - new nsAccTextChangeEvent(accessible, offset, length, PR_TRUE); - if (!event) - return; - - textAccessible->FireAccessibleEvent(event); -} - -void -nsDocAccessible::FireTextChangedEventOnDOMNodeRemoved(nsIContent *aChild, - nsIContent *aContainer, - PRInt32 aIndexInContainer) -{ - if (!mIsContentLoaded || !mDocument) { - return; + if (length <= 0) { + return nsnull; } - nsCOMPtr node(do_QueryInterface(aChild)); - if (!node) - return; + nsIAccessibleTextChangeEvent *event = + new nsAccTextChangeEvent(aContainerAccessible, offset, length, aIsInserting, aIsAsynch); + NS_IF_ADDREF(event); - nsCOMPtr accessible; - nsresult rv = GetAccessibleInParentChain(node, getter_AddRefs(accessible)); - if (NS_FAILED(rv) || !accessible) - return; - - nsRefPtr textAccessible; - rv = accessible->QueryInterface(NS_GET_IID(nsHyperTextAccessible), - getter_AddRefs(textAccessible)); - if (NS_FAILED(rv) || !textAccessible) - return; - - PRUint32 length = 1; - if (aChild && aChild->IsNodeOfType(nsINode::eTEXT)) { - length = aChild->TextLength(); - if (!length) - return; - } else { - // Don't fire event for the last html:br in an editor. - nsCOMPtr editor; - textAccessible->GetAssociatedEditor(getter_AddRefs(editor)); - if (editor) { - PRBool isEmpty = PR_FALSE; - editor->GetDocumentIsEmpty(&isEmpty); - if (isEmpty) - return; - } - } - - nsCOMPtr parentNode(do_QueryInterface(aContainer)); - if (!parentNode) - return; - - PRInt32 offset = 0; - rv = textAccessible->DOMPointToHypertextOffset(parentNode, aIndexInContainer, &offset); - if (NS_FAILED(rv)) - return; - - nsCOMPtr event = - new nsAccTextChangeEvent(accessible, offset, length, PR_FALSE); - if (!event) - return; - - textAccessible->FireAccessibleEvent(event); + return event; } - + nsresult nsDocAccessible::FireDelayedToolkitEvent(PRUint32 aEvent, nsIDOMNode *aDOMNode, void *aData, @@ -1492,9 +1448,38 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents() nsCOMPtr accessible; accessibleEvent->GetAccessible(getter_AddRefs(accessible)); + + PRUint32 eventType; + accessibleEvent->GetEventType(&eventType); + if (eventType == nsIAccessibleEvent::EVENT_DOM_CREATE || + eventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW) { + // Also fire text changes if the node being created could affect the text in an nsIAccessibleText parent. + // When a node is being made visible or is inserted, the text in an ancestor hyper text will gain characters + // At this point we now have the frame and accessible for this node if there is one. That is why we + // wait to fire this here, instead of in InvalidateCacheSubtree(), where we wouldn't be able to calculate + // the offset, length and text for the text change. + nsCOMPtr domNode; + accessibleEvent->GetDOMNode(getter_AddRefs(domNode)); + if (domNode && domNode != mDOMNode) { + nsCOMPtr containerAccessible; + GetAccessibleInParentChain(domNode, getter_AddRefs(containerAccessible)); + nsCOMPtr textChangeEvent = + CreateTextChangeEventForNode(containerAccessible, domNode, accessible, PR_TRUE, PR_TRUE); + if (textChangeEvent) { + PRBool isFromUserInput; + accessibleEvent->GetIsFromUserInput(&isFromUserInput); + nsCOMPtr hyperTextNode; + textChangeEvent->GetDOMNode(getter_AddRefs(hyperTextNode)); + nsAccEvent::PrepareForEvent(hyperTextNode, isFromUserInput); + // XXX Queue them up and merge the text change events + // XXX We need a way to ignore SplitNode and JoinNode() when they + // do not affect the text within the hypertext + FireAccessibleEvent(textChangeEvent); + } + } + } + if (accessible) { - PRUint32 eventType; - accessibleEvent->GetEventType(&eventType); if (eventType == nsIAccessibleEvent::EVENT_INTERNAL_LOAD) { nsCOMPtr docAccessible = do_QueryInterface(accessible); @@ -1534,6 +1519,14 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents() // Post event processing if (eventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE || eventType == nsIAccessibleEvent::EVENT_DOM_DESTROY) { + // Invalidate children + nsCOMPtr containerAccessible; + accessible->GetParent(getter_AddRefs(containerAccessible)); + nsCOMPtr privateContainerAccessible = + do_QueryInterface(containerAccessible); + if (privateContainerAccessible) { + privateContainerAccessible->InvalidateChildren(); + } // Shutdown nsIAccessNode's or nsIAccessibles for any DOM nodes in this subtree nsCOMPtr hidingNode; accessibleEvent->GetDOMNode(getter_AddRefs(hidingNode)); @@ -1702,6 +1695,12 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, } #endif + nsCOMPtr containerAccessible; + GetAccessibleInParentChain(childNode, getter_AddRefs(containerAccessible)); + if (!containerAccessible) { + containerAccessible = this; + } + if (!isShowing) { // Fire EVENT_ASYNCH_HIDE or EVENT_DOM_DESTROY if previous accessible existed for node being hidden. // Fire this before the accessible goes away. @@ -1713,6 +1712,19 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, NS_ENSURE_TRUE(removalEvent, NS_ERROR_OUT_OF_MEMORY); FireDelayedAccessibleEvent(removalEvent, eCoalesceFromSameSubtree, isAsynch); } + if (childNode != mDOMNode) { // Fire text change unless the node being removed is for this doc + // When a node is hidden or removed, the text in an ancestor hyper text will lose characters + // At this point we still have the frame and accessible for this node if there was one + // XXX Collate events when a range is deleted + // XXX We need a way to ignore SplitNode and JoinNode() when they + // do not affect the text within the hypertext + nsCOMPtr textChangeEvent = + CreateTextChangeEventForNode(containerAccessible, childNode, childAccessible, + PR_FALSE, isAsynch); + if (textChangeEvent) { + FireAccessibleEvent(textChangeEvent); + } + } } // We need to get an accessible for the mutation event's container node @@ -1722,18 +1734,12 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, // We're guaranteed success, because we will eventually end up at the doc accessible, // and there is always one of those. - nsCOMPtr containerAccessible; - GetAccessibleInParentChain(childNode, getter_AddRefs(containerAccessible)); - if (!containerAccessible) { - containerAccessible = this; - } - nsCOMPtr privateContainerAccessible = - do_QueryInterface(containerAccessible); - if (privateContainerAccessible) { - privateContainerAccessible->InvalidateChildren(); - } - if (aChild && !isHiding) { + nsCOMPtr privateContainerAccessible = + do_QueryInterface(containerAccessible); + if (privateContainerAccessible) { + privateContainerAccessible->InvalidateChildren(); + } // Fire EVENT_SHOW, EVENT_MENUPOPUP_START for newly visible content. // Fire after a short timer, because we want to make sure the view has been // updated to make this accessible content visible. If we don't wait, diff --git a/mozilla/accessible/src/base/nsDocAccessible.h b/mozilla/accessible/src/base/nsDocAccessible.h index a381d9269ab..649e8d205e7 100644 --- a/mozilla/accessible/src/base/nsDocAccessible.h +++ b/mozilla/accessible/src/base/nsDocAccessible.h @@ -107,7 +107,7 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap, /** * Non-virtual method to fire a delayed event after a 0 length timeout * - * @param aEvent - the nsIAccessibleEvent event ype + * @param aEvent - the nsIAccessibleEvent event type * @param aDOMNode - DOM node the accesible event should be fired for * @param aData - any additional data for the event * @param aAllowDupes - eAllowDupes: more than one event of the same type is allowed. @@ -161,21 +161,20 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap, */ void FireTextChangedEventOnDOMCharacterDataModified(nsIContent *aContent, CharacterDataChangeInfo* aInfo); - /** - * Fire text changed event for the inserted element if it is inside a text - * accessible. - */ - void FireTextChangedEventOnDOMNodeInserted(nsIContent *aChild, - nsIContent *aContainer, - PRInt32 aIndexInContainer); /** - * Fire text changed event for the removed element if it is inside a text - * accessible. + * Create a text change event for a changed node + * @param aContainerAccessible, the first accessible in the container + * @param aChangeNode, the node that is being inserted or removed, or shown/hidden + * @param aAccessibleForChangeNode, the accessible for that node, or nsnull if none exists + * @param aIsInserting, is aChangeNode being created or shown (vs. removed or hidden) */ - void FireTextChangedEventOnDOMNodeRemoved(nsIContent *aChild, - nsIContent *aContainer, - PRInt32 aIndexInContainer); + already_AddRefed + nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible, + nsIDOMNode *aChangeNode, + nsIAccessible *aAccessibleForNode, + PRBool aIsInserting, + PRBool aIsAsynch); nsAccessNodeHashtable mAccessNodeCache; void *mWnd; diff --git a/mozilla/accessible/src/html/nsHTMLTextAccessible.cpp b/mozilla/accessible/src/html/nsHTMLTextAccessible.cpp index 2a5dc70f04f..a29b8d7ad18 100644 --- a/mozilla/accessible/src/html/nsHTMLTextAccessible.cpp +++ b/mozilla/accessible/src/html/nsHTMLTextAccessible.cpp @@ -62,9 +62,9 @@ NS_IMETHODIMP nsHTMLTextAccessible::GetName(nsAString& aName) NS_IMETHODIMP nsHTMLTextAccessible::GetRole(PRUint32 *aRole) { nsIFrame *frame = GetFrame(); - NS_ENSURE_TRUE(frame, NS_ERROR_NULL_POINTER); - - if (frame->IsGeneratedContentFrame()) { + // Don't return on null frame -- we still return a role + // after accessible is shutdown/DEFUNCT + if (frame && frame->IsGeneratedContentFrame()) { *aRole = nsIAccessibleRole::ROLE_STATICTEXT; return NS_OK; } diff --git a/mozilla/accessible/src/html/nsHyperTextAccessible.cpp b/mozilla/accessible/src/html/nsHyperTextAccessible.cpp index a5c39aa7271..521559de1e1 100644 --- a/mozilla/accessible/src/html/nsHyperTextAccessible.cpp +++ b/mozilla/accessible/src/html/nsHyperTextAccessible.cpp @@ -526,7 +526,6 @@ nsresult nsHyperTextAccessible::DOMPointToHypertextOffset(nsIDOMNode* aNode, PRI NS_ENSURE_ARG_POINTER(aHyperTextOffset); *aHyperTextOffset = 0; NS_ENSURE_ARG_POINTER(aNode); - NS_ENSURE_TRUE(aNodeOffset >= 0, NS_ERROR_INVALID_ARG); if (aFinalAccessible) { *aFinalAccessible = nsnull; } @@ -536,7 +535,10 @@ nsresult nsHyperTextAccessible::DOMPointToHypertextOffset(nsIDOMNode* aNode, PRI unsigned short nodeType; aNode->GetNodeType(&nodeType); - if (nodeType == nsIDOMNode::TEXT_NODE) { + if (aNodeOffset == -1) { + findNode = aNode; + } + else if (nodeType == nsIDOMNode::TEXT_NODE) { // For text nodes, aNodeOffset comes in as a character offset // Text offset will be added at the end, if we find the offset in this hypertext // We want the "skipped" offset into the text (rendered text without the extra whitespace) @@ -618,6 +620,7 @@ nsresult nsHyperTextAccessible::DOMPointToHypertextOffset(nsIDOMNode* aNode, PRI NS_ADDREF(*aFinalAccessible = childAccessible); } } + return NS_OK; } diff --git a/mozilla/accessible/src/html/nsHyperTextAccessible.h b/mozilla/accessible/src/html/nsHyperTextAccessible.h index d025c05bf04..4af7bf12163 100644 --- a/mozilla/accessible/src/html/nsHyperTextAccessible.h +++ b/mozilla/accessible/src/html/nsHyperTextAccessible.h @@ -101,6 +101,9 @@ public: * * @param aNode - the node to look for * @param aNodeOffset - the offset to look for + * if -1 just look directly for the node + * if >=0 and aNode is text, this represents a char offset + * if >=0 and aNode is not text, this represents a child node offset * @param aResultOffset - the character offset into the current * nsHyperTextAccessible * @param aFinalAccessible [optional] - returns the accessible child which diff --git a/mozilla/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp b/mozilla/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp index 533fb9e026b..cd66a412f3d 100755 --- a/mozilla/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp +++ b/mozilla/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp @@ -89,28 +89,24 @@ nsHyperTextAccessibleWrap::GetModifiedText(PRBool aGetInsertedText, if (!gTextEvent) return NS_OK; + + PRBool isInserted; + gTextEvent->IsInserted(&isInserted); + if (aGetInsertedText != isInserted) + return NS_OK; nsCOMPtr targetAcc; gTextEvent->GetAccessible(getter_AddRefs(targetAcc)); if (targetAcc != this) return NS_OK; - PRBool isInserted; - gTextEvent->IsInserted(&isInserted); - - if (aGetInsertedText != isInserted) - return NS_OK; - - nsAutoString text; PRInt32 offset; PRUint32 length; gTextEvent->GetStart(&offset); gTextEvent->GetLength(&length); - GetText(offset, offset + length, aText); *aStartOffset = offset; *aEndOffset = offset + length; - - return NS_OK; + return gTextEvent->GetModifiedText(aText); } diff --git a/mozilla/content/base/src/Makefile.in b/mozilla/content/base/src/Makefile.in index c8072f94659..c4779856dd0 100644 --- a/mozilla/content/base/src/Makefile.in +++ b/mozilla/content/base/src/Makefile.in @@ -82,6 +82,7 @@ REQUIRES = xpcom \ util \ appshell \ shistory \ + accessibility \ $(NULL) EXPORTS = \ diff --git a/mozilla/content/base/src/nsGenericElement.cpp b/mozilla/content/base/src/nsGenericElement.cpp index c866cb56b1c..b7f8ec68b04 100644 --- a/mozilla/content/base/src/nsGenericElement.cpp +++ b/mozilla/content/base/src/nsGenericElement.cpp @@ -125,6 +125,11 @@ #include "nsIXULDocument.h" #endif /* MOZ_XUL */ +#ifdef ACCESSIBILITY +#include "nsIAccessibilityService.h" +#include "nsIAccessibleEvent.h" +#endif /* ACCESSIBILITY */ + #include "nsCycleCollectionParticipant.h" #include "nsCCUncollectableMarker.h" #include "nsCycleCollector.h" @@ -2694,6 +2699,22 @@ nsGenericElement::doRemoveChildAt(PRUint32 aIndex, PRBool aNotify, NS_PRECONDITION(!aParent || aParent->GetCurrentDoc() == aDocument, "Incorrect aDocument"); +#ifdef ACCESSIBILITY + // A11y needs to be notified of content removals first, so accessibility + // events can be fired before any changes occur + if (aNotify && aDocument) { + nsIPresShell *presShell = aDocument->GetPrimaryShell(); + if (presShell && presShell->IsAccessibilityActive()) { + nsCOMPtr accService = + do_GetService("@mozilla.org/accessibilityService;1"); + if (accService) { + accService->InvalidateSubtreeFor(presShell, aKid, + nsIAccessibleEvent::EVENT_DOM_DESTROY); + } + } + } +#endif + nsMutationGuard::DidMutate(); nsINode* container = NODE_FROM(aParent, aDocument);