Merge mozilla-central to tracemonkey.

This commit is contained in:
Robert Sayre 2010-01-29 09:51:21 -08:00
Родитель 539fc4642f c6707acced
Коммит 6eac0d504b
1854 изменённых файлов: 81274 добавлений и 39645 удалений

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

@ -88,7 +88,7 @@ DIST_GARBAGE = config.cache config.log config.status config-defs.h \
netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
$(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out
default alldep all::
default alldep all:: $(topsrcdir)/configure config.status
$(RM) -rf $(DIST)/sdk
$(RM) -rf $(DIST)/include
$(RM) -rf $(DIST)/private
@ -96,6 +96,20 @@ default alldep all::
$(RM) -rf $(DIST)/bin/components
$(RM) -rf _tests
$(topsrcdir)/configure: $(topsrcdir)/configure.in
@echo "STOP! configure.in has changed, and your configure is out of date."
@echo "Please rerun autoconf and re-configure your build directory."
@echo "To ignore this message, touch 'configure' in the source directory,"
@echo "but your build might not succeed."
@exit 1
config.status: $(topsrcdir)/configure
@echo "STOP! configure has changed and needs to be run in this build directory."
@echo "Please rerun configure."
@echo "To ignore this message, touch 'config.status' in the build directory,"
@echo "but your build might not succeed."
@exit 1
# Build pseudo-external modules first when export is explicitly called
export::
$(RM) -rf $(DIST)/sdk
@ -189,6 +203,21 @@ ifdef MOZ_CRASHREPORTER
$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
cd $(DIST)/crashreporter-symbols && \
zip -r9D "../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip" .
else
ifdef WINCE
ifdef SYMBOLSTORE_PATH
echo building symbol store with symstore.exe
$(RM) -rf $(DIST)/symbols
$(RM) -f "$(DIST)/$(SYMBOL_ARCHIVE_BASENAME).zip"
$(NSINSTALL) -D $(DIST)/symbols
$(SYMBOLSTORE_PATH) add -r -f "$(subst /,\,$(shell pwd -W))\*.PDB" \
-s $(DIST)/symbols/ -t "$(MOZ_PKG_APPNAME)" -v "$(MOZ_PKG_VERSION)"
echo packing symbols
$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
cd $(DIST)/symbols && \
zip -r9D "../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip" .
endif # SYMBOLSTORE_PATH
endif # WINCE
endif # MOZ_CRASHREPORTER
uploadsymbols:

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

@ -39,14 +39,12 @@
#include "nsISupports.idl"
#include "nsIAccessibleRetrieval.idl"
interface nsIAccessibleEventListener;
interface nsIDocument;
interface nsIFrame;
interface nsObjectFrame;
interface nsIContent;
interface nsITimer;
[uuid(61098f48-4fcc-4b05-9cf3-c11b8efbe682)]
[uuid(e0498def-1552-4763-8c47-6c6cc36c7aa0)]
interface nsIAccessibilityService : nsIAccessibleRetrieval
{
nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode);
@ -113,16 +111,6 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval
void invalidateSubtreeFor(in nsIPresShell aPresShell, in nsIContent aContent,
in PRUint32 aChangeType);
/**
* An internal doc load event has occured. Handle the event and remove it from the list.
* @param aTimer The timer created to handle this doc load event
* @param aClosure The nsIWebProgress* for the load event
* @param aEventType The type of load event, one of: nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START,
* nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE or
* nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED
*/
void processDocLoadEvent(in nsITimer aTimer, in voidPtr aClosure, in PRUint32 aEventType);
/**
* Notify accessibility that anchor jump has been accomplished to the given
* target. Used by layout.

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

@ -1107,24 +1107,22 @@ nsAccessibleWrap *GetAccessibleWrap(AtkObject *aAtkObj)
}
nsresult
nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
nsAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
{
nsresult rv = nsAccessible::FireAccessibleEvent(aEvent);
nsresult rv = nsAccessible::HandleAccEvent(aEvent);
NS_ENSURE_SUCCESS(rv, rv);
return FirePlatformEvent(aEvent);
}
nsresult
nsAccessibleWrap::FirePlatformEvent(nsIAccessibleEvent *aEvent)
nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
{
nsCOMPtr<nsIAccessible> accessible;
aEvent->GetAccessible(getter_AddRefs(accessible));
NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE);
PRUint32 type = 0;
nsresult rv = aEvent->GetEventType(&type);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 type = aEvent->GetEventType();
AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accessible);

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

@ -100,7 +100,7 @@ public:
// return the atk object for this nsAccessibleWrap
NS_IMETHOD GetNativeInterface(void **aOutAccessible);
NS_IMETHOD FireAccessibleEvent(nsIAccessibleEvent *aEvent);
virtual nsresult HandleAccEvent(nsAccEvent *aEvent);
AtkObject * GetAtkObject(void);
static AtkObject * GetAtkObject(nsIAccessible * acc);
@ -118,7 +118,7 @@ public:
}
protected:
virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent);
virtual nsresult FirePlatformEvent(nsAccEvent *aEvent);
nsresult FireAtkStateChangeEvent(nsIAccessibleEvent *aEvent,
AtkObject *aObject);

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

@ -665,7 +665,7 @@ nsApplicationAccessibleWrap::AddRootAccessible(nsIAccessible *aRootAccWrap)
AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap);
atk_object_set_parent(atkAccessible, mAtkObject);
PRUint32 count = mChildren.Count();
PRUint32 count = mChildren.Length();
// Emit children_changed::add in a timeout
// to make sure aRootAccWrap is fully initialized.

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

@ -49,7 +49,7 @@ LIBXUL_LIBRARY = 1
CPPSRCS = \
nsAccessNode.cpp \
nsAccessibleEventData.cpp \
nsAccEvent.cpp \
nsARIAGridAccessible.cpp \
nsARIAMap.cpp \
nsDocAccessible.cpp \
@ -63,6 +63,7 @@ CPPSRCS = \
nsAccessibleRelation.cpp \
nsAccessibleTreeWalker.cpp \
nsBaseWidgetAccessible.cpp \
nsEventShell.cpp \
nsFormControlAccessible.cpp \
nsRootAccessible.cpp \
nsApplicationAccessible.cpp \
@ -74,7 +75,7 @@ CPPSRCS = \
EXPORTS = \
nsRootAccessible.h \
nsAccessibleEventData.h \
nsAccEvent.h \
nsAccessNode.h \
$(NULL)

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

@ -146,6 +146,15 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoLiveAttr,
kNoReqStates
},
{
"directory",
nsIAccessibleRole::ROLE_LIST,
kUseMapRole,
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates
},
{
"document",
nsIAccessibleRole::ROLE_DOCUMENT,
@ -265,8 +274,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
},
{
"marquee",
nsIAccessibleRole::ROLE_NOTHING,
kUseNativeRole,
nsIAccessibleRole::ROLE_ANIMATION,
kUseMapRole,
eNoValue,
eNoAction,
eOffLiveAttr,

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

@ -36,7 +36,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsAccessibleEventData.h"
#include "nsAccEvent.h"
#include "nsAccessibilityAtoms.h"
#include "nsApplicationAccessibleWrap.h"
#include "nsCoreUtils.h"
@ -56,8 +56,9 @@
#include "nsIPresShell.h"
#include "nsPresContext.h"
PRBool nsAccEvent::gLastEventFromUserInput = PR_FALSE;
nsIDOMNode* nsAccEvent::gLastEventNodeWeak = 0;
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent. nsISupports
@ -77,64 +78,25 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEvent)
// nsAccEvent. Constructors
nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
PRBool aIsAsync, EEventRule aEventRule) :
PRBool aIsAsync, EIsFromUserInput aIsFromUserInput,
EEventRule aEventRule) :
mEventType(aEventType), mEventRule(aEventRule), mIsAsync(aIsAsync),
mAccessible(aAccessible)
{
CaptureIsFromUserInput();
CaptureIsFromUserInput(aIsFromUserInput);
}
nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
PRBool aIsAsync, EEventRule aEventRule) :
PRBool aIsAsync, EIsFromUserInput aIsFromUserInput,
EEventRule aEventRule) :
mEventType(aEventType), mEventRule(aEventRule), mIsAsync(aIsAsync),
mDOMNode(aDOMNode)
mNode(do_QueryInterface(aDOMNode))
{
CaptureIsFromUserInput();
CaptureIsFromUserInput(aIsFromUserInput);
}
void nsAccEvent::GetLastEventAttributes(nsIDOMNode *aNode,
nsIPersistentProperties *aAttributes)
{
if (aNode == gLastEventNodeWeak) {
// Only provide event-from-input for last event's node
nsAutoString oldValueUnused;
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("event-from-input"),
gLastEventFromUserInput ? NS_LITERAL_STRING("true") :
NS_LITERAL_STRING("false"),
oldValueUnused);
}
}
void
nsAccEvent::CaptureIsFromUserInput()
{
nsCOMPtr<nsIDOMNode> eventNode;
GetDOMNode(getter_AddRefs(eventNode));
if (!eventNode) {
#ifdef DEBUG
// XXX: remove this hack during reorganization of 506907. Meanwhile we
// want to get rid an assertion for application accessible events which
// don't have DOM node (see bug 506206).
nsRefPtr<nsApplicationAccessibleWrap> applicationAcc =
nsAccessNode::GetApplicationAccessible();
if (mAccessible != static_cast<nsIAccessible*>(applicationAcc.get()))
NS_ASSERTION(eventNode, "There should always be a DOM node for an event");
#endif
return;
}
if (!mIsAsync) {
PrepareForEvent(eventNode);
mIsFromUserInput = gLastEventFromUserInput;
}
// For asynch, cannot calculate if from user input.
// Don't reset global last input state here, do it
// at the end of FlushPendingEvents()
mIsFromUserInput = gLastEventFromUserInput;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent: nsIAccessibleEvent
NS_IMETHODIMP
nsAccEvent::GetIsFromUserInput(PRBool *aIsFromUserInput)
@ -150,64 +112,6 @@ nsAccEvent::SetIsFromUserInput(PRBool aIsFromUserInput)
return NS_OK;
}
void nsAccEvent::PrepareForEvent(nsIAccessibleEvent *aEvent,
PRBool aForceIsFromUserInput)
{
gLastEventFromUserInput = aForceIsFromUserInput;
nsCOMPtr<nsIDOMNode> eventNode;
aEvent->GetDOMNode(getter_AddRefs(eventNode));
if (!gLastEventFromUserInput) { // Caller is not forcing user input flag
aEvent->GetIsFromUserInput(&gLastEventFromUserInput);
if (!gLastEventFromUserInput) {
// Event does not have user input flag set to true
// One more try -- check to see if we are currently responding to user input
PrepareForEvent(eventNode);
}
}
gLastEventNodeWeak = eventNode;
// Make sure this event remembers whether it is from user input
aEvent->SetIsFromUserInput(gLastEventFromUserInput);
}
void nsAccEvent::PrepareForEvent(nsIDOMNode *aEventNode,
PRBool aForceIsFromUserInput)
{
if (!aEventNode) {
return;
}
gLastEventNodeWeak = aEventNode;
if (aForceIsFromUserInput) {
gLastEventFromUserInput = PR_TRUE;
return;
}
nsCOMPtr<nsIDOMDocument> domDoc;
aEventNode->GetOwnerDocument(getter_AddRefs(domDoc));
if (!domDoc) { // IF the node is a document itself
domDoc = do_QueryInterface(aEventNode);
}
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (!doc) {
NS_NOTREACHED("There should always be a document for an event");
return;
}
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
if (!presShell) {
NS_NOTREACHED("Threre should always be an pres shell for an event");
return;
}
nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
if (!esm) {
NS_NOTREACHED("There should always be an ESM for an event");
return;
}
gLastEventFromUserInput = esm->IsHandlingUserInputExternal();
}
NS_IMETHODIMP
nsAccEvent::GetEventType(PRUint32 *aEventType)
{
@ -234,13 +138,19 @@ nsAccEvent::GetDOMNode(nsIDOMNode **aDOMNode)
NS_ENSURE_ARG_POINTER(aDOMNode);
*aDOMNode = nsnull;
if (!mDOMNode) {
if (!mNode) {
nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(mAccessible));
NS_ENSURE_TRUE(accessNode, NS_ERROR_FAILURE);
accessNode->GetDOMNode(getter_AddRefs(mDOMNode));
nsCOMPtr<nsIDOMNode> DOMNode;
accessNode->GetDOMNode(getter_AddRefs(DOMNode));
mNode = do_QueryInterface(DOMNode);
}
NS_IF_ADDREF(*aDOMNode = mDOMNode);
if (mNode)
CallQueryInterface(mNode, aDOMNode);
return NS_OK;
}
@ -265,10 +175,13 @@ nsAccEvent::GetAccessibleDocument(nsIAccessibleDocument **aDocAccessible)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent: protected methods
already_AddRefed<nsIAccessible>
nsAccEvent::GetAccessibleByNode()
{
if (!mDOMNode)
if (!mNode)
return nsnull;
nsCOMPtr<nsIAccessibilityService> accService =
@ -276,19 +189,23 @@ nsAccEvent::GetAccessibleByNode()
if (!accService)
return nsnull;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mNode));
nsCOMPtr<nsIAccessible> accessible;
accService->GetAccessibleFor(mDOMNode, getter_AddRefs(accessible));
accService->GetAccessibleFor(DOMNode, getter_AddRefs(accessible));
#ifdef MOZ_XUL
// hack for xul tree table. We need a better way for firing delayed event
// against xul tree table. see bug 386821.
// There will be problem if some day we want to fire delayed event against
// the xul tree itself or an unselected treeitem.
nsAutoString localName;
mDOMNode->GetLocalName(localName);
if (localName.EqualsLiteral("tree")) {
nsCOMPtr<nsIContent> content(do_QueryInterface(mNode));
if (content && content->NodeInfo()->Equals(nsAccessibilityAtoms::tree,
kNameSpaceID_XUL)) {
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelect =
do_QueryInterface(mDOMNode);
do_QueryInterface(mNode);
if (multiSelect) {
PRInt32 treeIndex = -1;
multiSelect->GetCurrentIndex(&treeIndex);
@ -305,160 +222,52 @@ nsAccEvent::GetAccessibleByNode()
return accessible.forget();
}
/* static */
void
nsAccEvent::ApplyEventRules(nsTArray<nsRefPtr<nsAccEvent> > &aEventsToFire)
nsAccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
{
PRUint32 numQueuedEvents = aEventsToFire.Length();
PRInt32 tail = numQueuedEvents - 1;
nsCOMPtr<nsIDOMNode> targetNode;
GetDOMNode(getter_AddRefs(targetNode));
nsAccEvent* tailEvent = aEventsToFire[tail];
switch(tailEvent->mEventRule) {
case nsAccEvent::eCoalesceFromSameSubtree:
{
for (PRInt32 index = 0; index < tail; index ++) {
nsAccEvent* thisEvent = aEventsToFire[index];
if (thisEvent->mEventType != tailEvent->mEventType)
continue; // Different type
#ifdef DEBUG
if (!targetNode) {
// XXX: remove this hack during reorganization of 506907. Meanwhile we
// want to get rid an assertion for application accessible events which
// don't have DOM node (see bug 506206).
nsRefPtr<nsApplicationAccessibleWrap> applicationAcc =
nsAccessNode::GetApplicationAccessible();
if (thisEvent->mEventRule == nsAccEvent::eAllowDupes ||
thisEvent->mEventRule == nsAccEvent::eDoNotEmit)
continue; // Do not need to check
if (mAccessible != static_cast<nsIAccessible*>(applicationAcc.get()))
NS_ASSERTION(targetNode, "There should always be a DOM node for an event");
}
#endif
if (thisEvent->mDOMNode == tailEvent->mDOMNode) {
if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
CoalesceReorderEventsFromSameSource(thisEvent, tailEvent);
continue;
}
// Dupe
thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
continue;
}
if (nsCoreUtils::IsAncestorOf(tailEvent->mDOMNode,
thisEvent->mDOMNode)) {
// thisDOMNode is a descendant of tailDOMNode
if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
CoalesceReorderEventsFromSameTree(tailEvent, thisEvent);
continue;
}
// Do not emit thisEvent, also apply this result to sibling
// nodes of thisDOMNode.
thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
ApplyToSiblings(aEventsToFire, 0, index, thisEvent->mEventType,
thisEvent->mDOMNode, nsAccEvent::eDoNotEmit);
continue;
}
if (nsCoreUtils::IsAncestorOf(thisEvent->mDOMNode,
tailEvent->mDOMNode)) {
// tailDOMNode is a descendant of thisDOMNode
if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
CoalesceReorderEventsFromSameTree(thisEvent, tailEvent);
continue;
}
// Do not emit tailEvent, also apply this result to sibling
// nodes of tailDOMNode.
tailEvent->mEventRule = nsAccEvent::eDoNotEmit;
ApplyToSiblings(aEventsToFire, 0, tail, tailEvent->mEventType,
tailEvent->mDOMNode, nsAccEvent::eDoNotEmit);
break;
}
} // for (index)
if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit) {
// Not in another event node's subtree, and no other event is in
// this event node's subtree.
// This event should be emitted
// Apply this result to sibling nodes of tailDOMNode
ApplyToSiblings(aEventsToFire, 0, tail, tailEvent->mEventType,
tailEvent->mDOMNode, nsAccEvent::eAllowDupes);
}
} break; // case eCoalesceFromSameSubtree
case nsAccEvent::eRemoveDupes:
{
// Check for repeat events.
for (PRInt32 index = 0; index < tail; index ++) {
nsAccEvent* accEvent = aEventsToFire[index];
if (accEvent->mEventType == tailEvent->mEventType &&
accEvent->mEventRule == tailEvent->mEventRule &&
accEvent->mDOMNode == tailEvent->mDOMNode) {
accEvent->mEventRule = nsAccEvent::eDoNotEmit;
}
}
} break; // case eRemoveDupes
default:
break; // case eAllowDupes, eDoNotEmit
} // switch
}
/* static */
void
nsAccEvent::ApplyToSiblings(nsTArray<nsRefPtr<nsAccEvent> > &aEventsToFire,
PRUint32 aStart, PRUint32 aEnd,
PRUint32 aEventType, nsIDOMNode* aDOMNode,
EEventRule aEventRule)
{
for (PRUint32 index = aStart; index < aEnd; index ++) {
nsAccEvent* accEvent = aEventsToFire[index];
if (accEvent->mEventType == aEventType &&
accEvent->mEventRule != nsAccEvent::eDoNotEmit &&
nsCoreUtils::AreSiblings(accEvent->mDOMNode, aDOMNode)) {
accEvent->mEventRule = aEventRule;
}
}
}
/* static */
void
nsAccEvent::CoalesceReorderEventsFromSameSource(nsAccEvent *aAccEvent1,
nsAccEvent *aAccEvent2)
{
// Do not emit event2 if event1 is unconditional.
nsCOMPtr<nsAccReorderEvent> reorderEvent1 = do_QueryInterface(aAccEvent1);
if (reorderEvent1->IsUnconditionalEvent()) {
aAccEvent2->mEventRule = nsAccEvent::eDoNotEmit;
if (aIsFromUserInput != eAutoDetect) {
mIsFromUserInput = aIsFromUserInput == eFromUserInput ? PR_TRUE : PR_FALSE;
return;
}
// Do not emit event1 if event2 is unconditional.
nsCOMPtr<nsAccReorderEvent> reorderEvent2 = do_QueryInterface(aAccEvent2);
if (reorderEvent2->IsUnconditionalEvent()) {
aAccEvent1->mEventRule = nsAccEvent::eDoNotEmit;
if (!targetNode)
return;
nsCOMPtr<nsIPresShell> presShell = nsCoreUtils::GetPresShellFor(targetNode);
if (!presShell) {
NS_NOTREACHED("Threre should always be an pres shell for an event");
return;
}
// Do not emit event2 if event1 is valid, otherwise do not emit event1.
if (reorderEvent1->HasAccessibleInReasonSubtree())
aAccEvent2->mEventRule = nsAccEvent::eDoNotEmit;
else
aAccEvent1->mEventRule = nsAccEvent::eDoNotEmit;
}
void
nsAccEvent::CoalesceReorderEventsFromSameTree(nsAccEvent *aAccEvent,
nsAccEvent *aDescendantAccEvent)
{
// Do not emit descendant event if this event is unconditional.
nsCOMPtr<nsAccReorderEvent> reorderEvent = do_QueryInterface(aAccEvent);
if (reorderEvent->IsUnconditionalEvent()) {
aDescendantAccEvent->mEventRule = nsAccEvent::eDoNotEmit;
nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
if (!esm) {
NS_NOTREACHED("There should always be an ESM for an event");
return;
}
// Do not emit descendant event if this event is valid otherwise do not emit
// this event.
if (reorderEvent->HasAccessibleInReasonSubtree())
aDescendantAccEvent->mEventRule = nsAccEvent::eDoNotEmit;
else
aAccEvent->mEventRule = nsAccEvent::eDoNotEmit;
mIsFromUserInput = esm->IsHandlingUserInputExternal();
}
////////////////////////////////////////////////////////////////////////////////
// nsAccReorderEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccReorderEvent, nsAccEvent,
nsAccReorderEvent)
@ -468,7 +277,7 @@ nsAccReorderEvent::nsAccReorderEvent(nsIAccessible *aAccTarget,
PRBool aIsUnconditional,
nsIDOMNode *aReasonNode) :
nsAccEvent(::nsIAccessibleEvent::EVENT_REORDER, aAccTarget,
aIsAsynch, nsAccEvent::eCoalesceFromSameSubtree),
aIsAsynch, eAutoDetect, nsAccEvent::eCoalesceFromSameSubtree),
mUnconditionalEvent(aIsUnconditional), mReasonNode(aReasonNode)
{
}
@ -494,6 +303,7 @@ nsAccReorderEvent::HasAccessibleInReasonSubtree()
////////////////////////////////////////////////////////////////////////////////
// nsAccStateChangeEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
nsIAccessibleStateChangeEvent)
@ -556,16 +366,19 @@ nsAccStateChangeEvent::IsEnabled(PRBool *aIsEnabled)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccTextChangeEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextChangeEvent, nsAccEvent,
nsIAccessibleTextChangeEvent)
nsAccTextChangeEvent::
nsAccTextChangeEvent(nsIAccessible *aAccessible,
PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted, PRBool aIsAsynch):
PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted,
PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput) :
nsAccEvent(aIsInserted ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : nsIAccessibleEvent::EVENT_TEXT_REMOVED,
aAccessible, aIsAsynch),
aAccessible, aIsAsynch, aIsFromUserInput),
mStart(aStart), mLength(aLength), mIsInserted(aIsInserted)
{
#ifdef XP_WIN
@ -605,7 +418,10 @@ nsAccTextChangeEvent::GetModifiedText(nsAString& aModifiedText)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccCaretMoveEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccCaretMoveEvent, nsAccEvent,
nsIAccessibleCaretMoveEvent)
@ -632,7 +448,10 @@ nsAccCaretMoveEvent::GetCaretOffset(PRInt32* aCaretOffset)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccTableChangeEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccTableChangeEvent, nsAccEvent,
nsIAccessibleTableChangeEvent)

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

