| Index: ui/accessibility/ax_node_data.cc
|
| diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc
|
| index 3a02c6a4383c9baccbb179ceabf2bf849981e9b6..2cb05046ad47b8227fde6ac603fe3c9f5fa079e1 100644
|
| --- a/ui/accessibility/ax_node_data.cc
|
| +++ b/ui/accessibility/ax_node_data.cc
|
| @@ -27,6 +27,10 @@ bool IsFlagSet(uint32_t bitfield, uint32_t flag) {
|
| return 0 != (bitfield & (1 << flag));
|
| }
|
|
|
| +uint32_t ModifyFlag(uint32_t bitfield, uint32_t flag, bool set) {
|
| + return set ? (bitfield |= (1 << flag)) : (bitfield &= ~(1 << flag));
|
| +}
|
| +
|
| std::string StateBitfieldToString(uint32_t state) {
|
| std::string str;
|
| for (uint32_t i = AX_STATE_NONE + 1; i <= AX_STATE_LAST; ++i) {
|
| @@ -36,6 +40,18 @@ std::string StateBitfieldToString(uint32_t state) {
|
| return str;
|
| }
|
|
|
| +std::string ActionsBitfieldToString(uint32_t actions) {
|
| + std::string str;
|
| + for (uint32_t i = AX_ACTION_NONE + 1; i <= AX_ACTION_LAST; ++i) {
|
| + if (IsFlagSet(actions, i)) {
|
| + str += ToString(static_cast<AXAction>(i));
|
| + actions = ModifyFlag(actions, i, false);
|
| + str += actions ? "," : "";
|
| + }
|
| + }
|
| + return str;
|
| +}
|
| +
|
| std::string IntVectorToString(const std::vector<int>& items) {
|
| std::string str;
|
| for (size_t i = 0; i < items.size(); ++i) {
|
| @@ -170,7 +186,11 @@ bool IsNodeIdIntListAttribute(AXIntListAttribute attr) {
|
| }
|
|
|
| AXNodeData::AXNodeData()
|
| - : id(-1), role(AX_ROLE_UNKNOWN), state(0), offset_container_id(-1) {}
|
| + : id(-1),
|
| + role(AX_ROLE_UNKNOWN),
|
| + state(AX_STATE_NONE),
|
| + actions(AX_ACTION_NONE),
|
| + offset_container_id(-1) {}
|
|
|
| AXNodeData::~AXNodeData() {
|
| }
|
| @@ -179,6 +199,7 @@ AXNodeData::AXNodeData(const AXNodeData& other) {
|
| id = other.id;
|
| role = other.role;
|
| state = other.state;
|
| + actions = other.actions;
|
| string_attributes = other.string_attributes;
|
| int_attributes = other.int_attributes;
|
| float_attributes = other.float_attributes;
|
| @@ -196,6 +217,7 @@ AXNodeData& AXNodeData::operator=(AXNodeData other) {
|
| id = other.id;
|
| role = other.role;
|
| state = other.state;
|
| + actions = other.actions;
|
| string_attributes = other.string_attributes;
|
| int_attributes = other.int_attributes;
|
| float_attributes = other.float_attributes;
|
| @@ -424,13 +446,53 @@ void AXNodeData::SetValue(const base::string16& value) {
|
| SetValue(base::UTF16ToUTF8(value));
|
| }
|
|
|
| -bool AXNodeData::HasState(AXState state_flag) const {
|
| - return IsFlagSet(state, state_flag);
|
| -}
|
| +bool AXNodeData::HasState(AXState state_enum) const {
|
| + return IsFlagSet(state, state_enum);
|
| +}
|
| +
|
| +bool AXNodeData::HasAction(AXAction action_enum) const {
|
| + return IsFlagSet(actions, action_enum);
|
| +}
|
| +
|
| +void AXNodeData::AddState(AXState state_enum) {
|
| + DCHECK_NE(state_enum, AX_STATE_NONE);
|
| + state = ModifyFlag(state, state_enum, true);
|
| +}
|
| +
|
| +void AXNodeData::AddAction(AXAction action_enum) {
|
| + switch (action_enum) {
|
| + case AX_ACTION_NONE:
|
| + NOTREACHED();
|
| + break;
|
| +
|
| + // Note: all of the attributes are included here explicitly, rather than
|
| + // using "default:", so that it's a compiler error to add a new action
|
| + // without explicitly considering whether there are mutually exclusive
|
| + // actions that can be performed on a UI control at the same time.
|
| + case AX_ACTION_BLUR:
|
| + case AX_ACTION_FOCUS: {
|
| + AXAction excluded_action =
|
| + (action_enum == AX_ACTION_BLUR) ? AX_ACTION_FOCUS : AX_ACTION_BLUR;
|
| + DCHECK(HasAction(excluded_action));
|
| + } break;
|
| + case AX_ACTION_DECREMENT:
|
| + case AX_ACTION_DO_DEFAULT:
|
| + case AX_ACTION_GET_IMAGE_DATA:
|
| + case AX_ACTION_HIT_TEST:
|
| + case AX_ACTION_INCREMENT:
|
| + case AX_ACTION_REPLACE_SELECTED_TEXT:
|
| + case AX_ACTION_SCROLL_TO_MAKE_VISIBLE:
|
| + case AX_ACTION_SCROLL_TO_POINT:
|
| + case AX_ACTION_SET_ACCESSIBILITY_FOCUS:
|
| + case AX_ACTION_SET_SCROLL_OFFSET:
|
| + case AX_ACTION_SET_SELECTION:
|
| + case AX_ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT:
|
| + case AX_ACTION_SET_VALUE:
|
| + case AX_ACTION_SHOW_CONTEXT_MENU:
|
| + break;
|
| + }
|
|
|
| -void AXNodeData::AddState(AXState state_flag) {
|
| - DCHECK_NE(state_flag, AX_STATE_NONE);
|
| - state |= (1 << state_flag);
|
| + actions = ModifyFlag(actions, action_enum, true);
|
| }
|
|
|
| std::string AXNodeData::ToString() const {
|
| @@ -807,9 +869,6 @@ std::string AXNodeData::ToString() const {
|
| case AX_ATTR_ARIA_READONLY:
|
| result += " aria_readonly=" + value;
|
| break;
|
| - case AX_ATTR_CAN_SET_VALUE:
|
| - result += " can_set_value=" + value;
|
| - break;
|
| case AX_ATTR_UPDATE_LOCATION_ONLY:
|
| result += " update_location_only=" + value;
|
| break;
|
| @@ -905,6 +964,8 @@ std::string AXNodeData::ToString() const {
|
| }
|
| }
|
|
|
| + result += " actions=" + ActionsBitfieldToString(actions);
|
| +
|
| if (!child_ids.empty())
|
| result += " child_ids=" + IntVectorToString(child_ids);
|
|
|
|
|