Chromium Code Reviews| Index: ui/accessibility/platform/ax_platform_node_win.cc |
| diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc |
| index 9a3619ed7ff31aaba10d3a29579dffd7efb776fc..82415f02914de4e76efa4273f20a84cd6e1b8d8c 100644 |
| --- a/ui/accessibility/platform/ax_platform_node_win.cc |
| +++ b/ui/accessibility/platform/ax_platform_node_win.cc |
| @@ -33,48 +33,146 @@ |
| if (!delegate_) \ |
| return E_FAIL; |
| #define COM_OBJECT_VALIDATE_1_ARG(arg) \ |
| - if (!delegate_) return E_FAIL; \ |
| - if (!arg) return E_INVALIDARG |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!arg) \ |
| + return E_INVALIDARG; |
| #define COM_OBJECT_VALIDATE_2_ARGS(arg1, arg2) \ |
| - if (!delegate_) return E_FAIL; \ |
| - if (!arg1) return E_INVALIDARG; \ |
| - if (!arg2) return E_INVALIDARG |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!arg1) \ |
| + return E_INVALIDARG; \ |
| + if (!arg2) \ |
| + return E_INVALIDARG; |
| #define COM_OBJECT_VALIDATE_3_ARGS(arg1, arg2, arg3) \ |
| - if (!delegate_) return E_FAIL; \ |
| - if (!arg1) return E_INVALIDARG; \ |
| - if (!arg2) return E_INVALIDARG; \ |
| - if (!arg3) return E_INVALIDARG |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!arg1) \ |
| + return E_INVALIDARG; \ |
| + if (!arg2) \ |
| + return E_INVALIDARG; \ |
| + if (!arg3) \ |
| + return E_INVALIDARG; |
| #define COM_OBJECT_VALIDATE_4_ARGS(arg1, arg2, arg3, arg4) \ |
| - if (!delegate_) return E_FAIL; \ |
| - if (!arg1) return E_INVALIDARG; \ |
| - if (!arg2) return E_INVALIDARG; \ |
| - if (!arg3) return E_INVALIDARG; \ |
| - if (!arg4) return E_INVALIDARG |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!arg1) \ |
| + return E_INVALIDARG; \ |
| + if (!arg2) \ |
| + return E_INVALIDARG; \ |
| + if (!arg3) \ |
| + return E_INVALIDARG; \ |
| + if (!arg4) \ |
| + return E_INVALIDARG; |
| #define COM_OBJECT_VALIDATE_VAR_ID(var_id) \ |
|
dmazzoni
2017/04/18 04:25:34
I think you can get rid of all of the COM_OBJECT_V
|
| - if (!delegate_) return E_FAIL; \ |
| - if (!IsValidId(var_id)) return E_INVALIDARG |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!IsValidId(var_id)) \ |
| + return E_INVALIDARG; |
| + |
| #define COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, arg) \ |
| - if (!delegate_) return E_FAIL; \ |
| - if (!IsValidId(var_id)) return E_INVALIDARG; \ |
| - if (!arg) return E_INVALIDARG |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!IsValidId(var_id)) \ |
| + return E_INVALIDARG; \ |
| + if (!arg) \ |
| + return E_INVALIDARG; |
| #define COM_OBJECT_VALIDATE_VAR_ID_2_ARGS(var_id, arg1, arg2) \ |
| - if (!delegate_) return E_FAIL; \ |
| - if (!IsValidId(var_id)) return E_INVALIDARG; \ |
| - if (!arg1) return E_INVALIDARG; \ |
| - if (!arg2) return E_INVALIDARG |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!IsValidId(var_id)) \ |
| + return E_INVALIDARG; \ |
| + if (!arg1) \ |
| + return E_INVALIDARG; \ |
| + if (!arg2) \ |
| + return E_INVALIDARG; |
| #define COM_OBJECT_VALIDATE_VAR_ID_3_ARGS(var_id, arg1, arg2, arg3) \ |
| - if (!delegate_) return E_FAIL; \ |
| - if (!IsValidId(var_id)) return E_INVALIDARG; \ |
| - if (!arg1) return E_INVALIDARG; \ |
| - if (!arg2) return E_INVALIDARG; \ |
| - if (!arg3) return E_INVALIDARG |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!IsValidId(var_id)) \ |
| + return E_INVALIDARG; \ |
| + if (!arg1) \ |
| + return E_INVALIDARG; \ |
| + if (!arg2) \ |
| + return E_INVALIDARG; \ |
| + if (!arg3) \ |
| + return E_INVALIDARG; |
| #define COM_OBJECT_VALIDATE_VAR_ID_4_ARGS(var_id, arg1, arg2, arg3, arg4) \ |
| - if (!delegate_) return E_FAIL; \ |
| - if (!IsValidId(var_id)) return E_INVALIDARG; \ |
| - if (!arg1) return E_INVALIDARG; \ |
| - if (!arg2) return E_INVALIDARG; \ |
| - if (!arg3) return E_INVALIDARG; \ |
| - if (!arg4) return E_INVALIDARG |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!IsValidId(var_id)) \ |
| + return E_INVALIDARG; \ |
| + if (!arg1) \ |
| + return E_INVALIDARG; \ |
| + if (!arg2) \ |
| + return E_INVALIDARG; \ |
| + if (!arg3) \ |
| + return E_INVALIDARG; \ |
| + if (!arg4) \ |
| + return E_INVALIDARG; |
| +#define COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target) \ |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + target = GetTargetFromChildID(var_id); \ |
| + if (!target) \ |
| + return E_INVALIDARG; \ |
| + if (!target->delegate_) \ |
| + return E_INVALIDARG; |
| +#define COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, arg, target) \ |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!arg) \ |
| + return E_INVALIDARG; \ |
| + target = GetTargetFromChildID(var_id); \ |
| + if (!target) \ |
| + return E_INVALIDARG; \ |
| + if (!target->delegate_) \ |
| + return E_INVALIDARG; |
| +#define COM_OBJECT_VALIDATE_VAR_ID_2_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \ |
| + target) \ |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!arg1) \ |
| + return E_INVALIDARG; \ |
| + if (!arg2) \ |
| + return E_INVALIDARG; \ |
| + target = GetTargetFromChildID(var_id); \ |
| + if (!target) \ |
| + return E_INVALIDARG; \ |
| + if (!target->delegate_) \ |
| + return E_INVALIDARG; |
| +#define COM_OBJECT_VALIDATE_VAR_ID_3_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \ |
| + arg3, target) \ |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!arg1) \ |
| + return E_INVALIDARG; \ |
| + if (!arg2) \ |
| + return E_INVALIDARG; \ |
| + if (!arg3) \ |
| + return E_INVALIDARG; \ |
| + target = GetTargetFromChildID(var_id); \ |
| + if (!target) \ |
| + return E_INVALIDARG; \ |
| + if (!target->delegate_) \ |
| + return E_INVALIDARG; |
| +#define COM_OBJECT_VALIDATE_VAR_ID_4_ARGS_AND_GET_TARGET(var_id, arg1, arg2, \ |
| + arg3, arg4, target) \ |
| + if (!delegate_) \ |
| + return E_FAIL; \ |
| + if (!arg1) \ |
| + return E_INVALIDARG; \ |
| + if (!arg2) \ |
| + return E_INVALIDARG; \ |
| + if (!arg3) \ |
| + return E_INVALIDARG; \ |
| + if (!arg4) \ |
| + return E_INVALIDARG; \ |
| + target = GetTargetFromChildID(var_id); \ |
| + if (!target) \ |
| + return E_INVALIDARG; \ |
| + if (!target->delegate_) \ |
| + return E_INVALIDARG; |
| namespace ui { |
| @@ -128,6 +226,8 @@ AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) { |
| // static |
| AXPlatformNode* AXPlatformNode::FromNativeViewAccessible( |
| gfx::NativeViewAccessible accessible) { |
| + if (!accessible) |
| + return nullptr; |
| base::win::ScopedComPtr<AXPlatformNodeWin> ax_platform_node; |
| accessible->QueryInterface(ax_platform_node.Receive()); |
| return ax_platform_node.get(); |
| @@ -252,18 +352,23 @@ STDMETHODIMP AXPlatformNodeWin::accHitTest( |
| } |
| HRESULT AXPlatformNodeWin::accDoDefaultAction(VARIANT var_id) { |
| - COM_OBJECT_VALIDATE_VAR_ID(var_id); |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target); |
| AXActionData data; |
| data.action = ui::AX_ACTION_DO_DEFAULT; |
| - if (delegate_->AccessibilityPerformAction(data)) |
| + |
| + if (target->delegate_->AccessibilityPerformAction(data)) |
| return S_OK; |
| return E_FAIL; |
| } |
| STDMETHODIMP AXPlatformNodeWin::accLocation( |
| LONG* x_left, LONG* y_top, LONG* width, LONG* height, VARIANT var_id) { |
| - COM_OBJECT_VALIDATE_VAR_ID_4_ARGS(var_id, x_left, y_top, width, height); |
| - gfx::Rect bounds = delegate_->GetScreenBoundsRect(); |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_4_ARGS_AND_GET_TARGET(var_id, x_left, y_top, width, |
| + height, target); |
| + |
| + gfx::Rect bounds = target->delegate_->GetScreenBoundsRect(); |
| *x_left = bounds.x(); |
| *y_top = bounds.y(); |
| *width = bounds.width(); |
| @@ -337,41 +442,13 @@ STDMETHODIMP AXPlatformNodeWin::accNavigate( |
| STDMETHODIMP AXPlatformNodeWin::get_accChild(VARIANT var_child, |
| IDispatch** disp_child) { |
| - COM_OBJECT_VALIDATE_1_ARG(disp_child); |
| - LONG child_id = V_I4(&var_child); |
| - if (child_id == CHILDID_SELF) { |
| - *disp_child = this; |
| - (*disp_child)->AddRef(); |
| - return S_OK; |
| - } |
| - |
| - if (child_id >= 1 && child_id <= delegate_->GetChildCount()) { |
| - // Positive child ids are a 1-based child index, used by clients |
| - // that want to enumerate all immediate children. |
| - *disp_child = delegate_->ChildAtIndex(child_id - 1); |
| - if (!(*disp_child)) |
| - return E_INVALIDARG; |
| - (*disp_child)->AddRef(); |
| - return S_OK; |
| - } |
| - |
| - if (child_id >= 0) |
| - return E_INVALIDARG; |
| - |
| - // Negative child ids can be used to map to any descendant. |
| - AXPlatformNodeWin* child = static_cast<AXPlatformNodeWin*>( |
| - GetFromUniqueId(-child_id)); |
| - if (child && !IsDescendant(child)) |
| - child = nullptr; |
| - |
| - if (child) { |
| - *disp_child = child; |
| - (*disp_child)->AddRef(); |
| - return S_OK; |
| - } |
| - |
| *disp_child = nullptr; |
| - return E_INVALIDARG; |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_child, target); |
| + |
| + *disp_child = target; |
| + (*disp_child)->AddRef(); |
| + return S_OK; |
| } |
| STDMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) { |
| @@ -382,9 +459,11 @@ STDMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) { |
| STDMETHODIMP AXPlatformNodeWin::get_accDefaultAction( |
| VARIANT var_id, BSTR* def_action) { |
| - COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, def_action); |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, def_action, target); |
| + |
| int action; |
| - if (!GetIntAttribute(AX_ATTR_ACTION, &action)) { |
| + if (!target->GetIntAttribute(AX_ATTR_ACTION, &action)) { |
| *def_action = nullptr; |
| return S_FALSE; |
| } |
| @@ -403,8 +482,10 @@ STDMETHODIMP AXPlatformNodeWin::get_accDefaultAction( |
| STDMETHODIMP AXPlatformNodeWin::get_accDescription( |
| VARIANT var_id, BSTR* desc) { |
| - COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, desc); |
| - return GetStringAttributeAsBstr(ui::AX_ATTR_DESCRIPTION, desc); |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, desc, target); |
| + |
| + return target->GetStringAttributeAsBstr(ui::AX_ATTR_DESCRIPTION, desc); |
| } |
| STDMETHODIMP AXPlatformNodeWin::get_accFocus(VARIANT* focus_child) { |
| @@ -427,14 +508,18 @@ STDMETHODIMP AXPlatformNodeWin::get_accFocus(VARIANT* focus_child) { |
| STDMETHODIMP AXPlatformNodeWin::get_accKeyboardShortcut( |
| VARIANT var_id, BSTR* acc_key) { |
| - COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, acc_key); |
| - return GetStringAttributeAsBstr(ui::AX_ATTR_SHORTCUT, acc_key); |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, acc_key, target); |
| + |
| + return target->GetStringAttributeAsBstr(ui::AX_ATTR_SHORTCUT, acc_key); |
| } |
| STDMETHODIMP AXPlatformNodeWin::get_accName( |
| VARIANT var_id, BSTR* name) { |
| - COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, name); |
| - return GetStringAttributeAsBstr(ui::AX_ATTR_NAME, name); |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, name, target); |
| + |
| + return target->GetStringAttributeAsBstr(ui::AX_ATTR_NAME, name); |
| } |
| STDMETHODIMP AXPlatformNodeWin::get_accParent( |
| @@ -451,17 +536,19 @@ STDMETHODIMP AXPlatformNodeWin::get_accParent( |
| STDMETHODIMP AXPlatformNodeWin::get_accRole( |
| VARIANT var_id, VARIANT* role) { |
| - COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, role); |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, role, target); |
| role->vt = VT_I4; |
| - role->lVal = MSAARole(); |
| + role->lVal = target->MSAARole(); |
| return S_OK; |
| } |
| STDMETHODIMP AXPlatformNodeWin::get_accState( |
| VARIANT var_id, VARIANT* state) { |
| - COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, state); |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, state, target); |
| state->vt = VT_I4; |
| - state->lVal = MSAAState(); |
| + state->lVal = target->MSAAState(); |
| return S_OK; |
| } |
| @@ -472,17 +559,20 @@ STDMETHODIMP AXPlatformNodeWin::get_accHelp( |
| } |
| STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) { |
| - COM_OBJECT_VALIDATE_VAR_ID_1_ARG(var_id, value); |
| - return GetStringAttributeAsBstr(ui::AX_ATTR_VALUE, value); |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, value, target); |
| + return target->GetStringAttributeAsBstr(ui::AX_ATTR_VALUE, value); |
| } |
| STDMETHODIMP AXPlatformNodeWin::put_accValue(VARIANT var_id, |
| BSTR new_value) { |
| + AXPlatformNodeWin* target; |
| + COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target); |
| + |
| AXActionData data; |
| data.action = ui::AX_ACTION_SET_VALUE; |
| data.value = new_value; |
| - COM_OBJECT_VALIDATE_VAR_ID(var_id); |
| - if (delegate_->AccessibilityPerformAction(data)) |
| + if (target->delegate_->AccessibilityPerformAction(data)) |
| return S_OK; |
| return E_FAIL; |
| } |
| @@ -976,8 +1066,6 @@ STDMETHODIMP AXPlatformNodeWin::QueryService( |
| // |
| bool AXPlatformNodeWin::IsValidId(const VARIANT& child) const { |
| - // Since we have a separate IAccessible COM object for each node, we only |
| - // support the CHILDID_SELF id. |
| return (VT_I4 == child.vt) && (CHILDID_SELF == child.lVal); |
| } |
| @@ -1206,4 +1294,35 @@ LONG AXPlatformNodeWin::FindBoundary( |
| AX_TEXT_AFFINITY_DOWNSTREAM)); |
| } |
| +AXPlatformNodeWin* AXPlatformNodeWin::GetTargetFromChildID( |
| + const VARIANT& var_id) { |
| + LONG child_id = V_I4(&var_id); |
| + if (child_id == CHILDID_SELF) { |
| + return this; |
| + } |
| + |
| + if (child_id >= 1 && child_id <= delegate_->GetChildCount()) { |
| + // Positive child ids are a 1-based child index, used by clients |
| + // that want to enumerate all immediate children. |
| + AXPlatformNodeBase* base = |
| + FromNativeViewAccessible(delegate_->ChildAtIndex(child_id - 1)); |
| + return static_cast<AXPlatformNodeWin*>(base); |
| + } |
| + |
| + if (child_id >= 0) |
| + return nullptr; |
| + |
| + // Negative child ids can be used to map to any descendant. |
| + AXPlatformNode* node = GetFromUniqueId(-child_id); |
| + if (!node) |
| + return nullptr; |
| + |
| + AXPlatformNodeBase* base = |
| + FromNativeViewAccessible(node->GetNativeViewAccessible()); |
| + if (base && !IsDescendant(base)) |
| + base = nullptr; |
| + |
| + return static_cast<AXPlatformNodeWin*>(base); |
| +} |
| + |
| } // namespace ui |