Bug 540285 - stop explicit usage of nsAccEvent::prepareEvent, r=marcoz, davidb, ginn

--HG--
rename : accessible/tests/mochitest/Makefile.in => accessible/tests/mochitest/events/Makefile.in
rename : accessible/tests/mochitest/test_events_caretmove.html => accessible/tests/mochitest/events/test_caretmove.html
rename : accessible/tests/mochitest/test_events_coalescence.html => accessible/tests/mochitest/events/test_coalescence.html
rename : accessible/tests/mochitest/test_events_doc.html => accessible/tests/mochitest/events/test_doc.html
rename : accessible/tests/mochitest/test_events_draganddrop.html => accessible/tests/mochitest/events/test_dragndrop.html
rename : accessible/tests/mochitest/test_events_flush.html => accessible/tests/mochitest/events/test_flush.html
rename : accessible/tests/mochitest/test_events_focus.html => accessible/tests/mochitest/events/test_focus.html
rename : accessible/tests/mochitest/test_events_focus.xul => accessible/tests/mochitest/events/test_focus.xul
rename : accessible/tests/mochitest/test_events_focusdoc.html => accessible/tests/mochitest/events/test_focusdoc.html
rename : accessible/tests/mochitest/test_events_mutation.html => accessible/tests/mochitest/events/test_mutation.html
rename : accessible/tests/mochitest/test_events_scroll.xul => accessible/tests/mochitest/events/test_scroll.xul
rename : accessible/tests/mochitest/test_events_tree.xul => accessible/tests/mochitest/events/test_tree.xul
rename : accessible/tests/mochitest/test_events_valuechange.html => accessible/tests/mochitest/events/test_valuechange.html
This commit is contained in:
Alexander Surkov 2010-01-20 19:16:32 +08:00
parent dc9b88f357
commit 55e0e73cc8
26 changed files with 434 additions and 271 deletions

View File

@ -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)
{
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)
{
@ -265,6 +169,9 @@ nsAccEvent::GetAccessibleDocument(nsIAccessibleDocument **aDocAccessible)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent: protected methods
already_AddRefed<nsIAccessible>
nsAccEvent::GetAccessibleByNode()
{
@ -305,6 +212,51 @@ nsAccEvent::GetAccessibleByNode()
return accessible.forget();
}
void
nsAccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
{
nsCOMPtr<nsIDOMNode> targetNode;
GetDOMNode(getter_AddRefs(targetNode));
#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 (mAccessible != static_cast<nsIAccessible*>(applicationAcc.get()))
NS_ASSERTION(targetNode, "There should always be a DOM node for an event");
}
#endif
if (aIsFromUserInput != eAutoDetect) {
mIsFromUserInput = aIsFromUserInput == eFromUserInput ? PR_TRUE : PR_FALSE;
return;
}
if (!targetNode)
return;
nsCOMPtr<nsIPresShell> presShell = nsCoreUtils::GetPresShellFor(targetNode);
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;
}
mIsFromUserInput = esm->IsHandlingUserInputExternal();
}
////////////////////////////////////////////////////////////////////////////////
// nsAccEvent: static methods
/* static */
void
nsAccEvent::ApplyEventRules(nsTArray<nsRefPtr<nsAccEvent> > &aEventsToFire)
@ -459,6 +411,7 @@ nsAccEvent::CoalesceReorderEventsFromSameTree(nsAccEvent *aAccEvent,
////////////////////////////////////////////////////////////////////////////////
// nsAccReorderEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccReorderEvent, nsAccEvent,
nsAccReorderEvent)
@ -468,7 +421,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 +447,7 @@ nsAccReorderEvent::HasAccessibleInReasonSubtree()
////////////////////////////////////////////////////////////////////////////////
// nsAccStateChangeEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
nsIAccessibleStateChangeEvent)
@ -556,16 +510,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 +562,10 @@ nsAccTextChangeEvent::GetModifiedText(nsAString& aModifiedText)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccCaretMoveEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccCaretMoveEvent, nsAccEvent,
nsIAccessibleCaretMoveEvent)
@ -632,7 +592,10 @@ nsAccCaretMoveEvent::GetCaretOffset(PRInt32* aCaretOffset)
return NS_OK;
}
// nsAccTableChangeEvent
////////////////////////////////////////////////////////////////////////////////
// nsAccTableChangeEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccTableChangeEvent, nsAccEvent,
nsIAccessibleTableChangeEvent)

