Bug 754830 - calculate link states separately, r=tbsaunde

This commit is contained in:
Alexander Surkov 2012-05-17 18:37:37 +09:00
parent 1340fe289b
commit 00c4cda6a1
21 changed files with 118 additions and 70 deletions

View File

@ -746,13 +746,21 @@ nsAccessible::NativeState()
if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
state |= states::HASPOPUP;
// Add 'linked' state for simple xlink.
if (nsCoreUtils::IsXLink(mContent))
state |= states::LINKED;
// Bypass the link states specialization for non links.
if (!mRoleMapEntry || mRoleMapEntry->roleRule == kUseNativeRole ||
mRoleMapEntry->role == roles::LINK)
state |= NativeLinkState();
return state;
}
PRUint64
nsAccessible::NativeLinkState() const
{
// Expose linked state for simple xlink.
return nsCoreUtils::IsXLink(mContent) ? states::LINKED : 0;
}
/* readonly attribute boolean focusedChild; */
NS_IMETHODIMP
nsAccessible::GetFocusedChild(nsIAccessible** aChild)
@ -1618,7 +1626,7 @@ nsAccessible::State()
}
void
nsAccessible::ApplyARIAState(PRUint64* aState)
nsAccessible::ApplyARIAState(PRUint64* aState) const
{
if (!mContent->IsElement())
return;

View File

@ -185,7 +185,7 @@ public:
*
* @param [in/out] where to fill the states into.
*/
virtual void ApplyARIAState(PRUint64* aState);
virtual void ApplyARIAState(PRUint64* aState) const;
/**
* Returns the accessible name provided by native markup. It doesn't take
@ -227,12 +227,27 @@ public:
*/
virtual PRUint64 State();
/**
* Return link states present on the accessible.
*/
PRUint64 LinkState() const
{
PRUint64 state = NativeLinkState();
ApplyARIAState(&state);
return state;
}
/**
* Return the states of accessible, not taking into account ARIA states.
* Use State() to get complete set of states.
*/
virtual PRUint64 NativeState();
/**
* Return native link states present on the accessible.
*/
virtual PRUint64 NativeLinkState() const;
/**
* Return bit set of invisible and offscreen states.
*/

View File

@ -113,16 +113,12 @@ nsLinkableAccessible::TakeFocus()
}
PRUint64
nsLinkableAccessible::NativeState()
nsLinkableAccessible::NativeLinkState() const
{
PRUint64 states = nsAccessibleWrap::NativeState();
if (mIsLink) {
states |= states::LINKED;
if (mActionAcc->State() & states::TRAVERSED)
states |= states::TRAVERSED;
}
if (mIsLink)
return states::LINKED | (mActionAcc->LinkState() & states::TRAVERSED);
return states;
return 0;
}
void
@ -235,11 +231,10 @@ nsLinkableAccessible::BindToParent(nsAccessible* aParent,
// is traversed.
nsAccessible* walkUpAcc = this;
while ((walkUpAcc = walkUpAcc->Parent()) && !walkUpAcc->IsDoc()) {
if (walkUpAcc->Role() == roles::LINK &&
walkUpAcc->State() & states::LINKED) {
mIsLink = true;
mActionAcc = walkUpAcc;
return;
if (walkUpAcc->LinkState() & states::LINKED) {
mIsLink = true;
mActionAcc = walkUpAcc;
return;
}
if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {

View File

@ -96,7 +96,7 @@ public:
// nsAccessible
virtual void Value(nsString& aValue);
virtual PRUint64 NativeState();
virtual PRUint64 NativeLinkState() const;
// ActionAccessible
virtual PRUint8 ActionCount();

View File

@ -341,7 +341,7 @@ nsDocAccessible::NativeState()
// nsAccessible public method
void
nsDocAccessible::ApplyARIAState(PRUint64* aState)
nsDocAccessible::ApplyARIAState(PRUint64* aState) const
{
// Combine with states from outer doc
//

View File

@ -115,7 +115,7 @@ public:
virtual nsAccessible* FocusedChild();
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
virtual void ApplyARIAState(PRUint64* aState);
virtual void ApplyARIAState(PRUint64* aState) const;
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);

View File

@ -1045,7 +1045,7 @@ ARIAGridCellAccessible::IsSelected(bool* aIsSelected)
// nsAccessible
void
ARIAGridCellAccessible::ApplyARIAState(PRUint64* aState)
ARIAGridCellAccessible::ApplyARIAState(PRUint64* aState) const
{
nsHyperTextAccessibleWrap::ApplyARIAState(aState);

View File

@ -138,7 +138,7 @@ public:
NS_DECL_NSIACCESSIBLETABLECELL
// nsAccessible
virtual void ApplyARIAState(PRUint64* aState);
virtual void ApplyARIAState(PRUint64* aState) const;
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
};

View File

@ -333,7 +333,7 @@ ApplicationAccessible::IsPrimaryForNode() const
// nsAccessible public methods
void
ApplicationAccessible::ApplyARIAState(PRUint64* aState)
ApplicationAccessible::ApplyARIAState(PRUint64* aState) const
{
}

View File

@ -104,7 +104,7 @@ public:
// nsAccessible
virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
virtual void ApplyARIAState(PRUint64* aState);
virtual void ApplyARIAState(PRUint64* aState) const;
virtual void Description(nsString& aDescription);
virtual void Value(nsString& aValue);
virtual mozilla::a11y::role NativeRole();

View File

@ -437,7 +437,7 @@ HTMLTextFieldAccessible::Value(nsString& aValue)
}
void
HTMLTextFieldAccessible::ApplyARIAState(PRUint64* aState)
HTMLTextFieldAccessible::ApplyARIAState(PRUint64* aState) const
{
nsHyperTextAccessibleWrap::ApplyARIAState(aState);

View File

@ -145,7 +145,7 @@ public:
// nsAccessible
virtual void Value(nsString& aValue);
virtual void ApplyARIAState(PRUint64* aState);
virtual void ApplyARIAState(PRUint64* aState) const;
virtual nsresult GetNameInternal(nsAString& aName);
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 State();

View File

@ -231,19 +231,6 @@ nsHTMLAreaAccessible::IsPrimaryForNode() const
////////////////////////////////////////////////////////////////////////////////
// nsHTMLAreaAccessible: nsAccessible public
PRUint64
nsHTMLAreaAccessible::NativeState()
{
// Bypass the link states specialization for non links.
if (mRoleMapEntry &&
mRoleMapEntry->role != roles::NOTHING &&
mRoleMapEntry->role != roles::LINK) {
return nsAccessible::NativeState();
}
return nsHTMLLinkAccessible::NativeState();
}
nsAccessible*
nsHTMLAreaAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
EWhichChildAtPoint aWhichChild)

View File

@ -102,7 +102,6 @@ public:
// nsAccessible
virtual void Description(nsString& aDescription);
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint64 NativeState();
virtual nsAccessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
EWhichChildAtPoint aWhichChild);
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);

View File

@ -86,24 +86,23 @@ nsHTMLLinkAccessible::NativeState()
states |= states::SELECTABLE;
}
nsEventStates state = mContent->AsElement()->State();
if (state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED |
NS_EVENT_STATE_UNVISITED)) {
states |= states::LINKED;
return states;
}
if (state.HasState(NS_EVENT_STATE_VISITED))
states |= states::TRAVERSED;
PRUint64
nsHTMLLinkAccessible::NativeLinkState() const
{
nsEventStates eventState = mContent->AsElement()->State();
if (eventState.HasState(NS_EVENT_STATE_UNVISITED))
return states::LINKED;
return states;
}
if (eventState.HasState(NS_EVENT_STATE_VISITED))
return states::LINKED | states::TRAVERSED;
// This is a either named anchor (a link with also a name attribute) or
// it doesn't have any attributes. Check if 'click' event handler is
// registered, otherwise bail out.
if (nsCoreUtils::HasClickListener(mContent))
states |= states::LINKED;
return states;
return nsCoreUtils::HasClickListener(mContent) ? states::LINKED : 0;
}
void

