Bug 1468110 - add AccessibleNode boolean attributes, r=yzen, qdot

based on ARIA and AOM's ARIA reflection specs (https://wicg.github.io/aom/spec/aria-reflection.html)
This commit is contained in:
Tokio Kajitsuka 2018-07-06 18:29:49 +09:00
parent 7fa963c733
commit 6fd289ea7a
4 changed files with 99 additions and 1 deletions

View File

@ -42,7 +42,9 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(AccessibleNode)
NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode)
AccessibleNode::AccessibleNode(nsINode* aNode) : mDOMNode(aNode)
AccessibleNode::AccessibleNode(nsINode* aNode) :
mBooleanProperties(0),
mDOMNode(aNode)
{
nsAccessibilityService* accService = GetOrCreateAccService();
if (!accService) {

View File

@ -10,6 +10,7 @@
#include "nsWrapperCache.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Nullable.h"
class nsINode;
@ -24,6 +25,26 @@ namespace dom {
class DOMStringList;
struct ParentObject;
#define ANODE_ENUM(name) \
e##name,
#define ANODE_FUNC(typeName, type, name) \
dom::Nullable<type> Get##name() \
{ \
return GetProperty(AOM##typeName##Property::e##name); \
} \
\
void Set##name(const dom::Nullable<type>& a##name) \
{ \
SetProperty(AOM##typeName##Property::e##name, a##name); \
} \
#define ANODE_PROPS(typeName, type, ...) \
enum class AOM##typeName##Property { \
MOZ_FOR_EACH(ANODE_ENUM, (), (__VA_ARGS__)) \
}; \
MOZ_FOR_EACH(ANODE_FUNC, (typeName, type,), (__VA_ARGS__)) \
class AccessibleNode : public nsISupports,
public nsWrapperCache
{
@ -49,11 +70,52 @@ public:
static bool IsAOMEnabled(JSContext*, JSObject*);
ANODE_PROPS(Boolean, bool,
Atomic,
Busy,
Disabled,
Expanded,
Hidden,
Modal,
Multiline,
Multiselectable,
ReadOnly,
Required,
Selected
)
protected:
AccessibleNode(const AccessibleNode& aCopy) = delete;
AccessibleNode& operator=(const AccessibleNode& aCopy) = delete;
virtual ~AccessibleNode();
dom::Nullable<bool> GetProperty(AOMBooleanProperty aProperty)
{
int num = static_cast<int>(aProperty);
if (mBooleanProperties & (1U << (2 * num))) {
bool data = static_cast<bool>(mBooleanProperties & (1U << (2 * num + 1)));
return dom::Nullable<bool>(data);
}
return dom::Nullable<bool>();
}
void SetProperty(AOMBooleanProperty aProperty,
const dom::Nullable<bool>& aValue)
{
int num = static_cast<int>(aProperty);
if (aValue.IsNull()) {
mBooleanProperties &= ~(1U << (2 * num));
} else {
mBooleanProperties |= (1U << (2 * num));
mBooleanProperties = (aValue.Value() ? mBooleanProperties | (1U << (2 * num + 1))
: mBooleanProperties & ~(1U << (2 * num + 1)));
}
}
// The 2k'th bit indicates whether the k'th boolean property is used(1) or not(0)
// and 2k+1'th bit contains the property's value(1:true, 0:false)
uint32_t mBooleanProperties;
RefPtr<a11y::Accessible> mIntl;
RefPtr<nsINode> mDOMNode;
RefPtr<dom::DOMStringList> mStates;

View File

@ -41,6 +41,16 @@
});
}
function testBoolProp(anode, prop) {
is(anode[prop], null, `anode.${prop} should be null`);
anode[prop] = true;
is(anode[prop], true, `anode.${prop} was assigned true`);
anode[prop] = false;
is(anode[prop], false, `anode.${prop} was assigned false`);
anode[prop] = null;
is(anode[prop], null, `anode.${prop} was assigned null`);
}
// Check that the WebIDL is as expected.
function checkImplementation(ifrDoc) {
let anode = ifrDoc.accessibleNode;
@ -101,6 +111,13 @@
`${anode.attributes[i]} attribute is expected and found`);
}
const boolProps = ["atomic", "busy", "disabled", "expanded", "hidden", "modal",
"multiline", "multiselectable", "readOnly", "required", "selected"];
for (const boolProp of boolProps) {
testBoolProp(anode, boolProp);
}
// Check if an AccessibleNode is properly cached.
let node = ifrDoc.createElement("div");
anode = node.accessibleNode;

View File

@ -17,4 +17,21 @@ interface AccessibleNode {
boolean has(DOMString... attributes);
[Throws]
any get(DOMString attribute);
// Accessible properties
attribute boolean? modal;
attribute boolean? multiline;
attribute boolean? multiselectable;
attribute boolean? readOnly;
attribute boolean? required;
// Accessible states
attribute boolean? disabled;
attribute boolean? expanded;
attribute boolean? hidden;
attribute boolean? selected;
// Live regions
attribute boolean? atomic;
attribute boolean? busy;
};