diff --git a/accessible/aom/AccessibleNode.cpp b/accessible/aom/AccessibleNode.cpp index 95d34800ff8b..e11a9ce17560 100644 --- a/accessible/aom/AccessibleNode.cpp +++ b/accessible/aom/AccessibleNode.cpp @@ -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) { diff --git a/accessible/aom/AccessibleNode.h b/accessible/aom/AccessibleNode.h index eb1c4a9c521e..9898369a1984 100644 --- a/accessible/aom/AccessibleNode.h +++ b/accessible/aom/AccessibleNode.h @@ -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 Get##name() \ + { \ + return GetProperty(AOM##typeName##Property::e##name); \ + } \ + \ + void Set##name(const dom::Nullable& 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 GetProperty(AOMBooleanProperty aProperty) + { + int num = static_cast(aProperty); + if (mBooleanProperties & (1U << (2 * num))) { + bool data = static_cast(mBooleanProperties & (1U << (2 * num + 1))); + return dom::Nullable(data); + } + return dom::Nullable(); + } + + void SetProperty(AOMBooleanProperty aProperty, + const dom::Nullable& aValue) + { + int num = static_cast(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 mIntl; RefPtr mDOMNode; RefPtr mStates; diff --git a/accessible/tests/mochitest/aom/test_general.html b/accessible/tests/mochitest/aom/test_general.html index a02240e92342..9fd1a4243e76 100644 --- a/accessible/tests/mochitest/aom/test_general.html +++ b/accessible/tests/mochitest/aom/test_general.html @@ -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; diff --git a/dom/webidl/AccessibleNode.webidl b/dom/webidl/AccessibleNode.webidl index 584913b2e4c6..48c7ab5c9c31 100644 --- a/dom/webidl/AccessibleNode.webidl +++ b/dom/webidl/AccessibleNode.webidl @@ -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; };