Support official DHTML a11y application content type. r+sr=jst, a=mkaply

This commit is contained in:
aaronleventhal%moonset.net 2005-06-24 19:16:45 +00:00
Родитель cc15ff2330
Коммит 7e54b4fb70
12 изменённых файлов: 165 добавлений и 48 удалений

Просмотреть файл

@ -57,7 +57,7 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval
nsIAccessible createHTMLBlockAccessible(in nsISupports aFrame);
nsIAccessible createHTMLButtonAccessible(in nsISupports aFrame);
nsIAccessible createHTMLButtonAccessibleXBL(in nsIDOMNode aNode);
nsIAccessible createHTMLAccessibleByMarkup(in nsISupports aFrame, in nsIWeakReference aWeakShell, in nsIDOMNode aDOMNode);
nsIAccessible createHTMLAccessibleByMarkup(in nsISupports aFrame, in nsIWeakReference aWeakShell, in nsIDOMNode aDOMNode, in AString aRole);
nsIAccessible createHTMLLIAccessible(in nsISupports aFrame, in nsISupports aBulletFrame, in AString aBulletText);
nsIAccessible createHTMLCheckboxAccessible(in nsISupports aFrame);
nsIAccessible createHTMLCheckboxAccessibleXBL(in nsIDOMNode aNode);

Просмотреть файл

