зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to tracemonkey.
This commit is contained in:
Коммит
6eac0d504b
31
Makefile.in
31
Makefile.in
|
@ -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 (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;
|
||||
}
|
||||
if (mAccessible != static_cast<nsIAccessible*>(applicationAcc.get()))
|
||||
NS_ASSERTION(targetNode, "There should always be a DOM node for an event");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
|
@ -81,17 +92,19 @@ public:
|
|||
eRemoveDupes,
|
||||
// eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
|
||||
eDoNotEmit
|
||||
};
|
||||
};
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCEVENT_IMPL_CID)
|
||||
|
||||
// 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
|
||||
|
@ -206,38 +193,36 @@ 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)
|
||||
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);
|
||||
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)
|
||||
}
|
||||
|
||||
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,8 +270,8 @@ nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent *aTarget)
|
|||
}
|
||||
|
||||
if (targetAcc)
|
||||
return nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
|
||||
targetAcc);
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
|
||||
if (rectVisibility == nsRectVisibility_kZeroAreaRect && frame &&
|
||||
0 == (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
|
||||
// Consider zero area objects hidden unless they are absoultely 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) {
|
||||
++ positionInGroup;
|
||||
if (sibling == this)
|
||||
foundCurrent = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// If the sibling is separator
|
||||
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR) {
|
||||
if (foundCurrent) // the our group is ended
|
||||
// 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;
|
||||
|
||||
// not our group, continue the searching
|
||||
positionInGroup = 0;
|
||||
setSize = 0;
|
||||
else if (level == siblingLevel)
|
||||
++ positionInGroup;
|
||||
}
|
||||
}
|
||||
|
||||
sibling->GetNextSibling(getter_AddRefs(nextSibling));
|
||||
sibling = nextSibling;
|
||||
// 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;
|
||||
|
||||
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 (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;
|
||||
return level;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
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();
|
||||
nsRect scrollPort;
|
||||
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollableExternal();
|
||||
if (sf) {
|
||||
scrollPort = sf->GetScrollPortRect();
|
||||
} else {
|
||||
nsIFrame* rootFrame = presShell->GetRootFrame();
|
||||
if (!rootFrame) {
|
||||
return;
|
||||
}
|
||||
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));
|
||||
|
||||
nsIViewManager* vm = nsnull;
|
||||
if (presShell)
|
||||
vm = presShell->GetViewManager();
|
||||
|
||||
nsIScrollableView* scrollableView = nsnull;
|
||||
if (vm)
|
||||
vm->GetRootScrollableView(&scrollableView);
|
||||
|
||||
if (scrollableView)
|
||||
scrollableView->RemoveScrollPositionListener(this);
|
||||
if (!presShell)
|
||||
return;
|
||||
|
||||
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,264 +1602,170 @@ 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()
|
||||
{
|
||||
mInFlushPendingEvents = PR_TRUE;
|
||||
nsDocAccessible::ProcessPendingEvent(nsAccEvent *aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
aEvent->GetAccessible(getter_AddRefs(accessible));
|
||||
|
||||
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);
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
aEvent->GetDOMNode(getter_AddRefs(domNode));
|
||||
|
||||
PRUint32 eventType = aEvent->GetEventType();
|
||||
EIsFromUserInput isFromUserInput =
|
||||
aEvent->IsFromUserInput() ? eFromUserInput : eNoUserInput;
|
||||
|
||||
PRBool isAsync = aEvent->IsAsync();
|
||||
|
||||
if (domNode == gLastFocusedNode && isAsync &&
|
||||
(eventType == nsIAccessibleEvent::EVENT_SHOW ||
|
||||
eventType == nsIAccessibleEvent::EVENT_HIDE)) {
|
||||
// If frame type didn't change for this event, then we don't actually need to invalidate
|
||||
// However, we only keep track of the old frame type for the focus, where it's very
|
||||
// important not to destroy and recreate the accessible for minor style changes,
|
||||
// such as a:focus { overflow: scroll; }
|
||||
nsCOMPtr<nsIContent> focusContent(do_QueryInterface(domNode));
|
||||
if (focusContent) {
|
||||
nsIFrame *focusFrame = focusContent->GetPrimaryFrame();
|
||||
nsIAtom *newFrameType =
|
||||
(focusFrame && focusFrame->GetStyleVisibility()->IsVisible()) ?
|
||||
focusFrame->GetType() : nsnull;
|
||||
|
||||
if (newFrameType == gLastFocusedFrameType) {
|
||||
// Don't need to invalidate this current accessible, but can
|
||||
// just invalidate the children instead
|
||||
FireShowHideEvents(domNode, PR_TRUE, eventType, eNormalEvent,
|
||||
isAsync, isFromUserInput);
|
||||
return;
|
||||
}
|
||||
gLastFocusedFrameType = newFrameType;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
|
||||
|
||||
nsCOMPtr<nsIAccessibleEvent> accessibleEvent(mEventsToFire[index]);
|
||||
nsCOMPtr<nsIAccessible> containerAccessible;
|
||||
if (accessible)
|
||||
accessible->GetParent(getter_AddRefs(containerAccessible));
|
||||
|
||||
if (nsAccEvent::EventRule(accessibleEvent) == nsAccEvent::eDoNotEmit)
|
||||
continue;
|
||||
if (!containerAccessible) {
|
||||
GetAccessibleInParentChain(domNode, PR_TRUE,
|
||||
getter_AddRefs(containerAccessible));
|
||||
if (!containerAccessible)
|
||||
containerAccessible = this;
|
||||
}
|
||||
|
||||
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);
|
||||
if (isAsync) {
|
||||
// For asynch show, delayed invalidatation of parent's children
|
||||
nsRefPtr<nsAccessible> containerAcc =
|
||||
nsAccUtils::QueryAccessible(containerAccessible);
|
||||
if (containerAcc)
|
||||
containerAcc->InvalidateChildren();
|
||||
|
||||
PRBool isAsync = nsAccEvent::IsAsyncEvent(accessibleEvent);
|
||||
if (domNode == gLastFocusedNode && isAsync &&
|
||||
(eventType == nsIAccessibleEvent::EVENT_SHOW ||
|
||||
eventType == nsIAccessibleEvent::EVENT_HIDE)) {
|
||||
// If frame type didn't change for this event, then we don't actually need to invalidate
|
||||
// However, we only keep track of the old frame type for the focus, where it's very
|
||||
// important not to destroy and recreate the accessible for minor style changes,
|
||||
// such as a:focus { overflow: scroll; }
|
||||
nsCOMPtr<nsIContent> focusContent(do_QueryInterface(domNode));
|
||||
if (focusContent) {
|
||||
nsIFrame *focusFrame = focusContent->GetPrimaryFrame();
|
||||
nsIAtom *newFrameType =
|
||||
(focusFrame && focusFrame->GetStyleVisibility()->IsVisible()) ?
|
||||
focusFrame->GetType() : nsnull;
|
||||
// Some show events in the subtree may have been removed to
|
||||
// avoid firing redundant events. But, we still need to make sure any
|
||||
// accessibles parenting those shown nodes lose their child references.
|
||||
InvalidateChildrenInSubtree(domNode);
|
||||
}
|
||||
|
||||
if (newFrameType == gLastFocusedFrameType) {
|
||||
// Don't need to invalidate this current accessible, but can
|
||||
// just invalidate the children instead
|
||||
FireShowHideEvents(domNode, PR_TRUE, eventType, eNormalEvent,
|
||||
isAsync, isFromUserInput);
|
||||
continue;
|
||||
}
|
||||
gLastFocusedFrameType = newFrameType;
|
||||
// Also fire text changes if the node being created could affect the text in an nsIAccessibleText parent.
|
||||
// When a node is being made visible or is inserted, the text in an ancestor hyper text will gain characters
|
||||
// At this point we now have the frame and accessible for this node if there is one. That is why we
|
||||
// wait to fire this here, instead of in InvalidateCacheSubtree(), where we wouldn't be able to calculate
|
||||
// the offset, length and text for the text change.
|
||||
if (domNode && domNode != mDOMNode) {
|
||||
nsRefPtr<nsAccEvent> textChangeEvent =
|
||||
CreateTextChangeEventForNode(containerAccessible, domNode, accessible,
|
||||
PR_TRUE, PR_TRUE, isFromUserInput);
|
||||
if (textChangeEvent) {
|
||||
// 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
|
||||
nsEventShell::FireEvent(textChangeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
|
||||
// Fire show/create events for this node or first accessible descendants of it
|
||||
FireShowHideEvents(domNode, PR_FALSE, eventType, eNormalEvent, isAsync,
|
||||
isFromUserInput);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> containerAccessible;
|
||||
if (accessible)
|
||||
accessible->GetParent(getter_AddRefs(containerAccessible));
|
||||
if (accessible) {
|
||||
if (eventType == nsIAccessibleEvent::EVENT_INTERNAL_LOAD) {
|
||||
nsRefPtr<nsDocAccessible> docAcc =
|
||||
nsAccUtils::QueryAccessibleDocument(accessible);
|
||||
NS_ASSERTION(docAcc, "No doc accessible for doc load event");
|
||||
|
||||
if (!containerAccessible) {
|
||||
GetAccessibleInParentChain(domNode, PR_TRUE,
|
||||
getter_AddRefs(containerAccessible));
|
||||
if (!containerAccessible)
|
||||
containerAccessible = this;
|
||||
}
|
||||
|
||||
if (isAsync) {
|
||||
// For asynch show, delayed invalidatation of parent's children
|
||||
nsRefPtr<nsAccessible> containerAcc =
|
||||
nsAccUtils::QueryAccessible(containerAccessible);
|
||||
if (containerAcc)
|
||||
containerAcc->InvalidateChildren();
|
||||
|
||||
// Some show events in the subtree may have been removed to
|
||||
// avoid firing redundant events. But, we still need to make sure any
|
||||
// accessibles parenting those shown nodes lose their child references.
|
||||
InvalidateChildrenInSubtree(domNode);
|
||||
}
|
||||
|
||||
// Also fire text changes if the node being created could affect the text in an nsIAccessibleText parent.
|
||||
// When a node is being made visible or is inserted, the text in an ancestor hyper text will gain characters
|
||||
// At this point we now have the frame and accessible for this node if there is one. That is why we
|
||||
// wait to fire this here, instead of in InvalidateCacheSubtree(), where we wouldn't be able to calculate
|
||||
// the offset, length and text for the text change.
|
||||
if (domNode && domNode != mDOMNode) {
|
||||
nsCOMPtr<nsIAccessibleEvent> textChangeEvent =
|
||||
CreateTextChangeEventForNode(containerAccessible, domNode, accessible, PR_TRUE, PR_TRUE);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Fire show/create events for this node or first accessible descendants of it
|
||||
FireShowHideEvents(domNode, PR_FALSE, eventType, eNormalEvent, isAsync,
|
||||
isFromUserInput);
|
||||
continue;
|
||||
if (docAcc)
|
||||
docAcc->FireDocLoadEvents(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
|
||||
}
|
||||
|
||||
if (accessible) {
|
||||
if (eventType == nsIAccessibleEvent::EVENT_INTERNAL_LOAD) {
|
||||
nsRefPtr<nsDocAccessible> docAcc =
|
||||
nsAccUtils::QueryAccessibleDocument(accessible);
|
||||
NS_ASSERTION(docAcc, "No doc accessible for doc load event");
|
||||
|
||||
if (docAcc)
|
||||
docAcc->FireDocLoadEvents(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
|
||||
}
|
||||
else if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
|
||||
nsCOMPtr<nsIAccessibleText> accessibleText = do_QueryInterface(accessible);
|
||||
PRInt32 caretOffset;
|
||||
if (accessibleText && NS_SUCCEEDED(accessibleText->GetCaretOffset(&caretOffset))) {
|
||||
else if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
|
||||
nsCOMPtr<nsIAccessibleText> accessibleText = do_QueryInterface(accessible);
|
||||
PRInt32 caretOffset;
|
||||
if (accessibleText && NS_SUCCEEDED(accessibleText->GetCaretOffset(&caretOffset))) {
|
||||
#ifdef DEBUG_A11Y
|
||||
PRUnichar chAtOffset;
|
||||
accessibleText->GetCharacterAtOffset(caretOffset, &chAtOffset);
|
||||
printf("\nCaret moved to %d with char %c", caretOffset, chAtOffset);
|
||||
PRUnichar chAtOffset;
|
||||
accessibleText->GetCharacterAtOffset(caretOffset, &chAtOffset);
|
||||
printf("\nCaret moved to %d with char %c", caretOffset, chAtOffset);
|
||||
#endif
|
||||
#ifdef DEBUG_CARET
|
||||
// Test caret line # -- fire an EVENT_ALERT on the focused node so we can watch the
|
||||
// line-number object attribute on it
|
||||
nsCOMPtr<nsIAccessible> accForFocus;
|
||||
GetAccService()->GetAccessibleFor(gLastFocusedNode, getter_AddRefs(accForFocus));
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_ALERT, accForFocus);
|
||||
// Test caret line # -- fire an EVENT_ALERT on the focused node so we can watch the
|
||||
// line-number object attribute on it
|
||||
nsCOMPtr<nsIAccessible> accForFocus;
|
||||
GetAccService()->GetAccessibleFor(gLastFocusedNode, getter_AddRefs(accForFocus));
|
||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_ALERT, accForFocus);
|
||||
#endif
|
||||
nsCOMPtr<nsIAccessibleEvent> caretMoveEvent =
|
||||
new nsAccCaretMoveEvent(accessible, caretOffset);
|
||||
if (!caretMoveEvent)
|
||||
break; // Out of memory, break out to release kung fu death grip
|
||||
nsRefPtr<nsAccEvent> caretMoveEvent =
|
||||
new nsAccCaretMoveEvent(accessible, caretOffset);
|
||||
if (!caretMoveEvent)
|
||||
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,
|
||||
accessible, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (eventType == nsIAccessibleEvent::EVENT_REORDER) {
|
||||
// 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);
|
||||
if (reorderEvent->IsUnconditionalEvent() ||
|
||||
reorderEvent->HasAccessibleInReasonSubtree()) {
|
||||
nsAccEvent::PrepareForEvent(accessibleEvent);
|
||||
FireAccessibleEvent(accessibleEvent);
|
||||
PRInt32 selectionCount;
|
||||
accessibleText->GetSelectionCount(&selectionCount);
|
||||
if (selectionCount) { // There's a selection so fire selection change as well
|
||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED,
|
||||
accessible, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (eventType == nsIAccessibleEvent::EVENT_REORDER) {
|
||||
// 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(aEvent);
|
||||
if (reorderEvent->IsUnconditionalEvent() ||
|
||||
reorderEvent->HasAccessibleInReasonSubtree()) {
|
||||
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);
|
||||
// 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));
|
||||
if (hidingNode) {
|
||||
RefreshNodes(hidingNode); // Will this bite us with asynch events
|
||||
}
|
||||
}
|
||||
else {
|
||||
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;
|
||||
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,16 +1808,15 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode)
|
|||
if (!popup) {
|
||||
// Popup elements already fire these via DOMMenuInactive
|
||||
// handling in nsRootAccessible::HandleEvent
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
|
||||
accessible);
|
||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
|
||||
accessible);
|
||||
}
|
||||
}
|
||||
nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(accessible);
|
||||
|
||||
// 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.
|
||||
|
@ -239,19 +228,26 @@ protected:
|
|||
CharacterDataChangeInfo* aInfo,
|
||||
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)
|
||||
*/
|
||||
already_AddRefed<nsIAccessibleEvent>
|
||||
/**
|
||||
* 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<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.
|
||||
|
@ -265,19 +261,19 @@ protected:
|
|||
* Fire show/hide events for either the current node if it has an accessible,
|
||||
* or the first-line accessible descendants of the given node.
|
||||
*
|
||||
* @param aDOMNode [in] the given node
|
||||
* @param aAvoidOnThisNode [in] call with PR_TRUE the first time to
|
||||
* prevent event firing on root node for change
|
||||
* @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 aDOMNode [in] the given node
|
||||
* @param aAvoidOnThisNode [in] call with PR_TRUE the first time to
|
||||
* prevent event firing on root node for change
|
||||
* @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 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();
|
||||
}
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
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,
|
||||
accessible);
|
||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
|
||||
accessible);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SELECTION,
|
||||
treeItemAccessible);
|
||||
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,15 +811,15 @@ 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,
|
||||
accessible);
|
||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
|
||||
accessible);
|
||||
}
|
||||
}
|
||||
else if (eventType.EqualsLiteral("DOMMenuItemActive")) {
|
||||
|
@ -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,8 +899,8 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
}
|
||||
#ifdef DEBUG
|
||||
else if (eventType.EqualsLiteral("mouseover")) {
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START,
|
||||
accessible);
|
||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START,
|
||||
accessible);
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
|
@ -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,
|
||||
aAccessible);
|
||||
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);
|
||||
|
@ -95,20 +94,25 @@ public:
|
|||
// nsRootAccessible
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
PRBool FireAccessibleFocusEvent(nsIAccessible *aFocusAccessible,
|
||||
nsIDOMNode *aFocusNode,
|
||||
nsIDOMEvent *aFocusEvent,
|
||||
PRBool aForceEvent = PR_FALSE,
|
||||
PRBool aIsAsynch = PR_FALSE);
|
||||
/**
|
||||
* Fire an accessible focus event for the current focusAccssible
|
||||
* and attach a new selection listener, if necessary.
|
||||
*
|
||||
* @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,
|
||||
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:
|
||||
protected:
|
||||
NS_DECL_RUNNABLEMETHOD(nsRootAccessible, FireCurrentFocusEvent)
|
||||
|
||||
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();
|
||||
}
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
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();
|
||||
}
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
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();
|
||||
}
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
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,8 +811,8 @@ void nsHTMLSelectOptionAccessible::SelectionChangedIfOption(nsIContent *aPossibl
|
|||
if (!optionAccessible)
|
||||
return;
|
||||
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
|
||||
multiSelect);
|
||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
|
||||
multiSelect);
|
||||
|
||||
PRUint32 state = nsAccUtils::State(optionAccessible);
|
||||
PRUint32 eventType;
|
||||
|
@ -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
|
||||
|
@ -105,15 +105,13 @@ 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (description.IsEmpty())
|
||||
xpAccessible->GetDescription(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;
|
||||
|
||||
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;
|
||||
|
||||
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();
|
||||
}
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
if (aIndex != eAction_Click)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
DoCommand();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -776,26 +779,26 @@ 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
|
||||
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)
|
||||
posInSet = setSize; // we've found our button
|
||||
}
|
||||
sibling->GetNextSibling(getter_AddRefs(tempSibling));
|
||||
sibling.swap(tempSibling);
|
||||
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 (child == this)
|
||||
posInSet = setSize; // we've found our button
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,18 +336,17 @@ 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) {
|
||||
*aState |= nsIAccessibleStates::STATE_SELECTED;
|
||||
|
||||
|
||||
// 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,9 +1188,9 @@ nsXULTreeItemAccessibleBase::IsExpandable()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsXULTreeItemAccessible::
|
||||
nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
|
||||
nsIAccessible *aParent, nsITreeBoxObject *aTree,
|
||||
nsITreeView *aTreeView, PRInt32 aRow) :
|
||||
nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
|
||||
nsAccessible *aParent, nsITreeBoxObject *aTree,
|
||||
nsITreeView *aTreeView, PRInt32 aRow) :
|
||||
nsXULTreeItemAccessibleBase(aDOMNode, aShell, aParent, aTree, aTreeView, aRow)
|
||||
{
|
||||
mColumn = nsCoreUtils::GetFirstSensibleColumn(mTree);
|
||||
|
@ -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
|
||||
|
@ -35,29 +36,30 @@
|
|||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
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">
|
||||
©rightInfo1;<label
|
||||
class="text-link" href="&licenseLink;"
|
||||
>&licenseLinkText;</label>©rightInfo2;
|
||||
&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"/>
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче