Bug 740764 - Restrict object attributes inheritance through documents to ARIA attributes, r=tbsaunde

This commit is contained in:
Alexander Surkov 2012-10-19 16:15:23 +09:00
parent e51e7f1ce6
commit f910ee857d
32 changed files with 249 additions and 273 deletions

View File

@ -742,22 +742,20 @@ ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes)
AtkAttributeSet*
GetAttributeSet(Accessible* aAccessible)
{
nsCOMPtr<nsIPersistentProperties> attributes;
aAccessible->GetAttributes(getter_AddRefs(attributes));
if (attributes) {
// Deal with attributes that we only need to expose in ATK
if (aAccessible->State() & states::HASPOPUP) {
// There is no ATK state for haspopup, must use object attribute to expose the same info
nsAutoString oldValueUnused;
attributes->SetStringProperty(NS_LITERAL_CSTRING("haspopup"), NS_LITERAL_STRING("true"),
oldValueUnused);
}
return ConvertToAtkAttributeSet(attributes);
nsCOMPtr<nsIPersistentProperties> attributes = aAccessible->Attributes();
if (attributes) {
// There is no ATK state for haspopup, must use object attribute to expose
// the same info.
if (aAccessible->State() & states::HASPOPUP) {
nsAutoString unused;
attributes->SetStringProperty(NS_LITERAL_CSTRING("haspopup"),
NS_LITERAL_STRING("true"), unused);
}
return nullptr;
return ConvertToAtkAttributeSet(attributes);
}
return nullptr;
}
AtkAttributeSet *

View File

@ -92,7 +92,7 @@ const bool kUseNativeRole = false;
/**
* This mask indicates the attribute should not be exposed as an object
* attribute via the catch-all logic in Accessible::GetAttributes.
* attribute via the catch-all logic in Accessible::Attributes().
* This means it either isn't mean't to be exposed as an object attribute, or
* that it should, but is already handled in other code.
*/
@ -100,7 +100,7 @@ const uint8_t ATTR_BYPASSOBJ = 0x0001;
/**
* This mask indicates the attribute is expected to have an NMTOKEN or bool value.
* (See for example usage in Accessible::GetAttributes)
* (See for example usage in Accessible::Attributes())
*/
const uint8_t ATTR_VALTOKEN = 0x0010;

View File

@ -614,19 +614,16 @@ ARIAGridCellAccessible::ApplyARIAState(uint64_t* aState) const
*aState |= states::SELECTABLE | states::SELECTED;
}
nsresult
ARIAGridCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
already_AddRefed<nsIPersistentProperties>
ARIAGridCellAccessible::NativeAttributes()
{
if (IsDefunct())
return NS_ERROR_FAILURE;
nsresult rv = HyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPersistentProperties> attributes =
HyperTextAccessibleWrap::NativeAttributes();
// Expose "table-cell-index" attribute.
Accessible* thisRow = Row();
if (!thisRow)
return NS_OK;
return attributes.forget();
int32_t colIdx = 0, colCount = 0;
uint32_t childCount = thisRow->ChildCount();
@ -645,10 +642,9 @@ ARIAGridCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttribut
nsAutoString stringIdx;
stringIdx.AppendInt(rowIdx * colCount + colIdx);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
stringIdx);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tableCellIndex, stringIdx);
return NS_OK;
return attributes.forget();
}
void

View File

@ -116,7 +116,7 @@ public:
virtual TableCellAccessible* AsTableCell() { return this; }
virtual void Shutdown();
virtual void ApplyARIAState(uint64_t* aState) const;
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
protected:

View File

@ -1186,69 +1186,39 @@ Accessible::GetRole(uint32_t *aRole)
}
NS_IMETHODIMP
Accessible::GetAttributes(nsIPersistentProperties **aAttributes)
Accessible::GetAttributes(nsIPersistentProperties** aAttributes)
{
NS_ENSURE_ARG_POINTER(aAttributes); // In/out param. Created if necessary.
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nullptr;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPersistentProperties> attributes = *aAttributes;
if (!attributes) {
// Create only if an array wasn't already passed in
attributes = do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aAttributes = attributes);
}
nsresult rv = GetAttributesInternal(attributes);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPersistentProperties> attributes = Attributes();
attributes.swap(*aAttributes);
nsAutoString id;
nsAutoString oldValueUnused;
if (nsCoreUtils::GetID(mContent, id)) {
// Expose ID. If an <iframe id> exists override the one on the <body> of the source doc,
// because the specific instance is what makes the ID useful for scripts
attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, oldValueUnused);
}
nsAutoString xmlRoles;
return NS_OK;
}
already_AddRefed<nsIPersistentProperties>
Accessible::Attributes()
{
nsCOMPtr<nsIPersistentProperties> attributes = NativeAttributes();
if (!HasOwnContent() || !mContent->IsElement())
return attributes.forget();
// 'xml-roles' attribute coming from ARIA.
nsAutoString xmlRoles, unused;
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::role, xmlRoles)) {
attributes->SetStringProperty(NS_LITERAL_CSTRING("xml-roles"), xmlRoles, oldValueUnused);
attributes->SetStringProperty(NS_LITERAL_CSTRING("xml-roles"),
xmlRoles, unused);
}
if (HasNumericValue()) {
// We support values, so expose the string value as well, via the valuetext object attribute
// We test for the value interface because we don't want to expose traditional get_accValue()
// information such as URL's on links and documents, or text in an input
nsAutoString valuetext;
GetValue(valuetext);
attributes->SetStringProperty(NS_LITERAL_CSTRING("valuetext"), valuetext, oldValueUnused);
}
// Expose checkable object attribute if the accessible has checkable state
if (State() & states::CHECKABLE)
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::checkable, NS_LITERAL_STRING("true"));
// Expose 'explicit-name' attribute.
if (!nsTextEquivUtils::IsNameFromSubtreeAllowed(this) ||
Name(oldValueUnused) != eNameFromSubtree) {
attributes->SetStringProperty(NS_LITERAL_CSTRING("explicit-name"),
NS_LITERAL_STRING("true"), oldValueUnused);
}
// Group attributes (level/setsize/posinset)
GroupPos groupPos = GroupPosition();
nsAccUtils::SetAccGroupAttrs(attributes, groupPos.level,
groupPos.setSize, groupPos.posInSet);
// Expose object attributes from ARIA attributes.
aria::AttrIterator attribIter(mContent);
nsAutoString name, value;
while(attribIter.Next(name, value)) {
attributes->SetStringProperty(NS_ConvertUTF16toUTF8(name), value,
oldValueUnused);
}
while(attribIter.Next(name, value))
attributes->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused);
// If there is no aria-live attribute then expose default value of 'live'
// object attribute used for ARIA role of this accessible.
@ -1261,43 +1231,67 @@ Accessible::GetAttributes(nsIPersistentProperties **aAttributes)
}
}
return NS_OK;
return attributes.forget();
}
nsresult
Accessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
already_AddRefed<nsIPersistentProperties>
Accessible::NativeAttributes()
{
// If the accessible isn't primary for its node (such as list item bullet or
// xul tree item then don't calculate content based attributes.
nsCOMPtr<nsIPersistentProperties> attributes =
do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
nsAutoString unused;
// We support values, so expose the string value as well, via the valuetext
// object attribute. We test for the value interface because we don't want
// to expose traditional Value() information such as URL's on links and
// documents, or text in an input.
if (HasNumericValue()) {
nsAutoString valuetext;
GetValue(valuetext);
attributes->SetStringProperty(NS_LITERAL_CSTRING("valuetext"), valuetext,
unused);
}
// Expose checkable object attribute if the accessible has checkable state
if (State() & states::CHECKABLE) {
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::checkable,
NS_LITERAL_STRING("true"));
}
// Expose 'explicit-name' attribute.
if (!nsTextEquivUtils::IsNameFromSubtreeAllowed(this) ||
Name(unused) != eNameFromSubtree) {
attributes->SetStringProperty(NS_LITERAL_CSTRING("explicit-name"),
NS_LITERAL_STRING("true"), unused);
}
// Group attributes (level/setsize/posinset)
GroupPos groupPos = GroupPosition();
nsAccUtils::SetAccGroupAttrs(attributes, groupPos.level,
groupPos.setSize, groupPos.posInSet);
// If the accessible doesn't have own content (such as list item bullet or
// xul tree item) then don't calculate content based attributes.
if (!HasOwnContent())
return NS_OK;
return attributes.forget();
// Attributes set by this method will not be used to override attributes on a sub-document accessible
// when there is a <frame>/<iframe> element that spawned the sub-document
nsEventShell::GetEventAttributes(GetNode(), attributes);
nsEventShell::GetEventAttributes(GetNode(), 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>
nsAutoString _class;
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, _class))
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::_class, _class);
// Get container-foo computed live region properties based on the closest container with
// the live region attribute.
// Inner nodes override outer nodes within the same document --
// The inner nodes can be used to override live region behavior on more general outer nodes
// However, nodes in outer documents override nodes in inner documents:
// Outer doc author may want to override properties on a widget they used in an iframe
// Get container-foo computed live region properties based on the closest
// container with the live region attribute. Inner nodes override outer nodes
// within the same document. The inner nodes can be used to override live
// region behavior on more general outer nodes. However, nodes in outer
// documents override nodes in inner documents: outer doc author may want to
// override properties on a widget they used in an iframe.
nsIContent* startContent = mContent;
while (startContent) {
nsIDocument* doc = startContent->GetDocument();
nsIContent* rootContent = nsCoreUtils::GetRoleContent(doc);
if (!rootContent)
return NS_OK;
if (!doc)
break;
nsAccUtils::SetLiveContainerAttributes(aAttributes, startContent,
rootContent);
nsAccUtils::SetLiveContainerAttributes(attributes, startContent,
nsCoreUtils::GetRoleContent(doc));
// Allow ARIA live region markup from outer documents to override
nsCOMPtr<nsISupports> container = doc->GetContainer();
@ -1311,28 +1305,37 @@ Accessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
if (!sameTypeParent || sameTypeParent == docShellTreeItem)
break;
nsIDocument *parentDoc = doc->GetParentDocument();
nsIDocument* parentDoc = doc->GetParentDocument();
if (!parentDoc)
break;
startContent = parentDoc->FindContentForSubDocument(doc);
startContent = parentDoc->FindContentForSubDocument(doc);
}
if (!mContent->IsElement())
return NS_OK;
return attributes.forget();
nsAutoString id;
if (nsCoreUtils::GetID(mContent, id))
attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, unused);
// Expose class because it may have useful microformat information.
nsAutoString _class;
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, _class))
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::_class, _class);
// Expose tag.
nsAutoString tagName;
mContent->NodeInfo()->GetName(tagName);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tag, tagName);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tag, tagName);
// Expose draggable object attribute?
// Expose draggable object attribute.
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
if (htmlElement) {
bool draggable = false;
htmlElement->GetDraggable(&draggable);
if (draggable) {
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::draggable,
NS_LITERAL_STRING("true"));
}
}
@ -1340,7 +1343,7 @@ Accessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
// Don't calculate CSS-based object attributes when no frame (i.e.
// the accessible is unattached from the tree).
if (!mContent->GetPrimaryFrame())
return NS_OK;
return attributes.forget();
// CSS style based object attributes.
nsAutoString value;
@ -1348,33 +1351,33 @@ Accessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
// Expose 'display' attribute.
styleInfo.Display(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::display, value);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::display, value);
// Expose 'text-align' attribute.
styleInfo.TextAlign(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textAlign, value);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::textAlign, value);
// Expose 'text-indent' attribute.
styleInfo.TextIndent(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textIndent, value);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::textIndent, value);
// Expose 'margin-left' attribute.
styleInfo.MarginLeft(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginLeft, value);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::marginLeft, value);
// Expose 'margin-right' attribute.
styleInfo.MarginRight(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginRight, value);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::marginRight, value);
// Expose 'margin-top' attribute.
styleInfo.MarginTop(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginTop, value);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::marginTop, value);
// Expose 'margin-bottom' attribute.
styleInfo.MarginBottom(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::marginBottom, value);
return NS_OK;
return attributes.forget();
}
GroupPos

View File

@ -248,10 +248,9 @@ public:
virtual bool NativelyUnavailable() const;
/**
* Returns attributes for accessible without explicitly setted ARIA
* attributes.
* Return object attributes for the accessible.
*/
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual already_AddRefed<nsIPersistentProperties> Attributes();
/**
* Return group position (level, position in set and set size).
@ -712,6 +711,18 @@ public:
protected:
/**
* Return the accessible name provided by native markup. It doesn't take
* into account ARIA markup used to specify the name.
*/
virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName);
/**
* Return object attributes provided by native markup. It doesn't take into
* account ARIA.
*/
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes();
//////////////////////////////////////////////////////////////////////////////
// Initializing, cache and tree traverse methods
@ -801,12 +812,6 @@ protected:
//////////////////////////////////////////////////////////////////////////////
// Name helpers
/**
* Return the accessible name provided by native markup. It doesn't take
* into account ARIA markup used to specify the name.
*/
virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName);
/**
* Returns the accessible name specified by ARIA.
*/

View File

@ -110,12 +110,10 @@ ApplicationAccessible::State()
return IsDefunct() ? states::DEFUNCT : 0;
}
NS_IMETHODIMP
ApplicationAccessible::GetAttributes(nsIPersistentProperties** aAttributes)
already_AddRefed<nsIPersistentProperties>
ApplicationAccessible::NativeAttributes()
{
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nullptr;
return NS_OK;
return nullptr;
}
GroupPos

View File

@ -45,7 +45,6 @@ public:
NS_IMETHOD GetParent(nsIAccessible **aParent);
NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
NS_IMETHOD GetBounds(int32_t *aX, int32_t *aY,
int32_t *aWidth, int32_t *aHeight);
NS_IMETHOD SetSelected(bool aIsSelected);
@ -63,6 +62,7 @@ public:
virtual void Shutdown();
// Accessible
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
virtual GroupPos GroupPosition();
virtual ENameValueFlag Name(nsString& aName);
virtual void ApplyARIAState(uint64_t* aState) const;

View File

@ -339,17 +339,24 @@ DocAccessible::ApplyARIAState(uint64_t* aState) const
// Allow iframe/frame etc. to have final state override via ARIA
if (mParent)
mParent->ApplyARIAState(aState);
}
NS_IMETHODIMP
DocAccessible::GetAttributes(nsIPersistentProperties** aAttributes)
already_AddRefed<nsIPersistentProperties>
DocAccessible::Attributes()
{
Accessible::GetAttributes(aAttributes);
if (mParent) {
mParent->GetAttributes(aAttributes); // Add parent attributes (override inner)
}
return NS_OK;
nsCOMPtr<nsIPersistentProperties> attributes =
HyperTextAccessibleWrap::Attributes();
if (!mParent)
return attributes.forget();
// Override ARIA object attributes from outerdoc.
aria::AttrIterator attribIter(mParent->GetContent());
nsAutoString name, value, unused;
while(attribIter.Next(name, value))
attributes->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused);
return attributes.forget();
}
Accessible*

View File

@ -68,7 +68,6 @@ public:
virtual ~DocAccessible();
// nsIAccessible
NS_IMETHOD GetAttributes(nsIPersistentProperties** aAttributes);
NS_IMETHOD TakeFocus(void);
// nsIScrollPositionListener
@ -94,6 +93,7 @@ public:
virtual uint64_t NativeInteractiveState() const;
virtual bool NativelyUnavailable() const;
virtual void ApplyARIAState(uint64_t* aState) const;
virtual already_AddRefed<nsIPersistentProperties> Attributes();
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);

View File