View File

@ -54,6 +54,17 @@
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 \
{ /* 39bde096-317e-4294-b23b-4af4a9b283f7 */ \
0x39bde096, \
@ -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() {}
@ -107,13 +120,18 @@ public:
PRBool IsFromUserInput() const { return mIsFromUserInput; }
nsIAccessible* GetAccessible() const { return mAccessible; }
static void GetLastEventAttributes(nsIDOMNode *aNode,
nsIPersistentProperties *aAttributes);
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;
@ -123,33 +141,7 @@ protected:
nsCOMPtr<nsIDOMNode> mDOMNode;
nsCOMPtr<nsIAccessibleDocument> mDocAccessible;
private:
static PRBool gLastEventFromUserInput;
static nsIDOMNode* gLastEventNodeWeak;
public:
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
@ -259,7 +251,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

View File

@ -201,6 +201,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")

View File

@ -1540,7 +1540,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>

View File

@ -1085,11 +1085,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 ||
@ -1450,7 +1445,7 @@ nsDocAccessible::FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldA
// Dependent value change event for text changes in textfields
nsCOMPtr<nsIAccessibleEvent> valueChangeEvent =
new nsAccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aPossibleTextFieldAccessible,
PR_FALSE, nsAccEvent::eRemoveDupes);
PR_FALSE, eAutoDetect, nsAccEvent::eRemoveDupes);
FireDelayedAccessibleEvent(valueChangeEvent );
}
@ -1520,7 +1515,8 @@ nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessibl
nsIDOMNode *aChangeNode,
nsIAccessible *aAccessibleForChangeNode,
PRBool aIsInserting,
PRBool aIsAsynch)
PRBool aIsAsynch,
EIsFromUserInput aIsFromUserInput)
{
nsRefPtr<nsHyperTextAccessible> textAccessible;
aContainerAccessible->QueryInterface(NS_GET_IID(nsHyperTextAccessible),
@ -1587,7 +1583,7 @@ nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessibl
nsAccEvent *event =
new nsAccTextChangeEvent(aContainerAccessible, offset, length, aIsInserting,
aIsAsynch);
aIsAsynch, aIsFromUserInput);
NS_IF_ADDREF(event);
return event;
@ -1598,10 +1594,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);
new nsAccEvent(aEventType, aDOMNode, aIsAsynch, aIsFromUserInput, aAllowDupes);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
return FireDelayedAccessibleEvent(event);
@ -1694,7 +1691,9 @@ nsDocAccessible::FlushPendingEvents()
accEvent->GetDOMNode(getter_AddRefs(domNode));
PRUint32 eventType = accEvent->GetEventType();
PRBool isFromUserInput = accEvent->IsFromUserInput();
EIsFromUserInput isFromUserInput =
accEvent->IsFromUserInput() ? eFromUserInput : eNoUserInput;
PRBool isAsync = accEvent->IsAsync();
if (domNode == gLastFocusedNode && isAsync &&
@ -1755,9 +1754,9 @@ nsDocAccessible::FlushPendingEvents()
// the offset, length and text for the text change.
if (domNode && domNode != mDOMNode) {
nsRefPtr<nsAccEvent> textChangeEvent =
CreateTextChangeEventForNode(containerAccessible, domNode, accessible, PR_TRUE, PR_TRUE);
CreateTextChangeEventForNode(containerAccessible, domNode, accessible,
PR_TRUE, PR_TRUE, isFromUserInput);
if (textChangeEvent) {
nsAccEvent::PrepareForEvent(textChangeEvent, isFromUserInput);
// XXX Queue them up and merge the text change events
// XXX We need a way to ignore SplitNode and JoinNode() when they
// do not affect the text within the hypertext
@ -1818,15 +1817,12 @@ nsDocAccessible::FlushPendingEvents()
nsCOMPtr<nsAccReorderEvent> reorderEvent = do_QueryInterface(accEvent);
if (reorderEvent->IsUnconditionalEvent() ||
reorderEvent->HasAccessibleInReasonSubtree()) {
nsAccEvent::PrepareForEvent(accEvent);
nsEventShell::FireEvent(accEvent);
}
}
else {
// The input state was previously stored with the nsIAccessibleEvent,
// so use that state now when firing the event
nsAccEvent::PrepareForEvent(accEvent);
nsEventShell::FireEvent(accEvent);
// Post event processing
if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
// Shutdown nsIAccessNode's or nsIAccessibles for any DOM nodes in
@ -1853,9 +1849,6 @@ nsDocAccessible::FlushPendingEvents()
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.
}
@ -2105,7 +2098,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
@ -2253,7 +2246,7 @@ nsDocAccessible::FireShowHideEvents(nsIDOMNode *aDOMNode,
PRUint32 aEventType,
EEventFiringType aDelayedOrNormal,
PRBool aIsAsyncChange,
PRBool aForceIsFromUserInput)
EIsFromUserInput aIsFromUserInput)
{
NS_ENSURE_ARG(aDOMNode);
@ -2275,14 +2268,10 @@ nsDocAccessible::FireShowHideEvents(nsIDOMNode *aDOMNode,
// Found an accessible, so fire the show/hide on it and don't look further
// into this subtree.
nsRefPtr<nsAccEvent> event =
new nsAccEvent(aEventType, accessible, aIsAsyncChange,
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);
@ -2298,7 +2287,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);
}

View File

@ -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 } \
{ /* 11d54d4f-f135-4b1b-80e4-6425a64f703c */ \
0x11d54d4f, \
0xf135, \
0x4b1b, \
{ 0x80, 0xe4, 0x64, 0x25, 0xa6, 0x4f, 0x70, 0x3c } \
}
class nsDocAccessible : public nsHyperTextAccessibleWrap,
@ -127,7 +127,8 @@ 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.
@ -236,19 +237,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<nsAccEvent>
/**
* 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.
@ -262,19 +270,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

View File

@ -40,6 +40,10 @@
#include "nsAccessible.h"
////////////////////////////////////////////////////////////////////////////////
// nsEventShell
////////////////////////////////////////////////////////////////////////////////
void
nsEventShell::FireEvent(nsAccEvent *aEvent)
{
@ -50,17 +54,44 @@ nsEventShell::FireEvent(nsAccEvent *aEvent)
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)
PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput)
{
NS_ENSURE_TRUE(aAccessible,);
nsRefPtr<nsAccEvent> event = new nsAccEvent(aEventType, aAccessible,
aIsAsynch);
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;

View File

@ -59,7 +59,22 @@ public:
* this event is fired owing to is async.
*/
static void FireEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
PRBool aIsAsynch = PR_FALSE);
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;
};
#endif