View File

@ -57,6 +57,7 @@ public:
virtual void Value(nsString& aValue);
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
virtual PRUint64 NativeLinkState() const;
// ActionAccessible
virtual PRUint8 ActionCount();

View File

@ -754,12 +754,11 @@ XULTextFieldAccessible::Value(nsString& aValue)
}
void
XULTextFieldAccessible::ApplyARIAState(PRUint64* aState)
XULTextFieldAccessible::ApplyARIAState(PRUint64* aState) const
{
nsHyperTextAccessibleWrap::ApplyARIAState(aState);
aria::MapToState(aria::eARIAAutoComplete, mContent->AsElement(), aState);
}
PRUint64

View File

@ -265,7 +265,7 @@ public:
// nsAccessible
virtual void Value(nsString& aValue);
virtual void ApplyARIAState(PRUint64* aState);
virtual void ApplyARIAState(PRUint64* aState) const;
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
virtual bool CanHaveAnonChildren();

View File

@ -178,9 +178,9 @@ nsXULLinkAccessible::NativeRole()
PRUint64
nsXULLinkAccessible::NativeState()
nsXULLinkAccessible::NativeLinkState() const
{
return nsHyperTextAccessible::NativeState() | states::LINKED;
return states::LINKED;
}
PRUint8

View File

