diff --git a/accessible/public/nsIAccessibilityService.idl b/accessible/public/nsIAccessibilityService.idl index 016f163c7e60..dab7993a042b 100644 --- a/accessible/public/nsIAccessibilityService.idl +++ b/accessible/public/nsIAccessibilityService.idl @@ -51,11 +51,12 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval nsIAccessible createRootAccessible(in nsIPresShell aShell, in nsIDocument aDocument); nsIAccessible createHTML4ButtonAccessible(in nsISupports aFrame); + nsIAccessible createXULAlertAccessible(in nsIDOMNode aNode); nsIAccessible createHTMLAreaAccessible(in nsIWeakReference aPresShell, in nsIDOMNode aDOMNode, in nsIAccessible aAccParent); nsIAccessible createHTMLBlockAccessible(in nsISupports aFrame); nsIAccessible createHTMLButtonAccessible(in nsISupports aFrame); nsIAccessible createHTMLButtonAccessibleXBL(in nsIDOMNode aNode); - nsIAccessible createHTMLAccessibleByMarkup(in nsISupports aFrame); + nsIAccessible createHTMLAccessibleByMarkup(in nsISupports aFrame, in nsIWeakReference aWeakShell, in nsIDOMNode aDOMNode); nsIAccessible createHTMLLIAccessible(in nsISupports aFrame, in nsISupports aBulletFrame, in AString aBulletText); nsIAccessible createHTMLCheckboxAccessible(in nsISupports aFrame); nsIAccessible createHTMLCheckboxAccessibleXBL(in nsIDOMNode aNode); diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index e48fbbc5a72d..1d792c8b2972 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -76,6 +76,7 @@ #include "nsPIAccessNode.h" #ifdef MOZ_XUL +#include "nsXULAlertAccessible.h" #include "nsXULColorPickerAccessible.h" #include "nsXULFormControlAccessible.h" #include "nsXULMenuAccessible.h" @@ -418,34 +419,29 @@ nsAccessibilityService::CreateHTMLButtonAccessibleXBL(nsIDOMNode *aNode, nsIAcce } NS_IMETHODIMP -nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsISupports *aFrame, +nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsISupports *aFrame, + nsIWeakReference *aWeakShell, + nsIDOMNode *aNode, nsIAccessible **aAccessible) { - // Frame type was generic, we'll use the DOM to decide + // aFrame type was generic, we'll use the DOM to decide // if and what kind of accessible object is needed. // This method assumes we're in an HTML namespace. *aAccessible = nsnull; - nsIFrame* frame; - nsCOMPtr node; - nsCOMPtr weakShell; - nsresult rv = GetInfo(aFrame, &frame, getter_AddRefs(weakShell), getter_AddRefs(node)); - NS_ENSURE_SUCCESS(rv, rv); - nsIContent *content = frame->GetContent(); - NS_ENSURE_TRUE(content, NS_ERROR_FAILURE); - + nsCOMPtr content(do_QueryInterface(aNode)); nsIAtom *tag = content->Tag(); if (tag == nsAccessibilityAtoms::option) { - *aAccessible = new nsHTMLSelectOptionAccessible(node, weakShell); + *aAccessible = new nsHTMLSelectOptionAccessible(aNode, aWeakShell); } else if (tag == nsAccessibilityAtoms::optgroup) { - *aAccessible = new nsHTMLSelectOptGroupAccessible(node, weakShell); + *aAccessible = new nsHTMLSelectOptGroupAccessible(aNode, aWeakShell); } #ifndef MOZ_ACCESSIBILITY_ATK else if (tag == nsAccessibilityAtoms::ul || tag == nsAccessibilityAtoms::ol) { - *aAccessible = new nsHTMLListAccessible(node, weakShell); + *aAccessible = new nsHTMLListAccessible(aNode, aWeakShell); } else if (tag == nsAccessibilityAtoms::a) { - *aAccessible = new nsHTMLLinkAccessible(node, weakShell, frame); + *aAccessible = new nsHTMLLinkAccessible(aNode, aWeakShell, NS_STATIC_CAST(nsIFrame*, aFrame)); } #endif else if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::tabindex) || @@ -463,7 +459,7 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsISupports *aFrame, tag == nsAccessibilityAtoms::q #endif ) { - *aAccessible = new nsAccessibleWrap(node, weakShell); + *aAccessible = new nsAccessibleWrap(aNode, aWeakShell); } NS_IF_ADDREF(*aAccessible); return NS_OK; @@ -1230,6 +1226,24 @@ nsAccessibilityService::CreateXULMenuSeparatorAccessible(nsIDOMNode *aNode, nsIA return NS_OK; } +NS_IMETHODIMP +nsAccessibilityService::CreateXULAlertAccessible(nsIDOMNode *aNode, nsIAccessible **aAccessible) +{ +#ifdef MOZ_XUL + nsCOMPtr weakShell; + GetShellFromNode(aNode, getter_AddRefs(weakShell)); + + *aAccessible = new nsXULAlertAccessible(aNode, weakShell); + if (! *aAccessible) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*aAccessible); +#else + *_retval = nsnull; +#endif + return NS_OK; +} + NS_IMETHODIMP nsAccessibilityService::CreateXULProgressMeterAccessible(nsIDOMNode *aNode, nsIAccessible **_retval) { @@ -1793,7 +1807,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, if (!newAcc) { // Use markup (mostly tag name, perhaps attributes) to // decide if and what kind of accessible to create. - CreateHTMLAccessibleByMarkup(frame, getter_AddRefs(newAcc)); + CreateHTMLAccessibleByMarkup(frame, aWeakShell, aNode, getter_AddRefs(newAcc)); } } diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index c1092a3eb244..dba03400241b 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -1348,6 +1348,7 @@ nsRoleMapEntry nsAccessible::gWAIRoleMap[] = // Using RDF will also allow for role extensibility. // XXX Should we store attribute names in this table as atoms instead of strings? // Definition of nsRoleMapEntry and nsStateMapEntry contains comments explaining this table. + {"alert", ROLE_ALERT, eAggregateSubtree, 0, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, {"button", ROLE_PUSHBUTTON, eAggregateSubtree, 0, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, {"checkbox", ROLE_CHECKBUTTON, eAggregateSubtree, 0, {"checked", "true", STATE_CHECKED}, {"readonly", 0, STATE_READONLY}, {0, 0, 0}}, {"checkbox-tristate", ROLE_CHECKBUTTON, eAggregateSubtree, 0, {"checked", "true", STATE_CHECKED}, {"checked", "mixed", STATE_MIXED}, {"readonly", 0, STATE_READONLY}}, diff --git a/accessible/src/base/nsRootAccessible.cpp b/accessible/src/base/nsRootAccessible.cpp index 47fb6cf457d8..5c7e28884a21 100644 --- a/accessible/src/base/nsRootAccessible.cpp +++ b/accessible/src/base/nsRootAccessible.cpp @@ -232,6 +232,10 @@ nsresult nsRootAccessible::AddEventListeners() rv = target->AddEventListener(NS_LITERAL_STRING("ValueChange"), NS_STATIC_CAST(nsIDOMXULListener*, this), PR_TRUE); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register listener"); + // capture AlertActive events (fired whenever alert pops up) + rv = target->AddEventListener(NS_LITERAL_STRING("AlertActive"), NS_STATIC_CAST(nsIDOMXULListener*, this), PR_TRUE); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register listener"); + // add ourself as a OpenStateChange listener (custom event fired in tree.xml) rv = target->AddEventListener(NS_LITERAL_STRING("OpenStateChange"), NS_STATIC_CAST(nsIDOMXULListener*, this), PR_TRUE); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register listener"); @@ -288,6 +292,7 @@ nsresult nsRootAccessible::RemoveEventListeners() target->RemoveEventListener(NS_LITERAL_STRING("focus"), NS_STATIC_CAST(nsIDOMFocusListener*, this), PR_TRUE); target->RemoveEventListener(NS_LITERAL_STRING("select"), NS_STATIC_CAST(nsIDOMFormListener*, this), PR_TRUE); target->RemoveEventListener(NS_LITERAL_STRING("ValueChange"), NS_STATIC_CAST(nsIDOMXULListener*, this), PR_TRUE); + target->RemoveEventListener(NS_LITERAL_STRING("AlertActive"), NS_STATIC_CAST(nsIDOMXULListener*, this), PR_TRUE); target->RemoveEventListener(NS_LITERAL_STRING("OpenStateChange"), NS_STATIC_CAST(nsIDOMXULListener*, this), PR_TRUE); target->RemoveEventListener(NS_LITERAL_STRING("CheckboxStateChange"), NS_STATIC_CAST(nsIDOMXULListener*, this), PR_TRUE); target->RemoveEventListener(NS_LITERAL_STRING("RadioStateChange"), NS_STATIC_CAST(nsIDOMXULListener*, this), PR_TRUE); @@ -674,6 +679,10 @@ NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent) privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, accessible, nsnull); } + else if (eventType.EqualsLiteral("AlertActive")) { + privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_ALERT, + accessible, nsnull); + } else if (eventType.LowerCaseEqualsLiteral("checkboxstatechange") || eventType.LowerCaseEqualsLiteral("openstatechange")) { privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, diff --git a/accessible/src/msaa/nsAccessibleWrap.cpp b/accessible/src/msaa/nsAccessibleWrap.cpp index 33703b509cf5..3634750b1215 100644 --- a/accessible/src/msaa/nsAccessibleWrap.cpp +++ b/accessible/src/msaa/nsAccessibleWrap.cpp @@ -237,8 +237,9 @@ STDMETHODIMP nsAccessibleWrap::get_accName( nsAutoString name; if (NS_FAILED(xpAccessible->GetName(name))) return S_FALSE; - - *pszName = ::SysAllocString(name.get()); + if (!name.IsVoid()) { + *pszName = ::SysAllocString(name.get()); + } NS_ASSERTION(mIsInitialized, "Access node was not initialized"); } diff --git a/accessible/src/xul/Makefile.in b/accessible/src/xul/Makefile.in index a214b723f870..089bcc9f1b78 100644 --- a/accessible/src/xul/Makefile.in +++ b/accessible/src/xul/Makefile.in @@ -65,6 +65,7 @@ REQUIRES += editor endif CPPSRCS = \ + nsXULAlertAccessible.cpp \ nsXULColorPickerAccessible.cpp \ nsXULFormControlAccessible.cpp \ nsXULMenuAccessible.cpp \ diff --git a/toolkit/content/widgets/tabbrowser.xml b/toolkit/content/widgets/tabbrowser.xml index ac6e42eb47cc..e714468d50c0 100644 --- a/toolkit/content/widgets/tabbrowser.xml +++ b/toolkit/content/widgets/tabbrowser.xml @@ -227,6 +227,10 @@ message.docShell = aDocShell; message.closeButton = aShowCloseButton; aBrowser.isShowingMessage = true; + // Fire event for accessibility APIs + var event = document.createEvent("Events"); + event.initEvent("AlertActive", true, true); + message.dispatchEvent(event); ]]>