diff --git a/accessible/src/base/nsAccUtils.cpp b/accessible/src/base/nsAccUtils.cpp index e8295019ed8..03c223646c5 100644 --- a/accessible/src/base/nsAccUtils.cpp +++ b/accessible/src/base/nsAccUtils.cpp @@ -405,8 +405,7 @@ nsAccUtils::IsARIASelected(nsAccessible *aAccessible) } already_AddRefed -nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection, - nsINode **aNode) +nsAccUtils::GetTextAccessibleFromSelection(nsISelection* aSelection) { // Get accessible from selection's focus DOM point (the DOM point where // selection is ended). @@ -435,12 +434,9 @@ nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection, do { nsHyperTextAccessible* textAcc = nsnull; CallQueryInterface(accessible, &textAcc); - if (textAcc) { - if (aNode) - NS_ADDREF(*aNode = accessible->GetNode()); - + if (textAcc) return textAcc; - } + } while (accessible = accessible->GetParent()); NS_NOTREACHED("We must reach document accessible implementing nsIAccessibleText!"); diff --git a/accessible/src/base/nsAccUtils.h b/accessible/src/base/nsAccUtils.h index 9f3812fd41a..f7902890120 100644 --- a/accessible/src/base/nsAccUtils.h +++ b/accessible/src/base/nsAccUtils.h @@ -223,12 +223,10 @@ public: * Used for normal and misspelling selection changes processing. * * @param aSelection [in] the given selection - * @param aNode [out, optional] the DOM node of text accessible * @return text accessible */ static already_AddRefed - GetTextAccessibleFromSelection(nsISelection *aSelection, - nsINode **aNode = nsnull); + GetTextAccessibleFromSelection(nsISelection* aSelection); /** * Converts the given coordinates to coordinates relative screen. diff --git a/accessible/src/base/nsCaretAccessible.cpp b/accessible/src/base/nsCaretAccessible.cpp index f68e7d0c7c3..24b438b4af1 100644 --- a/accessible/src/base/nsCaretAccessible.cpp +++ b/accessible/src/base/nsCaretAccessible.cpp @@ -201,78 +201,76 @@ nsCaretAccessible::RemoveDocSelectionListener(nsIPresShell *aShell) } NS_IMETHODIMP -nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, - nsISelection *aSel, +nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument* aDOMDocument, + nsISelection* aSelection, PRInt16 aReason) { - NS_ENSURE_ARG(aDoc); + NS_ENSURE_ARG(aDOMDocument); + NS_ENSURE_STATE(mRootAccessible); - nsCOMPtr document(do_QueryInterface(aDoc)); - nsDocAccessible *docAccessible = GetAccService()->GetDocAccessible(document); + nsCOMPtr documentNode(do_QueryInterface(aDOMDocument)); + nsDocAccessible* document = GetAccService()->GetDocAccessible(documentNode); // Don't fire events until document is loaded. - if (!docAccessible || !docAccessible->IsContentLoaded()) + if (!document || !document->IsContentLoaded()) return NS_OK; - nsCOMPtr sel2(do_QueryInterface(aSel)); + nsCOMPtr sel2(do_QueryInterface(aSelection)); PRInt16 type = 0; sel2->GetType(&type); if (type == nsISelectionController::SELECTION_NORMAL) - return NormalSelectionChanged(aDoc, aSel); + NormalSelectionChanged(document, aSelection); - if (type == nsISelectionController::SELECTION_SPELLCHECK) - return SpellcheckSelectionChanged(aDoc, aSel); + else if (type == nsISelectionController::SELECTION_SPELLCHECK) + SpellcheckSelectionChanged(document, aSelection); return NS_OK; } -nsresult -nsCaretAccessible::NormalSelectionChanged(nsIDOMDocument *aDoc, - nsISelection *aSel) +void +nsCaretAccessible::NormalSelectionChanged(nsDocAccessible* aDocument, + nsISelection* aSelection) { - NS_ENSURE_TRUE(mRootAccessible, NS_ERROR_FAILURE); - - mLastUsedSelection = do_GetWeakReference(aSel); + mLastUsedSelection = do_GetWeakReference(aSelection); PRInt32 rangeCount = 0; - nsresult rv = aSel->GetRangeCount(&rangeCount); - NS_ENSURE_SUCCESS(rv, rv); - + aSelection->GetRangeCount(&rangeCount); if (rangeCount == 0) { mLastTextAccessible = nsnull; - return NS_OK; // No selection + return; // No selection } - nsCOMPtr textNode; nsRefPtr textAcc = - nsAccUtils::GetTextAccessibleFromSelection(aSel, getter_AddRefs(textNode)); - NS_ENSURE_STATE(textAcc); + nsAccUtils::GetTextAccessibleFromSelection(aSelection); + if (!textAcc) + return; - PRInt32 caretOffset; - rv = textAcc->GetCaretOffset(&caretOffset); - NS_ENSURE_SUCCESS(rv, rv); + PRInt32 caretOffset = -1; + nsresult rv = textAcc->GetCaretOffset(&caretOffset); + if (NS_FAILED(rv)) + return; if (textAcc == mLastTextAccessible && caretOffset == mLastCaretOffset) { - PRInt32 selectionCount; + PRInt32 selectionCount = 0; textAcc->GetSelectionCount(&selectionCount); // Don't swallow similar events when selecting text - if (!selectionCount) { - return NS_OK; // Swallow duplicate caret event - } + if (!selectionCount) + return; // Swallow duplicate caret event } + mLastCaretOffset = caretOffset; mLastTextAccessible.swap(textAcc); - nsRefPtr event = new AccCaretMoveEvent(textNode); - NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY); - - return mRootAccessible->FireDelayedAccessibleEvent(event); + nsRefPtr event = + new AccCaretMoveEvent(mLastTextAccessible->GetNode()); + if (event) + aDocument->FireDelayedAccessibleEvent(event); } -nsresult -nsCaretAccessible::SpellcheckSelectionChanged(nsIDOMDocument *aDoc, - nsISelection *aSel) +void +nsCaretAccessible::SpellcheckSelectionChanged(nsDocAccessible* aDocument, + nsISelection* aSelection) { // XXX: fire an event for accessible of focus node of the selection. If // spellchecking is enabled then we will fire the number of events for @@ -281,14 +279,14 @@ nsCaretAccessible::SpellcheckSelectionChanged(nsIDOMDocument *aDoc, // @spellcheck="false" on html:body) then we won't fire any event. nsRefPtr textAcc = - nsAccUtils::GetTextAccessibleFromSelection(aSel); - NS_ENSURE_STATE(textAcc); + nsAccUtils::GetTextAccessibleFromSelection(aSelection); + if (!textAcc) + return; nsRefPtr event = new AccEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED, textAcc); - - nsEventShell::FireEvent(event); - return NS_OK; + if (event) + aDocument->FireDelayedAccessibleEvent(event); } nsIntRect diff --git a/accessible/src/base/nsCaretAccessible.h b/accessible/src/base/nsCaretAccessible.h index 0d9818a9f00..a52f8596191 100644 --- a/accessible/src/base/nsCaretAccessible.h +++ b/accessible/src/base/nsCaretAccessible.h @@ -116,8 +116,18 @@ public: nsIntRect GetCaretRect(nsIWidget **aOutWidget); protected: - nsresult NormalSelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel); - nsresult SpellcheckSelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel); + /** + * Process normal selection change and fire caret move event. + */ + void NormalSelectionChanged(nsDocAccessible* aDocument, + nsISelection* aSelection); + + /** + * Process spellcheck selection change and fire text attribute changed event + * for invalid text attribute. + */ + void SpellcheckSelectionChanged(nsDocAccessible* aDocument, + nsISelection* aSelection); /** * Return selection controller for the given node. diff --git a/accessible/tests/mochitest/test_text_caret.html b/accessible/tests/mochitest/test_text_caret.html index 5c25b04e4ac..43bcfd45d1b 100644 --- a/accessible/tests/mochitest/test_text_caret.html +++ b/accessible/tests/mochitest/test_text_caret.html @@ -43,15 +43,16 @@ this.invoke = function setCaretOffsetInvoker_invoke() { this.target.caretOffset = aOffset; + todo(false, "Enable focus event handling when bug 422744 is fixed."); } this.getID = function setCaretOffsetInvoker_getID() { - "nsIAccessibleText::caretOffset test" + return "nsIAccessibleText::caretOffset test"; } this.eventSeq = [ - new invokerChecker(EVENT_FOCUS, this.target), + // new invokerChecker(EVENT_FOCUS, this.target), new caretMovedChecker(this.target, aOffset) ]; }