@ -287,9 +287,12 @@ interface nsIAccessible : nsISupports
const unsigned long STATE_HASPOPUP = 0x40000000; // New in MSAA 2.0
// Mapping important states that we don't have to unused alert states on MSAA
// as per discussions with AT vendors. On ATK there will be legitimate states for these
// as per discussions with AT vendors. On ATK there will be legitimate states for
// STATE_REQUIRED AND STATE_INVALID
const unsigned long STATE_REQUIRED = STATE_ALERT_LOW;
const unsigned long STATE_IMPORTANT = STATE_ALERT_MEDIUM;
const unsigned long STATE_INVALID = STATE_ALERT_HIGH;
const unsigned long STATE_CHECKABLE = STATE_MARQUEED;
/**
* Extended state flags (for now non-MSAA, for Java and Gnome/ATK support)

Просмотреть файл

@ -41,7 +41,7 @@
interface nsIAccessNode;
interface nsIContent;
[uuid(eae56f75-ee68-4120-b113-10f21b75509e)]
[uuid(c4aa12b5-2234-4505-aafb-af3a9d6f8144)]
interface nsPIAccessibleDocument : nsISupports
{
/**
@ -64,4 +64,5 @@ interface nsPIAccessibleDocument : nsISupports
void flushPendingEvents();
void fireDocLoadingEvent(in boolean isFinished);
void fireAnchorJumpEvent();
[notxpcom] boolean IsSpecialXHTMLApplication();
};

Просмотреть файл

@ -60,6 +60,7 @@ REQUIRES = commandhandler \
plugin \
pref \
string \
unicharutil \
uriloader \
view \
webshell \

Просмотреть файл

@ -86,10 +86,14 @@ ACCESSIBILITY_ATOM(optgroup, "optgroup")
ACCESSIBILITY_ATOM(option, "option")
ACCESSIBILITY_ATOM(q, "q")
ACCESSIBILITY_ATOM(select, "select")
ACCESSIBILITY_ATOM(table, "table")
ACCESSIBILITY_ATOM(tbody, "tbody")
ACCESSIBILITY_ATOM(td, "td")
ACCESSIBILITY_ATOM(th, "th")
ACCESSIBILITY_ATOM(tfoot, "tfoot")
ACCESSIBILITY_ATOM(thead, "thead")
ACCESSIBILITY_ATOM(toolbaritem, "toolbaritem") // XUL
ACCESSIBILITY_ATOM(tr, "tr")
ACCESSIBILITY_ATOM(ul, "ul")
// DHTML accessibility relationship attributes

Просмотреть файл

@ -74,6 +74,7 @@
#include "nsRootAccessibleWrap.h"
#include "nsTextFragment.h"
#include "nsPIAccessNode.h"
#include "nsUnicharUtils.h"
#include "nsIWebProgress.h"
#ifdef MOZ_XUL
@ -469,10 +470,32 @@ nsAccessibilityService::CreateHTMLButtonAccessibleXBL(nsIDOMNode *aNode, nsIAcce
return NS_OK;
}
NS_IMETHODIMP
PRBool nsAccessibilityService::GetRole(nsIContent *aContent,
nsIWeakReference *aWeakShell,
nsAString& aRole)
{
nsCOMPtr<nsIAccessibleDocument> docAccessible =
nsAccessNode::GetDocAccessibleFor(aWeakShell);
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc =
do_QueryInterface(docAccessible);
PRInt32 roleNameSpace = kNameSpaceID_None;
if (!privateAccessibleDoc ||
privateAccessibleDoc->IsSpecialXHTMLApplication()) {
// Application doctype does not need namespaced attributes for role and states
roleNameSpace = kNameSpaceID_None;
}
else {
roleNameSpace = kNameSpaceID_XHTML2_Unofficial;
}
return NS_CONTENT_ATTR_HAS_VALUE ==
aContent->GetAttr(roleNameSpace, nsAccessibilityAtoms::role, aRole);
}
nsresult
nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsISupports *aFrame,
nsIWeakReference *aWeakShell,
nsIDOMNode *aNode,
const nsAString& aRole,
nsIAccessible **aAccessible)
{
// aFrame type was generic, we'll use the DOM to decide
@ -494,14 +517,7 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsISupports *aFrame,
else if (tag == nsAccessibilityAtoms::a) {
*aAccessible = new nsHTMLLinkAccessible(aNode, aWeakShell, NS_STATIC_CAST(nsIFrame*, aFrame));
}
#endif
else if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::tabindex) ||
(content->HasAttr(kNameSpaceID_XHTML2_Unofficial, nsAccessibilityAtoms::role) &&
tag != nsAccessibilityAtoms::body && content->GetParent())
// The role from a <body> or doc element is already exposed in nsDocAccessible
#ifndef MOZ_ACCESSIBILITY_ATK
||
tag == nsAccessibilityAtoms::abbr ||
else if (tag == nsAccessibilityAtoms::abbr ||
tag == nsAccessibilityAtoms::acronym ||
tag == nsAccessibilityAtoms::blockquote ||
tag == nsAccessibilityAtoms::form ||
@ -514,9 +530,14 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsISupports *aFrame,
tag == nsAccessibilityAtoms::q ||
tag == nsAccessibilityAtoms::tbody ||
tag == nsAccessibilityAtoms::tfoot ||
tag == nsAccessibilityAtoms::thead
tag == nsAccessibilityAtoms::thead ||
#else
else if (
#endif
) {
content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::tabindex) ||
// The role from a <body> or doc element is already exposed in nsDocAccessible
(tag != nsAccessibilityAtoms::body && content->GetParent() &&
!aRole.IsEmpty())) {
*aAccessible = new nsAccessibleWrap(aNode, aWeakShell);
}
NS_IF_ADDREF(*aAccessible);
@ -1855,11 +1876,47 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
}
else {
// --- Try creating accessible for HTML ---
nsAutoString role;
GetRole(content, aWeakShell, role);
if (!content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::tabindex)) {
// If no tabindex, check for a Presentation role, which
// tells us not to expose this to the accessibility hierarchy.
if (StringEndsWith(role, NS_LITERAL_STRING(":presentation"),
nsCaseInsensitiveStringComparator())) {
return NS_ERROR_FAILURE;
}
else {
// If we're in table-related subcontent, check for the
// Presentation role on the containing table
nsIAtom *tag = content->Tag();
if (tag == nsAccessibilityAtoms::td ||
tag == nsAccessibilityAtoms::th ||
tag == nsAccessibilityAtoms::tr ||
tag == nsAccessibilityAtoms::tbody ||
tag == nsAccessibilityAtoms::tfoot ||
tag == nsAccessibilityAtoms::thead) {
nsIContent *tableContent = content;
nsAutoString tableRole;
while ((tableContent = tableContent->GetParent()) != nsnull) {
if (tableContent->Tag() == nsAccessibilityAtoms::table) {
if (GetRole(tableContent, aWeakShell, tableRole) &&
StringEndsWith(tableRole, NS_LITERAL_STRING(":presentation"),
nsCaseInsensitiveStringComparator())) {
// Table that we're a descendant of is presentational
return NS_ERROR_FAILURE;
}
break;
}
}
}
}
}
frame->GetAccessible(getter_AddRefs(newAcc)); // Try using frame to do it
if (!newAcc) {
// Use markup (mostly tag name, perhaps attributes) to
// decide if and what kind of accessible to create.
CreateHTMLAccessibleByMarkup(frame, aWeakShell, aNode, getter_AddRefs(newAcc));
CreateHTMLAccessibleByMarkup(frame, aWeakShell, aNode, role, getter_AddRefs(newAcc));
}
}

Просмотреть файл

@ -76,6 +76,7 @@ private:
nsIContent* FindContentForDocShell(nsIPresShell* aPresShell, nsIContent* aContent, nsIDocShell* aDocShell);
static nsAccessibilityService *gAccessibilityService;
nsresult InitAccessible(nsIAccessible *aAccessibleIn, nsIAccessible **aAccessibleOut);
PRBool GetRole(nsIContent *aContent, nsIWeakReference *aWeakShell, nsAString& aRole);
};
#endif /* __nsIAccessibilityService_h__ */