@ -38,8 +38,8 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef _nsAccessibleEventData_H_
#define _nsAccessibleEventData_H_
#ifndef _nsAccEvent_H_
#define _nsAccEvent_H_
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
@ -54,12 +54,23 @@
class nsIPresShell;
// Constants used to point whether the event is from user input.
enum EIsFromUserInput
{
// eNoUserInput: event is not from user input
eNoUserInput = 0,
// eFromUserInput: event is from user input
eFromUserInput = 1,
// eAutoDetect: the value should be obtained from event state manager
eAutoDetect = -1
};
#define NS_ACCEVENT_IMPL_CID \
{ /* 55b89892-a83d-4252-ba78-cbdf53a86936 */ \
0x55b89892, \
0xa83d, \
0x4252, \
{ 0xba, 0x78, 0xcb, 0xdf, 0x53, 0xa8, 0x69, 0x36 } \
{ /* 39bde096-317e-4294-b23b-4af4a9b283f7 */ \
0x39bde096, \
0x317e, \
0x4294, \
{ 0xb2, 0x3b, 0x4a, 0xf4, 0xa9, 0xb2, 0x83, 0xf7 } \
}
class nsAccEvent: public nsIAccessibleEvent
@ -73,7 +84,7 @@ public:
// This event will always be emitted.
eAllowDupes,
// eCoalesceFromSameSubtree : For events of the same type from the same
// subtree or the same node, only the umbrelle event on the ancestor
// subtree or the same node, only the umbrella event on the ancestor
// will be emitted.
eCoalesceFromSameSubtree,
// eRemoveDupes : For repeat events, only the newest event in queue
@ -88,10 +99,12 @@ public:
// Initialize with an nsIAccessible
nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect,
EEventRule aEventRule = eRemoveDupes);
// Initialize with an nsIDOMNode
nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect,
EEventRule aEventRule = eRemoveDupes);
virtual ~nsAccEvent() {}
@ -100,108 +113,35 @@ public:
NS_DECL_NSIACCESSIBLEEVENT
static void GetLastEventAttributes(nsIDOMNode *aNode,
nsIPersistentProperties *aAttributes);
// nsAccEvent
PRUint32 GetEventType() const { return mEventType; }
EEventRule GetEventRule() const { return mEventRule; }
PRBool IsAsync() const { return mIsAsync; }
PRBool IsFromUserInput() const { return mIsFromUserInput; }
nsIAccessible* GetAccessible() const { return mAccessible; }
protected:
/**
* Get an accessible from event target node.
*/
already_AddRefed<nsIAccessible> GetAccessibleByNode();
void CaptureIsFromUserInput();
/**
* Determine whether the event is from user input by event state manager if
* it's not pointed explicetly.
*/
void CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput);
PRBool mIsFromUserInput;
PRUint32 mEventType;
EEventRule mEventRule;
PRPackedBool mIsAsync;
nsCOMPtr<nsIAccessible> mAccessible;
nsCOMPtr<nsIDOMNode> mDOMNode;
nsCOMPtr<nsINode> mNode;
nsCOMPtr<nsIAccessibleDocument> mDocAccessible;
private:
static PRBool gLastEventFromUserInput;
static nsIDOMNode* gLastEventNodeWeak;
public:
static PRUint32 EventType(nsIAccessibleEvent *aAccEvent) {
PRUint32 eventType;
aAccEvent->GetEventType(&eventType);
return eventType;
}
static EEventRule EventRule(nsIAccessibleEvent *aAccEvent) {
nsRefPtr<nsAccEvent> accEvent =
nsAccUtils::QueryObject<nsAccEvent>(aAccEvent);
return accEvent->mEventRule;
}
static PRBool IsAsyncEvent(nsIAccessibleEvent *aAccEvent) {
nsRefPtr<nsAccEvent> accEvent =
nsAccUtils::QueryObject<nsAccEvent>(aAccEvent);
return accEvent->mIsAsync;
}
static PRBool IsFromUserInput(nsIAccessibleEvent *aAccEvent) {
PRBool isFromUserInput;
aAccEvent->GetIsFromUserInput(&isFromUserInput);
return isFromUserInput;
}
static void ResetLastInputState()
{gLastEventFromUserInput = PR_FALSE; gLastEventNodeWeak = nsnull; }
/**
* Find and cache the last input state. This will be called automatically
* for synchronous events. For asynchronous events it should be
* called from the synchronous code which is the true source of the event,
* before the event is fired.
* @param aChangeNode that event will be on
* @param aForceIsFromUserInput PR_TRUE if the caller knows that this event was
* caused by user input
*/
static void PrepareForEvent(nsIDOMNode *aChangeNode,
PRBool aForceIsFromUserInput = PR_FALSE);
/**
* The input state was previously stored with the nsIAccessibleEvent,
* so use that state now -- call this when about to flush an event that
* was waiting in an event queue
*/
static void PrepareForEvent(nsIAccessibleEvent *aEvent,
PRBool aForceIsFromUserInput = PR_FALSE);
/**
* Apply event rules to pending events, this method is called in
* FlushingPendingEvents().
* Result of this method:
* Event rule of filtered events will be set to eDoNotEmit.
* Events with other event rule are good to emit.
*/
static void ApplyEventRules(nsTArray<nsRefPtr<nsAccEvent> > &aEventsToFire);
private:
/**
* Apply aEventRule to same type event that from sibling nodes of aDOMNode.
* @param aEventsToFire array of pending events
* @param aStart start index of pending events to be scanned
* @param aEnd end index to be scanned (not included)
* @param aEventType target event type
* @param aDOMNode target are siblings of this node
* @param aEventRule the event rule to be applied
* (should be eDoNotEmit or eAllowDupes)
*/
static void ApplyToSiblings(nsTArray<nsRefPtr<nsAccEvent> > &aEventsToFire,
PRUint32 aStart, PRUint32 aEnd,
PRUint32 aEventType, nsIDOMNode* aDOMNode,
EEventRule aEventRule);
/**
* Do not emit one of two given reorder events fired for the same DOM node.
*/
static void CoalesceReorderEventsFromSameSource(nsAccEvent *aAccEvent1,
nsAccEvent *aAccEvent2);
/**
* Do not emit one of two given reorder events fired for DOM nodes in the case
* when one DOM node is in parent chain of second one.
*/
static void CoalesceReorderEventsFromSameTree(nsAccEvent *aAccEvent,
nsAccEvent *aDescendantAccEvent);
friend class nsAccEventQueue;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsAccEvent, NS_ACCEVENT_IMPL_CID)
@ -273,7 +213,8 @@ class nsAccTextChangeEvent: public nsAccEvent,
{
public:
nsAccTextChangeEvent(nsIAccessible *aAccessible, PRInt32 aStart, PRUint32 aLength,
PRBool aIsInserted, PRBool aIsAsynch = PR_FALSE);
PRBool aIsInserted, PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLETEXTCHANGEEVENT

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

@ -42,7 +42,7 @@
#include "nsIAccessibleStates.h"
#include "nsIAccessibleTypes.h"
#include "nsAccessibleEventData.h"
#include "nsAccEvent.h"
#include "nsHyperTextAccessible.h"
#include "nsHTMLTableAccessible.h"
#include "nsDocAccessible.h"
@ -103,6 +103,46 @@ nsAccUtils::SetAccGroupAttrs(nsIPersistentProperties *aAttributes,
}
}
PRInt32
nsAccUtils::GetDefaultLevel(nsAccessible *aAcc)
{
PRUint32 role = nsAccUtils::Role(aAcc);
if (role == nsIAccessibleRole::ROLE_OUTLINEITEM)
return 1;
if (role == nsIAccessibleRole::ROLE_ROW) {
nsCOMPtr<nsIAccessible> parent = aAcc->GetParent();
if (Role(parent) == nsIAccessibleRole::ROLE_TREE_TABLE) {
// It is a row inside flatten treegrid. Group level is always 1 until it
// is overriden by aria-level attribute.
return 1;
}
}
return 0;
}
PRInt32
nsAccUtils::GetARIAOrDefaultLevel(nsIAccessible *aAcc)
{
nsRefPtr<nsAccessible> acc = nsAccUtils::QueryObject<nsAccessible>(aAcc);
NS_ENSURE_TRUE(acc, 0);
nsCOMPtr<nsIDOMNode> node;
acc->GetDOMNode(getter_AddRefs(node));
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
NS_ENSURE_TRUE(content, 0);
PRInt32 level = 0;
nsCoreUtils::GetUIntAttr(content, nsAccessibilityAtoms::aria_level, &level);
if (level != 0)
return level;
return GetDefaultLevel(acc);
}
void
nsAccUtils::GetPositionAndSizeForXULSelectControlItem(nsIDOMNode *aNode,
PRInt32 *aPosInSet,
@ -308,21 +348,6 @@ nsAccUtils::HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom)
return PR_TRUE;
}
nsresult
nsAccUtils::FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
PRBool aIsAsynch)
{
NS_ENSURE_ARG(aAccessible);
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(aAccessible));
nsCOMPtr<nsIAccessibleEvent> event =
new nsAccEvent(aEventType, aAccessible, aIsAsynch);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
return acc->FireAccessibleEvent(event);
}
PRBool
nsAccUtils::HasAccessibleChildren(nsIDOMNode *aNode)
{

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

@ -92,6 +92,17 @@ public:
PRInt32 aLevel, PRInt32 aSetSize,
PRInt32 aPosInSet);
/**
* Get default value of the level for the given accessible.
*/
static PRInt32 GetDefaultLevel(nsAccessible *aAcc);
/**
* Return ARIA level value or the default one if ARIA is missed for the
* given accessible.
*/
static PRInt32 GetARIAOrDefaultLevel(nsIAccessible *aAcc);
/**
* Compute position in group (posinset) and group size (setsize) for
* nsIDOMXULSelectControlItemElement node.
@ -133,12 +144,6 @@ public:
*/
static PRBool HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom);
/**
* Fire accessible event of the given type for the given accessible.
*/
static nsresult FireAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
PRBool aIsAsynch = PR_FALSE);
/**
* Return true if the given DOM node contains accessible children.
*/
@ -335,6 +340,15 @@ public:
return object;
}
template<class DestinationType, class SourceType> static inline
already_AddRefed<DestinationType> QueryObject(nsRefPtr<SourceType>& aObject)
{
DestinationType* object = nsnull;
if (aObject)
CallQueryInterface(aObject.get(), &object);
return object;
}
/**
* Query nsAccessNode from the given nsIAccessible.

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

@ -64,7 +64,6 @@
#include "nsIPresShell.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "nsITimer.h"
#include "nsRootAccessible.h"
#include "nsFocusManager.h"
#include "nsIObserverService.h"
@ -75,11 +74,8 @@
nsIStringBundle *nsAccessNode::gStringBundle = 0;
nsIStringBundle *nsAccessNode::gKeyStringBundle = 0;
nsITimer *nsAccessNode::gDoCommandTimer = 0;
nsIDOMNode *nsAccessNode::gLastFocusedNode = 0;
#ifdef DEBUG
PRBool nsAccessNode::gIsAccessibilityActive = PR_FALSE;
#endif
PRBool nsAccessNode::gIsCacheDisabled = PR_FALSE;
PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
nsAccessNodeHashtable nsAccessNode::gGlobalDocAccessibleCache;
@ -232,7 +228,8 @@ NS_IMETHODIMP nsAccessNode::GetOwnerWindow(void **aWindow)
already_AddRefed<nsApplicationAccessibleWrap>
nsAccessNode::GetApplicationAccessible()
{
NS_ASSERTION(gIsAccessibilityActive, "Accessibility wasn't initialized!");
NS_ASSERTION(!nsAccessibilityService::gIsShutdown,
"Accessibility wasn't initialized!");
if (!gApplicationAccessible) {
nsApplicationAccessibleWrap::PreCreate();
@ -258,9 +255,6 @@ nsAccessNode::GetApplicationAccessible()
void nsAccessNode::InitXPAccessibility()
{
NS_ASSERTION(!gIsAccessibilityActive,
"Accessibility was initialized already!");
nsCOMPtr<nsIStringBundleService> stringBundleService =
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
if (stringBundleService) {
@ -281,9 +275,6 @@ void nsAccessNode::InitXPAccessibility()
prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
}
#ifdef DEBUG
gIsAccessibilityActive = PR_TRUE;
#endif
NotifyA11yInitOrShutdown(PR_TRUE);
}
@ -306,11 +297,8 @@ void nsAccessNode::ShutdownXPAccessibility()
// which happens when xpcom is shutting down
// at exit of program
NS_ASSERTION(gIsAccessibilityActive, "Accessibility was shutdown already!");
NS_IF_RELEASE(gStringBundle);
NS_IF_RELEASE(gKeyStringBundle);
NS_IF_RELEASE(gDoCommandTimer);
NS_IF_RELEASE(gLastFocusedNode);
nsApplicationAccessibleWrap::Unload();
@ -321,9 +309,6 @@ void nsAccessNode::ShutdownXPAccessibility()
NS_IF_RELEASE(gApplicationAccessible);
gApplicationAccessible = nsnull;
#ifdef DEBUG
gIsAccessibilityActive = PR_FALSE;
#endif
NotifyA11yInitOrShutdown(PR_FALSE);
}

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

@ -63,7 +63,6 @@ class nsPresContext;
class nsIAccessibleDocument;
class nsIFrame;
class nsIDOMNodeList;
class nsITimer;
class nsRootAccessible;
class nsApplicationAccessibleWrap;
class nsIDocShellTreeItem;
@ -101,11 +100,11 @@ NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x22)
PR_END_MACRO
#define NS_ACCESSNODE_IMPL_CID \
{ /* 13555f6e-0c0f-4002-84f6-558d47b8208e */ \
0x13555f6e, \
0xc0f, \
0x4002, \
{ 0x84, 0xf6, 0x55, 0x8d, 0x47, 0xb8, 0x20, 0x8e } \
{ /* 2b07e3d7-00b3-4379-aa0b-ea22e2c8ffda */ \
0x2b07e3d7, \
0x00b3, \
0x4379, \
{ 0xaa, 0x0b, 0xea, 0x22, 0xe2, 0xc8, 0xff, 0xda } \
}
class nsAccessNode: public nsIAccessNode
@ -169,9 +168,20 @@ class nsAccessNode: public nsIAccessNode
*/
virtual nsIFrame* GetFrame();
/**
* Return the corresponding press shell for this accessible.
*/
already_AddRefed<nsIPresShell> GetPresShell();
/**
* Return true if the accessible still has presentation shell. Light-weight
* version of IsDefunct() method.
*/
PRBool HasWeakShell() const { return !!mWeakShell; }
protected:
nsresult MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode);
already_AddRefed<nsIPresShell> GetPresShell();
nsPresContext* GetPresContext();
already_AddRefed<nsIAccessibleDocument> GetDocAccessible();
void LastRelease();
@ -191,10 +201,7 @@ protected:
// Static data, we do our own refcounting for our static data
static nsIStringBundle *gStringBundle;
static nsIStringBundle *gKeyStringBundle;
static nsITimer *gDoCommandTimer;
#ifdef DEBUG
static PRBool gIsAccessibilityActive;
#endif
static PRBool gIsCacheDisabled;
static PRBool gIsFormFillEnabled;

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

@ -153,6 +153,7 @@ ACCESSIBILITY_ATOM(toolbarspring, "toolbarspring") // XUL
ACCESSIBILITY_ATOM(toolbarspacer, "toolbarspacer") // XUL
ACCESSIBILITY_ATOM(tooltip, "tooltip") // XUL
ACCESSIBILITY_ATOM(tr, "tr")
ACCESSIBILITY_ATOM(tree, "tree")
ACCESSIBILITY_ATOM(ul, "ul")
// Alphabetical list of attributes (DOM)
@ -201,6 +202,7 @@ ACCESSIBILITY_ATOM(value, "value")
// Alphabetical list of object attributes
ACCESSIBILITY_ATOM(checkable, "checkable")
ACCESSIBILITY_ATOM(display, "display")
ACCESSIBILITY_ATOM(eventFromInput, "event-from-input")
ACCESSIBILITY_ATOM(textAlign, "text-align")
ACCESSIBILITY_ATOM(textIndent, "text-indent")

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