View File

@ -393,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));
@ -480,7 +481,8 @@ nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
menuBarAccessNode->GetDOMNode(getter_AddRefs(mCurrentARIAMenubar));
if (mCurrentARIAMenubar) {
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_START,
menuBarAccessible);
menuBarAccessible, PR_FALSE,
aIsFromUserInput);
}
}
}
@ -489,7 +491,7 @@ nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
else if (mCurrentARIAMenubar) {
nsCOMPtr<nsIAccessibleEvent> menuEndEvent =
new nsAccEvent(nsIAccessibleEvent::EVENT_MENU_END, mCurrentARIAMenubar,
PR_FALSE, nsAccEvent::eAllowDupes);
PR_FALSE, aIsFromUserInput, nsAccEvent::eAllowDupes);
if (menuEndEvent) {
FireDelayedAccessibleEvent(menuEndEvent);
}
@ -535,7 +537,7 @@ nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_FOCUS,
finalFocusNode, nsAccEvent::eRemoveDupes,
aIsAsynch);
aIsAsynch, aIsFromUserInput);
return PR_TRUE;
}
@ -879,19 +881,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);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_START,
accessible, PR_TRUE);
accessible, PR_TRUE, eFromUserInput);
}
else if (eventType.EqualsLiteral("DOMMenuBarInactive")) { // Always asynch, always from user input
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_END,
accessible, PR_TRUE);
accessible, PR_TRUE, eFromUserInput);
FireCurrentFocusEvent();
}
else if (eventType.EqualsLiteral("ValueChange")) {

View File

@ -54,11 +54,11 @@
#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;
@ -95,20 +95,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.

View File

@ -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 \

View File

@ -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);

View File

@ -0,0 +1,65 @@
#
# ***** 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 *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = accessible/events
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_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)

View File

@ -0,0 +1,81 @@
<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));
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>

View File

@ -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)));