Просмотреть файл

@ -39,6 +39,7 @@
#include "nsAccessible.h"
#include "nsIAccessibleDocument.h"
#include "nsPIAccessibleDocument.h"
#include "nsIDocument.h"
#include "nsIDOMNSDocument.h"
#include "nsIImageDocument.h"
@ -249,16 +250,30 @@ NS_IMETHODIMP nsAccessible::SetNextSibling(nsIAccessible *aNextSibling)
return NS_OK;
}
PRBool nsAccessible::IsSpecialXHTMLApplication()
{
nsCOMPtr<nsIAccessibleDocument> docAccessible(GetDocAccessible());
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc =
do_QueryInterface(docAccessible);
return privateAccessibleDoc ?
privateAccessibleDoc->IsSpecialXHTMLApplication() :
PR_FALSE;
}
NS_IMETHODIMP nsAccessible::Init()
{
nsIContent *content = GetRoleContent(mDOMNode);
nsAutoString roleString;
PRInt32 roleNameSpace = IsSpecialXHTMLApplication() ? kNameSpaceID_None :
kNameSpaceID_XHTML2_Unofficial;
if (content &&
NS_CONTENT_ATTR_HAS_VALUE == content->GetAttr(kNameSpaceID_XHTML2_Unofficial,
NS_CONTENT_ATTR_HAS_VALUE == content->GetAttr(roleNameSpace,
nsAccessibilityAtoms::role,
roleString)) {
// QI to nsIDOM3Node causes some overhead. Unfortunately we need to do this each
// time there is a role attribute, because the prefixe to namespace mappings
// time there is a role attribute, because the prefix to namespace mappings
// can change within any subtree via the xmlns attribute
nsCOMPtr<nsIDOM3Node> dom3Node(do_QueryInterface(content));
if (dom3Node) {
@ -283,6 +298,7 @@ NS_IMETHODIMP nsAccessible::Init()
if (length > 1 && StringBeginsWith(roleString, prefix)) {
roleString.Cut(0, length);
nsCString utf8Role = NS_ConvertUCS2toUTF8(roleString); // For easy comparison
ToLowerCase(utf8Role);
PRUint32 index;
for (index = 0; gWAIRoleMap[index].roleString; index ++) {
if (utf8Role.Equals(gWAIRoleMap[index].roleString)) {
@ -1515,13 +1531,14 @@ nsRoleMapEntry nsAccessible::gWAIRoleMap[] =
{"button", ROLE_PUSHBUTTON, eNameOkFromChildren, eNoValue, eNoReqStates,
{"pressed", BOOL_STATE, STATE_PRESSED},
{"haspopup", BOOL_STATE, STATE_HASPOPUP}, END_ENTRY},
{"button-submit", ROLE_PUSHBUTTON, eNameOkFromChildren, eNoValue, STATE_DEFAULT, END_ENTRY},
{"checkbox", ROLE_CHECKBUTTON, eNameOkFromChildren, eNoValue, eNoReqStates,
{"buttonsubmit", ROLE_PUSHBUTTON, eNameOkFromChildren, eNoValue, STATE_DEFAULT, END_ENTRY},
{"buttoncancel", ROLE_PUSHBUTTON, eNameOkFromChildren, eNoValue, eNoReqStates, END_ENTRY},
{"checkbox", ROLE_CHECKBUTTON, eNameOkFromChildren, eNoValue, STATE_CHECKABLE,
{"checked", BOOL_STATE, STATE_CHECKED},
{"readonly", BOOL_STATE, STATE_READONLY},
{"invalid", BOOL_STATE, STATE_INVALID},
{"required", BOOL_STATE, STATE_REQUIRED}, END_ENTRY},
{"checkbox-tristate", ROLE_CHECKBUTTON, eNameOkFromChildren, eNoValue, eNoReqStates,
{"checkboxtristate", ROLE_CHECKBUTTON, eNameOkFromChildren, eNoValue, STATE_CHECKABLE,
{"checked", BOOL_STATE, STATE_CHECKED},
{"checked", "mixed", STATE_MIXED},
{"readonly", BOOL_STATE, STATE_READONLY},
@ -1541,19 +1558,19 @@ nsRoleMapEntry nsAccessible::gWAIRoleMap[] =
{"list", ROLE_LIST, eNameLabelOrTitle, eNoValue, eNoReqStates,
{"readonly", BOOL_STATE, STATE_READONLY},
{"multiselect", BOOL_STATE, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE}, END_ENTRY},
{"listitem", ROLE_LISTITEM, eNameOkFromChildren, eNoValue, STATE_SELECTABLE, END_ENTRY},
{"listitem-checkbox", ROLE_LISTITEM, eNameOkFromChildren, eNoValue, STATE_SELECTABLE,
{"checked", BOOL_STATE, STATE_CHECKED}, END_ENTRY },
{"listitem", ROLE_LISTITEM, eNameOkFromChildren, eNoValue, STATE_SELECTABLE,
{"checked", BOOL_STATE, STATE_CHECKED | STATE_CHECKABLE},
{"checked", "false", STATE_CHECKABLE}, END_ENTRY},
{"menu", ROLE_MENUPOPUP, eNameLabelOrTitle, eNoValue, eNoReqStates, END_ENTRY},
{"menubar", ROLE_MENUBAR, eNameLabelOrTitle, eNoValue, eNoReqStates, END_ENTRY},
{"menuitem", ROLE_MENUITEM, eNameOkFromChildren, eNoValue, eNoReqStates,
{"haspopup", BOOL_STATE, STATE_HASPOPUP}, END_ENTRY},
{"menuitem-radio", ROLE_MENUITEM, eNameOkFromChildren, eNoValue, eNoReqStates,
{"haspopup", BOOL_STATE, STATE_HASPOPUP},
{"checked", BOOL_STATE, STATE_CHECKED}, END_ENTRY},
{"menuitem-checkbox", ROLE_MENUITEM, eNameOkFromChildren, eNoValue, eNoReqStates,
{"checked", BOOL_STATE, STATE_CHECKED | STATE_CHECKABLE},
{"checked", "false", STATE_CHECKABLE}, END_ENTRY},
{"menuitemradio", ROLE_MENUITEM, eNameOkFromChildren, eNoValue, eNoReqStates,
{"haspopup", BOOL_STATE, STATE_HASPOPUP},
{"checked", BOOL_STATE, STATE_CHECKED}, END_ENTRY},
{"checked", BOOL_STATE, STATE_CHECKED | STATE_CHECKABLE},
{"checked", "false", STATE_CHECKABLE}, END_ENTRY},
{"grid", ROLE_TABLE, eNameLabelOrTitle, eNoValue, STATE_FOCUSABLE,
{"readonly", BOOL_STATE, STATE_READONLY}, END_ENTRY},
{"gridcell", ROLE_CELL, eNameOkFromChildren, eHasValueMinMax, STATE_SELECTABLE,
@ -1604,14 +1621,11 @@ nsRoleMapEntry nsAccessible::gWAIRoleMap[] =
{"readonly", BOOL_STATE, STATE_READONLY},
{"multiselectable", BOOL_STATE, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE}, END_ENTRY},
{"treeitem", ROLE_OUTLINEITEM, eNameOkFromChildren, eNoValue, STATE_SELECTABLE,
{"selected", BOOL_STATE, STATE_SELECTED},
{"expanded", BOOL_STATE, STATE_EXPANDED},
{"expanded", "false", STATE_COLLAPSED}, END_ENTRY},
{"treeitem-checkbox", ROLE_OUTLINEITEM, eNameOkFromChildren, eNoValue, STATE_SELECTABLE,
{"selected", BOOL_STATE, STATE_SELECTED},
{"expanded", BOOL_STATE, STATE_EXPANDED},
{"expanded", "false", STATE_COLLAPSED},
{"checked", BOOL_STATE, STATE_CHECKED}, END_ENTRY},
{"checked", BOOL_STATE, STATE_CHECKED | STATE_CHECKABLE},
{"checked", "false", STATE_CHECKABLE}, END_ENTRY},
{nsnull, ROLE_NOTHING, eNameLabelOrTitle, eNoValue, eNoReqStates, END_ENTRY} // Last item
};
@ -1633,6 +1647,7 @@ NS_IMETHODIMP nsAccessible::GetFinalRole(PRUint32 *aRole)
}
PRBool nsAccessible::MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut,
PRInt32 aNameSpace,
nsStateMapEntry *aStateMapEntry)
{
// Return true if we should continue
@ -1642,7 +1657,7 @@ PRBool nsAccessible::MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut
nsAutoString attribValue;
nsCOMPtr<nsIAtom> attribAtom = do_GetAtom(aStateMapEntry->attributeName); // XXX put atoms directly in entry
if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttr(kNameSpaceID_StatesWAI_Unofficial,
if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttr(aNameSpace,
attribAtom,
attribValue)) {
if (aStateMapEntry->attributeValue == BOOL_STATE) {
@ -1698,15 +1713,18 @@ NS_IMETHODIMP nsAccessible::GetFinalState(PRUint32 *aState)
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
if (content) {
PRInt32 stateNS = IsSpecialXHTMLApplication() ? kNameSpaceID_None :
kNameSpaceID_StatesWAI_Unofficial;
finalState |= mRoleMapEntry->state;
if (MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap1) &&
MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap2) &&
MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap3) &&
MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap4)) {
MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap5);
if (MappedAttrState(content, &finalState, stateNS, &mRoleMapEntry->attributeMap1) &&
MappedAttrState(content, &finalState, stateNS, &mRoleMapEntry->attributeMap2) &&
MappedAttrState(content, &finalState, stateNS, &mRoleMapEntry->attributeMap3) &&
MappedAttrState(content, &finalState, stateNS, &mRoleMapEntry->attributeMap4) &&
MappedAttrState(content, &finalState, stateNS, &mRoleMapEntry->attributeMap5)) {
MappedAttrState(content, &finalState, stateNS, &mRoleMapEntry->attributeMap6);
}
// Anything can be disabled/unavailable
MappedAttrState(content, &finalState, &gDisabledStateMap);
MappedAttrState(content, &finalState, stateNS, &gDisabledStateMap);
}
*aState = finalState;

Просмотреть файл

@ -102,6 +102,7 @@ struct nsRoleMapEntry
nsStateMapEntry attributeMap3;
nsStateMapEntry attributeMap4;
nsStateMapEntry attributeMap5;
nsStateMapEntry attributeMap6;
};
class nsAccessible : public nsAccessNodeWrap,
@ -139,7 +140,8 @@ public:
static PRBool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom);
protected:
PRBool MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut, nsStateMapEntry *aStateMapEntry);
PRBool MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut,
PRInt32 aStateNameSpace, nsStateMapEntry *aStateMapEntry);
virtual nsIFrame* GetBoundsFrame();
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
PRBool IsPartiallyVisible(PRBool *aIsOffscreen);
@ -176,6 +178,8 @@ protected:
static void DoCommandCallback(nsITimer *aTimer, void *aClosure);
nsresult DoCommand();
PRBool IsSpecialXHTMLApplication(); // Forwards to nsPIAccessibleDocument getter
// Data Members
nsCOMPtr<nsIAccessible> mParent;
nsIAccessible *mFirstChild, *mNextSibling;