@ -161,19 +161,6 @@ nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
if (progress)
progress->RemoveProgressListener(static_cast<nsIWebProgressListener*>(this));
// Cancel and release load timers.
while (mLoadTimers.Count() > 0 ) {
nsCOMPtr<nsITimer> timer = mLoadTimers.ObjectAt(0);
void *closure = nsnull;
timer->GetClosure(&closure);
if (closure) {
nsIWebProgress *webProgress = static_cast<nsIWebProgress*>(closure);
NS_RELEASE(webProgress); // Release nsIWebProgress for timer
}
timer->Cancel();
mLoadTimers.RemoveObjectAt(0);
}
// Application is going to be closed, shutdown accessibility and mark
// accessibility service as shutdown to prevent calls of its methods.
// Don't null accessibility service static member at this point to be safe
@ -207,37 +194,35 @@ NS_IMETHODIMP nsAccessibilityService::OnStateChange(nsIWebProgress *aWebProgress
if (NS_FAILED(aStatus) && (aStateFlags & STATE_START))
return NS_OK;
nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1");
if (!timer)
return NS_OK;
mLoadTimers.AppendObject(timer);
NS_ADDREF(aWebProgress);
if (aStateFlags & STATE_START) {
NS_DISPATCH_RUNNABLEMETHOD_ARG2(ProcessDocLoadEvent, this, aWebProgress,
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START)
} else if (NS_SUCCEEDED(aStatus)) {
NS_DISPATCH_RUNNABLEMETHOD_ARG2(ProcessDocLoadEvent, this, aWebProgress,
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE)
} else { // Failed end load
NS_DISPATCH_RUNNABLEMETHOD_ARG2(ProcessDocLoadEvent, this, aWebProgress,
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED)
}
if (aStateFlags & STATE_START)
timer->InitWithFuncCallback(StartLoadCallback, aWebProgress, 0,
nsITimer::TYPE_ONE_SHOT);
else if (NS_SUCCEEDED(aStatus))
timer->InitWithFuncCallback(EndLoadCallback, aWebProgress, 0,
nsITimer::TYPE_ONE_SHOT);
else // Failed end load
timer->InitWithFuncCallback(FailedLoadCallback, aWebProgress, 0,
nsITimer::TYPE_ONE_SHOT);
return NS_OK;
}
NS_IMETHODIMP nsAccessibilityService::ProcessDocLoadEvent(nsITimer *aTimer, void *aClosure, PRUint32 aEventType)
void
nsAccessibilityService::ProcessDocLoadEvent(nsIWebProgress *aWebProgress,
PRUint32 aEventType)
{
if (gIsShutdown)
return;
nsCOMPtr<nsIDOMWindow> domWindow;
nsIWebProgress *webProgress = static_cast<nsIWebProgress*>(aClosure);
webProgress->GetDOMWindow(getter_AddRefs(domWindow));
NS_RELEASE(webProgress);
mLoadTimers.RemoveObject(aTimer);
NS_ENSURE_STATE(domWindow);
aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
NS_ENSURE_TRUE(domWindow,);
if (aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START) {
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(domWindow));
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
NS_ENSURE_STATE(docShell);
NS_ENSURE_TRUE(docShell,);
PRUint32 loadType;
docShell->GetLoadType(&loadType);
if (loadType == LOAD_RELOAD_NORMAL ||
@ -251,17 +236,15 @@ NS_IMETHODIMP nsAccessibilityService::ProcessDocLoadEvent(nsITimer *aTimer, void
nsCOMPtr<nsIDOMDocument> domDoc;
domWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMNode> docNode = do_QueryInterface(domDoc);
NS_ENSURE_STATE(docNode);
NS_ENSURE_TRUE(docNode,);
nsCOMPtr<nsIAccessible> accessible;
GetAccessibleFor(docNode, getter_AddRefs(accessible));
nsRefPtr<nsDocAccessible> docAcc =
nsAccUtils::QueryAccessibleDocument(accessible);
NS_ENSURE_STATE(docAcc);
NS_ENSURE_TRUE(docAcc,);
docAcc->FireDocLoadEvents(aEventType);
return NS_OK;
}
NS_IMETHODIMP
@ -287,7 +270,7 @@ nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent *aTarget)
}
if (targetAcc)
return nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
targetAcc);
return NS_OK;
@ -297,31 +280,8 @@ NS_IMETHODIMP
nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
nsIAccessible *aTarget)
{
return nsAccUtils::FireAccEvent(aEvent, aTarget);
}
void nsAccessibilityService::StartLoadCallback(nsITimer *aTimer, void *aClosure)
{
if (gAccessibilityService)
gAccessibilityService->
ProcessDocLoadEvent(aTimer, aClosure,
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START);
}
void nsAccessibilityService::EndLoadCallback(nsITimer *aTimer, void *aClosure)
{
if (gAccessibilityService)
gAccessibilityService->
ProcessDocLoadEvent(aTimer, aClosure,
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
}
void nsAccessibilityService::FailedLoadCallback(nsITimer *aTimer, void *aClosure)
{
if (gAccessibilityService)
gAccessibilityService->
ProcessDocLoadEvent(aTimer, aClosure,
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
nsEventShell::FireEvent(aEvent, aTarget);
return NS_OK;
}
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
@ -555,7 +515,8 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame *aFrame,
else if (tag == nsAccessibilityAtoms::optgroup) {
*aAccessible = new nsHTMLSelectOptGroupAccessible(aNode, aWeakShell);
}
else if (tag == nsAccessibilityAtoms::ul || tag == nsAccessibilityAtoms::ol) {
else if (tag == nsAccessibilityAtoms::ul || tag == nsAccessibilityAtoms::ol ||
tag == nsAccessibilityAtoms::dl) {
*aAccessible = new nsHTMLListAccessible(aNode, aWeakShell);
}
else if (tag == nsAccessibilityAtoms::a) {
@ -570,17 +531,18 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame *aFrame,
*aAccessible = new nsHTMLLinkAccessible(aNode, aWeakShell);
}
else if (tag == nsAccessibilityAtoms::li && aFrame->GetType() != nsAccessibilityAtoms::blockFrame) {
// Normally this is created by the list item frame which knows about the bullet frame
// However, in this case the list item must have been styled using display: foo
else if (tag == nsAccessibilityAtoms::dt ||
(tag == nsAccessibilityAtoms::li &&
aFrame->GetType() != nsAccessibilityAtoms::blockFrame)) {
// Normally for li, it is created by the list item frame (in nsBlockFrame)
// which knows about the bullet frame; however, in this case the list item
// must have been styled using display: foo
*aAccessible = new nsHTMLLIAccessible(aNode, aWeakShell, EmptyString());
}
else if (tag == nsAccessibilityAtoms::abbr ||
tag == nsAccessibilityAtoms::acronym ||
tag == nsAccessibilityAtoms::blockquote ||
tag == nsAccessibilityAtoms::dd ||
tag == nsAccessibilityAtoms::dl ||
tag == nsAccessibilityAtoms::dt ||
tag == nsAccessibilityAtoms::form ||
tag == nsAccessibilityAtoms::h1 ||
tag == nsAccessibilityAtoms::h2 ||

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

@ -40,9 +40,11 @@
#define __nsAccessibilityService_h__
#include "nsIAccessibilityService.h"
#include "nsCoreUtils.h"
#include "nsCOMArray.h"
#include "nsIObserver.h"
#include "nsITimer.h"
#include "nsIWebProgress.h"
#include "nsIWebProgressListener.h"
#include "nsWeakReference.h"
@ -157,10 +159,19 @@ private:
*/
PRBool HasUniversalAriaProperty(nsIContent *aContent, nsIWeakReference *aWeakShell);
static void StartLoadCallback(nsITimer *aTimer, void *aClosure);
static void EndLoadCallback(nsITimer *aTimer, void *aClosure);
static void FailedLoadCallback(nsITimer *aTimer, void *aClosure);
nsCOMArray<nsITimer> mLoadTimers;
/**
* Process the internal doc load event.
*
* @param aWebProgress [in] the nsIWebProgress object for the load event
* @param aEventType [in] the type of load event, one of:
* nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START,
* nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE,
* nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED
*/
void ProcessDocLoadEvent(nsIWebProgress *aWebProgress, PRUint32 aEventType);
NS_DECL_RUNNABLEMETHOD_ARG2(nsAccessibilityService, ProcessDocLoadEvent,
nsCOMPtr<nsIWebProgress>, PRUint32)
};
/**

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

@ -71,7 +71,7 @@
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsIFrame.h"
#include "nsIViewManager.h"
#include "nsIView.h"
#include "nsIDocShellTreeItem.h"
#include "nsIScrollableFrame.h"
#include "nsFocusManager.h"
@ -84,7 +84,6 @@
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIURI.h"
#include "nsITimer.h"
#include "nsArrayUtils.h"
#include "nsIMutableArray.h"
#include "nsIObserverService.h"
@ -148,13 +147,19 @@ nsAccessibleDOMStringList::Contains(const nsAString& aString, PRBool *aResult)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsAccessible, nsAccessNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mChildren)
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mParent");
cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mParent.get()));
PRUint32 i, length = tmp->mChildren.Length();
for (i = 0; i < length; ++i) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChildren[i]");
cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mChildren[i].get()));
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsAccessible, nsAccessNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mChildren)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mChildren)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_ADDREF_INHERITED(nsAccessible, nsAccessNode)
@ -209,8 +214,9 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
}
if (aIID.Equals(NS_GET_IID(nsIAccessibleHyperLink))) {
nsCOMPtr<nsIAccessible> parent(GetParent());
nsCOMPtr<nsIAccessibleHyperText> hyperTextParent(do_QueryInterface(parent));
nsCOMPtr<nsIAccessibleHyperText> hyperTextParent =
nsAccUtils::QueryObject<nsIAccessibleHyperText>(GetParent());
if (hyperTextParent) {
*aInstancePtr = static_cast<nsIAccessibleHyperLink*>(this);
NS_ADDREF_THIS();
@ -442,8 +448,8 @@ nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
// Copy access key from label node unless it is labeled
// via an ancestor <label>, in which case that would be redundant
nsCOMPtr<nsIContent> labelContent(nsCoreUtils::GetLabelContent(content));
nsCOMPtr<nsIDOMNode> labelNode = do_QueryInterface(labelContent);
if (labelNode && !nsCoreUtils::IsAncestorOf(labelNode, mDOMNode))
nsCOMPtr<nsINode> thisNode = do_QueryInterface(mDOMNode);
if (labelContent && !nsCoreUtils::IsAncestorOf(labelContent, thisNode))
key = nsCoreUtils::GetAccessKeyFor(labelContent);
}
@ -483,8 +489,7 @@ nsAccessible::Shutdown()
// sure none of its children point to this parent
InvalidateChildren();
if (mParent) {
nsRefPtr<nsAccessible> parent(nsAccUtils::QueryAccessible(mParent));
parent->InvalidateChildren();
mParent->InvalidateChildren();
mParent = nsnull;
}
@ -569,7 +574,7 @@ nsAccessible::GetChildAt(PRInt32 aChildIndex, nsIAccessible **aChild)
if (aChildIndex < 0)
aChildIndex = childCount - 1;
nsIAccessible* child = GetChildAt(aChildIndex);
nsAccessible* child = GetChildAt(aChildIndex);
if (!child)
return NS_ERROR_INVALID_ARG;
@ -684,10 +689,6 @@ PRBool nsAccessible::IsVisible(PRBool *aIsOffscreen)
if (!shell)
return PR_FALSE;
nsIViewManager* viewManager = shell->GetViewManager();
if (!viewManager)
return PR_FALSE;
nsIFrame *frame = GetFrame();
if (!frame) {
return PR_FALSE;
@ -699,45 +700,24 @@ PRBool nsAccessible::IsVisible(PRBool *aIsOffscreen)
return PR_FALSE;
}
nsPresContext *presContext = shell->GetPresContext();
if (!presContext)
return PR_FALSE;
// Get the bounds of the current frame, relative to the current view.
// We don't use the more accurate GetBoundsRect, because that is more expensive
// and the STATE_OFFSCREEN flag that this is used for only needs to be a rough
// indicator
nsSize frameSize = frame->GetSize();
nsRectVisibility rectVisibility =
shell->GetRectVisibility(frame, nsRect(nsPoint(0,0), frameSize),
nsPresContext::CSSPixelsToAppUnits(kMinPixels));
nsRect relFrameRect = frame->GetRect();
nsIView *containingView = frame->GetViewExternal();
if (containingView) {
// When frame itself has a view, it has the same bounds as the view
relFrameRect.x = relFrameRect.y = 0;
}
else {
nsPoint frameOffset;
frame->GetOffsetFromView(frameOffset, &containingView);
if (!containingView)
return PR_FALSE; // no view -- not visible
relFrameRect.x = frameOffset.x;
relFrameRect.y = frameOffset.y;
}
if (frame->GetRect().IsEmpty()) {
PRBool isEmpty = PR_TRUE;
nsRectVisibility rectVisibility;
viewManager->GetRectVisibility(containingView, relFrameRect,
nsPresContext::CSSPixelsToAppUnits(kMinPixels),
&rectVisibility);
if (rectVisibility == nsRectVisibility_kZeroAreaRect) {
nsIAtom *frameType = frame->GetType();
if (frameType == nsAccessibilityAtoms::textFrame) {
// Zero area rects can occur in the first frame of a multi-frame text flow,
// in which case the rendered text is not empty and the frame should not be marked invisible
nsAutoString renderedText;
frame->GetRenderedText (&renderedText, nsnull, nsnull, 0, 1);
if (!renderedText.IsEmpty()) {
rectVisibility = nsRectVisibility_kVisible;
}
isEmpty = renderedText.IsEmpty();
}
else if (frameType == nsAccessibilityAtoms::inlineFrame) {
// Yuck. Unfortunately inline frames can contain larger frames inside of them,
@ -745,26 +725,17 @@ PRBool nsAccessible::IsVisible(PRBool *aIsOffscreen)
// GetBounds() will do that for us.
PRInt32 x, y, width, height;
GetBounds(&x, &y, &width, &height);
if (width > 0 && height > 0) {
rectVisibility = nsRectVisibility_kVisible;
}
}
isEmpty = width == 0 || height == 0;
}
if (rectVisibility == nsRectVisibility_kZeroAreaRect && frame &&
0 == (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
// Consider zero area objects hidden unless they are absoultely positioned
if (isEmpty && !(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
// Consider zero area objects hidden unless they are absolutely positioned
// or floating and may have descendants that have a non-zero size
return PR_FALSE;
}
}
// Currently one of:
// nsRectVisibility_kVisible,
// nsRectVisibility_kAboveViewport,
// nsRectVisibility_kBelowViewport,
// nsRectVisibility_kLeftOfViewport,
// nsRectVisibility_kRightOfViewport
// This view says it is visible, but we need to check the parent view chain :(
// The frame intersects the viewport, but we need to check the parent view chain :(
nsCOMPtr<nsIDOMDocument> domDoc;
mDOMNode->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
@ -772,7 +743,10 @@ PRBool nsAccessible::IsVisible(PRBool *aIsOffscreen)
return PR_FALSE;
}
PRBool isVisible = CheckVisibilityInParentChain(doc, containingView);
nsIFrame* frameWithView =
frame->HasView() ? frame : frame->GetAncestorWithViewExternal();
nsIView* view = frameWithView->GetViewExternal();
PRBool isVisible = CheckVisibilityInParentChain(doc, view);
if (isVisible && rectVisibility == nsRectVisibility_kVisible) {
*aIsOffscreen = PR_FALSE;
}
@ -1381,7 +1355,7 @@ nsAccessible::GetXULName(nsAString& aLabel)
}
nsresult
nsAccessible::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
nsAccessible::HandleAccEvent(nsAccEvent *aEvent)
{
NS_ENSURE_ARG_POINTER(aEvent);
nsCOMPtr<nsIDOMNode> eventNode;
@ -1565,7 +1539,7 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
oldValueUnused);
}
nsAccEvent::GetLastEventAttributes(mDOMNode, aAttributes);
nsEventShell::GetEventAttributes(mDOMNode, aAttributes);
// Expose class because it may have useful microformat information
// Let the class from an iframe's document be exposed, don't override from <iframe class>
@ -1669,29 +1643,12 @@ nsAccessible::GroupPosition(PRInt32 *aGroupLevel,
if (!content)
return NS_OK;
nsAutoString value;
PRInt32 error = NS_OK;
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_level, value);
if (!value.IsEmpty()) {
PRInt32 level = value.ToInteger(&error);
if (NS_SUCCEEDED(error))
*aGroupLevel = level;
}
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_posinset, value);
if (!value.IsEmpty()) {
PRInt32 posInSet = value.ToInteger(&error);
if (NS_SUCCEEDED(error))
*aPositionInGroup = posInSet;
}
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_setsize, value);
if (!value.IsEmpty()) {
PRInt32 sizeSet = value.ToInteger(&error);
if (NS_SUCCEEDED(error))
*aSimilarItemsInGroup = sizeSet;
}
nsCoreUtils::GetUIntAttr(content, nsAccessibilityAtoms::aria_level,
aGroupLevel);
nsCoreUtils::GetUIntAttr(content, nsAccessibilityAtoms::aria_posinset,
aPositionInGroup);
nsCoreUtils::GetUIntAttr(content, nsAccessibilityAtoms::aria_setsize,
aSimilarItemsInGroup);
// If ARIA is missed and the accessible is visible then calculate group
// position from hierarchy.
@ -1751,11 +1708,13 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
if (nsAccUtils::Role(tabPanel) == nsIAccessibleRole::ROLE_PROPERTYPAGE) {
nsCOMPtr<nsIAccessNode> tabPanelAccessNode(do_QueryInterface(tabPanel));
nsCOMPtr<nsIDOMNode> tabPanelNode;
tabPanelAccessNode->GetDOMNode(getter_AddRefs(tabPanelNode));
NS_ENSURE_STATE(tabPanelNode);
nsCOMPtr<nsIDOMNode> tabPanelDOMNode;
tabPanelAccessNode->GetDOMNode(getter_AddRefs(tabPanelDOMNode));
NS_ENSURE_STATE(tabPanelDOMNode);
if (nsCoreUtils::IsAncestorOf(tabPanelNode, gLastFocusedNode))
nsCOMPtr<nsINode> tabPanelNode(do_QueryInterface(tabPanelDOMNode));
nsCOMPtr<nsINode> lastFocusedNode(do_QueryInterface(gLastFocusedNode));
if (nsCoreUtils::IsAncestorOf(tabPanelNode, lastFocusedNode))
*aState |= nsIAccessibleStates::STATE_SELECTED;
}
}
@ -2162,8 +2121,8 @@ nsAccessible::DoAction(PRUint8 aIndex)
return NS_ERROR_FAILURE;
if (GetActionRule(nsAccUtils::State(this)) != eNoAction) {
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
return DoCommand(content);
DoCommand();
return NS_OK;
}
return NS_ERROR_INVALID_ARG;
@ -2343,9 +2302,7 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
if (view) {
nsIScrollableFrame *scrollFrame = do_QueryFrame(frame);
if (scrollFrame || view->GetWidget() || !frame->GetParent()) {
nsCOMPtr<nsIAccessible> accTarget;
GetParent(getter_AddRefs(accTarget));
return nsRelUtils::AddTarget(aRelationType, aRelation, accTarget);
return nsRelUtils::AddTarget(aRelationType, aRelation, GetParent());
}
}
}
@ -2536,44 +2493,15 @@ NS_IMETHODIMP nsAccessible::GetNativeInterface(void **aOutAccessible)
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
void
nsAccessible::DoCommand(nsIContent *aContent, PRUint32 aActionIndex)
{
if (gDoCommandTimer) {
// Already have timer going for another command
NS_WARNING("Doubling up on do command timers doesn't work. This wasn't expected.");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1");
NS_ENSURE_TRUE(timer, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIContent> content = aContent;
if (!content)
content = do_QueryInterface(mDOMNode);
// Command closure object memory will be free in DoCommandCallback().
nsCommandClosure *closure =
new nsCommandClosure(this, content, aActionIndex);
NS_ENSURE_TRUE(closure, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(gDoCommandTimer = timer);
return gDoCommandTimer->InitWithFuncCallback(DoCommandCallback,
static_cast<void*>(closure),
0, nsITimer::TYPE_ONE_SHOT);
}
void
nsAccessible::DoCommandCallback(nsITimer *aTimer, void *aClosure)
{
NS_ASSERTION(gDoCommandTimer,
"How did we get here if there was no gDoCommandTimer?");
NS_RELEASE(gDoCommandTimer);
nsCommandClosure *closure = static_cast<nsCommandClosure*>(aClosure);
closure->accessible->DispatchClickEvent(closure->content,
closure->actionIndex);
delete closure;
NS_DISPATCH_RUNNABLEMETHOD_ARG2(DispatchClickEvent, this,
content, aActionIndex)
}
void
@ -2692,9 +2620,7 @@ NS_IMETHODIMP nsAccessible::AddChildToSelection(PRInt32 aIndex)
NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
nsCOMPtr<nsIAccessible> child;
GetChildAt(aIndex, getter_AddRefs(child));
nsAccessible* child = GetChildAt(aIndex);
PRUint32 state = nsAccUtils::State(child);
if (!(state & nsIAccessibleStates::STATE_SELECTABLE)) {
return NS_OK;
@ -2711,9 +2637,7 @@ NS_IMETHODIMP nsAccessible::RemoveChildFromSelection(PRInt32 aIndex)
NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
nsCOMPtr<nsIAccessible> child;
GetChildAt(aIndex, getter_AddRefs(child));
nsAccessible* child = GetChildAt(aIndex);
PRUint32 state = nsAccUtils::State(child);
if (!(state & nsIAccessibleStates::STATE_SELECTED)) {
return NS_OK;
@ -2731,9 +2655,7 @@ NS_IMETHODIMP nsAccessible::IsChildSelected(PRInt32 aIndex, PRBool *aIsSelected)
*aIsSelected = PR_FALSE;
NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
nsCOMPtr<nsIAccessible> child;
GetChildAt(aIndex, getter_AddRefs(child));
nsAccessible* child = GetChildAt(aIndex);
PRUint32 state = nsAccUtils::State(child);
if (state & nsIAccessibleStates::STATE_SELECTED) {
*aIsSelected = PR_TRUE;
@ -2860,7 +2782,7 @@ nsAccessible::GetSelected(PRBool *aSelected)
nsresult nsAccessible::GetLinkOffset(PRInt32* aStartOffset, PRInt32* aEndOffset)
{
*aStartOffset = *aEndOffset = 0;
nsCOMPtr<nsIAccessible> parent(GetParent());
nsAccessible* parent = GetParent();
if (!parent) {
return NS_ERROR_FAILURE;
}
@ -2940,7 +2862,7 @@ nsAccessible::GetNameInternal(nsAString& aName)
}
void
nsAccessible::SetParent(nsIAccessible *aParent)
nsAccessible::SetParent(nsAccessible *aParent)
{
NS_PRECONDITION(aParent, "This method isn't used to set null parent!");
@ -2950,9 +2872,8 @@ nsAccessible::SetParent(nsIAccessible *aParent)
// The old parent's children now need to be invalidated, since
// it no longer owns the child, the new parent does
NS_ASSERTION(PR_FALSE, "Adopting child!");
nsRefPtr<nsAccessible> oldParent = nsAccUtils::QueryAccessible(mParent);
if (oldParent)
oldParent->InvalidateChildren();
if (mParent)
mParent->InvalidateChildren();
}
mParent = aParent;
@ -2961,10 +2882,9 @@ nsAccessible::SetParent(nsIAccessible *aParent)
void
nsAccessible::InvalidateChildren()
{
PRInt32 childCount = mChildren.Count();
PRInt32 childCount = mChildren.Length();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsRefPtr<nsAccessible> child =
nsAccUtils::QueryObject<nsAccessible>(mChildren.ObjectAt(childIdx));
nsAccessible* child = mChildren.ElementAt(childIdx);
child->mParent = nsnull;
}
@ -2972,7 +2892,7 @@ nsAccessible::InvalidateChildren()
mAreChildrenInitialized = PR_FALSE;
}
nsIAccessible*
nsAccessible*
nsAccessible::GetParent()
{
if (IsDefunct())
@ -2991,8 +2911,9 @@ nsAccessible::GetParent()
docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE,
getter_AddRefs(parent));
#ifdef DEBUG
nsRefPtr<nsAccessible> parentAcc = nsAccUtils::QueryAccessible(parent);
#ifdef DEBUG
NS_ASSERTION(!parentAcc->IsDefunct(), "Defunct parent!");
parentAcc->EnsureChildren();
@ -3000,22 +2921,21 @@ nsAccessible::GetParent()
NS_WARNING("Bad accessible tree!");
#endif
return parent;
return parentAcc;
}
nsIAccessible*
nsAccessible*
nsAccessible::GetChildAt(PRUint32 aIndex)
{
if (EnsureChildren())
return nsnull;
nsIAccessible *child = mChildren.SafeObjectAt(aIndex);
nsAccessible *child = mChildren.SafeElementAt(aIndex, nsnull);
if (!child)
return nsnull;
#ifdef DEBUG
nsRefPtr<nsAccessible> childAcc = nsAccUtils::QueryAccessible(child);
nsCOMPtr<nsIAccessible> realParent = childAcc->mParent;
nsAccessible* realParent = child->mParent;
NS_ASSERTION(!realParent || realParent == this,
"Two accessibles have the same first child accessible!");
#endif
@ -3026,7 +2946,7 @@ nsAccessible::GetChildAt(PRUint32 aIndex)
PRInt32
nsAccessible::GetChildCount()
{
return EnsureChildren() ? -1 : mChildren.Count();
return EnsureChildren() ? -1 : mChildren.Length();
}
PRInt32
@ -3038,33 +2958,26 @@ nsAccessible::GetIndexOf(nsIAccessible *aChild)
PRInt32
nsAccessible::GetIndexInParent()
{
nsIAccessible *parent = GetParent();
if (!parent)
return -1;
nsRefPtr<nsAccessible> parentAcc =
nsAccUtils::QueryObject<nsAccessible>(parent);
return parentAcc->GetIndexOf(this);
nsAccessible *parent = GetParent();
return parent ? parent->GetIndexOf(this) : -1;
}
already_AddRefed<nsIAccessible>
nsAccessible*
nsAccessible::GetCachedParent()
{
if (IsDefunct())
return nsnull;
nsCOMPtr<nsIAccessible> cachedParent = mParent;
return cachedParent.forget();
return mParent;
}
already_AddRefed<nsIAccessible>
nsAccessible*
nsAccessible::GetCachedFirstChild()
{
if (IsDefunct())
return nsnull;
nsCOMPtr<nsIAccessible> cachedFirstChild = GetChildAt(0);
return cachedFirstChild.forget();
return mChildren.SafeElementAt(0, nsnull);
}
@ -3085,10 +2998,11 @@ nsAccessible::CacheChildren()
walker.GetFirstChild();
while (walker.mState.accessible) {
mChildren.AppendObject(walker.mState.accessible);
nsRefPtr<nsAccessible> acc =
nsAccUtils::QueryObject<nsAccessible>(walker.mState.accessible);
mChildren.AppendElement(acc);
acc->SetParent(this);
walker.GetNextSibling();
@ -3096,14 +3010,14 @@ nsAccessible::CacheChildren()
}
void
nsAccessible::TestChildCache(nsIAccessible *aCachedChild)
nsAccessible::TestChildCache(nsAccessible *aCachedChild)
{
#ifdef DEBUG_A11Y
// All cached accessible nodes should be in the parent
// It will assert if not all the children were created
// when they were first cached, and no invalidation
// ever corrected parent accessible's child cache.
PRUint32 childCount = mChildren.Count();
PRUint32 childCount = mChildren.Length();
if (childCount == 0) {
NS_ASSERTION(mAreChildrenInitialized,
"Children are stored but not initailzied!");
@ -3111,7 +3025,7 @@ nsAccessible::TestChildCache(nsIAccessible *aCachedChild)
}
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsIAccessible *child = GetChildAt(childIdx);
nsAccessible *child = GetChildAt(childIdx);
if (child == aCachedChild)
break;
}
@ -3148,7 +3062,7 @@ nsAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError)
return nsnull;
}
nsIAccessible *parent = GetParent();
nsAccessible *parent = GetParent();
if (!parent) {
if (aError)
*aError = NS_ERROR_UNEXPECTED;
@ -3156,10 +3070,7 @@ nsAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError)
return nsnull;
}
nsRefPtr<nsAccessible> parentAcc =
nsAccUtils::QueryObject<nsAccessible>(parent);
PRInt32 indexInParent = parentAcc->GetIndexOf(this);
PRInt32 indexInParent = parent->GetIndexOf(this);
if (indexInParent == -1) {
if (aError)
*aError = NS_ERROR_UNEXPECTED;
@ -3168,14 +3079,14 @@ nsAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError)
}
if (aError) {
PRInt32 childCount = parentAcc->GetChildCount();
PRInt32 childCount = parent->GetChildCount();
if (indexInParent + aOffset >= childCount) {
*aError = NS_OK; // fail peacefully
return nsnull;
}
}
nsIAccessible *child = parentAcc->GetChildAt(indexInParent + aOffset);
nsAccessible *child = parent->GetChildAt(indexInParent + aOffset);
if (aError && !child)
*aError = NS_ERROR_UNEXPECTED;
@ -3343,50 +3254,74 @@ nsAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet, PRInt32 *aSetSize)
role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
baseRole = nsIAccessibleRole::ROLE_MENUITEM;
nsCOMPtr<nsIAccessible> parent = GetParent();
nsAccessible* parent = GetParent();
NS_ENSURE_TRUE(parent,);
// Compute 'posinset' and 'setsize' attributes.
PRInt32 positionInGroup = 0;
PRInt32 setSize = 0;
PRInt32 indexInParent = parent->GetIndexOf(this);
PRInt32 level = nsAccUtils::GetARIAOrDefaultLevel(this);
nsCOMPtr<nsIAccessible> sibling, nextSibling;
parent->GetFirstChild(getter_AddRefs(sibling));
NS_ENSURE_TRUE(sibling,);
// Compute 'posinset'.
PRInt32 positionInGroup = 1;
for (PRInt32 idx = indexInParent - 1; idx >= 0; idx--) {
nsAccessible* sibling = parent->GetChildAt(idx);
PRBool foundCurrent = PR_FALSE;
PRUint32 siblingRole, siblingBaseRole;
while (sibling) {
siblingRole = nsAccUtils::Role(sibling);
PRUint32 siblingRole = siblingRole = nsAccUtils::Role(sibling);
siblingBaseRole = siblingRole;
// If the sibling is separator then the group is ended.
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
break;
PRUint32 siblingBaseRole = siblingRole;
if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
// If sibling is visible and has the same base role.
// If sibling is visible and has the same base role
if (siblingBaseRole == baseRole &&
!(nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
++ setSize;
if (!foundCurrent) {
// and check if it's hierarchical flatten structure, i.e. if the sibling
// level is lesser than this one then group is ended, if the sibling level
// is greater than this one then the group is splited by some child
// elements (group will be continued).
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
if (siblingLevel < level)
break;
else if (level == siblingLevel)
++ positionInGroup;
if (sibling == this)
foundCurrent = PR_TRUE;
}
}
// If the sibling is separator
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR) {
if (foundCurrent) // the our group is ended
// Compute 'setsize'.
PRInt32 setSize = positionInGroup;
PRInt32 siblingCount = parent->GetChildCount();
for (PRInt32 idx = indexInParent + 1; idx < siblingCount; idx++) {
nsAccessible* sibling = parent->GetChildAt(idx);
NS_ENSURE_TRUE(sibling,);
PRUint32 siblingRole = nsAccUtils::Role(sibling);
// If the sibling is separator then the group is ended.
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
break;
// not our group, continue the searching
positionInGroup = 0;
setSize = 0;
}
PRUint32 siblingBaseRole = siblingRole;
if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
sibling->GetNextSibling(getter_AddRefs(nextSibling));
sibling = nextSibling;
// If sibling is visible and has the same base role
if (siblingBaseRole == baseRole &&
!(nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
// and check if it's hierarchical flatten structure.
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
if (siblingLevel < level)
break;
else if (level == siblingLevel)
++ setSize;
}
}
*aPosInSet = positionInGroup;
@ -3396,15 +3331,17 @@ nsAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet, PRInt32 *aSetSize)
PRInt32
nsAccessible::GetLevelInternal()
{
PRInt32 level = nsAccUtils::GetDefaultLevel(this);
PRUint32 role = nsAccUtils::Role(this);
nsCOMPtr<nsIAccessible> parent = GetParent();
nsAccessible* parent = GetParent();
if (role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
// Always expose 'level' attribute for 'outlineitem' accessible. The number
// of nested 'grouping' accessibles containing 'outlineitem' accessible is
// its level.
PRInt32 level = 1;
nsCOMPtr<nsIAccessible> nextParent;
level = 1;
while (parent) {
PRUint32 parentRole = nsAccUtils::Role(parent);
@ -3413,22 +3350,17 @@ nsAccessible::GetLevelInternal()
if (parentRole == nsIAccessibleRole::ROLE_GROUPING)
++ level;
parent->GetParent(getter_AddRefs(nextParent));
parent.swap(nextParent);
parent = parent->GetParent();
}
return level;
}
if (role == nsIAccessibleRole::ROLE_LISTITEM) {
} else if (role == nsIAccessibleRole::ROLE_LISTITEM) {
// Expose 'level' attribute on nested lists. We assume nested list is a last
// child of listitem of parent list. We don't handle the case when nested
// lists have more complex structure, for example when there are accessibles
// between parent listitem and nested list.
// Calculate 'level' attribute based on number of parent listitems.
PRInt32 level = 0;
nsCOMPtr<nsIAccessible> nextParent;
level = 0;
while (parent) {
PRUint32 parentRole = nsAccUtils::Role(parent);
@ -3438,40 +3370,28 @@ nsAccessible::GetLevelInternal()
else if (parentRole != nsIAccessibleRole::ROLE_LIST)
break;
parent->GetParent(getter_AddRefs(nextParent));
parent.swap(nextParent);
parent = parent->GetParent();
}
if (level == 0) {
// If this listitem is on top of nested lists then expose 'level'
// attribute.
nsCOMPtr<nsIAccessible> parent(GetParent()), sibling, nextSibling;
parent->GetFirstChild(getter_AddRefs(sibling));
nsAccessible* parent(GetParent());
PRInt32 siblingCount = parent->GetChildCount();
for (PRInt32 siblingIdx = 0; siblingIdx < siblingCount; siblingIdx++) {
nsAccessible* sibling = parent->GetChildAt(siblingIdx);
while (sibling) {
nsCOMPtr<nsIAccessible> siblingChild;
sibling->GetLastChild(getter_AddRefs(siblingChild));
if (nsAccUtils::Role(siblingChild) == nsIAccessibleRole::ROLE_LIST) {
level = 1;
break;
}
sibling->GetNextSibling(getter_AddRefs(nextSibling));
sibling.swap(nextSibling);
}
} else {
++ level; // level is 1-index based
}
}
return level;
}
if (role == nsIAccessibleRole::ROLE_ROW &&
nsAccUtils::Role(parent) == nsIAccessibleRole::ROLE_TREE_TABLE) {
// It is a row inside flatten treegrid. Group level is always 1 until it is
// overriden by aria-level attribute.
return 1;
}
return 0;
}

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

@ -42,6 +42,7 @@
#include "nsAccessNodeWrap.h"
#include "nsARIAMap.h"
#include "nsEventShell.h"
#include "nsRelUtils.h"
#include "nsTextEquivUtils.h"
@ -103,11 +104,11 @@ private:
#define NS_ACCESSIBLE_IMPL_CID \
{ /* 81a84b69-de5a-412f-85ff-deb005c5a68d */ \
0x81a84b69, \
0xde5a, \
0x412f, \
{ 0x85, 0xff, 0xde, 0xb0, 0x05, 0xc5, 0xa6, 0x8d } \
{ /* 133c8bf4-4913-4355-bd50-426bd1d6e1ad */ \
0x133c8bf4, \
0x4913, \
0x4355, \
{ 0xbd, 0x50, 0x42, 0x6b, 0xd1, 0xd6, 0xe1, 0xad } \
}
class nsAccessible : public nsAccessNodeWrap,
@ -228,7 +229,7 @@ public:
/**
* Set accessible parent.
*/
void SetParent(nsIAccessible *aParent);
void SetParent(nsAccessible *aParent);
/**
* Set the child count to -1 (unknown) and null out cached child pointers.
@ -243,12 +244,12 @@ public:
/**
* Return parent accessible.
*/
virtual nsIAccessible* GetParent();
virtual nsAccessible* GetParent();
/**
* Return child accessible at the given index.
*/
virtual nsIAccessible* GetChildAt(PRUint32 aIndex);
virtual nsAccessible* GetChildAt(PRUint32 aIndex);
/**
* Return child accessible count.
@ -268,20 +269,21 @@ public:
/**
* Return parent accessible only if cached.
*/
already_AddRefed<nsIAccessible> GetCachedParent();
nsAccessible* GetCachedParent();
/**
* Return first child accessible only if cached.
*/
already_AddRefed<nsIAccessible> GetCachedFirstChild();
nsAccessible* GetCachedFirstChild();
//////////////////////////////////////////////////////////////////////////////
// Miscellaneous methods
/**
* Fire accessible event.
* Handle accessible event, i.e. process it, notifies observers and fires
* platform specific event.
*/
virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aAccEvent);
virtual nsresult HandleAccEvent(nsAccEvent *aAccEvent);
/**
* Return true if there are accessible children in anonymous content
@ -312,7 +314,7 @@ protected:
/**
* Assert if child not in parent's cache.
*/
void TestChildCache(nsIAccessible *aCachedChild);
void TestChildCache(nsAccessible *aCachedChild);
/**
* Cache children if necessary. Return true if the accessible is defunct.
@ -372,20 +374,6 @@ protected:
//////////////////////////////////////////////////////////////////////////////
// Action helpers
/**
* Used to describe click action target. See DoCommand() method.
*/
struct nsCommandClosure
{
nsCommandClosure(nsAccessible *aAccessible, nsIContent *aContent,
PRUint32 aActionIndex) :
accessible(aAccessible), content(aContent), actionIndex(aActionIndex) {}
nsRefPtr<nsAccessible> accessible;
nsCOMPtr<nsIContent> content;
PRUint32 actionIndex;
};
/**
* Prepares click action that will be invoked in timeout.
*
@ -398,21 +386,16 @@ protected:
* @param aContent [in, optional] element to click
* @param aActionIndex [in, optional] index of accessible action
*/
nsresult DoCommand(nsIContent *aContent = nsnull, PRUint32 aActionIndex = 0);
/**
* Dispatch click event to target by calling DispatchClickEvent() method.
*
* @param aTimer [in] timer object
* @param aClosure [in] nsCommandClosure object describing a target.
*/
static void DoCommandCallback(nsITimer *aTimer, void *aClosure);
void DoCommand(nsIContent *aContent = nsnull, PRUint32 aActionIndex = 0);
/**
* Dispatch click event.
*/
virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex);
NS_DECL_RUNNABLEMETHOD_ARG2(nsAccessible, DispatchClickEvent,
nsCOMPtr<nsIContent>, PRUint32)
//////////////////////////////////////////////////////////////////////////////
// Helpers
@ -445,17 +428,17 @@ protected:
/**
* Fires platform accessible event. It's notification method only. It does
* change nothing on Gecko side. Mostly you should use
* nsIAccessible::FireAccessibleEvent excepting special cases like we have
* in xul:tree accessible to lie to AT. Must be overridden in wrap classes.
* change nothing on Gecko side. Don't use it until you're sure what you do
* (see example in XUL tree accessible), use nsEventShell::FireEvent()
* instead. MUST be overridden in wrap classes.
*
* @param aEvent the accessible event to fire.
*/
virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent) = 0;
virtual nsresult FirePlatformEvent(nsAccEvent *aEvent) = 0;
// Data Members
nsCOMPtr<nsIAccessible> mParent;
nsCOMArray<nsIAccessible> mChildren;
nsRefPtr<nsAccessible> mParent;
nsTArray<nsRefPtr<nsAccessible> > mChildren;
PRBool mAreChildrenInitialized;
nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well

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

@ -160,7 +160,7 @@ nsApplicationAccessible::GetStateInternal(PRUint32 *aState,
return NS_OK;
}
nsIAccessible*
nsAccessible*
nsApplicationAccessible::GetParent()
{
return nsnull;
@ -207,10 +207,12 @@ nsApplicationAccessible::AddRootAccessible(nsIAccessible *aRootAccessible)
{
NS_ENSURE_ARG_POINTER(aRootAccessible);
if (!mChildren.AppendObject(aRootAccessible))
nsRefPtr<nsAccessible> rootAcc =
nsAccUtils::QueryObject<nsAccessible>(aRootAccessible);
if (!mChildren.AppendElement(rootAcc))
return NS_ERROR_FAILURE;
nsRefPtr<nsAccessible> rootAcc = nsAccUtils::QueryAccessible(aRootAccessible);
rootAcc->SetParent(this);
return NS_OK;
@ -224,5 +226,5 @@ nsApplicationAccessible::RemoveRootAccessible(nsIAccessible *aRootAccessible)
// It's not needed to void root accessible parent because this method is
// called on root accessible shutdown and its parent will be cleared
// properly.
return mChildren.RemoveObject(aRootAccessible) ? NS_OK : NS_ERROR_FAILURE;
return mChildren.RemoveElement(aRootAccessible) ? NS_OK : NS_ERROR_FAILURE;
}

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

@ -79,7 +79,7 @@ public:
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsIAccessible* GetParent();
virtual nsAccessible* GetParent();
virtual void InvalidateChildren();

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

@ -269,7 +269,7 @@ nsCaretAccessible::NormalSelectionChanged(nsIDOMDocument *aDoc,
mLastCaretOffset = caretOffset;
mLastTextAccessible = textAcc;
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccCaretMoveEvent(textNode);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
@ -292,12 +292,12 @@ nsCaretAccessible::SpellcheckSelectionChanged(nsIDOMDocument *aDoc,
nsCOMPtr<nsIAccessible> acc(do_QueryInterface(textAcc));
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
acc, nsnull);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
return mRootAccessible->FireAccessibleEvent(event);
nsEventShell::FireEvent(event);
return NS_OK;
}
nsIntRect

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

@ -56,7 +56,6 @@
#include "nsIDOMWindowInternal.h"
#include "nsIDOMXULElement.h"
#include "nsIDocShell.h"
#include "nsIDocumentViewer.h"
#include "nsIContentViewer.h"
#include "nsIEventListenerManager.h"
#include "nsIPresShell.h"
@ -67,6 +66,7 @@
#include "nsISelectionController.h"
#include "nsPIDOMWindow.h"
#include "nsGUIEvent.h"
#include "nsIView.h"
#include "nsContentCID.h"
#include "nsComponentManagerUtils.h"
@ -313,36 +313,26 @@ nsCoreUtils::GetRoleContent(nsIDOMNode *aDOMNode)
}
PRBool
nsCoreUtils::IsAncestorOf(nsIDOMNode *aPossibleAncestorNode,
nsIDOMNode *aPossibleDescendantNode)
nsCoreUtils::IsAncestorOf(nsINode *aPossibleAncestorNode,
nsINode *aPossibleDescendantNode)
{
NS_ENSURE_TRUE(aPossibleAncestorNode && aPossibleDescendantNode, PR_FALSE);
nsCOMPtr<nsIDOMNode> loopNode = aPossibleDescendantNode;
nsCOMPtr<nsIDOMNode> parentNode;
while (NS_SUCCEEDED(loopNode->GetParentNode(getter_AddRefs(parentNode))) &&
parentNode) {
if (parentNode == aPossibleAncestorNode) {
nsINode *parentNode = aPossibleDescendantNode;
while ((parentNode = parentNode->GetNodeParent())) {
if (parentNode == aPossibleAncestorNode)
return PR_TRUE;
}
loopNode.swap(parentNode);
}
return PR_FALSE;
}
PRBool
nsCoreUtils::AreSiblings(nsIDOMNode *aDOMNode1,
nsIDOMNode *aDOMNode2)
nsCoreUtils::AreSiblings(nsINode *aNode1, nsINode *aNode2)
{
NS_ENSURE_TRUE(aDOMNode1 && aDOMNode2, PR_FALSE);
NS_ENSURE_TRUE(aNode1 && aNode2, PR_FALSE);
nsCOMPtr<nsIDOMNode> parentNode1, parentNode2;
if (NS_SUCCEEDED(aDOMNode1->GetParentNode(getter_AddRefs(parentNode1))) &&
NS_SUCCEEDED(aDOMNode2->GetParentNode(getter_AddRefs(parentNode2))) &&
parentNode1 == parentNode2) {
return PR_TRUE;
}
return PR_FALSE;
return aNode1->GetNodeParent() == aNode2->GetNodeParent();
}
nsresult
@ -419,7 +409,7 @@ nsCoreUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame,
nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
scrollPoint -= deltaPoint;
scrollableFrame->ScrollTo(scrollPoint);
scrollableFrame->ScrollTo(scrollPoint, nsIScrollableFrame::INSTANT);
}
void
@ -559,17 +549,12 @@ nsCoreUtils::GetDOMNodeForContainer(nsIDocShellTreeItem *aContainer)
if (!cv)
return nsnull;
nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(cv));
if (!docv)
return nsnull;
nsCOMPtr<nsIDocument> doc;
docv->GetDocument(getter_AddRefs(doc));
nsIDocument* doc = cv->GetDocument();
if (!doc)
return nsnull;
nsIDOMNode* node = nsnull;
CallQueryInterface(doc.get(), &node);
CallQueryInterface(doc, &node);
return node;
}
@ -580,6 +565,23 @@ nsCoreUtils::GetID(nsIContent *aContent, nsAString& aID)
return idAttribute ? aContent->GetAttr(kNameSpaceID_None, idAttribute, aID) : PR_FALSE;
}
PRBool
nsCoreUtils::GetUIntAttr(nsIContent *aContent, nsIAtom *aAttr, PRInt32 *aUInt)
{
nsAutoString value;
aContent->GetAttr(kNameSpaceID_None, aAttr, value);
if (!value.IsEmpty()) {
PRInt32 error = NS_OK;
PRInt32 integer = value.ToInteger(&error);
if (NS_SUCCEEDED(error) && integer > 0) {
*aUInt = integer;
return PR_TRUE;
}
}
return PR_FALSE;
}
PRBool
nsCoreUtils::IsXLink(nsIContent *aContent)
{

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

@ -140,19 +140,23 @@ public:
/**
* Is the first passed in node an ancestor of the second?
* Note: A node is not considered to be the ancestor of itself.
* @param aPossibleAncestorNode -- node to test for ancestor-ness of aPossibleDescendantNode
* @param aPossibleDescendantNode -- node to test for descendant-ness of aPossibleAncestorNode
* @return PR_TRUE if aPossibleAncestorNode is an ancestor of aPossibleDescendantNode
*
* @param aPossibleAncestorNode [in] node to test for ancestor-ness of
* aPossibleDescendantNode
* @param aPossibleDescendantNode [in] node to test for descendant-ness of
* aPossibleAncestorNode
* @return PR_TRUE if aPossibleAncestorNode is an ancestor of
* aPossibleDescendantNode
*/
static PRBool IsAncestorOf(nsIDOMNode *aPossibleAncestorNode,
nsIDOMNode *aPossibleDescendantNode);
static PRBool IsAncestorOf(nsINode *aPossibleAncestorNode,
nsINode *aPossibleDescendantNode);
/**
* Are the first node and the second siblings?
*
* @return PR_TRUE if aDOMNode1 and aDOMNode2 have same parent
*/
static PRBool AreSiblings(nsIDOMNode *aDOMNode1,
nsIDOMNode *aDOMNode2);
static PRBool AreSiblings(nsINode *aNode1, nsINode *aNode2);
/**
* Helper method to scroll range into view, used for implementation of
@ -250,6 +254,13 @@ public:
*/
static PRBool GetID(nsIContent *aContent, nsAString& aID);
/**
* Convert attribute value of the given node to positive integer. If no
* attribute or wrong value then false is returned.
*/
static PRBool GetUIntAttr(nsIContent *aContent, nsIAtom *aAttr,
PRInt32 *aUInt);
/**
* Check if the given element is XLink.
*
@ -457,5 +468,132 @@ public:
static void GeneratePopupTree(nsIDOMNode *aNode, PRBool aIsAnon = PR_FALSE);
};
////////////////////////////////////////////////////////////////////////////////
// nsRunnable helpers
////////////////////////////////////////////////////////////////////////////////
/**
* Use NS_DECL_RUNNABLEMETHOD_ macros to declare a runnable class for the given
* method of the given class. There are three macros:
* NS_DECL_RUNNABLEMETHOD(Class, Method)
* NS_DECL_RUNNABLEMETHOD_ARG1(Class, Method, Arg1Type)
* NS_DECL_RUNNABLEMETHOD_ARG2(Class, Method, Arg1Type, Arg2Type)
* Note Arg1Type and Arg2Type must be types which keeps the objects alive.
*
* Use NS_DISPATCH_RUNNABLEMETHOD_ macros to create an instance of declared
* runnable class and dispatch it to main thread. Availabe macros are:
* NS_DISPATCH_RUNNABLEMETHOD(Method, Object)
* NS_DISPATCH_RUNNABLEMETHOD_ARG1(Method, Object, Arg1)
* NS_DISPATCH_RUNNABLEMETHOD_ARG2(Method, Object, Arg1, Arg2)
*/
#define NS_DECL_RUNNABLEMETHOD_HELPER(ClassType, Method) \
void Revoke() \
{ \
NS_IF_RELEASE(mObj); \
} \
\
protected: \
virtual ~nsRunnableMethod_##Method() \
{ \
NS_IF_RELEASE(mObj); \
} \
\
private: \
ClassType *mObj; \
#define NS_DECL_RUNNABLEMETHOD(ClassType, Method) \
class nsRunnableMethod_##Method : public nsRunnable \
{ \
public: \
nsRunnableMethod_##Method(ClassType *aObj) : mObj(aObj) \
{ \
NS_IF_ADDREF(mObj); \
} \
\
NS_IMETHODIMP Run() \
{ \
if (!mObj) \
return NS_OK; \
(mObj-> Method)(); \
return NS_OK; \
} \
\
NS_DECL_RUNNABLEMETHOD_HELPER(ClassType, Method) \
\
};
#define NS_DECL_RUNNABLEMETHOD_ARG1(ClassType, Method, Arg1Type) \
class nsRunnableMethod_##Method : public nsRunnable \
{ \
public: \
nsRunnableMethod_##Method(ClassType *aObj, Arg1Type aArg1) : \
mObj(aObj), mArg1(aArg1) \
{ \
NS_IF_ADDREF(mObj); \
} \
\
NS_IMETHODIMP Run() \
{ \
if (!mObj) \
return NS_OK; \
(mObj-> Method)(mArg1); \
return NS_OK; \
} \
\
NS_DECL_RUNNABLEMETHOD_HELPER(ClassType, Method) \
Arg1Type mArg1; \
};
#define NS_DECL_RUNNABLEMETHOD_ARG2(ClassType, Method, Arg1Type, Arg2Type) \
class nsRunnableMethod_##Method : public nsRunnable \
{ \
public: \
\
nsRunnableMethod_##Method(ClassType *aObj, \
Arg1Type aArg1, Arg2Type aArg2) : \
mObj(aObj), mArg1(aArg1), mArg2(aArg2) \
{ \
NS_IF_ADDREF(mObj); \
} \
\
NS_IMETHODIMP Run() \
{ \
if (!mObj) \
return NS_OK; \
(mObj-> Method)(mArg1, mArg2); \
return NS_OK; \
} \
\
NS_DECL_RUNNABLEMETHOD_HELPER(ClassType, Method) \
Arg1Type mArg1; \
Arg2Type mArg2; \
};
#define NS_DISPATCH_RUNNABLEMETHOD(Method, Obj) \
{ \
nsCOMPtr<nsIRunnable> runnable = \
new nsRunnableMethod_##Method(Obj); \
if (runnable) \
NS_DispatchToMainThread(runnable); \
}
#define NS_DISPATCH_RUNNABLEMETHOD_ARG1(Method, Obj, Arg1) \
{ \
nsCOMPtr<nsIRunnable> runnable = \
new nsRunnableMethod_##Method(Obj, Arg1); \
if (runnable) \
NS_DispatchToMainThread(runnable); \
}
#define NS_DISPATCH_RUNNABLEMETHOD_ARG2(Method, Obj, Arg1, Arg2) \
{ \
nsCOMPtr<nsIRunnable> runnable = \
new nsRunnableMethod_##Method(Obj, Arg1, Arg2); \
if (runnable) \
NS_DispatchToMainThread(runnable); \
}
#endif

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