@ -1135,21 +1135,19 @@ HyperTextAccessible::GetLevelInternal()
return AccessibleWrap::GetLevelInternal();
}
nsresult
HyperTextAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
already_AddRefed<nsIPersistentProperties>
HyperTextAccessible::NativeAttributes()
{
nsresult rv = AccessibleWrap::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPersistentProperties> attributes =
AccessibleWrap::NativeAttributes();
// Indicate when the current object uses block-level formatting
// via formatting: block
// XXX: 'formatting' attribute is deprecated and will be removed in Mozilla2,
// use 'display' attribute instead.
// 'formatting' attribute is deprecated, 'display' attribute should be
// instead.
nsIFrame *frame = GetFrame();
if (frame && frame->GetType() == nsGkAtoms::blockFrame) {
nsAutoString oldValueUnused;
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("formatting"), NS_LITERAL_STRING("block"),
oldValueUnused);
nsAutoString unused;
attributes->SetStringProperty(NS_LITERAL_CSTRING("formatting"),
NS_LITERAL_STRING("block"), unused);
}
if (FocusMgr()->IsFocused(this)) {
@ -1157,8 +1155,7 @@ HyperTextAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
if (lineNumber >= 1) {
nsAutoString strLineNumber;
strLineNumber.AppendInt(lineNumber);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::lineNumber,
strLineNumber);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::lineNumber, strLineNumber);
}
}
@ -1167,22 +1164,22 @@ HyperTextAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
// a landmark since it usually contains headings. We're not yet sure how the
// web will use html:footer but our best bet right now is as contentinfo.
if (mContent->Tag() == nsGkAtoms::nav)
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("navigation"));
else if (mContent->Tag() == nsGkAtoms::section)
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("region"));
else if (mContent->Tag() == nsGkAtoms::footer)
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("contentinfo"));
else if (mContent->Tag() == nsGkAtoms::aside)
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("complementary"));
else if (mContent->Tag() == nsGkAtoms::article)
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("article"));
return NS_OK;
return attributes.forget();
}
/*

View File

@ -51,7 +51,7 @@ public:
// Accessible
virtual int32_t GetLevelInternal();
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
virtual mozilla::a11y::role NativeRole();
virtual uint64_t NativeState();

View File

@ -169,21 +169,18 @@ ImageAccessible::GetImageSize(int32_t* aWidth, int32_t* aHeight)
}
// Accessible
nsresult
ImageAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
already_AddRefed<nsIPersistentProperties>
ImageAccessible::NativeAttributes()
{
if (IsDefunct())
return NS_ERROR_FAILURE;
nsresult rv = LinkableAccessible::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPersistentProperties> attributes =
LinkableAccessible::NativeAttributes();
nsAutoString src;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
if (!src.IsEmpty())
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::src, src);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::src, src);
return NS_OK;
return attributes.forget();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -38,7 +38,7 @@ public:
// Accessible
virtual a11y::role NativeRole();
virtual uint64_t NativeState();
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
// ActionAccessible
virtual uint8_t ActionCount();

View File

@ -67,19 +67,6 @@ OuterDocAccessible::ChildAtPoint(int32_t aX, int32_t aY,
return child;
}
nsresult
OuterDocAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
{
nsAutoString tag;
aAttributes->GetStringProperty(NS_LITERAL_CSTRING("tag"), tag);
if (!tag.IsEmpty()) {
// We're overriding the ARIA attributes on an sub document, but we don't want to
// override the other attributes
return NS_OK;
}
return Accessible::GetAttributesInternal(aAttributes);
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible

View File

@ -38,7 +38,6 @@ public:
// Accessible
virtual mozilla::a11y::role NativeRole();
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
EWhichChildAtPoint aWhichChild);

View File

@ -89,15 +89,14 @@ HTMLOutputAccessible::NativeRole()
return roles::SECTION;
}
nsresult
HTMLOutputAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
already_AddRefed<nsIPersistentProperties>
HTMLOutputAccessible::NativeAttributes()
{
nsresult rv = AccessibleWrap::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::live,
nsCOMPtr<nsIPersistentProperties> attributes =
AccessibleWrap::NativeAttributes();
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::live,
NS_LITERAL_STRING("polite"));
return NS_OK;
return attributes.forget();
}

View File

@ -77,7 +77,7 @@ public:
// Accessible
virtual a11y::role NativeRole();
virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
virtual Relation RelationByType(uint32_t aType);
};

View File

@ -675,16 +675,16 @@ HTMLFigureAccessible::
{
}
nsresult
HTMLFigureAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
already_AddRefed<nsIPersistentProperties>
HTMLFigureAccessible::NativeAttributes()
{
nsresult rv = HyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPersistentProperties> attributes =
HyperTextAccessibleWrap::NativeAttributes();
// Expose figure xml-role.
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
NS_LITERAL_STRING("figure"));
return NS_OK;
return attributes.forget();
}
role

View File

@ -189,7 +189,7 @@ public:
HTMLFigureAccessible(nsIContent* aContent, DocAccessible* aDoc);
// Accessible
virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
virtual mozilla::a11y::role NativeRole();
virtual Relation RelationByType(uint32_t aType);

View File

@ -93,27 +93,25 @@ HTMLTableCellAccessible::NativeInteractiveState() const
return HyperTextAccessibleWrap::NativeInteractiveState() | states::SELECTABLE;
}
nsresult
HTMLTableCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
already_AddRefed<nsIPersistentProperties>
HTMLTableCellAccessible::NativeAttributes()
{
if (IsDefunct())
return NS_ERROR_FAILURE;
nsresult rv = HyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPersistentProperties> attributes =
HyperTextAccessibleWrap::NativeAttributes();
// table-cell-index attribute
TableAccessible* table = Table();
if (!table)
return NS_OK;
return attributes.forget();
int32_t rowIdx = -1, colIdx = -1;
rv = GetCellIndexes(rowIdx, colIdx);
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = GetCellIndexes(rowIdx, colIdx);
if (NS_FAILED(rv))
return attributes.forget();
nsAutoString stringIdx;
stringIdx.AppendInt(table->CellIndexAt(rowIdx, colIdx));
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex, stringIdx);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tableCellIndex, stringIdx);
// abbr attribute
@ -132,15 +130,15 @@ HTMLTableCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttribu
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::abbr, abbrText);
if (!abbrText.IsEmpty())
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::abbr, abbrText);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::abbr, abbrText);
// axis attribute
nsAutoString axisText;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::axis, axisText);
if (!axisText.IsEmpty())
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::axis, axisText);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::axis, axisText);
return NS_OK;
return attributes.forget();
}
////////////////////////////////////////////////////////////////////////////////
@ -408,19 +406,18 @@ HTMLTableAccessible::NativeName(nsString& aName)
return eNameOK;
}
nsresult
HTMLTableAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
already_AddRefed<nsIPersistentProperties>
HTMLTableAccessible::NativeAttributes()
{
nsresult rv = AccessibleWrap::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPersistentProperties> attributes =
AccessibleWrap::NativeAttributes();
if (IsProbablyLayoutTable()) {
nsAutoString oldValueUnused;
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
NS_LITERAL_STRING("true"), oldValueUnused);
nsAutoString unused;
attributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
NS_LITERAL_STRING("true"), unused);
}
return NS_OK;
return attributes.forget();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -42,7 +42,7 @@ public:
virtual a11y::role NativeRole();
virtual uint64_t NativeState();
virtual uint64_t NativeInteractiveState() const;
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
// TableCellAccessible
virtual TableAccessible* Table() const MOZ_OVERRIDE;
@ -145,7 +145,7 @@ public:
virtual void Description(nsString& aDescription);
virtual a11y::role NativeRole();
virtual uint64_t NativeState();
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
virtual Relation RelationByType(uint32_t aRelationType);
// HTMLTableAccessible

View File

@ -439,11 +439,10 @@ GetClosestInterestingAccessible(id anObject)
// XXX maybe we should cache the subrole.
nsAutoString xmlRoles;
nsCOMPtr<nsIPersistentProperties> attributes;
// XXX we don't need all the attributes (see bug 771113)
nsresult rv = mGeckoAccessible->GetAttributes(getter_AddRefs(attributes));
if (NS_SUCCEEDED(rv) && attributes)
nsCOMPtr<nsIPersistentProperties> attributes = mGeckoAccessible->Attributes();
if (attributes)
nsAccUtils::GetAccAttr(attributes, nsGkAtoms::xmlroles, xmlRoles);
nsWhitespaceTokenizer tokenizer(xmlRoles);

View File

@ -1440,11 +1440,7 @@ __try {
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsCOMPtr<nsIPersistentProperties> attributes;
nsresult rv = GetAttributes(getter_AddRefs(attributes));
if (NS_FAILED(rv))
return GetHRESULT(rv);
nsCOMPtr<nsIPersistentProperties> attributes = Attributes();
return ConvertToIA2Attributes(attributes, aAttributes);
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }

View File

@ -21,15 +21,11 @@ using namespace mozilla::a11y;
NS_IMPL_ISUPPORTS_INHERITED0(ApplicationAccessibleWrap,
ApplicationAccessible)
NS_IMETHODIMP
ApplicationAccessibleWrap::GetAttributes(nsIPersistentProperties** aAttributes)
already_AddRefed<nsIPersistentProperties>
ApplicationAccessibleWrap::NativeAttributes()
{
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nullptr;
nsCOMPtr<nsIPersistentProperties> attributes =
do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
NS_ENSURE_STATE(attributes);
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
if (gfxInfo) {
@ -42,8 +38,7 @@ ApplicationAccessibleWrap::GetAttributes(nsIPersistentProperties** aAttributes)
unused);
}
attributes.swap(*aAttributes);
return NS_OK;
return attributes.forget();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -22,8 +22,8 @@ public:
// nsISupporst
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetAttributes(nsIPersistentProperties** aAttributes);
// nsAccessible
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
// IUnknown
STDMETHODIMP QueryInterface(REFIID, void**);

View File

@ -188,8 +188,7 @@ uiaRawElmProvider::GetPropertyValue(PROPERTYID aPropertyId,
case UIA_AriaRolePropertyId: {
nsAutoString xmlRoles;
nsCOMPtr<nsIPersistentProperties> attributes;
mAcc->GetAttributes(getter_AddRefs(attributes));
nsCOMPtr<nsIPersistentProperties> attributes = mAcc->Attributes();
attributes->GetStringProperty(NS_LITERAL_CSTRING("xml-roles"), xmlRoles);
if(!xmlRoles.IsEmpty()) {

View File

@ -857,22 +857,20 @@ XULListCellAccessible::NativeRole()
return roles::CELL;
}
nsresult
XULListCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
already_AddRefed<nsIPersistentProperties>
XULListCellAccessible::NativeAttributes()
{
NS_ENSURE_ARG_POINTER(aAttributes);
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPersistentProperties> attributes =
HyperTextAccessibleWrap::NativeAttributes();
// "table-cell-index" attribute
TableAccessible* table = Table();
NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
if (!table) // we expect to be in a listbox (table)
return attributes.forget();
nsAutoString stringIdx;
stringIdx.AppendInt(table->CellIndexAt(RowIdx(), ColIdx()));
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
stringIdx);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tableCellIndex, stringIdx);
return NS_OK;
return attributes.forget();
}

View File

@ -174,7 +174,7 @@ public:
// Accessible
virtual TableCellAccessible* AsTableCell() { return this; }
virtual void Shutdown();
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
virtual a11y::role NativeRole();
// TableCellAccessible

View File

@ -727,31 +727,29 @@ XULTreeGridCellAccessible::Init()
////////////////////////////////////////////////////////////////////////////////
// XULTreeGridCellAccessible: Accessible public implementation
nsresult
XULTreeGridCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
already_AddRefed<nsIPersistentProperties>
XULTreeGridCellAccessible::NativeAttributes()
{
NS_ENSURE_ARG_POINTER(aAttributes);
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPersistentProperties> attributes =
do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
// "table-cell-index" attribute
TableAccessible* table = Table();
if (!table)
return NS_ERROR_FAILURE;
return attributes.forget();
nsAutoString stringIdx;
stringIdx.AppendInt(table->CellIndexAt(mRow, ColIdx()));
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex, stringIdx);
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tableCellIndex, stringIdx);
// "cycles" attribute
bool isCycler = false;
nsresult rv = mColumn->GetCycler(&isCycler);
if (NS_SUCCEEDED(rv) && isCycler)
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::cycles,
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::cycles,
NS_LITERAL_STRING("true"));
return NS_OK;
return attributes.forget();
}
role

View File

@ -158,7 +158,7 @@ public:
virtual void Shutdown();
virtual ENameValueFlag Name(nsString& aName);
virtual Accessible* FocusedChild();
virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
virtual int32_t IndexInParent() const;
virtual Relation RelationByType(uint32_t aType);
virtual a11y::role NativeRole();

View File

@ -38,8 +38,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
testAttrs("sortNone", {"sort" : "none"}, true);
testAttrs("sortOther", {"sort" : "other"}, true);
// inherited attributes by subdocuments
var subdoc = getAccessible("iframe").firstChild;
testAttrs(subdoc, {"busy" : "true"}, true);
// live object attribute
// HTML
testAttrs("output", {"live" : "polite"}, true);
@ -172,6 +176,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
<div id="sortNone" role="columnheader" aria-sort="none"></div>
<div id="sortOther" role="columnheader" aria-sort="other"></div>
<!-- inherited from iframe -->
<iframe id="iframe" src="data:text/html,<html><body></body></html>"
aria-busy="true"></iframe>
<!-- html -->
<output id="output"></output>