Просмотреть файл

@ -54,6 +54,7 @@
#include "nsIDOMDocumentType.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMNSHTMLDocument.h"
#include "nsIHTMLDocument.h"
#include "nsIDOMWindow.h"
#include "nsIEditingSession.h"
#include "nsIFrame.h"
@ -65,6 +66,7 @@
#include "nsIScriptGlobalObject.h"
#include "nsIServiceManager.h"
#include "nsIScrollableView.h"
#include "nsUnicharUtils.h"
#include "nsIURI.h"
#include "nsIWebNavigation.h"
#ifdef MOZ_XUL
@ -80,7 +82,8 @@
//-----------------------------------------------------
nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
nsBlockAccessible(aDOMNode, aShell), mWnd(nsnull),
mEditor(nsnull), mScrollPositionChangedTicks(0)
mEditor(nsnull), mScrollPositionChangedTicks(0),
mIsSpecialXHTMLApplication(PR_FALSE)
{
// Because of the way document loading happens, the new nsIWidget is created before
// the old one is removed. Since it creates the nsDocAccessible, for a brief moment
@ -282,7 +285,7 @@ NS_IMETHODIMP nsDocAccessible::GetDocType(nsAString& aDocType)
} else
#endif
if (domDoc && NS_SUCCEEDED(domDoc->GetDoctype(getter_AddRefs(docType))) && docType) {
return docType->GetName(aDocType);
return docType->GetPublicId(aDocType);
}
return NS_ERROR_FAILURE;
@ -397,6 +400,23 @@ NS_IMETHODIMP nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *a
NS_IMETHODIMP nsDocAccessible::Init()
{
// If we're an HTML doc in standards mode, we might be
// using a special XHTML web application doc type.
// If we are, the DHTML role and state attributes can
// be in the default namespace for the document
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
nsAutoString docType;
if (htmlDoc) {
nsCompatibility mode = htmlDoc->GetCompatibilityMode();
if (mode == eCompatibility_FullStandards) {
GetDocType(docType);
if (docType.Find(NS_LITERAL_STRING("Application")) >= 0) {
// This means role and state needn't be namespaced
mIsSpecialXHTMLApplication = PR_TRUE;
}
}
}
// Hook up our new accessible with our parent
if (!mParent) {
nsIDocument *parentDoc = mDocument->GetParentDocument();
@ -1067,14 +1087,15 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
if (aChangeEventType == nsIAccessibleEvent::EVENT_SHOW && aChild) {
// Fire EVENT_SHOW, EVENT_MENUPOPUPSTART or EVENT_ALERT event for
// newly visible content. Create new accessible if necessary to do so.
PRInt32 roleNameSpace = IsSpecialXHTMLApplication() ? kNameSpaceID_None :
kNameSpaceID_XHTML2_Unofficial;
nsAutoString role;
aChild->GetAttr(kNameSpaceID_XHTML2_Unofficial, nsAccessibilityAtoms::role,
role);
aChild->GetAttr(roleNameSpace, nsAccessibilityAtoms::role, role);
PRUint32 event = 0;
if (StringEndsWith(role, NS_LITERAL_STRING(":alert"))) {
if (StringEndsWith(role, NS_LITERAL_STRING(":alert"), nsCaseInsensitiveStringComparator())) {
event = nsIAccessibleEvent::EVENT_ALERT;
}
else if (StringEndsWith(role, NS_LITERAL_STRING(":menu"))) {
else if (StringEndsWith(role, NS_LITERAL_STRING(":menu"), nsCaseInsensitiveStringComparator())) {
event = nsIAccessibleEvent::EVENT_MENUPOPUPSTART;
}
@ -1134,3 +1155,7 @@ NS_IMETHODIMP nsDocAccessible::FireToolkitEvent(PRUint32 aEvent, nsIAccessible*
return obsService->NotifyObservers(accEvent, NS_ACCESSIBLE_EVENT_TOPIC, nsnull);
}
PRBool nsDocAccessible::IsSpecialXHTMLApplication()
{
return mIsSpecialXHTMLApplication;
}

Просмотреть файл

@ -116,6 +116,7 @@ class nsDocAccessible : public nsBlockAccessible,
nsCOMPtr<nsIEditor> mEditor; // Editor, if there is one
PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
nsCOMArray<nsIAccessibleEvent> mEventsToFire;
PRBool mIsSpecialXHTMLApplication;
};
#endif

Просмотреть файл

@ -423,7 +423,9 @@ STDMETHODIMP nsAccessibleWrap::get_accRole(
if (content) {
nsAutoString roleString;
if (role != ROLE_CLIENT) {
content->GetAttr(kNameSpaceID_XHTML2_Unofficial, nsAccessibilityAtoms::role, roleString);
PRInt32 roleNameSpace = IsSpecialXHTMLApplication() ? kNameSpaceID_None :
kNameSpaceID_XHTML2_Unofficial;
content->GetAttr(roleNameSpace, nsAccessibilityAtoms::role, roleString);
}
if (roleString.IsEmpty()) {
nsINodeInfo *nodeInfo = content->GetNodeInfo();