@ -38,7 +38,7 @@
#include "nsRootAccessible.h"
#include "nsAccessibilityAtoms.h"
#include "nsAccessibleEventData.h"
#include "nsAccEvent.h"
#include "nsAccessibilityService.h"
#include "nsIMutableArray.h"
#include "nsICommandManager.h"
@ -62,9 +62,8 @@
#include "nsINameSpaceManager.h"
#include "nsIPresShell.h"
#include "nsIServiceManager.h"
#include "nsIScrollableView.h"
#include "nsIViewManager.h"
#include "nsIView.h"
#include "nsIScrollableFrame.h"
#include "nsUnicharUtils.h"
#include "nsIURI.h"
#include "nsIWebNavigation.h"
@ -86,8 +85,7 @@ nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull;
nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
nsHyperTextAccessibleWrap(aDOMNode, aShell), mWnd(nsnull),
mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE),
mIsLoadCompleteFired(PR_FALSE), mInFlushPendingEvents(PR_FALSE),
mFireEventTimerStarted(PR_FALSE)
mIsLoadCompleteFired(PR_FALSE)
{
// XXX aaronl should we use an algorithm for the initial cache size?
mAccessNodeCache.Init(kDefaultCacheSize);
@ -152,17 +150,14 @@ ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode,
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
PRUint32 i, length = tmp->mEventsToFire.Length();
for (i = 0; i < length; ++i) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEventsToFire[i]");
cb.NoteXPCOMChild(tmp->mEventsToFire[i].get());
}
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEventQueue");
cb.NoteXPCOMChild(tmp->mEventQueue.get());
tmp->mAccessNodeCache.EnumerateRead(ElementTraverser, &cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mEventsToFire)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEventQueue)
tmp->ClearCache(tmp->mAccessNodeCache);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -346,9 +341,8 @@ nsDocAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
nsresult rv = nsAccessible::GetARIAState(aState, aExtraState);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsAccessible> parent = nsAccUtils::QueryAccessible(mParent);
if (parent) // Allow iframe/frame etc. to have final state override via ARIA
return parent->GetARIAState(aState, aExtraState);
if (mParent) // Allow iframe/frame etc. to have final state override via ARIA
return mParent->GetARIAState(aState, aExtraState);
return rv;
}
@ -554,13 +548,13 @@ NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNod
// It will assert if not all the children were created
// when they were first cached, and no invalidation
// ever corrected parent accessible's child cache.
nsCOMPtr<nsIAccessible> accessible = do_QueryInterface(*aAccessNode);
nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(accessible);
nsRefPtr<nsAccessible> acc =
nsAccUtils::QueryObject<nsAccessible>(*aAccessNode);
if (acc) {
nsCOMPtr<nsIAccessible> parent = acc->GetCachedParent();
nsRefPtr<nsAccessible> parentAcc(nsAccUtils::QueryAccessible(parent));
if (parentAcc)
parentAcc->TestChildCache(accessible);
nsAccessible* parent(acc->GetCachedParent());
if (parent)
parent->TestChildCache(acc);
}
#endif
return NS_OK;
@ -611,9 +605,12 @@ nsDocAccessible::Init()
nsresult rv = nsHyperTextAccessibleWrap::Init();
NS_ENSURE_SUCCESS(rv, rv);
// Initialize event queue.
mEventQueue = new nsAccEventQueue(this);
// Fire reorder event to notify new accessible document has been created and
// attached to the tree.
nsCOMPtr<nsIAccessibleEvent> reorderEvent =
nsRefPtr<nsAccEvent> reorderEvent =
new nsAccReorderEvent(mParent, PR_FALSE, PR_TRUE, mDOMNode);
NS_ENSURE_TRUE(reorderEvent, NS_ERROR_OUT_OF_MEMORY);
@ -628,6 +625,9 @@ nsDocAccessible::Shutdown()
return NS_OK; // Already shutdown
}
mEventQueue->Shutdown();
mEventQueue = nsnull;
nsCOMPtr<nsIDocShellTreeItem> treeItem =
nsCoreUtils::GetDocShellTreeItemFor(mDOMNode);
ShutdownChildDocuments(treeItem);
@ -643,21 +643,6 @@ nsDocAccessible::Shutdown()
nsHyperTextAccessibleWrap::Shutdown();
if (mFireEventTimer) {
// Doc being shut down before delayed events were processed.
mFireEventTimer->Cancel();
mFireEventTimer = nsnull;
mEventsToFire.Clear();
if (mFireEventTimerStarted && !mInFlushPendingEvents) {
// Make sure we release the kung fu death grip which is always there when
// fire event timer was started but FlushPendingEvents() callback wasn't
// triggered yet. If FlushPendingEvents() is in call stack, kung fu death
// grip will be released there.
NS_RELEASE_THIS();
}
}
// Remove from the cache after other parts of Shutdown(), so that Shutdown() procedures
// can find the doc or root accessible in the cache if they need it.
// We don't do this during ShutdownAccessibility() because that is already clearing the cache
@ -726,31 +711,28 @@ void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame)
if (!presShell) {
return;
}
nsIViewManager* vm = presShell->GetViewManager();
if (!vm) {
nsRect scrollPort;
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollableExternal();
if (sf) {
scrollPort = sf->GetScrollPortRect();
} else {
nsIFrame* rootFrame = presShell->GetRootFrame();
if (!rootFrame) {
return;
}
nsIScrollableView* scrollableView = nsnull;
vm->GetRootScrollableView(&scrollableView);
nsRect viewBounds(0, 0, 0, 0);
if (scrollableView) {
viewBounds = scrollableView->View()->GetBounds();
}
else {
nsIView *view;
vm->GetRootView(view);
if (view) {
viewBounds = view->GetBounds();
}
scrollPort = rootFrame->GetRect();
}
if (parentDoc) { // After first time thru loop
aBounds.IntersectRect(viewBounds, aBounds);
// XXXroc bogus code! scrollPort is relative to the viewport of
// this document, but we're intersecting rectangles derived from
// multiple documents and assuming they're all in the same coordinate
// system. See bug 514117.
aBounds.IntersectRect(scrollPort, aBounds);
}
else { // First time through loop
aBounds = viewBounds;
aBounds = scrollPort;
}
document = parentDoc = document->GetParentDocument();
@ -878,9 +860,9 @@ nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
if (isFinished) {
// Need to wait until scrollable view is available
// Need to wait until scrollable frame is available
AddScrollListener();
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(GetParent()));
nsRefPtr<nsAccessible> acc(GetParent());
if (acc) {
// Make the parent forget about the old document as a child
acc->InvalidateChildren();
@ -900,9 +882,9 @@ nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
nsCOMPtr<nsIDocShellTreeItem> sameTypeRootOfFocus;
focusedTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRootOfFocus));
if (sameTypeRoot == sameTypeRootOfFocus) {
nsCOMPtr<nsIAccessibleEvent> accEvent =
nsRefPtr<nsAccEvent> accEvent =
new nsAccStateChangeEvent(this, nsIAccessibleStates::STATE_BUSY, PR_FALSE, PR_FALSE);
FireAccessibleEvent(accEvent);
nsEventShell::FireEvent(accEvent);
}
}
}
@ -913,13 +895,13 @@ nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
if (!isFinished) {
// Fire state change event to set STATE_BUSY when document is loading. For
// example, Window-Eyes expects to get it.
nsCOMPtr<nsIAccessibleEvent> accEvent =
nsRefPtr<nsAccEvent> accEvent =
new nsAccStateChangeEvent(this, nsIAccessibleStates::STATE_BUSY,
PR_FALSE, PR_TRUE);
FireAccessibleEvent(accEvent);
nsEventShell::FireEvent(accEvent);
}
nsAccUtils::FireAccEvent(aEventType, this);
nsEventShell::FireEvent(aEventType, this);
}
}
@ -933,7 +915,7 @@ void nsDocAccessible::ScrollTimerCallback(nsITimer *aTimer, void *aClosure)
// We only want to fire accessibilty scroll event when scrolling stops or pauses
// Therefore, we wait for no scroll events to occur between 2 ticks of this timer
// That indicates a pause in scrolling, so we fire the accessibilty scroll event
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SCROLLING_END, docAcc);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SCROLLING_END, docAcc);
docAcc->mScrollPositionChangedTicks = 0;
if (docAcc->mScrollWatchTimer) {
@ -948,45 +930,37 @@ void nsDocAccessible::ScrollTimerCallback(nsITimer *aTimer, void *aClosure)
void nsDocAccessible::AddScrollListener()
{
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
if (!presShell)
return;
nsIViewManager* vm = nsnull;
if (presShell)
vm = presShell->GetViewManager();
nsIScrollableView* scrollableView = nsnull;
if (vm)
vm->GetRootScrollableView(&scrollableView);
if (scrollableView)
scrollableView->AddScrollPositionListener(this);
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollableExternal();
if (sf) {
sf->AddScrollPositionListener(this);
}
}
// nsDocAccessible protected member
void nsDocAccessible::RemoveScrollListener()
{
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
if (!presShell)
return;
nsIViewManager* vm = nsnull;
if (presShell)
vm = presShell->GetViewManager();
nsIScrollableView* scrollableView = nsnull;
if (vm)
vm->GetRootScrollableView(&scrollableView);
if (scrollableView)
scrollableView->RemoveScrollPositionListener(this);
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollableExternal();
if (sf) {
sf->RemoveScrollPositionListener(this);
}
}
////////////////////////////////////////////////////////////////////////////////
// nsIScrollPositionListener
NS_IMETHODIMP nsDocAccessible::ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY)
NS_IMETHODIMP nsDocAccessible::ScrollPositionWillChange(nscoord aX, nscoord aY)
{
return NS_OK;
}
NS_IMETHODIMP nsDocAccessible::ScrollPositionDidChange(nsIScrollableView *aScrollableView, nscoord aX, nscoord aY)
NS_IMETHODIMP nsDocAccessible::ScrollPositionDidChange(nscoord aX, nscoord aY)
{
// Start new timer, if the timer cycles at least 1 full cycle without more scroll position changes,
// then the ::Notify() method will fire the accessibility event for scroll position changes
@ -1015,10 +989,10 @@ NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic
{
if (!nsCRT::strcmp(aTopic,"obs_documentCreated")) {
// State editable will now be set, readonly is now clear
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(this, nsIAccessibleStates::EXT_STATE_EDITABLE,
PR_TRUE, PR_TRUE);
FireAccessibleEvent(event);
nsEventShell::FireEvent(event);
}
return NS_OK;
@ -1102,11 +1076,6 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
if (!targetNode || !nsAccUtils::IsNodeRelevant(targetNode))
return;
// Since we're in synchronous code, we can store whether the current attribute
// change is from user input or not. If the attribute change causes an asynchronous
// layout change, that event can use the last known user input state
nsAccEvent::PrepareForEvent(targetNode);
// Universal boolean properties that don't require a role. Fire the state
// change when disabled or aria-disabled attribute is set.
if (aAttribute == nsAccessibilityAtoms::disabled ||
@ -1119,14 +1088,14 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
// Note. We use the attribute instead of the disabled state bit because
// ARIA's aria-disabled does not affect the disabled state bit.
nsCOMPtr<nsIAccessibleEvent> enabledChangeEvent =
nsRefPtr<nsAccEvent> enabledChangeEvent =
new nsAccStateChangeEvent(targetNode,
nsIAccessibleStates::EXT_STATE_ENABLED,
PR_TRUE);
FireDelayedAccessibleEvent(enabledChangeEvent);
nsCOMPtr<nsIAccessibleEvent> sensitiveChangeEvent =
nsRefPtr<nsAccEvent> sensitiveChangeEvent =
new nsAccStateChangeEvent(targetNode,
nsIAccessibleStates::EXT_STATE_SENSITIVE,
PR_TRUE);
@ -1202,7 +1171,7 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
}
if (aAttribute == nsAccessibilityAtoms::contenteditable) {
nsCOMPtr<nsIAccessibleEvent> editableChangeEvent =
nsRefPtr<nsAccEvent> editableChangeEvent =
new nsAccStateChangeEvent(targetNode,
nsIAccessibleStates::EXT_STATE_EDITABLE,
PR_TRUE);
@ -1220,7 +1189,7 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
return;
if (aAttribute == nsAccessibilityAtoms::aria_required) {
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(targetNode,
nsIAccessibleStates::STATE_REQUIRED,
PR_FALSE);
@ -1229,7 +1198,7 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
}
if (aAttribute == nsAccessibilityAtoms::aria_invalid) {
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(targetNode,
nsIAccessibleStates::STATE_INVALID,
PR_FALSE);
@ -1263,7 +1232,7 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
const PRUint32 kState = (aAttribute == nsAccessibilityAtoms::aria_checked) ?
nsIAccessibleStates::STATE_CHECKED :
nsIAccessibleStates::STATE_PRESSED;
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(targetNode, kState, PR_FALSE);
FireDelayedAccessibleEvent(event);
if (targetNode == gLastFocusedNode) {
@ -1278,7 +1247,7 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
PRBool isMixed =
(nsAccUtils::State(accessible) & nsIAccessibleStates::STATE_MIXED) != 0;
if (wasMixed != isMixed) {
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(targetNode,
nsIAccessibleStates::STATE_MIXED,
PR_FALSE, isMixed);
@ -1290,7 +1259,7 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
}
if (aAttribute == nsAccessibilityAtoms::aria_expanded) {
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(targetNode,
nsIAccessibleStates::STATE_EXPANDED,
PR_FALSE);
@ -1299,7 +1268,7 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
}
if (aAttribute == nsAccessibilityAtoms::aria_readonly) {
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(targetNode,
nsIAccessibleStates::STATE_READONLY,
PR_FALSE);
@ -1421,7 +1390,7 @@ nsDocAccessible::ParentChainChanged(nsIContent *aContent)
////////////////////////////////////////////////////////////////////////////////
// nsAccessible
nsIAccessible*
nsAccessible*
nsDocAccessible::GetParent()
{
if (IsDefunct())
@ -1444,7 +1413,9 @@ nsDocAccessible::GetParent()
// hierarchy. GetAccessibleFor() is bad because it doesn't support our
// concept of multiple presshells per doc.
// It should be changed to use GetAccessibleInWeakShell()
accService->GetAccessibleFor(ownerNode, getter_AddRefs(mParent));
nsCOMPtr<nsIAccessible> parent;
accService->GetAccessibleFor(ownerNode, getter_AddRefs(parent));
mParent = nsAccUtils::QueryObject<nsAccessible>(parent);
}
}
@ -1463,10 +1434,10 @@ nsDocAccessible::FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldA
return;
// Dependent value change event for text changes in textfields
nsCOMPtr<nsIAccessibleEvent> valueChangeEvent =
nsRefPtr<nsAccEvent> valueChangeEvent =
new nsAccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aPossibleTextFieldAccessible,
PR_FALSE, nsAccEvent::eRemoveDupes);
FireDelayedAccessibleEvent(valueChangeEvent );
PR_FALSE, eAutoDetect, nsAccEvent::eRemoveDupes);
FireDelayedAccessibleEvent(valueChangeEvent);
}
void
@ -1520,22 +1491,23 @@ nsDocAccessible::FireTextChangeEventForText(nsIContent *aContent,
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccTextChangeEvent(accessible, offset,
renderedEndOffset - renderedStartOffset,
aIsInserted, PR_FALSE);
textAccessible->FireAccessibleEvent(event);
nsEventShell::FireEvent(event);
FireValueChangeForTextFields(accessible);
}
}
already_AddRefed<nsIAccessibleEvent>
already_AddRefed<nsAccEvent>
nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible,
nsIDOMNode *aChangeNode,
nsIAccessible *aAccessibleForChangeNode,
PRBool aIsInserting,
PRBool aIsAsynch)
PRBool aIsAsynch,
EIsFromUserInput aIsFromUserInput)
{
nsRefPtr<nsHyperTextAccessible> textAccessible;
aContainerAccessible->QueryInterface(NS_GET_IID(nsHyperTextAccessible),
@ -1560,13 +1532,18 @@ nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessibl
if (!changeAccessible) {
return nsnull; // No descendant content that represents any text in the hypertext parent
}
nsCOMPtr<nsINode> changeNode(do_QueryInterface(aChangeNode));
nsCOMPtr<nsIAccessible> child = changeAccessible;
while (PR_TRUE) {
nsCOMPtr<nsIAccessNode> childAccessNode =
do_QueryInterface(changeAccessible);
nsCOMPtr<nsIDOMNode> childNode;
childAccessNode->GetDOMNode(getter_AddRefs(childNode));
if (!nsCoreUtils::IsAncestorOf(aChangeNode, childNode)) {
nsCOMPtr<nsIDOMNode> childDOMNode;
childAccessNode->GetDOMNode(getter_AddRefs(childDOMNode));
nsCOMPtr<nsINode> childNode(do_QueryInterface(childDOMNode));
if (!nsCoreUtils::IsAncestorOf(changeNode, childNode)) {
break; // We only want accessibles with DOM nodes as children of this node
}
length += nsAccUtils::TextLength(child);
@ -1600,8 +1577,9 @@ nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessibl
return nsnull;
}
nsIAccessibleEvent *event =
new nsAccTextChangeEvent(aContainerAccessible, offset, length, aIsInserting, aIsAsynch);
nsAccEvent *event =
new nsAccTextChangeEvent(aContainerAccessible, offset, length, aIsInserting,
aIsAsynch, aIsFromUserInput);
NS_IF_ADDREF(event);
return event;
@ -1612,10 +1590,11 @@ nsresult
nsDocAccessible::FireDelayedAccessibleEvent(PRUint32 aEventType,
nsIDOMNode *aDOMNode,
nsAccEvent::EEventRule aAllowDupes,
PRBool aIsAsynch)
PRBool aIsAsynch,
EIsFromUserInput aIsFromUserInput)
{
nsCOMPtr<nsIAccessibleEvent> event =
new nsAccEvent(aEventType, aDOMNode, aIsAsynch, aAllowDupes);
nsRefPtr<nsAccEvent> event =
new nsAccEvent(aEventType, aDOMNode, aIsAsynch, aIsFromUserInput, aAllowDupes);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
return FireDelayedAccessibleEvent(event);
@ -1623,92 +1602,31 @@ nsDocAccessible::FireDelayedAccessibleEvent(PRUint32 aEventType,
// nsDocAccessible public member
nsresult
nsDocAccessible::FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent)
nsDocAccessible::FireDelayedAccessibleEvent(nsAccEvent *aEvent)
{
NS_ENSURE_ARG(aEvent);
nsRefPtr<nsAccEvent> accEvent = nsAccUtils::QueryObject<nsAccEvent>(aEvent);
mEventsToFire.AppendElement(accEvent);
if (mEventQueue)
mEventQueue->Push(aEvent);
// Filter events.
nsAccEvent::ApplyEventRules(mEventsToFire);
// Process events.
return PreparePendingEventsFlush();
}
nsresult
nsDocAccessible::PreparePendingEventsFlush()
{
nsresult rv = NS_OK;
// Create timer if we don't have it yet.
if (!mFireEventTimer) {
mFireEventTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
// If there are delayed events in the queue and event timer wasn't started
// then initialize the timer so that delayed event will be processed in
// FlushPendingEvents.
if (mEventsToFire.Length() > 0 && !mFireEventTimerStarted) {
rv = mFireEventTimer->InitWithFuncCallback(FlushEventsCallback,
this, 0,
nsITimer::TYPE_ONE_SHOT);
if (NS_SUCCEEDED(rv)) {
// Kung fu death grip to prevent crash in callback.
NS_ADDREF_THIS();
mFireEventTimerStarted = PR_TRUE;
}
}
return rv;
return NS_OK;
}
void
nsDocAccessible::FlushPendingEvents()
nsDocAccessible::ProcessPendingEvent(nsAccEvent *aEvent)
{
mInFlushPendingEvents = PR_TRUE;
PRUint32 length = mEventsToFire.Length();
NS_ASSERTION(length, "How did we get here without events to fire?");
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
if (!presShell)
length = 0; // The doc is now shut down, don't fire events in it anymore
else {
// Flush layout so that all the frame construction, reflow, and styles are
// up-to-date. This will ensure we can get frames for the related nodes, as
// well as get the most current information for calculating things like
// visibility. We don't flush the display because we don't care about
// painting. If no flush is necessary the method will simple return.
presShell->FlushPendingNotifications(Flush_Layout);
}
// Process only currently queued events. In the meantime, newly appended
// events will not be processed.
for (PRUint32 index = 0; index < length; index ++) {
// No presshell means the document was shut down duiring event handling
// by AT.
if (!mWeakShell)
break;
nsCOMPtr<nsIAccessibleEvent> accessibleEvent(mEventsToFire[index]);
if (nsAccEvent::EventRule(accessibleEvent) == nsAccEvent::eDoNotEmit)
continue;
nsCOMPtr<nsIAccessible> accessible;
accessibleEvent->GetAccessible(getter_AddRefs(accessible));
nsCOMPtr<nsIDOMNode> domNode;
accessibleEvent->GetDOMNode(getter_AddRefs(domNode));
PRUint32 eventType = nsAccEvent::EventType(accessibleEvent);
PRBool isFromUserInput = nsAccEvent::IsFromUserInput(accessibleEvent);
aEvent->GetAccessible(getter_AddRefs(accessible));
nsCOMPtr<nsIDOMNode> domNode;
aEvent->GetDOMNode(getter_AddRefs(domNode));
PRUint32 eventType = aEvent->GetEventType();
EIsFromUserInput isFromUserInput =
aEvent->IsFromUserInput() ? eFromUserInput : eNoUserInput;
PRBool isAsync = aEvent->IsAsync();
PRBool isAsync = nsAccEvent::IsAsyncEvent(accessibleEvent);
if (domNode == gLastFocusedNode && isAsync &&
(eventType == nsIAccessibleEvent::EVENT_SHOW ||
eventType == nsIAccessibleEvent::EVENT_HIDE)) {
@ -1728,7 +1646,7 @@ nsDocAccessible::FlushPendingEvents()
// just invalidate the children instead
FireShowHideEvents(domNode, PR_TRUE, eventType, eNormalEvent,
isAsync, isFromUserInput);
continue;
return;
}
gLastFocusedFrameType = newFrameType;
}
@ -1766,21 +1684,21 @@ nsDocAccessible::FlushPendingEvents()
// 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.
if (domNode && domNode != mDOMNode) {
nsCOMPtr<nsIAccessibleEvent> textChangeEvent =
CreateTextChangeEventForNode(containerAccessible, domNode, accessible, PR_TRUE, PR_TRUE);
nsRefPtr<nsAccEvent> textChangeEvent =
CreateTextChangeEventForNode(containerAccessible, domNode, accessible,
PR_TRUE, PR_TRUE, isFromUserInput);
if (textChangeEvent) {
nsAccEvent::PrepareForEvent(textChangeEvent, 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);
nsEventShell::FireEvent(textChangeEvent);
}
}
// Fire show/create events for this node or first accessible descendants of it
FireShowHideEvents(domNode, PR_FALSE, eventType, eNormalEvent, isAsync,
isFromUserInput);
continue;
return;
}
if (accessible) {
@ -1806,19 +1724,19 @@ nsDocAccessible::FlushPendingEvents()
// line-number object attribute on it
nsCOMPtr<nsIAccessible> accForFocus;
GetAccService()->GetAccessibleFor(gLastFocusedNode, getter_AddRefs(accForFocus));
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_ALERT, accForFocus);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_ALERT, accForFocus);
#endif
nsCOMPtr<nsIAccessibleEvent> caretMoveEvent =
nsRefPtr<nsAccEvent> caretMoveEvent =
new nsAccCaretMoveEvent(accessible, caretOffset);
if (!caretMoveEvent)
break; // Out of memory, break out to release kung fu death grip
return;
FireAccessibleEvent(caretMoveEvent);
nsEventShell::FireEvent(caretMoveEvent);
PRInt32 selectionCount;
accessibleText->GetSelectionCount(&selectionCount);
if (selectionCount) { // There's a selection so fire selection change as well
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED,
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED,
accessible, PR_TRUE);
}
}
@ -1827,60 +1745,27 @@ nsDocAccessible::FlushPendingEvents()
// Fire reorder event if it's unconditional (see InvalidateCacheSubtree
// method) or if changed node (that is the reason of this reorder event)
// is accessible or has accessible children.
nsCOMPtr<nsAccReorderEvent> reorderEvent = do_QueryInterface(accessibleEvent);
nsCOMPtr<nsAccReorderEvent> reorderEvent = do_QueryInterface(aEvent);
if (reorderEvent->IsUnconditionalEvent() ||
reorderEvent->HasAccessibleInReasonSubtree()) {
nsAccEvent::PrepareForEvent(accessibleEvent);
FireAccessibleEvent(accessibleEvent);
nsEventShell::FireEvent(aEvent);
}
}
else {
// The input state was previously stored with the nsIAccessibleEvent,
// so use that state now when firing the event
nsAccEvent::PrepareForEvent(accessibleEvent);
FireAccessibleEvent(accessibleEvent);
nsEventShell::FireEvent(aEvent);
// Post event processing
if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
// Shutdown nsIAccessNode's or nsIAccessibles for any DOM nodes in
// this subtree.
nsCOMPtr<nsIDOMNode> hidingNode;
accessibleEvent->GetDOMNode(getter_AddRefs(hidingNode));
aEvent->GetDOMNode(getter_AddRefs(hidingNode));
if (hidingNode) {
RefreshNodes(hidingNode); // Will this bite us with asynch events
}
}
}
}
}
// Mark we are ready to start event processing timer again.
mFireEventTimerStarted = PR_FALSE;
// If the document accessible is alive then remove processed events from the
// queue (otherwise they were removed on shutdown already) and reinitialize
// queue processing callback if necessary (new events might occur duiring
// delayed event processing).
if (mWeakShell) {
mEventsToFire.RemoveElementsAt(0, length);
PreparePendingEventsFlush();
}
// After a flood of events, reset so that user input flag is off.
nsAccEvent::ResetLastInputState();
mInFlushPendingEvents = PR_FALSE;
NS_RELEASE_THIS(); // Release kung fu death grip.
}
void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure)
{
nsDocAccessible *accessibleDoc = static_cast<nsDocAccessible*>(aClosure);
NS_ASSERTION(accessibleDoc, "How did we get here without an accessible document?");
if (accessibleDoc) {
// A lot of crashes were happening here, so now we're reffing the doc
// now until the events are flushed
accessibleDoc->FlushPendingEvents();
}
}
void nsDocAccessible::InvalidateChildrenInSubtree(nsIDOMNode *aStartNode)
@ -1923,7 +1808,7 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode)
if (!popup) {
// Popup elements already fire these via DOMMenuInactive
// handling in nsRootAccessible::HandleEvent
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
accessible);
}
}
@ -1931,8 +1816,7 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode)
// We only need to shutdown the accessibles here if one of them has been
// created.
nsCOMPtr<nsIAccessible> childAccessible = acc->GetCachedFirstChild();
if (childAccessible) {
if (acc->GetCachedFirstChild()) {
nsCOMPtr<nsIArray> children;
// use GetChildren() to fetch children at one time, instead of using
// GetNextSibling(), because after we shutdown the first child,
@ -2118,7 +2002,7 @@ nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// away.
nsresult rv = FireShowHideEvents(childNode, PR_FALSE,
nsIAccessibleEvent::EVENT_HIDE,
eDelayedEvent, isAsynch, PR_FALSE);
eDelayedEvent, isAsynch);
NS_ENSURE_SUCCESS(rv,);
if (childNode != mDOMNode) { // Fire text change unless the node being removed is for this doc
@ -2127,11 +2011,11 @@ nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// 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<nsIAccessibleEvent> textChangeEvent =
nsRefPtr<nsAccEvent> textChangeEvent =
CreateTextChangeEventForNode(containerAccessible, childNode, childAccessible,
PR_FALSE, isAsynch);
if (textChangeEvent) {
FireAccessibleEvent(textChangeEvent);
nsEventShell::FireEvent(textChangeEvent);
}
}
}
@ -2209,7 +2093,7 @@ nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
PRBool isUnconditionalEvent = childAccessible ||
aChild && nsAccUtils::HasAccessibleChildren(childNode);
nsCOMPtr<nsIAccessibleEvent> reorderEvent =
nsRefPtr<nsAccEvent> reorderEvent =
new nsAccReorderEvent(containerAccessible, isAsynch,
isUnconditionalEvent,
aChild ? childNode.get() : nsnull);
@ -2266,7 +2150,7 @@ nsDocAccessible::FireShowHideEvents(nsIDOMNode *aDOMNode,
PRUint32 aEventType,
EEventFiringType aDelayedOrNormal,
PRBool aIsAsyncChange,
PRBool aForceIsFromUserInput)
EIsFromUserInput aIsFromUserInput)
{
NS_ENSURE_ARG(aDOMNode);
@ -2287,19 +2171,16 @@ nsDocAccessible::FireShowHideEvents(nsIDOMNode *aDOMNode,
if (accessible) {
// Found an accessible, so fire the show/hide on it and don't look further
// into this subtree.
nsCOMPtr<nsIAccessibleEvent> event =
new nsAccEvent(aEventType, accessible, aIsAsyncChange,
nsRefPtr<nsAccEvent> event =
new nsAccEvent(aEventType, accessible, aIsAsyncChange, aIsFromUserInput,
nsAccEvent::eCoalesceFromSameSubtree);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
if (aForceIsFromUserInput) {
nsAccEvent::PrepareForEvent(event, aForceIsFromUserInput);
}
if (aDelayedOrNormal == eDelayedEvent)
return FireDelayedAccessibleEvent(event);
return FireAccessibleEvent(event);
nsEventShell::FireEvent(event);
return NS_OK;
}
// Could not find accessible to show hide yet, so fire on any
@ -2310,7 +2191,7 @@ nsDocAccessible::FireShowHideEvents(nsIDOMNode *aDOMNode,
nsCOMPtr<nsIDOMNode> childNode = do_QueryInterface(node->GetChildAt(index));
nsresult rv = FireShowHideEvents(childNode, PR_FALSE, aEventType,
aDelayedOrNormal, aIsAsyncChange,
aForceIsFromUserInput);
aIsFromUserInput);
NS_ENSURE_SUCCESS(rv, rv);
}

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

@ -56,11 +56,11 @@ class nsIScrollableView;
const PRUint32 kDefaultCacheSize = 256;
#define NS_DOCACCESSIBLE_IMPL_CID \
{ /* 9e97d7af-b20a-4a5a-a8d9-bcae0de0b7a2 */ \
0x9e97d7af, \
0xb20a, \
0x4a5a, \
{ 0xa8, 0xd9, 0xbc, 0xae, 0x0d, 0xe0, 0xb7, 0xa2 } \
{ /* 5641921c-a093-4292-9dca-0b51813db57d */ \
0x5641921c, \
0xa093, \
0x4292, \
{ 0x9d, 0xca, 0x0b, 0x51, 0x81, 0x3d, 0xb5, 0x7d } \
}
class nsDocAccessible : public nsHyperTextAccessibleWrap,
@ -90,12 +90,9 @@ public:
NS_IMETHOD TakeFocus(void);
// nsIScrollPositionListener
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView,
nscoord aX, nscoord aY);
virtual void ViewPositionDidChange(nsIScrollableView* aScrollable,
nsTArray<nsIWidget::Configuration>* aConfigurations) {}
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView,
nscoord aX, nscoord aY);
NS_IMETHOD ScrollPositionWillChange(nscoord aX, nscoord aY);
virtual void ViewPositionDidChange(nsTArray<nsIWidget::Configuration>* aConfigurations) {}
NS_IMETHOD ScrollPositionDidChange(nscoord aX, nscoord aY);
// nsIDocumentObserver
NS_DECL_NSIDOCUMENTOBSERVER
@ -112,7 +109,7 @@ public:
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
virtual nsIAccessible* GetParent();
virtual nsAccessible* GetParent();
// nsIAccessibleText
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
@ -130,14 +127,15 @@ public:
*/
nsresult FireDelayedAccessibleEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
PRBool aIsAsynch = PR_FALSE);
PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect);
/**
* Fire accessible event after timeout.
*
* @param aEvent [in] the event to fire
*/
nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent);
nsresult FireDelayedAccessibleEvent(nsAccEvent *aEvent);
/**
* Find the accessible object in the accessibility cache that corresponds to
@ -174,9 +172,10 @@ public:
virtual void FireDocLoadEvents(PRUint32 aEventType);
/**
* Used to flush pending events, called after timeout. See FlushPendingEvents.
* Process the event when the queue of pending events is untwisted. Fire
* accessible events as result of the processing.
*/
static void FlushEventsCallback(nsITimer *aTimer, void *aClosure);
void ProcessPendingEvent(nsAccEvent* aEvent);
protected:
/**
@ -216,16 +215,6 @@ protected:
*/
void ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute);
/**
* Process delayed (pending) events resulted in normal events firing.
*/
void FlushPendingEvents();
/**
* Start the timer to flush delayed (pending) events.
*/
nsresult PreparePendingEventsFlush();
/**
* Fire text changed event for character data changed. The method is used
* from nsIMutationObserver methods.
@ -240,18 +229,25 @@ protected:
PRBool aIsInserted);
/**
* 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)
* Create a text change event for a changed node.
*
* @param aContainerAccessible [in] the parent accessible for the node
* @param aNode [in] the node that is being inserted or
* removed, or shown/hidden
* @param aAccessible [in] the accessible for that node, or nsnull
* if none exists
* @param aIsInserting [in] is aChangeNode being created or shown
* (vs. removed or hidden)
* @param aIsAsync [in] whether casual change is async
* @param aIsFromUserInput [in] the event is known to be from user input
*/
already_AddRefed<nsIAccessibleEvent>
already_AddRefed<nsAccEvent>
CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible,
nsIDOMNode *aChangeNode,
nsIAccessible *aAccessibleForNode,
nsIDOMNode *aNode,
nsIAccessible *aAccessible,
PRBool aIsInserting,
PRBool aIsAsynch);
PRBool aIsAsynch,
EIsFromUserInput aIsFromUserInput = eAutoDetect);
/**
* Used to define should the event be fired on a delay.
@ -271,13 +267,13 @@ protected:
* @param aEventType [in] event type to fire an event
* @param aDelayedOrNormal [in] whether to fire the event on a delay
* @param aIsAsyncChange [in] whether casual change is async
* @param aForceIsFromUserInput [in] the event is known to be from user input
* @param aIsFromUserInput [in] the event is known to be from user input
*/
nsresult FireShowHideEvents(nsIDOMNode *aDOMNode, PRBool aAvoidOnThisNode,
PRUint32 aEventType,
EEventFiringType aDelayedOrNormal,
PRBool aIsAsyncChange,
PRBool aForceIsFromUserInput);
EIsFromUserInput aIsFromUserInput = eAutoDetect);
/**
* If the given accessible object is a ROLE_ENTRY, fire a value change event for it
@ -288,16 +284,13 @@ protected:
void *mWnd;
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsITimer> mScrollWatchTimer;
nsCOMPtr<nsITimer> mFireEventTimer;
PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
PRPackedBool mIsContentLoaded;
PRPackedBool mIsLoadCompleteFired;
protected:
PRBool mInFlushPendingEvents;
PRBool mFireEventTimerStarted;
nsTArray<nsRefPtr<nsAccEvent> > mEventsToFire;
nsRefPtr<nsAccEventQueue> mEventQueue;
static PRUint32 gLastFocusedAccessiblesState;
static nsIAtom *gLastFocusedFrameType;

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

@ -0,0 +1,407 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsEventShell.h"
#include "nsDocAccessible.h"
////////////////////////////////////////////////////////////////////////////////
// nsEventShell
////////////////////////////////////////////////////////////////////////////////
void
nsEventShell::FireEvent(nsAccEvent *aEvent)
{
if (!aEvent)
return;
nsRefPtr<nsAccessible> acc =
nsAccUtils::QueryObject<nsAccessible>(aEvent->GetAccessible());
NS_ENSURE_TRUE(acc,);
nsCOMPtr<nsIDOMNode> node;
aEvent->GetDOMNode(getter_AddRefs(node));
if (node) {
sEventTargetNode = node;
sEventFromUserInput = aEvent->IsFromUserInput();
}
acc->HandleAccEvent(aEvent);
sEventTargetNode = nsnull;
}
void
nsEventShell::FireEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput)
{
NS_ENSURE_TRUE(aAccessible,);
nsRefPtr<nsAccEvent> event = new nsAccEvent(aEventType, aAccessible,
aIsAsynch, aIsFromUserInput);
FireEvent(event);
}
void
nsEventShell::GetEventAttributes(nsIDOMNode *aNode,
nsIPersistentProperties *aAttributes)
{
if (aNode != sEventTargetNode)
return;
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::eventFromInput,
sEventFromUserInput ? NS_LITERAL_STRING("true") :
NS_LITERAL_STRING("false"));
}
////////////////////////////////////////////////////////////////////////////////
// nsEventShell: private
PRBool nsEventShell::sEventFromUserInput = PR_FALSE;
nsCOMPtr<nsIDOMNode> nsEventShell::sEventTargetNode;
////////////////////////////////////////////////////////////////////////////////
// nsAccEventQueue
////////////////////////////////////////////////////////////////////////////////
nsAccEventQueue::nsAccEventQueue(nsDocAccessible *aDocument):
mProcessingStarted(PR_FALSE), mDocument(aDocument)
{
}
nsAccEventQueue::~nsAccEventQueue()
{
NS_ASSERTION(mDocument, "Queue wasn't shut down!");
}
////////////////////////////////////////////////////////////////////////////////
// nsAccEventQueue: nsISupports and cycle collection
NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccEventQueue)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccEventQueue)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAccEventQueue)
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDocument");
cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mDocument.get()));
PRUint32 i, length = tmp->mEvents.Length();
for (i = 0; i < length; ++i) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvents[i]");
cb.NoteXPCOMChild(tmp->mEvents[i].get());
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsAccEventQueue)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mEvents)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccEventQueue)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEventQueue)
////////////////////////////////////////////////////////////////////////////////
// nsAccEventQueue: public
void
nsAccEventQueue::Push(nsAccEvent *aEvent)
{
mEvents.AppendElement(aEvent);
// Filter events.
CoalesceEvents();
// Process events.
PrepareFlush();
}
void
nsAccEventQueue::Shutdown()
{
mDocument = nsnull;
mEvents.Clear();
}
////////////////////////////////////////////////////////////////////////////////
// nsAccEventQueue: private
void
nsAccEventQueue::PrepareFlush()
{
// If there are pending events in the queue and events flush isn't planed
// yet start events flush asyncroniously.
if (mEvents.Length() > 0 && !mProcessingStarted) {
NS_DISPATCH_RUNNABLEMETHOD(Flush, this)
mProcessingStarted = PR_TRUE;
}
}
void
nsAccEventQueue::Flush()
{
// If the document accessible is now shut down, don't fire events in it
// anymore.
if (!mDocument)
return;
nsCOMPtr<nsIPresShell> presShell = mDocument->GetPresShell();
if (!presShell)
return;
// Flush layout so that all the frame construction, reflow, and styles are
// up-to-date. This will ensure we can get frames for the related nodes, as
// well as get the most current information for calculating things like
// visibility. We don't flush the display because we don't care about
// painting. If no flush is necessary the method will simple return.
presShell->FlushPendingNotifications(Flush_Layout);
// Process only currently queued events. Newly appended events duiring events
// flusing won't be processed.
PRUint32 length = mEvents.Length();
NS_ASSERTION(length, "How did we get here without events to fire?");
for (PRUint32 index = 0; index < length; index ++) {
// No presshell means the document was shut down duiring event handling
// by AT.
if (!mDocument || !mDocument->HasWeakShell())
break;
nsAccEvent *accEvent = mEvents[index];
if (accEvent->mEventRule != nsAccEvent::eDoNotEmit)
mDocument->ProcessPendingEvent(accEvent);
}
// Mark we are ready to start event processing again.
mProcessingStarted = PR_FALSE;
// If the document accessible is alive then remove processed events from the
// queue (otherwise they were removed on shutdown already) and reinitialize
// queue processing callback if necessary (new events might occur duiring
// delayed event processing).
if (mDocument && mDocument->HasWeakShell()) {
mEvents.RemoveElementsAt(0, length);
PrepareFlush();
}
}
void
nsAccEventQueue::CoalesceEvents()
{
PRUint32 numQueuedEvents = mEvents.Length();
PRInt32 tail = numQueuedEvents - 1;
nsAccEvent* tailEvent = mEvents[tail];
switch(tailEvent->mEventRule) {
case nsAccEvent::eCoalesceFromSameSubtree:
{
for (PRInt32 index = 0; index < tail; index ++) {
nsAccEvent* thisEvent = mEvents[index];
if (thisEvent->mEventType != tailEvent->mEventType)
continue; // Different type
if (thisEvent->mEventRule == nsAccEvent::eAllowDupes ||
thisEvent->mEventRule == nsAccEvent::eDoNotEmit)
continue; // Do not need to check
if (thisEvent->mNode == tailEvent->mNode) {
if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
CoalesceReorderEventsFromSameSource(thisEvent, tailEvent);
continue;
}
// Dupe
thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
continue;
}
// More older show event target (thisNode) can't be contained by recent
// show event target (tailNode), i.e be a descendant of tailNode.
// XXX: target of older show event caused by DOM node appending can be
// contained by target of recent show event caused by style change.
// XXX: target of older show event caused by style change can be
// contained by target of recent show event caused by style change.
PRBool thisCanBeDescendantOfTail =
tailEvent->mEventType != nsIAccessibleEvent::EVENT_SHOW ||
tailEvent->mIsAsync;
if (thisCanBeDescendantOfTail &&
nsCoreUtils::IsAncestorOf(tailEvent->mNode, thisEvent->mNode)) {
// thisNode is a descendant of tailNode.
if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
CoalesceReorderEventsFromSameTree(tailEvent, thisEvent);
continue;
}
// Do not emit thisEvent, also apply this result to sibling nodes of
// thisNode.
thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
ApplyToSiblings(0, index, thisEvent->mEventType,
thisEvent->mNode, nsAccEvent::eDoNotEmit);
continue;
}
#ifdef DEBUG
if (!thisCanBeDescendantOfTail &&
nsCoreUtils::IsAncestorOf(tailEvent->mNode, thisEvent->mNode)) {
NS_NOTREACHED("Older event target is a descendant of recent event target!");
}
#endif
// More older hide event target (thisNode) can't contain recent hide
// event target (tailNode), i.e. be ancestor of tailNode.
if (tailEvent->mEventType != nsIAccessibleEvent::EVENT_HIDE &&
nsCoreUtils::IsAncestorOf(thisEvent->mNode, tailEvent->mNode)) {
// tailNode is a descendant of thisNode
if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
CoalesceReorderEventsFromSameTree(thisEvent, tailEvent);
continue;
}
// Do not emit tailEvent, also apply this result to sibling nodes of
// tailNode.
tailEvent->mEventRule = nsAccEvent::eDoNotEmit;
ApplyToSiblings(0, tail, tailEvent->mEventType,
tailEvent->mNode, nsAccEvent::eDoNotEmit);
break;
}
#ifdef DEBUG
if (tailEvent->mEventType == nsIAccessibleEvent::EVENT_HIDE &&
nsCoreUtils::IsAncestorOf(thisEvent->mNode, tailEvent->mNode)) {
NS_NOTREACHED("More older hide event target is an ancestor of recent hide event target!");
}
#endif
} // for (index)
if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit) {
// Not in another event node's subtree, and no other event is in this
// event node's subtree. This event should be emitted. Apply this result
// to sibling nodes of tailNode.
// We should do this in all cases even when tailEvent is hide event and
// it's caused by DOM node removal because the rule can applied for
// sibling event targets caused by style changes.
ApplyToSiblings(0, tail, tailEvent->mEventType,
tailEvent->mNode, nsAccEvent::eAllowDupes);
}
} break; // case eCoalesceFromSameSubtree
case nsAccEvent::eRemoveDupes:
{
// Check for repeat events.
for (PRInt32 index = 0; index < tail; index ++) {
nsAccEvent* accEvent = mEvents[index];
if (accEvent->mEventType == tailEvent->mEventType &&
accEvent->mEventRule == tailEvent->mEventRule &&
accEvent->mNode == tailEvent->mNode) {
accEvent->mEventRule = nsAccEvent::eDoNotEmit;
}
}
} break; // case eRemoveDupes
default:
break; // case eAllowDupes, eDoNotEmit
} // switch
}
void
nsAccEventQueue::ApplyToSiblings(PRUint32 aStart, PRUint32 aEnd,
PRUint32 aEventType, nsINode* aNode,
nsAccEvent::EEventRule aEventRule)
{
for (PRUint32 index = aStart; index < aEnd; index ++) {
nsAccEvent* accEvent = mEvents[index];
if (accEvent->mEventType == aEventType &&
accEvent->mEventRule != nsAccEvent::eDoNotEmit &&
nsCoreUtils::AreSiblings(accEvent->mNode, aNode)) {
accEvent->mEventRule = aEventRule;
}
}
}
void
nsAccEventQueue::CoalesceReorderEventsFromSameSource(nsAccEvent *aAccEvent1,
nsAccEvent *aAccEvent2)
{
// Do not emit event2 if event1 is unconditional.
nsCOMPtr<nsAccReorderEvent> reorderEvent1 = do_QueryInterface(aAccEvent1);
if (reorderEvent1->IsUnconditionalEvent()) {
aAccEvent2->mEventRule = nsAccEvent::eDoNotEmit;
return;
}
// Do not emit event1 if event2 is unconditional.
nsCOMPtr<nsAccReorderEvent> reorderEvent2 = do_QueryInterface(aAccEvent2);
if (reorderEvent2->IsUnconditionalEvent()) {
aAccEvent1->mEventRule = nsAccEvent::eDoNotEmit;
return;
}
// Do not emit event2 if event1 is valid, otherwise do not emit event1.
if (reorderEvent1->HasAccessibleInReasonSubtree())
aAccEvent2->mEventRule = nsAccEvent::eDoNotEmit;
else
aAccEvent1->mEventRule = nsAccEvent::eDoNotEmit;
}
void
nsAccEventQueue::CoalesceReorderEventsFromSameTree(nsAccEvent *aAccEvent,
nsAccEvent *aDescendantAccEvent)
{
// Do not emit descendant event if this event is unconditional.
nsCOMPtr<nsAccReorderEvent> reorderEvent = do_QueryInterface(aAccEvent);
if (reorderEvent->IsUnconditionalEvent()) {
aDescendantAccEvent->mEventRule = nsAccEvent::eDoNotEmit;
return;
}
// Do not emit descendant event if this event is valid otherwise do not emit
// this event.
if (reorderEvent->HasAccessibleInReasonSubtree())
aDescendantAccEvent->mEventRule = nsAccEvent::eDoNotEmit;
else
aAccEvent->mEventRule = nsAccEvent::eDoNotEmit;
}

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

@ -0,0 +1,159 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _nsEventShell_H_
#define _nsEventShell_H_
#include "nsCoreUtils.h"
#include "nsAccEvent.h"
/**
* Used for everything about events.
*/
class nsEventShell
{
public:
/**
* Fire the accessible event.
*/
static void FireEvent(nsAccEvent *aEvent);
/**
* Fire accessible event of the given type for the given accessible.
*
* @param aEventType [in] the event type
* @param aAccessible [in] the event target
* @param aIsAsync [in, optional] specifies whether the origin change
* this event is fired owing to is async.
*/
static void FireEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect);
/**
* Append 'event-from-input' object attribute if the accessible event has
* been fired just now for the given node.
*
* @param aNode [in] the DOM node
* @param aAttributes [in, out] the attributes
*/
static void GetEventAttributes(nsIDOMNode *aNode,
nsIPersistentProperties *aAttributes);
private:
static nsCOMPtr<nsIDOMNode> sEventTargetNode;
static PRBool sEventFromUserInput;
};
/**
* Event queue.
*/
class nsAccEventQueue : public nsISupports
{
public:
nsAccEventQueue(nsDocAccessible *aDocument);
~nsAccEventQueue();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsAccEventQueue)
/**
* Push event to queue, coalesce it if necessary. Start pending processing.
*/
void Push(nsAccEvent *aEvent);
/**
* Shutdown the queue.
*/
void Shutdown();
private:
/**
* Start pending events procesing asyncroniously.
*/
void PrepareFlush();
/**
* Process pending events. It calls nsDocAccessible::ProcessPendingEvent()
* where the real event processing is happen.
*/
void Flush();
NS_DECL_RUNNABLEMETHOD(nsAccEventQueue, Flush)
/**
* Coalesce redurant events from the queue.
*/
void CoalesceEvents();
/**
* Apply aEventRule to same type event that from sibling nodes of aDOMNode.
* @param aEventsToFire array of pending events
* @param aStart start index of pending events to be scanned
* @param aEnd end index to be scanned (not included)
* @param aEventType target event type
* @param aDOMNode target are siblings of this node
* @param aEventRule the event rule to be applied
* (should be eDoNotEmit or eAllowDupes)
*/
void ApplyToSiblings(PRUint32 aStart, PRUint32 aEnd,
PRUint32 aEventType, nsINode* aNode,
nsAccEvent::EEventRule aEventRule);
/**
* Do not emit one of two given reorder events fired for the same DOM node.
*/
void CoalesceReorderEventsFromSameSource(nsAccEvent *aAccEvent1,
nsAccEvent *aAccEvent2);
/**
* Do not emit one of two given reorder events fired for DOM nodes in the case
* when one DOM node is in parent chain of second one.
*/
void CoalesceReorderEventsFromSameTree(nsAccEvent *aAccEvent,
nsAccEvent *aDescendantAccEvent);
PRBool mProcessingStarted;
nsRefPtr<nsDocAccessible> mDocument;
nsTArray<nsRefPtr<nsAccEvent> > mEvents;
};
#endif

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