@ -88,7 +88,7 @@ public:
virtual void Value(nsString& aValue);
virtual nsresult GetNameInternal(nsAString& aName);
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
virtual PRUint64 NativeLinkState() const;
// ActionAccessible
virtual PRUint8 ActionCount();

View File

@ -8,6 +8,8 @@
<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="../common.js"></script>
@ -15,19 +17,53 @@
src="../role.js"></script>
<script type="application/javascript"
src="../states.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript">
function doTest()
{
testStates("link1", STATE_LINKED);
testStates("link2", STATE_LINKED);
testStates("link3", STATE_LINKED);
testStates("link4", STATE_LINKED);
testStates("link5", 0, 0, STATE_LINKED);
// a@href and its text node
testStates("link_href", STATE_LINKED);
testStates(getAccessible("link_href").firstChild, STATE_LINKED);
SimpleTest.finish();
// a@onclick
testStates("link_click", STATE_LINKED);
// a@onmousedown
testStates("link_mousedown", STATE_LINKED);
// a@onmouseup
testStates("link_mouseup", STATE_LINKED);
// a@role="link"
testStates("link_arialink", STATE_LINKED);
// a@role="button"
testStates("link_ariabutton", 0, 0, STATE_LINKED);
// a (no @href, no click event listener)
testStates("link_notlink", 0, 0, STATE_LINKED);
// a: traversal state
testStates("link_traversed", 0, 0, STATE_TRAVERSED);
registerA11yEventListener(EVENT_DOCUMENT_LOAD_COMPLETE,
traversedLinkTester);
synthesizeMouse(getNode("link_traversed"), 1, 1, { shiftKey: true });
}
var traversedLinkTester = {
handleEvent: function traversedLinkTester_handleEvent(aEvent) {
unregisterA11yEventListener(EVENT_DOCUMENT_LOAD_COMPLETE,
traversedLinkTester);
aEvent.accessible.rootDocument.window.close();
testStates("link_traversed", STATE_TRAVERSED);
SimpleTest.finish();
}
};
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
@ -41,16 +77,25 @@
title="Expose click action if mouseup and mousedown are registered">
Mozilla Bug 423409
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=754830"
title="Calculate link states separately">
Mozilla Bug 754830
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<a id="link1" href="http://mozilla.org">link</a>
<a id="link2" onclick="">link</a>
<a id="link3" onmousedown="">link</a>
<a id="link4" onmouseup="">link</a>
<a id="link5">not link</a>
<a id="link_href" href="http://mozilla.org">link</a>
<a id="link_click" onclick="">link</a>
<a id="link_mousedown" onmousedown="">link</a>
<a id="link_mouseup" onmouseup="">link</a>
<a id="link_arialink" role="link">aria link</a>
<a id="link_ariabutton" role="button">aria button</a>
<a id="link_notlink">not link</a>
<a id="link_traversed" href="http://www.example.com" target="_top">example.com</a>
</body>
</html>