@ -74,13 +74,14 @@ NS_IMETHODIMP nsRadioButtonAccessible::GetActionName(PRUint8 aIndex, nsAString&
return NS_ERROR_INVALID_ARG;
}
/** Our only action is to click */
NS_IMETHODIMP nsRadioButtonAccessible::DoAction(PRUint8 aIndex)
NS_IMETHODIMP
nsRadioButtonAccessible::DoAction(PRUint8 aIndex)
{
if (aIndex == eAction_Click) {
return DoCommand();
}
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
DoCommand();
return NS_OK;
}
nsresult

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

@ -127,7 +127,7 @@ nsOuterDocAccessible::CacheChildren()
return;
// Success getting inner document as first child -- now we cache it.
mChildren.AppendObject(innerAccessible);
mChildren.AppendElement(innerAcc);
innerAcc->SetParent(this);
}

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

@ -37,7 +37,7 @@
// NOTE: alphabetically ordered
#include "nsAccessibilityService.h"
#include "nsAccessibleEventData.h"
#include "nsAccEvent.h"
#include "nsApplicationAccessibleWrap.h"
#include "nsHTMLSelectAccessible.h"
@ -66,10 +66,8 @@
#include "nsIMenuFrame.h"
#include "nsIHTMLDocument.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIScrollableView.h"
#include "nsISelectionPrivate.h"
#include "nsIServiceManager.h"
#include "nsIViewManager.h"
#include "nsPIDOMWindow.h"
#include "nsIWebBrowserChrome.h"
#include "nsReadableUtils.h"
@ -293,7 +291,7 @@ nsresult nsRootAccessible::AddEventListeners()
* const* e_end = docEvents + NS_ARRAY_LENGTH(docEvents);
e < e_end; ++e) {
nsresult rv = nstarget->AddEventListener(NS_ConvertASCIItoUTF16(*e),
this, PR_TRUE, PR_TRUE);
this, PR_TRUE, PR_TRUE, 1);
NS_ENSURE_SUCCESS(rv, rv);
}
}
@ -395,7 +393,8 @@ nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
nsIDOMNode *aNode,
nsIDOMEvent *aFocusEvent,
PRBool aForceEvent,
PRBool aIsAsynch)
PRBool aIsAsynch,
EIsFromUserInput aIsFromUserInput)
{
if (mCaretAccessible) {
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aFocusEvent));
@ -481,17 +480,18 @@ nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
if (menuBarAccessNode) {
menuBarAccessNode->GetDOMNode(getter_AddRefs(mCurrentARIAMenubar));
if (mCurrentARIAMenubar) {
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_START,
menuBarAccessible);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_START,
menuBarAccessible, PR_FALSE,
aIsFromUserInput);
}
}
}
}
}
else if (mCurrentARIAMenubar) {
nsCOMPtr<nsIAccessibleEvent> menuEndEvent =
nsRefPtr<nsAccEvent> menuEndEvent =
new nsAccEvent(nsIAccessibleEvent::EVENT_MENU_END, mCurrentARIAMenubar,
PR_FALSE, nsAccEvent::eAllowDupes);
PR_FALSE, aIsFromUserInput, nsAccEvent::eAllowDupes);
if (menuEndEvent) {
FireDelayedAccessibleEvent(menuEndEvent);
}
@ -537,13 +537,17 @@ nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_FOCUS,
finalFocusNode, nsAccEvent::eRemoveDupes,
aIsAsynch);
aIsAsynch, aIsFromUserInput);
return PR_TRUE;
}
void nsRootAccessible::FireCurrentFocusEvent()
void
nsRootAccessible::FireCurrentFocusEvent()
{
if (IsDefunct())
return;
nsCOMPtr<nsIDOMNode> focusedNode = GetCurrentFocus();
if (!focusedNode) {
return; // No current focus
@ -683,10 +687,10 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
PRBool isEnabled = (state & (nsIAccessibleStates::STATE_CHECKED |
nsIAccessibleStates::STATE_SELECTED)) != 0;
nsCOMPtr<nsIAccessibleEvent> accEvent =
nsRefPtr<nsAccEvent> accEvent =
new nsAccStateChangeEvent(accessible, nsIAccessibleStates::STATE_CHECKED,
PR_FALSE, isEnabled);
acc->FireAccessibleEvent(accEvent);
nsEventShell::FireEvent(accEvent);
if (isEnabled)
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent);
@ -699,12 +703,13 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
PRBool isEnabled = !!(state & nsIAccessibleStates::STATE_CHECKED);
nsCOMPtr<nsIAccessibleEvent> accEvent =
nsRefPtr<nsAccEvent> accEvent =
new nsAccStateChangeEvent(accessible,
nsIAccessibleStates::STATE_CHECKED,
PR_FALSE, isEnabled);
return acc->FireAccessibleEvent(accEvent);
nsEventShell::FireEvent(accEvent);
return NS_OK;
}
nsCOMPtr<nsIAccessible> treeItemAccessible;
@ -735,10 +740,11 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
PRUint32 state = nsAccUtils::State(accessible); // collapsed/expanded changed
PRBool isEnabled = (state & nsIAccessibleStates::STATE_EXPANDED) != 0;
nsCOMPtr<nsIAccessibleEvent> accEvent =
nsRefPtr<nsAccEvent> accEvent =
new nsAccStateChangeEvent(accessible, nsIAccessibleStates::STATE_EXPANDED,
PR_FALSE, isEnabled);
return FireAccessibleEvent(accEvent);
nsEventShell::FireEvent(accEvent);
return NS_OK;
}
if (treeItemAccessible && eventType.EqualsLiteral("select")) {
@ -753,12 +759,14 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
// for each tree item. Perhaps each tree item will need to cache its
// selection state and fire an event after a DOM "select" event when
// that state changes. nsXULTreeAccessible::UpdateTreeSelection();
return nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
accessible);
return NS_OK;
}
return nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SELECTION,
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION,
treeItemAccessible);
return NS_OK;
}
}
else
@ -768,13 +776,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
// Got focus event for the window, we will make sure that an accessible
// focus event for initial focus is fired. We do this on a short timer
// because the initial focus may not have been set yet.
if (!mFireFocusTimer) {
mFireFocusTimer = do_CreateInstance("@mozilla.org/timer;1");
}
if (mFireFocusTimer) {
mFireFocusTimer->InitWithFuncCallback(FireFocusCallback, this,
0, nsITimer::TYPE_ONE_SHOT);
}
NS_DISPATCH_RUNNABLEMETHOD(FireCurrentFocusEvent, this)
}
// Keep a reference to the target node. We might want to change
@ -809,14 +811,14 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
FireAccessibleFocusEvent(accessible, focusedItem, aEvent);
}
else if (eventType.EqualsLiteral("AlertActive")) {
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_ALERT, accessible);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_ALERT, accessible);
}
else if (eventType.EqualsLiteral("popupshown")) {
HandlePopupShownEvent(accessible);
}
else if (eventType.EqualsLiteral("DOMMenuInactive")) {
if (nsAccUtils::Role(accessible) == nsIAccessibleRole::ROLE_MENUPOPUP) {
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
accessible);
}
}
@ -877,19 +879,18 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
}
}
if (fireFocus) {
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE); // Always asynch, always from user input
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE, PR_TRUE);
// Always asynch, always from user input.
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE,
PR_TRUE, eFromUserInput);
}
}
else if (eventType.EqualsLiteral("DOMMenuBarActive")) { // Always asynch, always from user input
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_START,
accessible, PR_TRUE);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_START,
accessible, PR_TRUE, eFromUserInput);
}
else if (eventType.EqualsLiteral("DOMMenuBarInactive")) { // Always asynch, always from user input
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_END,
accessible, PR_TRUE);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_END,
accessible, PR_TRUE, eFromUserInput);
FireCurrentFocusEvent();
}
else if (eventType.EqualsLiteral("ValueChange")) {
@ -898,7 +899,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
}
#ifdef DEBUG
else if (eventType.EqualsLiteral("mouseover")) {
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START,
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START,
accessible);
}
#endif
@ -931,13 +932,6 @@ void nsRootAccessible::GetTargetNode(nsIDOMEvent *aEvent, nsIDOMNode **aTargetNo
NS_ADDREF(*aTargetNode = eventTarget);
}
void nsRootAccessible::FireFocusCallback(nsITimer *aTimer, void *aClosure)
{
nsRootAccessible *rootAccessible = static_cast<nsRootAccessible*>(aClosure);
NS_ASSERTION(rootAccessible, "How did we get here without a root accessible?");
rootAccessible->FireCurrentFocusEvent();
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessNode
@ -967,11 +961,6 @@ nsRootAccessible::Shutdown()
mCurrentARIAMenubar = nsnull;
if (mFireFocusTimer) {
mFireFocusTimer->Cancel();
mFireFocusTimer = nsnull;
}
return nsDocAccessibleWrap::Shutdown();
}
@ -1062,7 +1051,7 @@ nsRootAccessible::GetRelationByType(PRUint32 aRelationType,
////////////////////////////////////////////////////////////////////////////////
// nsAccessible
nsIAccessible*
nsAccessible*
nsRootAccessible::GetParent()
{
// Parent has been setted in nsApplicationAccesible::AddRootAccessible()
@ -1105,8 +1094,9 @@ nsRootAccessible::HandlePopupShownEvent(nsIAccessible *aAccessible)
if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {
// Don't fire menupopup events for combobox and autocomplete lists.
return nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START,
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START,
aAccessible);
return NS_OK;
}
if (role == nsIAccessibleRole::ROLE_TOOLTIP) {
@ -1114,8 +1104,8 @@ nsRootAccessible::HandlePopupShownEvent(nsIAccessible *aAccessible)
// The accessible for it stays the same no matter where it moves.
// AT's expect to get an EVENT_SHOW for the tooltip.
// In event callback the tooltip's accessible will be ready.
return nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SHOW,
aAccessible);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SHOW, aAccessible);
return NS_OK;
}
if (role == nsIAccessibleRole::ROLE_COMBOBOX_LIST) {
@ -1127,14 +1117,15 @@ nsRootAccessible::HandlePopupShownEvent(nsIAccessible *aAccessible)
PRUint32 comboboxRole = nsAccUtils::Role(comboboxAcc);
if (comboboxRole == nsIAccessibleRole::ROLE_COMBOBOX ||
comboboxRole == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(comboboxAcc,
nsIAccessibleStates::STATE_EXPANDED,
PR_FALSE, PR_TRUE);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(comboboxAcc));
return acc->FireAccessibleEvent(event);
nsEventShell::FireEvent(event);
return NS_OK;
}
}
@ -1150,8 +1141,11 @@ nsRootAccessible::HandlePopupHidingEvent(nsIDOMNode *aNode,
// DOMMenuItemActive events inside of a combo box that closes. The real focus
// is on the combo box. It's also the case when a popup gets focus in ATK --
// when it closes we need to fire an event to restore focus to where it was.
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
nsCOMPtr<nsINode> lastFocusedNode(do_QueryInterface(gLastFocusedNode));
if (gLastFocusedNode &&
nsCoreUtils::IsAncestorOf(aNode, gLastFocusedNode)) {
nsCoreUtils::IsAncestorOf(node, lastFocusedNode)) {
// Focus was on or inside of a popup that's being hidden
FireCurrentFocusEvent();
}
@ -1171,14 +1165,14 @@ nsRootAccessible::HandlePopupHidingEvent(nsIDOMNode *aNode,
PRUint32 comboboxRole = nsAccUtils::Role(comboboxAcc);
if (comboboxRole == nsIAccessibleRole::ROLE_COMBOBOX ||
comboboxRole == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(comboboxAcc,
nsIAccessibleStates::STATE_EXPANDED,
PR_FALSE, PR_FALSE);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(comboboxAcc));
return acc->FireAccessibleEvent(event);
nsEventShell::FireEvent(event);
return NS_OK;
}
return NS_OK;

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

@ -51,14 +51,13 @@
#include "nsIDocument.h"
#include "nsIDOMFocusListener.h"
#include "nsIDOMFormListener.h"
#include "nsITimer.h"
#define NS_ROOTACCESSIBLE_IMPL_CID \
{ /* 7565f0d1-1465-4b71-906c-a623ac279f5d */ \
0x7565f0d1, \
0x1465, \
0x4b71, \
{ 0x90, 0x6c, 0xa6, 0x23, 0xac, 0x27, 0x9f, 0x5d } \
{ /* eaba2cf0-21b1-4e2b-b711-d3a89dcd5e1a */ \
0xeaba2cf0, \
0x21b1, \
0x4e2b, \
{ 0xb7, 0x11, 0xd3, 0xa8, 0x9d, 0xcd, 0x5e, 0x1a } \
}
const PRInt32 SCROLL_HASH_START_SIZE = 6;
@ -87,7 +86,7 @@ public:
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsIAccessible* GetParent();
virtual nsAccessible* GetParent();
// nsDocAccessible
virtual void FireDocLoadEvents(PRUint32 aEventType);
@ -98,17 +97,22 @@ public:
/**
* Fire an accessible focus event for the current focusAccssible
* and attach a new selection listener, if necessary.
* @param aFocusAccessible The accessible which has received focus.
* @param aFocusNode The DOM Node which has received focus.
* @param aFocusEvent DOM focus event that caused the node/accessible to receive focus
* @param aForceEvent Fire a focus event even if the last focused item was the same
* @return Boolean -- was a focus event actually fired
*
* @param aFocusAccessible [in] the accessible which has received focus
* @param aFocusNode [in] the DOM node which has received focus
* @param aFocusEvent [in] DOM focus event that caused
* the node/accessible to receive focus
* @param aForceEvent [in] fire a focus event even if the last focused
* item was the same
* @return boolean -- was a focus event actually fired
*/
PRBool FireAccessibleFocusEvent(nsIAccessible *aFocusAccessible,
nsIDOMNode *aFocusNode,
nsIDOMEvent *aFocusEvent,
PRBool aForceEvent = PR_FALSE,
PRBool aIsAsynch = PR_FALSE);
PRBool aIsAsynch = PR_FALSE,
EIsFromUserInput aIsFromUserInput = eAutoDetect);
/**
* Fire an accessible focus event for the current focused node,
* if there is a focus.
@ -117,11 +121,9 @@ public:
nsCaretAccessible *GetCaretAccessible();
private:
nsCOMPtr<nsITimer> mFireFocusTimer;
static void FireFocusCallback(nsITimer *aTimer, void *aClosure);
protected:
NS_DECL_RUNNABLEMETHOD(nsRootAccessible, FireCurrentFocusEvent)
protected:
nsresult AddEventListeners();
nsresult RemoveEventListeners();
nsresult HandleEventWithTarget(nsIDOMEvent* aEvent,

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

@ -98,12 +98,14 @@ NS_IMETHODIMP nsHTMLCheckboxAccessible::GetActionName(PRUint8 aIndex, nsAString&
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsHTMLCheckboxAccessible::DoAction(PRUint8 index)
NS_IMETHODIMP
nsHTMLCheckboxAccessible::DoAction(PRUint8 aIndex)
{
if (index == 0) { // 0 is the magic value for default action
return DoCommand();
}
if (aIndex != 0)
return NS_ERROR_INVALID_ARG;
DoCommand();
return NS_OK;
}
nsresult
@ -256,12 +258,14 @@ NS_IMETHODIMP nsHTMLButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& a
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsHTMLButtonAccessible::DoAction(PRUint8 index)
NS_IMETHODIMP
nsHTMLButtonAccessible::DoAction(PRUint8 aIndex)
{
if (index == eAction_Click) {
return DoCommand();
}
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
DoCommand();
return NS_OK;
}
nsresult
@ -349,12 +353,14 @@ NS_IMETHODIMP nsHTML4ButtonAccessible::GetActionName(PRUint8 aIndex, nsAString&
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsHTML4ButtonAccessible::DoAction(PRUint8 index)
NS_IMETHODIMP
nsHTML4ButtonAccessible::DoAction(PRUint8 aIndex)
{
if (index == 0) {
return DoCommand();
}
if (aIndex != 0)
return NS_ERROR_INVALID_ARG;
DoCommand();
return NS_OK;
}
nsresult
@ -673,19 +679,20 @@ nsHTMLLegendAccessible::GetRelationByType(PRUint32 aRelationType,
if (aRelationType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
// Look for groupbox parent
nsCOMPtr<nsIAccessible> groupboxAccessible = GetParent();
if (nsAccUtils::Role(groupboxAccessible) == nsIAccessibleRole::ROLE_GROUPING) {
nsAccessible* groupbox = GetParent();
if (nsAccUtils::Role(groupbox) == nsIAccessibleRole::ROLE_GROUPING) {
// XXX: if group box exposes more than one relation of the given type
// then we fail.
nsCOMPtr<nsIAccessible> testLabelAccessible =
nsRelUtils::GetRelatedAccessible(groupboxAccessible,
nsRelUtils::GetRelatedAccessible(groupbox,
nsIAccessibleRelation::RELATION_LABELLED_BY);
if (testLabelAccessible == this) {
// We're the first child of the parent groupbox, see
// nsHTMLGroupboxAccessible::GetRelationByType().
return nsRelUtils::
AddTarget(aRelationType, aRelation, groupboxAccessible);
AddTarget(aRelationType, aRelation, groupbox);
}
}
}

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

@ -173,8 +173,8 @@ nsHTMLImageAccessible::CacheChildren()
if (!areaAccessible)
return;
mChildren.AppendObject(areaAccessible);
areaAcc = nsAccUtils::QueryObject<nsAccessible>(areaAccessible);
mChildren.AppendElement(areaAcc);
areaAcc->SetParent(this);
}
}

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

@ -160,8 +160,8 @@ nsHTMLLinkAccessible::DoAction(PRUint8 aIndex)
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
return DoCommand(content);
DoCommand();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

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

@ -403,10 +403,10 @@ nsHTMLSelectListAccessible::CacheOptSiblings(nsIContent *aParentContent)
GetAccService()->GetAccessibleInWeakShell(childNode, mWeakShell,
getter_AddRefs(accessible));
if (accessible) {
mChildren.AppendObject(accessible);
nsRefPtr<nsAccessible> acc =
nsAccUtils::QueryObject<nsAccessible>(accessible);
mChildren.AppendElement(acc);
acc->SetParent(this);
}
@ -445,7 +445,10 @@ nsHyperTextAccessibleWrap(aDOMNode, aShell)
}
}
}
SetParent(parentAccessible);
nsRefPtr<nsAccessible> parentAcc =
nsAccUtils::QueryObject<nsAccessible>(parentAccessible);
SetParent(parentAcc);
}
////////////////////////////////////////////////////////////////////////////////
@ -585,12 +588,12 @@ nsHTMLSelectOptionAccessible::GetStateInternal(PRUint32 *aState,
// visibility implementation unless they get reimplemented in layout
*aState &= ~nsIAccessibleStates::STATE_OFFSCREEN;
// <select> is not collapsed: compare bounds to calculate STATE_OFFSCREEN
nsCOMPtr<nsIAccessible> listAccessible = GetParent();
if (listAccessible) {
nsAccessible* listAcc = GetParent();
if (listAcc) {
PRInt32 optionX, optionY, optionWidth, optionHeight;
PRInt32 listX, listY, listWidth, listHeight;
GetBounds(&optionX, &optionY, &optionWidth, &optionHeight);
listAccessible->GetBounds(&listX, &listY, &listWidth, &listHeight);
listAcc->GetBounds(&listX, &listY, &listWidth, &listHeight);
if (optionY < listY || optionY + optionHeight > listY + listHeight) {
*aState |= nsIAccessibleStates::STATE_OFFSCREEN;
}
@ -672,10 +675,10 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessible::DoAction(PRUint8 index)
return NS_ERROR_FAILURE;
// Clear old selection
nsCOMPtr<nsIDOMNode> oldHTMLOptionNode, selectNode;
nsCOMPtr<nsIAccessible> parent(GetParent());
nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(parent));
NS_ASSERTION(accessNode, "Unable to QI to nsIAccessNode");
accessNode->GetDOMNode(getter_AddRefs(selectNode));
nsAccessible* parent = GetParent();
NS_ASSERTION(parent, "No parent!");
parent->GetDOMNode(getter_AddRefs(selectNode));
GetFocusedOptionNode(selectNode, getter_AddRefs(oldHTMLOptionNode));
nsCOMPtr<nsIDOMHTMLOptionElement> oldHTMLOption(do_QueryInterface(oldHTMLOptionNode));
if (oldHTMLOption)
@ -808,7 +811,7 @@ void nsHTMLSelectOptionAccessible::SelectionChangedIfOption(nsIContent *aPossibl
if (!optionAccessible)
return;
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
multiSelect);
PRUint32 state = nsAccUtils::State(optionAccessible);
@ -820,7 +823,7 @@ void nsHTMLSelectOptionAccessible::SelectionChangedIfOption(nsIContent *aPossibl
eventType = nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
}
nsAccUtils::FireAccEvent(eventType, optionAccessible);
nsEventShell::FireEvent(eventType, optionAccessible);
}
////////////////////////////////////////////////////////////////////////////////
@ -953,7 +956,7 @@ nsHTMLComboboxAccessible::CacheChildren()
mListAccessible->Init();
}
mChildren.AppendObject(mListAccessible);
mChildren.AppendElement(mListAccessible);
mListAccessible->SetParent(this);
}
@ -1170,11 +1173,11 @@ void nsHTMLComboboxListAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBo
{
*aBoundingFrame = nsnull;
nsCOMPtr<nsIAccessible> comboAccessible = GetParent();
if (!comboAccessible)
nsAccessible* comboAcc = GetParent();
if (!comboAcc)
return;
if (0 == (nsAccUtils::State(comboAccessible) & nsIAccessibleStates::STATE_COLLAPSED)) {
if (0 == (nsAccUtils::State(comboAcc) & nsIAccessibleStates::STATE_COLLAPSED)) {
nsHTMLSelectListAccessible::GetBoundsRect(aBounds, aBoundingFrame);
return;
}
@ -1198,7 +1201,7 @@ void nsHTMLComboboxListAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBo
}
// nsHTMLComboboxListAccessible. nsAccessible public mehtod
nsIAccessible*
nsAccessible*
nsHTMLComboboxListAccessible::GetParent()
{
return mParent;

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

@ -271,7 +271,7 @@ public:
// nsAccessible
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
virtual nsIAccessible* GetParent();
virtual nsAccessible* GetParent();
};
#endif

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

@ -461,20 +461,20 @@ nsHTMLTableAccessible::CacheChildren()
nsAccessible::CacheChildren();
// Move caption accessible so that it's the first child.
PRInt32 length = mChildren.Count();
PRInt32 length = mChildren.Length();
for (PRInt32 idx = 0; idx < length; idx++) {
// Check for the first caption, because nsAccessibilityService ensures we
// don't create accessibles for the other captions, since only the first is
// actually visible.
nsIAccessible* child = mChildren.ObjectAt(idx);
nsAccessible* child = mChildren.ElementAt(idx);
if (nsAccUtils::Role(child) == nsIAccessibleRole::ROLE_CAPTION) {
if (idx == 0)
break;
nsCOMPtr<nsIAccessible> tmp = mChildren.ObjectAt(0);
mChildren.ReplaceObjectAt(child, 0);
mChildren.ReplaceObjectAt(tmp, idx);
nsRefPtr<nsAccessible> tmp = mChildren[0];
mChildren[0] = child;
mChildren[idx] = tmp;
break;
}
}

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

@ -270,7 +270,7 @@ void
nsHTMLLIAccessible::CacheChildren()
{
if (mBulletAccessible) {
mChildren.AppendObject(mBulletAccessible);
mChildren.AppendElement(mBulletAccessible);
mBulletAccessible->SetParent(this);
}
@ -339,11 +339,11 @@ nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset
if (aLength > maxLength) {
aLength = maxLength;
}
aText += nsDependentSubstring(mBulletText, aStartOffset, aLength);
aText += Substring(mBulletText, aStartOffset, aLength);
return NS_OK;
}
nsIAccessible*
nsAccessible*
nsHTMLListBulletAccessible::GetParent()
{
return mParent;

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

@ -116,7 +116,7 @@ public:
virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
PRUint32 aLength);
virtual nsIAccessible* GetParent();
virtual nsAccessible* GetParent();
protected:
// XXX: Ideally we'd get the bullet text directly from the bullet frame via

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

@ -232,10 +232,10 @@ nsHyperTextAccessible::CacheChildren()
walker.GetFirstChild();
while (walker.mState.accessible) {
mChildren.AppendObject(walker.mState.accessible);
nsRefPtr<nsAccessible> acc =
nsAccUtils::QueryObject<nsAccessible>(walker.mState.accessible);
mChildren.AppendElement(acc);
acc->SetParent(this);
walker.GetNextSibling();
@ -859,7 +859,7 @@ nsHyperTextAccessible::GetRelativeOffset(nsIPresShell *aPresShell,
hyperTextOffset = 0;
}
else if (aAmount == eSelectBeginLine) {
nsIAccessible *firstChild = mChildren.SafeObjectAt(0);
nsAccessible *firstChild = mChildren.SafeElementAt(0, nsnull);
// For line selection with needsStart, set start of line exactly to line break
if (pos.mContentOffset == 0 && firstChild &&
nsAccUtils::Role(firstChild) == nsIAccessibleRole::ROLE_STATICTEXT &&
@ -1602,11 +1602,13 @@ nsHyperTextAccessible::GetCaretOffset(PRInt32 *aCaretOffset)
// No caret if the focused node is not inside this DOM node and this DOM node
// is not inside of focused node.
nsCOMPtr<nsINode> thisNode(do_QueryInterface(mDOMNode));
nsCOMPtr<nsINode> lastFocusedNode(do_QueryInterface(gLastFocusedNode));
PRBool isInsideOfFocusedNode =
nsCoreUtils::IsAncestorOf(gLastFocusedNode, mDOMNode);
nsCoreUtils::IsAncestorOf(lastFocusedNode, thisNode);
if (!isInsideOfFocusedNode && mDOMNode != gLastFocusedNode &&
!nsCoreUtils::IsAncestorOf(mDOMNode, gLastFocusedNode))
!nsCoreUtils::IsAncestorOf(thisNode, lastFocusedNode))
return NS_OK;
// Turn the focus node and offset of the selection into caret hypretext
@ -1627,10 +1629,12 @@ nsHyperTextAccessible::GetCaretOffset(PRInt32 *aCaretOffset)
// No caret if this DOM node is inside of focused node but the selection's
// focus point is not inside of this DOM node.
if (isInsideOfFocusedNode) {
nsCOMPtr<nsIDOMNode> resultNode =
nsCOMPtr<nsIDOMNode> resultDOMNode =
nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
if (resultNode != mDOMNode &&
!nsCoreUtils::IsAncestorOf(mDOMNode, resultNode))
nsCOMPtr<nsINode> resultNode(do_QueryInterface(resultDOMNode));
if (resultNode != thisNode &&
!nsCoreUtils::IsAncestorOf(thisNode, resultNode))
return NS_OK;
}
@ -1653,7 +1657,8 @@ PRInt32 nsHyperTextAccessible::GetCaretLineNumber()
nsCOMPtr<nsIDOMNode> caretNode;
domSel->GetFocusNode(getter_AddRefs(caretNode));
nsCOMPtr<nsIContent> caretContent = do_QueryInterface(caretNode);
if (!caretContent || !nsCoreUtils::IsAncestorOf(mDOMNode, caretNode)) {
nsCOMPtr<nsINode> thisNode(do_QueryInterface(mDOMNode));
if (!caretContent || !nsCoreUtils::IsAncestorOf(thisNode, caretContent)) {
return -1;
}

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

@ -44,7 +44,7 @@
#include "nsIAccessibleText.h"
#include "nsIAccessibleHyperText.h"
#include "nsIAccessibleEditableText.h"
#include "nsAccessibleEventData.h"
#include "nsAccEvent.h"
#include "nsTextAttrs.h"
#include "nsFrameSelection.h"

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

@ -77,7 +77,7 @@ class nsAccessibleWrap : public nsAccessible
virtual nsresult Shutdown ();
virtual void InvalidateChildren();
virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aEvent);
virtual nsresult HandleAccEvent(nsAccEvent *aEvent);
// ignored means that the accessible might still have children, but is not displayed
// to the user. it also has no native accessible object represented for it.
@ -97,7 +97,7 @@ class nsAccessibleWrap : public nsAccessible
protected:
virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent);
virtual nsresult FirePlatformEvent(nsAccEvent *aEvent);
PRBool AncestorIsFlat() {
// we don't create a native object if we're child of a "flat" accessible; for example, on OS X buttons
@ -106,14 +106,12 @@ class nsAccessibleWrap : public nsAccessible
// to maintain a scripting environment where the XPCOM accessible hierarchy look the same
// on all platforms, we still let the C++ objects be created though.
nsCOMPtr<nsIAccessible> curParent = GetParent();
while (curParent) {
if (nsAccUtils::MustPrune(curParent))
nsAccessible* parent(GetParent());
while (parent) {
if (nsAccUtils::MustPrune(parent))
return PR_TRUE;
nsCOMPtr<nsIAccessible> newParent;
curParent->GetParent(getter_AddRefs(newParent));
curParent.swap(newParent);
parent = parent->GetParent();
}
// no parent was flat
return PR_FALSE;

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

@ -160,13 +160,11 @@ nsAccessibleWrap::Shutdown ()
}
nsresult
nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
nsAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
NS_ENSURE_ARG_POINTER(aEvent);
nsresult rv = nsAccessible::FireAccessibleEvent(aEvent);
nsresult rv = nsAccessible::HandleAccEvent(aEvent);
NS_ENSURE_SUCCESS(rv, rv);
return FirePlatformEvent(aEvent);
@ -175,13 +173,11 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
}
nsresult
nsAccessibleWrap::FirePlatformEvent(nsIAccessibleEvent *aEvent)
nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
PRUint32 eventType;
nsresult rv = aEvent->GetEventType(&eventType);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 eventType = aEvent->GetEventType();
// ignore everything but focus-changed and value-changed events for now.
if (eventType != nsIAccessibleEvent::EVENT_FOCUS &&
@ -189,7 +185,7 @@ nsAccessibleWrap::FirePlatformEvent(nsIAccessibleEvent *aEvent)
return NS_OK;
nsCOMPtr<nsIAccessible> accessible;
rv = aEvent->GetAccessible(getter_AddRefs(accessible));
nsresult rv = aEvent->GetAccessible(getter_AddRefs(accessible));
NS_ENSURE_STATE(accessible);
mozAccessible *nativeAcc = nil;
@ -300,8 +296,7 @@ nsAccessibleWrap::GetUnignoredChildren(nsTArray<nsRefPtr<nsAccessibleWrap> > &aC
already_AddRefed<nsIAccessible>
nsAccessibleWrap::GetUnignoredParent()
{
nsCOMPtr<nsIAccessible> parent(GetParent());
nsAccessibleWrap *parentWrap = static_cast<nsAccessibleWrap*>(parent.get());
nsAccessibleWrap *parentWrap = static_cast<nsAccessibleWrap*>(GetParent());
if (!parentWrap)
return nsnull;
@ -310,7 +305,7 @@ nsAccessibleWrap::GetUnignoredParent()
return parentWrap->GetUnignoredParent();
nsIAccessible *outValue = nsnull;
NS_IF_ADDREF(outValue = parent.get());
NS_IF_ADDREF(outValue = parentWrap);
return outValue;
}

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

@ -593,9 +593,6 @@ __try {
void nsAccessNodeWrap::InitAccessibility()
{
NS_ASSERTION(!gIsAccessibilityActive,
"Accessibility was initialized already!");
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
if (prefBranch) {
prefBranch->GetBoolPref("accessibility.disableenumvariant", &gIsEnumVariantSupportDisabled);
@ -622,8 +619,6 @@ void nsAccessNodeWrap::ShutdownAccessibility()
NS_IF_RELEASE(gTextEvent);
::DestroyCaret();
NS_ASSERTION(gIsAccessibilityActive, "Accessibility was shutdown already!");
nsAccessNode::ShutdownXPAccessibility();
}

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

@ -58,6 +58,7 @@
#include "nsIServiceManager.h"
#include "nsTextFormatter.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsRoleMap.h"
#include "nsEventMap.h"
#include "nsArrayUtils.h"
@ -237,12 +238,14 @@ __try {
}
}
nsCOMPtr<nsIAccessible> xpParentAccessible(GetParent());
NS_ASSERTION(xpParentAccessible, "No parent accessible where we're not direct child of window");
if (!xpParentAccessible) {
nsAccessible* xpParentAcc = GetParent();
NS_ASSERTION(xpParentAcc,
"No parent accessible where we're not direct child of window");
if (!xpParentAcc)
return E_UNEXPECTED;
}
*ppdispParent = NativeAccessible(xpParentAccessible);
*ppdispParent = NativeAccessible(xpParentAcc);
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
@ -278,11 +281,10 @@ __try {
return S_OK;
}
nsCOMPtr<nsIAccessible> childAccessible;
if (!nsAccUtils::MustPrune(this)) {
GetChildAt(varChild.lVal - 1, getter_AddRefs(childAccessible));
if (childAccessible) {
*ppdispChild = NativeAccessible(childAccessible);
nsAccessible* child = GetChildAt(varChild.lVal - 1);
if (child) {
*ppdispChild = NativeAccessible(child);
}
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@ -430,20 +432,8 @@ __try {
groupLevel);
}
if (!description.IsEmpty()) {
*pszDescription = ::SysAllocStringLen(description.get(),
description.Length());
return *pszDescription ? S_OK : E_OUTOFMEMORY;
}
if (description.IsEmpty())
xpAccessible->GetDescription(description);
if (!description.IsEmpty()) {
// Signal to screen readers that this description is speakable
// and is not a formatted positional information description
// Don't localize the "Description: " part of this string, it will be
// parsed out by assistive technologies.
description = NS_LITERAL_STRING("Description: ") + description;
}
*pszDescription = ::SysAllocStringLen(description.get(),
description.Length());
@ -483,8 +473,7 @@ __try {
// a ROLE_OUTLINEITEM for consistency and compatibility.
// We need this because ARIA has a role of "row" for both grid and treegrid
if (xpRole == nsIAccessibleRole::ROLE_ROW) {
nsCOMPtr<nsIAccessible> parent = GetParent();
if (nsAccUtils::Role(parent) == nsIAccessibleRole::ROLE_TREE_TABLE)
if (nsAccUtils::Role(GetParent()) == nsIAccessibleRole::ROLE_TREE_TABLE)
msaaRole = ROLE_SYSTEM_OUTLINEITEM;
}
@ -565,8 +554,13 @@ STDMETHODIMP nsAccessibleWrap::get_accHelp(
/* [optional][in] */ VARIANT varChild,
/* [retval][out] */ BSTR __RPC_FAR *pszHelp)
{
__try {
*pszHelp = NULL;
return S_FALSE;
} __except(FilterA11yExceptions(::GetExceptionCode(),
GetExceptionInformation())) { }
return E_FAIL;
}
STDMETHODIMP nsAccessibleWrap::get_accHelpTopic(
@ -574,9 +568,14 @@ STDMETHODIMP nsAccessibleWrap::get_accHelpTopic(
/* [optional][in] */ VARIANT varChild,
/* [retval][out] */ long __RPC_FAR *pidTopic)
{
__try {
*pszHelpFile = NULL;
*pidTopic = 0;
return E_NOTIMPL;
return S_FALSE;
} __except(FilterA11yExceptions(::GetExceptionCode(),
GetExceptionInformation())) { }
return E_FAIL;
}
STDMETHODIMP nsAccessibleWrap::get_accKeyboardShortcut(
@ -1102,7 +1101,7 @@ __try {
for (; numElementsFetched < aNumElementsRequested;
numElementsFetched++, mEnumVARIANTPosition++) {
nsIAccessible* accessible = GetChildAt(mEnumVARIANTPosition);
nsAccessible* accessible = GetChildAt(mEnumVARIANTPosition);
if (!accessible)
break;
@ -1286,8 +1285,7 @@ __try {
// Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call
// the IA2 role a ROLE_OUTLINEITEM.
if (xpRole == nsIAccessibleRole::ROLE_ROW) {
nsCOMPtr<nsIAccessible> parent = GetParent();
if (nsAccUtils::Role(parent) == nsIAccessibleRole::ROLE_TREE_TABLE)
if (nsAccUtils::Role(GetParent()) == nsIAccessibleRole::ROLE_TREE_TABLE)
*aRole = ROLE_SYSTEM_OUTLINEITEM;
}
@ -1658,21 +1656,18 @@ NS_IMETHODIMP nsAccessibleWrap::GetNativeInterface(void **aOutAccessible)
// nsAccessible
nsresult
nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
nsAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
{
NS_ENSURE_ARG(aEvent);
nsresult rv = nsAccessible::FireAccessibleEvent(aEvent);
nsresult rv = nsAccessible::HandleAccEvent(aEvent);
NS_ENSURE_SUCCESS(rv, rv);
return FirePlatformEvent(aEvent);
}
nsresult
nsAccessibleWrap::FirePlatformEvent(nsIAccessibleEvent *aEvent)
nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
{
PRUint32 eventType = 0;
aEvent->GetEventType(&eventType);
PRUint32 eventType = aEvent->GetEventType();
NS_ENSURE_TRUE(eventType > 0 &&
eventType < nsIAccessibleEvent::EVENT_LAST_ENTRY,

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

@ -307,7 +307,7 @@ class nsAccessibleWrap : public nsAccessible,
UINT *puArgErr);
// nsAccessible
virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aEvent);
virtual nsresult HandleAccEvent(nsAccEvent *aEvent);
// Helper methods
static PRInt32 GetChildIDFor(nsIAccessible* aAccessible);
@ -342,7 +342,7 @@ class nsAccessibleWrap : public nsAccessible,
void UnattachIEnumVariant();
protected:
virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent);
virtual nsresult FirePlatformEvent(nsAccEvent *aEvent);
// mEnumVARIANTPosition not the current accessible's position, but a "cursor" of
// where we are in the current list of children, with respect to

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

@ -100,11 +100,8 @@ void
nsHTMLWin32ObjectOwnerAccessible::CacheChildren()
{
if (mNativeAccessible) {
mChildren.AppendObject(mNativeAccessible);
nsRefPtr<nsAccessible> nativeAcc =
nsAccUtils::QueryObject<nsAccessible>(mNativeAccessible);
nativeAcc->SetParent(this);
mChildren.AppendElement(mNativeAccessible);
mNativeAccessible->SetParent(this);
}
}

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

@ -69,7 +69,7 @@ protected:
virtual void CacheChildren();
void* mHwnd;
nsCOMPtr<nsIAccessible> mNativeAccessible;
nsRefPtr<nsAccessible> mNativeAccessible;
};
/**

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

@ -49,10 +49,9 @@ IMPL_IUNKNOWN_INHERITED2(nsHyperTextAccessibleWrap,
CAccessibleEditableText);
nsresult
nsHyperTextAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
nsHyperTextAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
{
PRUint32 eventType;
aEvent->GetEventType(&eventType);
PRUint32 eventType = aEvent->GetEventType();
if (eventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED ||
eventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) {
@ -74,7 +73,7 @@ nsHyperTextAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent)
}
}
return nsHyperTextAccessible::FireAccessibleEvent(aEvent);
return nsHyperTextAccessible::HandleAccEvent(aEvent);
}
nsresult

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

@ -61,7 +61,7 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsAccessible
virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aEvent);
virtual nsresult HandleAccEvent(nsAccEvent *aEvent);
protected:
virtual nsresult GetModifiedText(PRBool aGetInsertedText, nsAString& aText,

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

@ -53,7 +53,7 @@ class nsAccessibleWrap : public nsAccessible
virtual ~nsAccessibleWrap();
protected:
virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent) {
virtual nsresult FirePlatformEvent(nsAccEvent *aEvent) {
return NS_OK;
}
};

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

@ -136,8 +136,8 @@ nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
if (!accessible)
continue;
mChildren.AppendObject(accessible);
acc = nsAccUtils::QueryObject<nsAccessible>(accessible);
mChildren.AppendElement(acc);
acc->SetParent(this);
}
}
@ -626,7 +626,8 @@ nsXFormsSelectableItemAccessible::DoAction(PRUint8 aIndex)
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
return DoCommand();
DoCommand();
return NS_OK;
}
PRBool

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

@ -130,10 +130,11 @@ nsXFormsTriggerAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
NS_IMETHODIMP
nsXFormsTriggerAccessible::DoAction(PRUint8 aIndex)
{
if (aIndex == eAction_Click)
return DoCommand();
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
DoCommand();
return NS_OK;
}
// nsXFormsInputAccessible
@ -246,7 +247,8 @@ nsXFormsInputBooleanAccessible::DoAction(PRUint8 aIndex)
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
return DoCommand();
DoCommand();
return NS_OK;
}
// nsXFormsInputDateAccessible

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

@ -175,10 +175,10 @@ nsXULColorPickerAccessible::CacheChildren()
// Get an accessbile for menupopup or panel elements.
if (role == nsIAccessibleRole::ROLE_ALERT) {
mChildren.AppendObject(walker.mState.accessible);
nsRefPtr<nsAccessible> menupopupAcc =
nsAccUtils::QueryObject<nsAccessible>(walker.mState.accessible);
mChildren.AppendElement(menupopupAcc);
menupopupAcc->SetParent(this);
return;

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

@ -96,10 +96,11 @@ nsXULButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
NS_IMETHODIMP
nsXULButtonAccessible::DoAction(PRUint8 aIndex)
{
if (aIndex == 0)
return DoCommand();
if (aIndex != 0)
return NS_ERROR_INVALID_ARG;
DoCommand();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
@ -229,17 +230,17 @@ nsXULButtonAccessible::CacheChildren()
if (!menupopupAccessible)
return;
mChildren.AppendObject(menupopupAccessible);
nsRefPtr<nsAccessible> menupopupAcc =
nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
mChildren.AppendElement(menupopupAcc);
menupopupAcc->SetParent(this);
if (buttonAccessible) {
mChildren.AppendObject(buttonAccessible);
nsRefPtr<nsAccessible> buttonAcc =
nsAccUtils::QueryObject<nsAccessible>(buttonAccessible);
mChildren.AppendElement(buttonAcc);
buttonAcc->SetParent(this);
}
}
@ -419,12 +420,14 @@ NS_IMETHODIMP nsXULCheckboxAccessible::GetActionName(PRUint8 aIndex, nsAString&
/**
* Tell the checkbox to do its only action -- check( or uncheck) itself
*/
NS_IMETHODIMP nsXULCheckboxAccessible::DoAction(PRUint8 index)
NS_IMETHODIMP
nsXULCheckboxAccessible::DoAction(PRUint8 aIndex)
{
if (index == eAction_Click) {
return DoCommand();
}
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
DoCommand();
return NS_OK;
}
/**
@ -776,27 +779,27 @@ void
nsXULToolbarButtonAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
PRInt32 *aSetSize)
{
nsCOMPtr<nsIAccessible> parent(GetParent());
PRInt32 setSize = 0;
PRInt32 posInSet = 0;
if (parent) {
nsCOMPtr<nsIAccessible> sibling;
nsCOMPtr<nsIAccessible> tempSibling;
parent->GetFirstChild(getter_AddRefs(sibling));
while (sibling) {
if (IsSeparator(sibling)) { // end of a group of buttons
nsAccessible* parent(GetParent());
NS_ENSURE_TRUE(parent,);
PRInt32 childCount = parent->GetChildCount();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible* child = parent->GetChildAt(childIdx);
if (IsSeparator(child)) { // end of a group of buttons
if (posInSet)
break; // we've found our group, so we're done
setSize = 0; // not our group, so start a new group
} else {
setSize++; // another button in the group
if (sibling == this)
if (child == this)
posInSet = setSize; // we've found our button
}
sibling->GetNextSibling(getter_AddRefs(tempSibling));
sibling.swap(tempSibling);
}
}
*aPosInSet = posInSet;
@ -804,11 +807,10 @@ nsXULToolbarButtonAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
}
PRBool
nsXULToolbarButtonAccessible::IsSeparator(nsIAccessible *aAccessible)
nsXULToolbarButtonAccessible::IsSeparator(nsAccessible *aAccessible)
{
nsCOMPtr<nsIDOMNode> domNode;
nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible));
accessNode->GetDOMNode(getter_AddRefs(domNode));
aAccessible->GetDOMNode(getter_AddRefs(domNode));
nsCOMPtr<nsIContent> contentDomNode(do_QueryInterface(domNode));
if (!contentDomNode)

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

@ -191,7 +191,8 @@ public:
virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
PRInt32 *aSetSize);
static PRBool IsSeparator(nsIAccessible *aAccessible);
// nsXULToolbarButtonAccessible
static PRBool IsSeparator(nsAccessible *aAccessible);
};
class nsXULToolbarAccessible : public nsAccessibleWrap

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

@ -147,7 +147,8 @@ nsXULColumnItemAccessible::DoAction(PRUint8 aIndex)
if (aIndex != eAction_Click)
return NS_ERROR_INVALID_ARG;
return DoCommand();
DoCommand();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

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

@ -85,13 +85,11 @@ nsresult nsXULSelectableAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMet
if (!mSelectControl) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIAccessible> childAcc;
GetChildAt(aIndex, getter_AddRefs(childAcc));
nsCOMPtr<nsIAccessNode> accNode = do_QueryInterface(childAcc);
NS_ENSURE_TRUE(accNode, NS_ERROR_FAILURE);
nsAccessible* child = GetChildAt(aIndex);
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMNode> childNode;
accNode->GetDOMNode(getter_AddRefs(childNode));
child->GetDOMNode(getter_AddRefs(childNode));
nsCOMPtr<nsIDOMXULSelectControlItemElement> item(do_QueryInterface(childNode));
NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
@ -338,8 +336,8 @@ nsXULMenuitemAccessible::GetStateInternal(PRUint32 *aState,
// Is collapsed?
PRBool isCollapsed = PR_FALSE;
nsCOMPtr<nsIAccessible> parentAccessible(GetParent());
if (nsAccUtils::State(parentAccessible) & nsIAccessibleStates::STATE_INVISIBLE)
nsAccessible* parentAcc = GetParent();
if (nsAccUtils::State(parentAcc) & nsIAccessibleStates::STATE_INVISIBLE)
isCollapsed = PR_TRUE;
if (isSelected) {
@ -348,8 +346,7 @@ nsXULMenuitemAccessible::GetStateInternal(PRUint32 *aState,
// Selected and collapsed?
if (isCollapsed) {
// Set selected option offscreen/invisible according to combobox state
nsCOMPtr<nsIAccessible> grandParentAcc;
parentAccessible->GetParent(getter_AddRefs(grandParentAcc));
nsAccessible* grandParentAcc = parentAcc->GetParent();
NS_ENSURE_TRUE(grandParentAcc, NS_ERROR_FAILURE);
NS_ASSERTION(nsAccUtils::Role(grandParentAcc) == nsIAccessibleRole::ROLE_COMBOBOX,
"grandparent of combobox listitem is not combobox");
@ -423,9 +420,9 @@ nsXULMenuitemAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
if (accesskey.IsEmpty())
return NS_OK;
nsCOMPtr<nsIAccessible> parentAccessible(GetParent());
if (parentAccessible) {
if (nsAccUtils::RoleInternal(parentAccessible) ==
nsAccessible* parentAcc = GetParent();
if (parentAcc) {
if (nsAccUtils::RoleInternal(parentAcc) ==
nsIAccessibleRole::ROLE_MENUBAR) {
// If top level menu item, add Alt+ or whatever modifier text to string
// No need to cache pref service, this happens rarely

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

@ -120,7 +120,8 @@ nsXULSliderAccessible::DoAction(PRUint8 aIndex)
nsCOMPtr<nsIContent> sliderContent(GetSliderNode());
NS_ENSURE_STATE(sliderContent);
return DoCommand(sliderContent);
DoCommand(sliderContent);
return NS_OK;
}
// nsIAccessibleValue

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

@ -44,17 +44,19 @@
#include "nsIDOMXULSelectCntrlEl.h"
#include "nsIDOMXULSelectCntrlItemEl.h"
/**
* XUL Tab
*/
////////////////////////////////////////////////////////////////////////////////
// nsXULTabAccessible
////////////////////////////////////////////////////////////////////////////////
/** Constructor */
nsXULTabAccessible::nsXULTabAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
nsLeafAccessible(aNode, aShell)
nsXULTabAccessible::
nsXULTabAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
nsAccessibleWrap(aNode, aShell)
{
}
/** Only one action available */
////////////////////////////////////////////////////////////////////////////////
// nsXULTabAccessible: nsIAccessible
NS_IMETHODIMP nsXULTabAccessible::GetNumActions(PRUint8 *_retval)
{
*_retval = 1;
@ -86,7 +88,9 @@ NS_IMETHODIMP nsXULTabAccessible::DoAction(PRUint8 index)
return NS_ERROR_INVALID_ARG;
}
/** We are a tab */
////////////////////////////////////////////////////////////////////////////////
// nsXULTabAccessible: nsAccessible
nsresult
nsXULTabAccessible::GetRoleInternal(PRUint32 *aRole)
{
@ -94,14 +98,13 @@ nsXULTabAccessible::GetRoleInternal(PRUint32 *aRole)
return NS_OK;
}
/**
* Possible states: focused, focusable, unavailable(disabled), offscreen
*/
nsresult
nsXULTabAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
{
// Possible states: focused, focusable, unavailable(disabled), offscreen.
// get focus and disable status from base class
nsresult rv = nsLeafAccessible::GetStateInternal(aState, aExtraState);
nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
NS_ENSURE_A11Y_SUCCESS(rv, rv);
// In the past, tabs have been focusable in classic theme
@ -129,11 +132,12 @@ nsXULTabAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
return NS_OK;
}
// nsIAccessible
NS_IMETHODIMP
nsXULTabAccessible::GetRelationByType(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation)
{
nsresult rv = nsLeafAccessible::GetRelationByType(aRelationType,
nsresult rv = nsAccessibleWrap::GetRelationByType(aRelationType,
aRelation);
NS_ENSURE_SUCCESS(rv, rv);
@ -159,43 +163,35 @@ nsXULTabAccessible::GetRelationByType(PRUint32 aRelationType,
// assume tab and tabpanels are related 1 to 1. We follow algorithm from
// the setter 'selectedIndex' of tabbox.xml#tabs binding.
nsCOMPtr<nsIAccessible> tabsAcc = GetParent();
nsAccessible* tabsAcc = GetParent();
NS_ENSURE_TRUE(nsAccUtils::Role(tabsAcc) == nsIAccessibleRole::ROLE_PAGETABLIST,
NS_ERROR_FAILURE);
PRInt32 tabIndex = -1;
nsCOMPtr<nsIAccessible> childAcc;
tabsAcc->GetFirstChild(getter_AddRefs(childAcc));
while (childAcc) {
PRInt32 childCount = tabsAcc->GetChildCount();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible* childAcc = tabsAcc->GetChildAt(childIdx);
if (nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_PAGETAB)
tabIndex++;
if (childAcc == this)
break;
nsCOMPtr<nsIAccessible> acc;
childAcc->GetNextSibling(getter_AddRefs(acc));
childAcc.swap(acc);
}
nsCOMPtr<nsIAccessible> tabBoxAcc;
tabsAcc->GetParent(getter_AddRefs(tabBoxAcc));
nsAccessible* tabBoxAcc = tabsAcc->GetParent();
NS_ENSURE_TRUE(nsAccUtils::Role(tabBoxAcc) == nsIAccessibleRole::ROLE_PANE,
NS_ERROR_FAILURE);
tabBoxAcc->GetFirstChild(getter_AddRefs(childAcc));
while (childAcc) {
childCount = tabBoxAcc->GetChildCount();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible* childAcc = tabBoxAcc->GetChildAt(childIdx);
if (nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_PROPERTYPAGE) {
if (tabIndex == 0)
return nsRelUtils::AddTarget(aRelationType, aRelation, childAcc);
tabIndex--;
}
nsCOMPtr<nsIAccessible> acc;
childAcc->GetNextSibling(getter_AddRefs(acc));
childAcc.swap(acc);
}
return NS_OK;

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

@ -46,7 +46,7 @@
/**
* An individual tab, xul:tab element
*/
class nsXULTabAccessible : public nsLeafAccessible
class nsXULTabAccessible : public nsAccessibleWrap
{
public:
enum { eAction_Switch = 0 };

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

@ -233,8 +233,8 @@ nsXULLinkAccessible::DoAction(PRUint8 aIndex)
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
return DoCommand(content);
DoCommand();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

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

@ -461,7 +461,7 @@ nsXULTreeAccessible::SelectAllSelection(PRBool *aIsMultiSelectable)
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeAccessible: nsAccessible implementation
nsIAccessible*
nsAccessible*
nsXULTreeAccessible::GetChildAt(PRUint32 aIndex)
{
PRInt32 childCount = nsAccessible::GetChildCount();
@ -473,7 +473,10 @@ nsXULTreeAccessible::GetChildAt(PRUint32 aIndex)
nsCOMPtr<nsIAccessible> child;
GetTreeItemAccessible(aIndex - childCount, getter_AddRefs(child));
return child;
nsRefPtr<nsAccessible> childAcc =
nsAccUtils::QueryObject<nsAccessible>(child);
return childAcc;
}
PRInt32
@ -567,9 +570,9 @@ nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
nsRefPtr<nsAccessible> accessible =
nsAccUtils::QueryAccessible(accessNode);
nsCOMPtr<nsIAccessibleEvent> event =
nsRefPtr<nsAccEvent> event =
new nsAccEvent(nsIAccessibleEvent::EVENT_HIDE, accessible, PR_FALSE);
FireAccessibleEvent(event);
nsEventShell::FireEvent(event);
accessible->Shutdown();
@ -680,7 +683,7 @@ nsXULTreeAccessible::TreeViewChanged()
// Fire only notification destroy/create events on accessible tree to lie to
// AT because it should be expensive to fire destroy events for each tree item
// in cache.
nsCOMPtr<nsIAccessibleEvent> eventDestroy =
nsRefPtr<nsAccEvent> eventDestroy =
new nsAccEvent(nsIAccessibleEvent::EVENT_HIDE, this, PR_FALSE);
if (!eventDestroy)
return;
@ -691,7 +694,7 @@ nsXULTreeAccessible::TreeViewChanged()
mTree->GetView(getter_AddRefs(mTreeView));
nsCOMPtr<nsIAccessibleEvent> eventCreate =
nsRefPtr<nsAccEvent> eventCreate =
new nsAccEvent(nsIAccessibleEvent::EVENT_SHOW, this, PR_FALSE);
if (!eventCreate)
return;
@ -717,7 +720,7 @@ nsXULTreeAccessible::CreateTreeItemAccessible(PRInt32 aRow,
nsXULTreeItemAccessibleBase::
nsXULTreeItemAccessibleBase(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
nsIAccessible *aParent, nsITreeBoxObject *aTree,
nsAccessible *aParent, nsITreeBoxObject *aTree,
nsITreeView *aTreeView, PRInt32 aRow) :
mTree(aTree), mTreeView(aTreeView), mRow(aRow),
nsAccessibleWrap(aDOMNode, aShell)
@ -932,7 +935,8 @@ nsXULTreeItemAccessibleBase::DoAction(PRUint8 aIndex)
(aIndex != eAction_Expand || !IsExpandable()))
return NS_ERROR_INVALID_ARG;
return DoCommand(nsnull, aIndex);
DoCommand(nsnull, aIndex);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
@ -1082,7 +1086,7 @@ nsXULTreeItemAccessibleBase::GetStateInternal(PRUint32 *aState,
return NS_OK;
}
nsIAccessible*
nsAccessible*
nsXULTreeItemAccessibleBase::GetParent()
{
return IsDefunct() ? nsnull : mParent.get();
@ -1184,8 +1188,8 @@ nsXULTreeItemAccessibleBase::IsExpandable()
////////////////////////////////////////////////////////////////////////////////
nsXULTreeItemAccessible::
nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
nsIAccessible *aParent, nsITreeBoxObject *aTree,
nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
nsAccessible *aParent, nsITreeBoxObject *aTree,
nsITreeView *aTreeView, PRInt32 aRow) :
nsXULTreeItemAccessibleBase(aDOMNode, aShell, aParent, aTree, aTreeView, aRow)
{
@ -1271,7 +1275,7 @@ nsXULTreeItemAccessible::RowInvalidated(PRInt32 aStartColIdx,
GetName(name);
if (name != mCachedName) {
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
mCachedName = name;
}
}

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

@ -89,7 +89,7 @@ public:
PRBool aDeepestChild,
nsIAccessible **aChild);
virtual nsIAccessible* GetChildAt(PRUint32 aIndex);
virtual nsAccessible* GetChildAt(PRUint32 aIndex);
virtual PRInt32 GetChildCount();
virtual PRInt32 GetIndexOf(nsIAccessible *aChild);
@ -166,7 +166,7 @@ class nsXULTreeItemAccessibleBase : public nsAccessibleWrap
{
public:
nsXULTreeItemAccessibleBase(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
nsIAccessible *aParent, nsITreeBoxObject *aTree,
nsAccessible *aParent, nsITreeBoxObject *aTree,
nsITreeView *aTreeView, PRInt32 aRow);
// nsISupports
@ -201,7 +201,7 @@ public:
// nsAccessible
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsIAccessible* GetParent();
virtual nsAccessible* GetParent();
// nsXULTreeItemAccessibleBase
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)
@ -255,7 +255,7 @@ class nsXULTreeItemAccessible : public nsXULTreeItemAccessibleBase
{
public:
nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
nsIAccessible *aParent, nsITreeBoxObject *aTree,
nsAccessible *aParent, nsITreeBoxObject *aTree,
nsITreeView *aTreeView, PRInt32 aRow);
NS_IMETHOD GetName(nsAString& aName);

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

@ -604,7 +604,7 @@ nsXULTreeGridAccessible::CreateTreeItemAccessible(PRInt32 aRow,
nsXULTreeGridRowAccessible::
nsXULTreeGridRowAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
nsIAccessible *aTreeAcc, nsITreeBoxObject* aTree,
nsAccessible *aTreeAcc, nsITreeBoxObject* aTree,
nsITreeView *aTreeView, PRInt32 aRow) :
nsXULTreeItemAccessibleBase(aDOMNode, aShell, aTreeAcc, aTree, aTreeView, aRow)
{
@ -689,7 +689,7 @@ nsXULTreeGridRowAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
return NS_OK;
}
nsIAccessible*
nsAccessible*
nsXULTreeGridRowAccessible::GetChildAt(PRUint32 aIndex)
{
if (IsDefunct())
@ -702,7 +702,9 @@ nsXULTreeGridRowAccessible::GetChildAt(PRUint32 aIndex)
nsCOMPtr<nsIAccessible> cell;
GetCellAccessible(column, getter_AddRefs(cell));
return cell;
nsRefPtr<nsAccessible> cellAcc = nsAccUtils::QueryObject<nsAccessible>(cell);
return cellAcc;
}
PRInt32
@ -971,13 +973,17 @@ nsXULTreeGridCellAccessible::DoAction(PRUint8 aIndex)
PRBool isCycler = PR_FALSE;
mColumn->GetCycler(&isCycler);
if (isCycler)
return DoCommand();
if (isCycler) {
DoCommand();
return NS_OK;
}
PRInt16 type;
mColumn->GetType(&type);
if (type == nsITreeColumn::TYPE_CHECKBOX && IsEditable())
return DoCommand();
if (type == nsITreeColumn::TYPE_CHECKBOX && IsEditable()) {
DoCommand();
return NS_OK;
}
return NS_ERROR_INVALID_ARG;
}
@ -994,10 +1000,7 @@ nsXULTreeGridCellAccessible::GetTable(nsIAccessibleTable **aTable)
if (IsDefunct())
return NS_OK;
nsCOMPtr<nsIAccessible> accessible;
mParent->GetParent(getter_AddRefs(accessible));
CallQueryInterface(accessible, aTable);
CallQueryInterface(mParent->GetParent(), aTable);
return NS_OK;
}
@ -1222,7 +1225,7 @@ nsXULTreeGridCellAccessible::GetStateInternal(PRUint32 *aStates,
return NS_OK;
}
nsIAccessible*
nsAccessible*
nsXULTreeGridCellAccessible::GetParent()
{
return IsDefunct() ? nsnull : mParent.get();
@ -1253,11 +1256,10 @@ nsXULTreeGridCellAccessible::CellInvalidated()
mTreeView->GetCellValue(mRow, mColumn, textEquiv);
if (mCachedTextEquiv != textEquiv) {
PRBool isEnabled = textEquiv.EqualsLiteral("true");
nsCOMPtr<nsIAccessibleEvent> accEvent =
nsRefPtr<nsAccEvent> accEvent =
new nsAccStateChangeEvent(this, nsIAccessibleStates::STATE_CHECKED,
PR_FALSE, isEnabled);
if (accEvent)
FireAccessibleEvent(accEvent);
nsEventShell::FireEvent(accEvent);
mCachedTextEquiv = textEquiv;
}
@ -1267,7 +1269,7 @@ nsXULTreeGridCellAccessible::CellInvalidated()
mTreeView->GetCellText(mRow, mColumn, textEquiv);
if (mCachedTextEquiv != textEquiv) {
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
mCachedTextEquiv = textEquiv;
}
}

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

@ -78,7 +78,7 @@ class nsXULTreeGridRowAccessible : public nsXULTreeItemAccessibleBase
{
public:
nsXULTreeGridRowAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
nsIAccessible *aParent, nsITreeBoxObject *aTree,
nsAccessible *aParent, nsITreeBoxObject *aTree,
nsITreeView *aTreeView, PRInt32 aRow);
// nsISupports and cycle collection
@ -95,7 +95,7 @@ public:
PRBool aDeepestChild,
nsIAccessible **aChild);
virtual nsIAccessible* GetChildAt(PRUint32 aIndex);
virtual nsAccessible* GetChildAt(PRUint32 aIndex);
virtual PRInt32 GetChildCount();
virtual PRInt32 GetIndexOf(nsIAccessible *aChild);
@ -164,7 +164,7 @@ public:
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsIAccessible* GetParent();
virtual nsAccessible* GetParent();
// nsXULTreeGridCellAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)

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

@ -42,7 +42,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = accessible
DIRS = attributes selectable tree
DIRS = attributes events selectable tree
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
@ -91,18 +91,6 @@ _TEST_FILES =\
test_elm_listbox.xul \
$(warning test_elm_media.html temporarily disabled) \
test_elm_plugin.html \
test_events_caretmove.html \
$(warning test_events_coalescence.html temporarily disabled) \
$(warning test_events_doc.html temporarily disabled) \
test_events_draganddrop.html \
test_events_flush.html \
test_events_focus.html \
test_events_focus.xul \
test_events_focusdoc.html \
test_events_mutation.html \
test_events_scroll.xul \
test_events_tree.xul \
test_events_valuechange.html \
test_invalidate_accessnode.html \
test_name.html \
test_name.xul \

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

@ -97,6 +97,17 @@
testGroupAttrs("r2", 2, 3);
testGroupAttrs("r3", 3, 3);
//////////////////////////////////////////////////////////////////////////
// ARIA tree
testGroupAttrs("ti1", 1, 3, 1);
testGroupAttrs("ti2", 1, 2, 2);
testGroupAttrs("ti3", 2, 2, 2);
testGroupAttrs("ti4", 2, 3, 1);
testGroupAttrs("ti5", 1, 3, 2);
testGroupAttrs("ti6", 2, 3, 2);
testGroupAttrs("ti7", 3, 3, 2);
testGroupAttrs("ti8", 3, 3, 1);
//////////////////////////////////////////////////////////////////////////
// ARIA grid
testGroupAttrs("grid_row1", 1, 2);
@ -109,15 +120,15 @@
//////////////////////////////////////////////////////////////////////////
// ARIA treegrid
testGroupAttrs("treegrid_row1", 1, 3, 1);
testGroupAttrs("treegrid_row1", 1, 2, 1);
testGroupAttrs("treegrid_cell1", 1, 2);
testGroupAttrs("treegrid_cell2", 2, 2);
testGroupAttrs("treegrid_row2", 2, 3, 2);
testGroupAttrs("treegrid_row2", 1, 1, 2);
testGroupAttrs("treegrid_cell3", 1, 2);
testGroupAttrs("treegrid_cell4", 2, 2);
testGroupAttrs("treegrid_row3", 3, 3, 1);
testGroupAttrs("treegrid_row3", 2, 2, 1);
testGroupAttrs("treegrid_cell5", 1, 2);
testGroupAttrs("treegrid_cell6", 2, 2);
@ -234,6 +245,35 @@
<li id="r3" role="radio" aria-checked="false">Jimmy Johns</li>
</ul>
<table role="tree">
<tr role="presentation">
<td role="treeitem" aria-expanded="true" aria-level="1"
id="ti1">vegetables</td>
</tr>
<tr role="presentation">
<td role="treeitem" aria-level="2" id="ti2">cucumber</td>
</tr>
<tr role="presentation">
<td role="treeitem" aria-level="2" id="ti3">carrot</td>
</tr>
<tr role="presentation">
<td role="treeitem" aria-expanded="false" aria-level="1"
id="ti4">cars</td>
</tr>
<tr role="presentation">
<td role="treeitem" aria-level="2" id="ti5">mercedes</td>
</tr>
<tr role="presentation">
<td role="treeitem" aria-level="2" id="ti6">BMW</td>
</tr>
<tr role="presentation">
<td role="treeitem" aria-level="2" id="ti7">Audi</td>
</tr>
<tr role="presentation">
<td role="treeitem" aria-level="1" id="ti8">people</td>
</tr>
</table>
<table role="grid">
<tr role="row" id="grid_row1">
<td role="gridcell" id="grid_cell1">cell1</td>

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

@ -1,15 +1,15 @@
////////////////////////////////////////////////////////////////////////////////
// Constants
const EVENT_DOCUMENT_LOAD_COMPLETE = nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE;
const EVENT_HIDE = nsIAccessibleEvent.EVENT_HIDE;
const EVENT_SHOW = nsIAccessibleEvent.EVENT_SHOW;
const EVENT_DOCUMENT_LOAD_COMPLETE =
nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE;
const EVENT_FOCUS = nsIAccessibleEvent.EVENT_FOCUS;
const EVENT_NAME_CHANGE = nsIAccessibleEvent.EVENT_NAME_CHANGE;
const EVENT_SCROLLING_START = nsIAccessibleEvent.EVENT_SCROLLING_START;
const EVENT_STATE_CHANGE = nsIAccessibleEvent.EVENT_STATE_CHANGE;
const EVENT_REORDER = nsIAccessibleEvent.EVENT_REORDER;
const EVENT_SCROLLING_START = nsIAccessibleEvent.EVENT_SCROLLING_START;
const EVENT_SHOW = nsIAccessibleEvent.EVENT_SHOW;
const EVENT_STATE_CHANGE = nsIAccessibleEvent.EVENT_STATE_CHANGE;
const EVENT_TEXT_CARET_MOVED = nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED;
////////////////////////////////////////////////////////////////////////////////
// General
@ -587,7 +587,7 @@ function sequence()
/**
* Invokers defined below take a checker object implementing 'check' method
* which will be called when proper event is handled. Invokers listen default
* event type registered in event queue object.
* event type registered in event queue object until it is passed explicetly.
*
* Note, you don't need to initialize 'target' and 'type' members of checker
* object. The 'target' member will be initialized by invoker object and you are
@ -597,9 +597,9 @@ function sequence()
/**
* Click invoker.
*/
function synthClick(aNodeOrID, aChecker)
function synthClick(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker);
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.invoke = function synthClick_invoke()
{
@ -609,7 +609,7 @@ function synthClick(aNodeOrID, aChecker)
synthesizeMouse(this.DOMNode, 1, 1, {});
}
this.getID = function synthFocus_getID()
this.getID = function synthClick_getID()
{
return prettyName(aNodeOrID) + " click";
}
@ -618,16 +618,16 @@ function synthClick(aNodeOrID, aChecker)
/**
* General key press invoker.
*/
function synthKey(aNodeOrID, aKey, aArgs, aChecker)
function synthKey(aNodeOrID, aKey, aArgs, aChecker, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker);
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.invoke = function synthKey_invoke()
{
synthesizeKey(this.mKey, this.mArgs);
}
this.getID = function synthFocus_getID()
this.getID = function synthKey_getID()
{
return prettyName(aNodeOrID) + " '" + this.mKey + "' key";
}
@ -639,12 +639,12 @@ function synthKey(aNodeOrID, aKey, aArgs, aChecker)
/**
* Tab key invoker.
*/
function synthTab(aNodeOrID, aChecker)
function synthTab(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_TAB", { shiftKey: false },
aChecker);
aChecker, aEventType);
this.getID = function synthTabTest_getID()
this.getID = function synthTab_getID()
{
return prettyName(aNodeOrID) + " tab";
}
@ -653,10 +653,10 @@ function synthTab(aNodeOrID, aChecker)
/**
* Shift tab key invoker.
*/
function synthShiftTab(aNodeOrID, aChecker)
function synthShiftTab(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_TAB", { shiftKey: true },
aChecker);
aChecker, aEventType);
this.getID = function synthTabTest_getID()
{
@ -667,9 +667,10 @@ function synthShiftTab(aNodeOrID, aChecker)
/**
* Down arrow key invoker.
*/
function synthDownKey(aNodeOrID, aChecker)
function synthDownKey(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_DOWN", null, aChecker);
this.__proto__ = new synthKey(aNodeOrID, "VK_DOWN", null, aChecker,
aEventType);
this.getID = function synthDownKey_getID()
{
@ -680,9 +681,10 @@ function synthDownKey(aNodeOrID, aChecker)
/**
* Right arrow key invoker.
*/
function synthRightKey(aNodeOrID, aChecker)
function synthRightKey(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_RIGHT", null, aChecker);
this.__proto__ = new synthKey(aNodeOrID, "VK_RIGHT", null, aChecker,
aEventType);
this.getID = function synthRightKey_getID()
{
@ -690,12 +692,26 @@ function synthRightKey(aNodeOrID, aChecker)
}
}
/**
* Home key invoker.
*/
function synthHomeKey(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_HOME", null, aChecker,
aEventType);
this.getID = function synthHomeKey_getID()
{
return prettyName(aNodeOrID) + " key home";
}
}
/**
* Focus invoker.
*/
function synthFocus(aNodeOrID, aChecker)
function synthFocus(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker);
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.invoke = function synthFocus_invoke()
{
@ -711,9 +727,9 @@ function synthFocus(aNodeOrID, aChecker)
/**
* Select all invoker.
*/
function synthSelectAll(aNodeOrID, aChecker)
function synthSelectAll(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker);
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.invoke = function synthSelectAll_invoke()
{
@ -851,6 +867,10 @@ function dumpInfoToDOM(aInfo, aDumpNode)
return;
var dumpElm = document.getElementById(dumpID);
if (!dumpElm) {
ok(false, "No dump element '" + dumpID + "' within the document!");
return;
}
var containerTagName = document instanceof nsIDOMHTMLDocument ?
"div" : "description";
@ -905,11 +925,14 @@ function sequenceItem(aProcessor, aEventType, aTarget, aItemID)
/**
* Invoker base class for prepare an action.
*/
function synthAction(aNodeOrID, aChecker)
function synthAction(aNodeOrID, aChecker, aEventType)
{
this.DOMNode = getNode(aNodeOrID);
aChecker.target = this.DOMNode;
if (aEventType)
this.eventSeq = [ new invokerChecker(aEventType, this.DOMNode) ];
this.check = function synthAction_check(aEvent)
{
aChecker.check(aEvent);

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

@ -15,15 +15,16 @@
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1998
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Alexander Surkov <surkov.alexander@gmail.com> (original author)
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
@ -39,25 +40,26 @@ DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = accessible/events
include $(DEPTH)/config/autoconf.mk
MODULE = extensions
EXTRA_COMPONENTS = nsExtensionManager.js
EXTRA_PP_COMPONENTS = \
nsBlocklistService.js \
nsAddonRepository.js \
$(NULL)
EXTRA_JS_MODULES = \
LightweightThemeManager.jsm \
$(NULL)
GARBAGE += nsExtensionManager.js
include $(topsrcdir)/config/rules.mk
nsExtensionManager.js: nsExtensionManager.js.in
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > $@
_TEST_FILES =\
test_attrs.html \
test_caretmove.html \
$(warning test_coalescence.html temporarily disabled) \
$(warning test_doc.html temporarily disabled) \
test_dragndrop.html \
test_flush.html \
test_focus.html \
test_focus.xul \
test_focusdoc.html \
test_mutation.html \
test_scroll.xul \
test_tree.xul \
test_valuechange.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)

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

@ -0,0 +1,84 @@
<html>
<head>
<title>Event object attributes tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/events.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/attributes.js"></script>
<script type="application/javascript">
/**
* Test "event-from-input" object attribute.
*/
function checker(aValue, aNoTargetID)
{
this.noTarget = getNode(aNoTargetID);
this.check = function checker_check(aEvent)
{
testAttrs(aEvent.accessible, { "event-from-input": aValue }, true);
var accessible = getAccessible(this.noTarget);
testAbsentAttrs(accessible, { "event-from-input": "" });
}
}
/**
* Do tests.
*/
var gQueue = null;
// gA11yEventDumpID = "eventdump"; // debug stuff
function doTests()
{
gQueue = new eventQueue();
var id = "textbox", noTargetId = "textarea";
gQueue.push(new synthFocus(id, new checker("false", noTargetId), EVENT_FOCUS));
if (!MAC) { // Mac failure is bug 541093
gQueue.push(new synthHomeKey(id, new checker("false", noTargetId), EVENT_TEXT_CARET_MOVED));
}
gQueue.invoke(); // Will call SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTests);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=540285"
title="Event object attributes testing">
Mozilla Bug 540285
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<input id="textbox" value="hello">
<textarea id="textarea"></textarea>
<div id="eventdump"></div>
</body>
</html>

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

@ -76,7 +76,7 @@
testCaretOffset("p", -1);
// test caret move events and caret offsets
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED);
gQueue = new eventQueue(EVENT_TEXT_CARET_MOVED);
var id = "textbox";
gQueue.push(new synthFocus(id, new checker(5)));

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

@ -2,6 +2,7 @@
// Role constants
const ROLE_ALERT = nsIAccessibleRole.ROLE_ALERT;
const ROLE_ANIMATION = nsIAccessibleRole.ROLE_ANIMATION;
const ROLE_APPLICATION = nsIAccessibleRole.ROLE_APPLICATION;
const ROLE_APP_ROOT = nsIAccessibleRole.ROLE_APP_ROOT;
const ROLE_AUTOCOMPLETE = nsIAccessibleRole.ROLE_AUTOCOMPLETE;
@ -36,10 +37,14 @@ const ROLE_NOTHING = nsIAccessibleRole.ROLE_NOTHING;
const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
const ROLE_OUTLINE = nsIAccessibleRole.ROLE_OUTLINE;
const ROLE_OUTLINEITEM = nsIAccessibleRole.ROLE_OUTLINEITEM;
const ROLE_PAGETAB = nsIAccessibleRole.ROLE_PAGETAB;
const ROLE_PAGETABLIST = nsIAccessibleRole.ROLE_PAGETABLIST;
const ROLE_PANE = nsIAccessibleRole.ROLE_PANE;
const ROLE_PARAGRAPH = nsIAccessibleRole.ROLE_PARAGRAPH;
const ROLE_PARENT_MENUITEM = nsIAccessibleRole.ROLE_PARENT_MENUITEM;
const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
const ROLE_PROPERTYPAGE = nsIAccessibleRole.ROLE_PROPERTYPAGE;
const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
const ROLE_RADIOBUTTON = nsIAccessibleRole.ROLE_RADIOBUTTON;
const ROLE_ROW = nsIAccessibleRole.ROLE_ROW;
@ -53,6 +58,7 @@ const ROLE_TABLE = nsIAccessibleRole.ROLE_TABLE;
const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
const ROLE_TOOLTIP = nsIAccessibleRole.ROLE_TOOLTIP;
const ROLE_TREE_TABLE = nsIAccessibleRole.ROLE_TREE_TABLE;
const ROLE_WHITESPACE = nsIAccessibleRole.ROLE_WHITESPACE;

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

@ -3,6 +3,7 @@
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=481114
https://bugzilla.mozilla.org/show_bug.cgi?id=469688
https://bugzilla.mozilla.org/show_bug.cgi?id=520188
https://bugzilla.mozilla.org/show_bug.cgi?id=529289
-->
<head>
@ -29,9 +30,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=529289
// weak roles that are forms of "live regions"
testRole("log_table", ROLE_TABLE);
testRole("marquee_h1", ROLE_HEADING);
testRole("timer_div", ROLE_SECTION);
// other roles that are forms of "live regions"
testRole("marquee_h1", ROLE_ANIMATION);
// strong landmark
testRole("application", ROLE_APPLICATION);
@ -64,8 +67,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=529289
for (a in abstract_roles)
testRole(abstract_roles[a], ROLE_SECTION);
// aria scrollbar
// misc roles
testRole("scrollbar", ROLE_SCROLLBAR);
testRole("dir", ROLE_LIST);
SimpleTest.finish();
}
@ -77,6 +82,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=529289
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=481114">Mozilla Bug 481114</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469688">Mozilla Bug 469688</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469688">Mozilla Bug 520188</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289">Mozilla Bug 529289</a>
</a>
<p id="display"></p>
@ -139,7 +145,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=529289
<div role="section" id="section">section</div>
<div role="sectionhead" id="sectionhead">sectionhead</div>
<!-- aria scrollbar -->
<!-- misc roles -->
<div role="scrollbar" id="scrollbar">scrollbar</div>
<div id="dir" role="directory">
<div role="listitem">A</div>
<div role="listitem">B</div>
<div role="listitem">C</div>
</div>
</body>
</html>

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

@ -46,6 +46,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=472326
// get broken.
testRole("p", ROLE_PARAGRAPH);
// Test dl, dt, dd
testRole("definitionlist", ROLE_LIST);
testRole("definitionterm", ROLE_LISTITEM);
testRole("definitiondescription", ROLE_PARAGRAPH);
SimpleTest.finish();
}
@ -79,5 +84,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=472326
<h4 id="head4">A heading level 4</h4>
<h5 id="head5">A heading level 5</h5>
<h6 id="head6">A heading level 6</h6>
<dl id="definitionlist">
<dt id="definitionterm">gecko</dt>
<dd id="definitiondescription">geckos have sticky toes</dd>
</dl>
</body>
</html>

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

@ -60,6 +60,8 @@ _TEST_FILES =\
test_media.html \
test_menu.xul \
test_select.html \
test_tabbox.xul \
test_tabbrowser.xul \
test_table.html \
test_tree.xul \
test_txtcntr.html \

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

@ -43,6 +43,9 @@
testAccessibleTree("btn1", accTree);
testAccessibleTree("submit", accTree);
testAccessibleTree("image_submit", accTree);
// button
accTree = {
role: ROLE_PUSHBUTTON,
@ -69,6 +72,11 @@
href="https://bugzilla.mozilla.org/show_bug.cgi?id=342045">
Mozilla Bug 342045
</a>
<a target="_blank"
title="add test for role of input type='image'"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=524521">
Mozilla Bug 524521
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
@ -79,5 +87,7 @@
<input type="button" value="button" id="btn1">
<button id="btn2">button</button>
<input type="submit" id="submit">
<input type="image" id="image_submit">
</body>
</html>

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

@ -0,0 +1,94 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Accessible XUL tabbox hierarchy tests">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js" />
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Test
function doTest()
{
//////////////////////////////////////////////////////////////////////////
// tabbox
var accTree = {
role: ROLE_PANE,
children: [
{
role: ROLE_PAGETABLIST,
children: [
{
role: ROLE_PAGETAB,
children: []
},
{
role: ROLE_PAGETAB,
children: []
}
]
},
{
role: ROLE_PROPERTYPAGE,
children: []
},
{
role: ROLE_PROPERTYPAGE,
children: []
}
]
};
testAccessibleTree("tabbox", accTree);
SimpleTest.finish()
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=540389"
title=" WARNING: Bad accessible tree!: [tabbrowser tab] ">
Mozilla Bug 540389
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<vbox flex="1">
<tabbox id="tabbox">
<tabs>
<tab label="tab1"/>
<tab label="tab2"/>
</tabs>
<tabpanels>
<tabpanel/>
<tabpanel/>
</tabpanels>
</tabbox>
</vbox>
</hbox>
</window>

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

@ -0,0 +1,152 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/browser.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Accessible XUL tabbrowser hierarchy tests">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js" />
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Test
const Ci = Components.interfaces;
// Hack to make xul:tabbrowser work.
var XULBrowserWindow = {
isBusy: false,
setOverLink: function (link, b) {
}
};
var gFindBar = {
hidden: true
};
function doTest()
{
if (LINUX) {
// XXX: bug 540529
todo(false, "Failure on Linux.");
SimpleTest.finish();
return;
}
var tabBrowser = document.getElementById("tabbrowser");
var progressListener =
{
onStateChange: function onStateChange(aWebProgress,
aRequest,
aStateFlags,
aStatus)
{
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP)
testAccTree();
}
};
tabBrowser.addProgressListener(progressListener,
Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
tabBrowser.loadTabs(["about:", "about:mozilla"], false, true);
}
function testAccTree()
{
var accTree = {
role: ROLE_PANE,
children: [
{
role: ROLE_TOOLTIP
},
{
role: ROLE_MENUPOPUP
},
{
role: ROLE_PAGETABLIST,
children: [
{
role: ROLE_PAGETAB,
children: [
{
role: ROLE_PUSHBUTTON
}
]
},
{
role: ROLE_PAGETAB,
children: [
{
role: ROLE_PUSHBUTTON
}
]
},
{
role: ROLE_PUSHBUTTON
},
{
role: ROLE_PUSHBUTTON
}
]
},
{
role: ROLE_PROPERTYPAGE
},
{
role: ROLE_PROPERTYPAGE
}
]
};
testAccessibleTree(getNode("tabbrowser").mTabBox, accTree);
SimpleTest.finish()
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=540389"
title=" WARNING: Bad accessible tree!: [tabbrowser tab] ">
Mozilla Bug 540389
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<!-- Hack to make xul:tabbrowser work -->
<menubar>
<menu label="menu">
<menupopup>
<menuitem label="close window hook" id="menu_closeWindow"/>
<menuitem label="close hook" id="menu_close"/>
</menupopup>
</menu>
</menubar>
<tabbrowser type="content-primary" flex="1" id="tabbrowser"/>
</hbox>
</window>

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

@ -47,7 +47,6 @@ SourceRepository=@MOZ_SOURCE_REPO@
#ifdef MOZ_SOURCE_STAMP
SourceStamp=@MOZ_SOURCE_STAMP@
#endif
Copyright=Copyright (c) 1998 - 2010 mozilla.org
ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
[Gecko]

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

@ -74,7 +74,7 @@
<key>CFBundleExecutable</key>
<string>firefox-bin</string>
<key>CFBundleGetInfoString</key>
<string>%APP_NAME% %APP_VERSION%, © 1998-2010 Contributors</string>
<string>%APP_NAME% %APP_VERSION%</string>
<key>CFBundleIconFile</key>
<string>firefox</string>
<key>CFBundleIdentifier</key>

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

@ -311,14 +311,6 @@ pref("browser.microsummary.updateGenerators", true);
pref("browser.search.suggest.enabled", true);
pref("browser.sessionhistory.max_entries", 50);
#ifndef WINCE
pref("browser.history_expire_days", 180);
pref("browser.history_expire_days_min", 90);
#else
pref("browser.history_expire_days", 90);
pref("browser.history_expire_days_min", 45);
#endif
pref("browser.history_expire_sites", 40000);
// handle links targeting new windows
// 0=default window, 1=current window/tab, 2=new window, 3=new tab in most recent window
@ -784,6 +776,9 @@ pref("browser.sessionstore.max_resumed_crashes", 1);
// allow META refresh by default
pref("accessibility.blockautorefresh", false);
// Whether history is enabled or not.
pref("places.history.enabled", true);
// The percentage of system memory that the Places database can use. Out of the
// allowed cache size it will at most use the size of the database file.
// Changes to this value are effective after an application restart.
@ -909,7 +904,7 @@ pref("toolbar.customization.usesheet", true);
pref("toolbar.customization.usesheet", false);
#endif
pref("dom.ipc.plugins.enabled", false);
pref("dom.ipc.plugins.enabled", true);
#ifdef XP_WIN
#ifndef WINCE

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

@ -85,10 +85,9 @@
<label id="distribution"/>
<label id="distributionId"/>
<description id="copyright">
&copyrightInfo1;<label
class="text-link" href="&licenseLink;"
>&licenseLinkText;</label>&copyrightInfo2;
&logoCopyright;
<label
class="text-link" href="about:license"
>&licenseLinkText;</label>&licenseLinkSuffix;&logoTrademark;
</description>
<textbox id="userAgent" multiline="true" readonly="true" flex="1"/>
</vbox>

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

@ -78,6 +78,7 @@
<menupopup id="menu_HelpPopup" onpopupshowing="buildHelpMenu();">
<menuitem id="menu_openHelp"
oncommand="openHelpLink('firefox-help')"
onclick="checkForMiddleClick(this, event);"
label="&productHelp.label;"
accesskey="&productHelp.accesskey;"
#ifdef XP_MACOSX
@ -89,7 +90,8 @@
#ifdef XP_WIN
<menuitem label="&helpForIEUsers.label;"
accesskey="&helpForIEUsers.accesskey;"
oncommand="openHelpLink('ieusers');"/>
oncommand="openHelpLink('ieusers');"
onclick="checkForMiddleClick(this, event);"/>
#endif
<menuitem id="troubleShooting"
accesskey="&helpTroubleshootingInfo.accesskey;"

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

@ -605,8 +605,8 @@
key="key_privatebrowsing"
command="Tools:PrivateBrowsing"/>
<menuitem id="sanitizeItem"
accesskey="&clearRecentHistoryCmd.accesskey;"
label="&clearRecentHistoryCmd.label;"
accesskey="&clearRecentHistory.accesskey;"
label="&clearRecentHistory.label;"
key="key_sanitize"
command="Tools:Sanitize"/>
#ifndef XP_UNIX

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

@ -732,8 +732,10 @@ var allTabs = {
siblingPreview.parentNode.insertBefore(preview, siblingPreview);
else
this.container.lastChild.appendChild(preview);
if (this.isOpen && !preview.hidden)
if (this.isOpen && !preview.hidden) {
this._reflow();
preview.focus();
}
break;
case "TabClose":
this._removePreview(preview);
@ -814,7 +816,7 @@ var allTabs = {
while (this.container.hasChildNodes())
this.container.removeChild(this.container.firstChild);
for (let i = 0; i < rows; i++)
for (let i = rows || 1; i > 0; i--)
this.container.appendChild(document.createElement("hbox"));
var row = this.container.firstChild;

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

@ -84,6 +84,24 @@
<handlers>
<handler event="command" action="allTabs.pick(this);"/>
<handler event="click" button="1" action="gBrowser.removeTab(this._tab);"/>
<handler event="dragstart"><![CDATA[
event.dataTransfer.mozSetDataAt("application/x-moz-node", this._tab, 0);
]]></handler>
<handler event="dragover"><![CDATA[
let tab = event.dataTransfer.mozGetDataAt("application/x-moz-node", 0);
if (tab && tab.parentNode == gBrowser.tabContainer)
event.preventDefault();
]]></handler>
<handler event="drop"><![CDATA[
let tab = event.dataTransfer.mozGetDataAt("application/x-moz-node", 0);
if (tab && tab.parentNode == gBrowser.tabContainer) {
let newIndex = Array.indexOf(gBrowser.tabContainer.childNodes, this._tab);
gBrowser.moveTabTo(tab, newIndex);
}
]]></handler>
</handlers>
</binding>
</bindings>

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

@ -1536,10 +1536,6 @@ var gAutoHideTabbarPrefListener = {
function initializeSanitizer()
{
// Always use the label with ellipsis
var label = gNavigatorBundle.getString("sanitizeWithPromptLabel2");
document.getElementById("sanitizeItem").setAttribute("label", label);
const kDidSanitizeDomain = "privacy.sanitize.didShutdownSanitize";
if (gPrefService.prefHasUserValue(kDidSanitizeDomain)) {
gPrefService.clearUserPref(kDidSanitizeDomain);
@ -1611,7 +1607,7 @@ function gotoHistoryIndex(aEvent)
var sessionHistory = getWebNavigation().sessionHistory;
var entry = sessionHistory.getEntryAtIndex(index, false);
var url = entry.URI.spec;
openUILinkIn(url, where);
openUILinkIn(url, where, {relatedToCurrent: true});
return true;
}
}
@ -1631,7 +1627,7 @@ function BrowserForward(aEvent) {
var currentIndex = sessionHistory.index;
var entry = sessionHistory.getEntryAtIndex(currentIndex + 1, false);
var url = entry.URI.spec;
openUILinkIn(url, where);
openUILinkIn(url, where, {relatedToCurrent: true});
}
}
@ -1650,7 +1646,7 @@ function BrowserBack(aEvent) {
var currentIndex = sessionHistory.index;
var entry = sessionHistory.getEntryAtIndex(currentIndex - 1, false);
var url = entry.URI.spec;
openUILinkIn(url, where);
openUILinkIn(url, where, {relatedToCurrent: true});
}
}
@ -1704,7 +1700,8 @@ function BrowserReloadOrDuplicate(aEvent) {
if (where == "current")
BrowserReload();
else
openUILinkIn(getWebNavigation().currentURI.spec, where);
openUILinkIn(getWebNavigation().currentURI.spec, where,
{relatedToCurrent: true});
}
function BrowserReload() {
@ -2719,6 +2716,7 @@ var browserDragAndDrop = {
if (types.contains("application/x-moz-file") ||
types.contains("text/x-moz-url") ||
types.contains("text/uri-list") ||
types.contains("text/x-moz-text-internal") ||
types.contains("text/plain")) {
aEvent.preventDefault();
@ -3341,12 +3339,8 @@ function BrowserCustomizeToolbar()
else
sheetFrame.setAttribute("src", customizeURL);
// XXXmano: there's apparently no better way to get this when the iframe is
// hidden
var sheetWidth = sheetFrame.style.width.match(/([0-9]+)px/)[1];
document.getElementById("customizeToolbarSheetPopup")
.openPopup(gNavToolbox, "after_start",
(window.innerWidth - sheetWidth) / 2, 0);
.openPopup(gNavToolbox, "after_start", 0, 0);
return sheetFrame.contentWindow;
} else {
@ -4526,6 +4520,13 @@ nsBrowserAccess.prototype = {
return null;
}
if (isExternal && (!aURI || aURI.spec == "about:blank")) {
win.BrowserOpenTab(); // this also focuses the location bar
win.focus();
newWindow = win.content;
break;
}
let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
let referrer = aOpener ? makeURI(aOpener.location.href) : null;
@ -5278,8 +5279,10 @@ function stylesheetFillPopup(menuPopup) {
continue;
// Skip any stylesheets that don't match the screen media type.
let (media = currentStyleSheet.media.mediaText.toLowerCase()) {
if (media && (media.indexOf("screen") == -1) && (media.indexOf("all") == -1))
if (currentStyleSheet.media.length > 0) {
let media = currentStyleSheet.media.mediaText.split(", ");
if (media.indexOf("screen") == -1 &&
media.indexOf("all") == -1)
continue;
}

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

@ -300,7 +300,9 @@
<!-- Bookmarks and history tooltip -->
<tooltip id="bhTooltip"/>
<panel id="customizeToolbarSheetPopup" noautohide="true">
<panel id="customizeToolbarSheetPopup"
noautohide="true"
onpopupshown="this.moveTo(this.boxObject.screenX + (window.innerWidth - this.boxObject.width) / 2, this.boxObject.screenY);">
<iframe id="customizeToolbarSheetIFrame"
style="&dialog.style;"
hidden="true"/>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше