Chromium Code Reviews| Index: ui/views/accessibility/native_view_accessibility_win.cc |
| diff --git a/ui/views/accessibility/native_view_accessibility_win.cc b/ui/views/accessibility/native_view_accessibility_win.cc |
| index 10c17ff3d6d636f153644cf34b0ece332e4d2a6a..f0a1ae510e15d2c203b250fd899a8830ad6185dd 100644 |
| --- a/ui/views/accessibility/native_view_accessibility_win.cc |
| +++ b/ui/views/accessibility/native_view_accessibility_win.cc |
| @@ -189,6 +189,7 @@ void AccessibleWebViewRegistry::QueryIAccessible2Interface(View* web_view) { |
| long NativeViewAccessibilityWin::next_unique_id_ = 1; |
| int NativeViewAccessibilityWin::view_storage_ids_[kMaxViewStorageIds] = {0}; |
| int NativeViewAccessibilityWin::next_view_storage_id_index_ = 0; |
| +std::vector<int> NativeViewAccessibilityWin::alert_target_view_storage_ids_; |
| // static |
| NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { |
| @@ -210,6 +211,7 @@ NativeViewAccessibilityWin::NativeViewAccessibilityWin() |
| } |
| NativeViewAccessibilityWin::~NativeViewAccessibilityWin() { |
| + RemoveAlertTarget(); |
| } |
| void NativeViewAccessibilityWin::NotifyAccessibilityEvent( |
| @@ -236,6 +238,10 @@ void NativeViewAccessibilityWin::NotifyAccessibilityEvent( |
| ::NotifyWinEvent(MSAAEvent(event_type), hwnd, OBJID_CLIENT, child_id); |
| next_view_storage_id_index_ = |
| (next_view_storage_id_index_ + 1) % kMaxViewStorageIds; |
| + |
| + // Keep track of views that are a target of an alert event. |
| + if (event_type == ui::AX_EVENT_ALERT) |
| + AddAlertTarget(); |
| } |
| gfx::NativeViewAccessible NativeViewAccessibilityWin::GetNativeObject() { |
| @@ -865,6 +871,39 @@ STDMETHODIMP NativeViewAccessibilityWin::get_windowHandle(HWND* window_handle) { |
| return *window_handle ? S_OK : S_FALSE; |
| } |
| +STDMETHODIMP NativeViewAccessibilityWin::get_relationTargetsOfType( |
| + BSTR type_bstr, |
| + long max_targets, |
| + IUnknown ***targets, |
| + long *n_targets) { |
| + if (!view_) |
| + return E_FAIL; |
| + |
| + if (!targets || !n_targets || max_targets <= 0) |
| + return E_INVALIDARG; |
| + |
| + *n_targets = 0; |
| + base::string16 type(type_bstr); |
| + if (type != L"alerts" || view_->parent()) |
| + return S_OK; |
| + |
| + ViewStorage* view_storage = ViewStorage::GetInstance(); |
| + for (size_t i = 0; i < alert_target_view_storage_ids_.size(); ++i) { |
| + int view_storage_id = alert_target_view_storage_ids_[i]; |
| + View* view = view_storage->RetrieveView(view_storage_id); |
| + if (!view || !view_->Contains(view)) |
| + continue; |
| + |
| + (*targets)[*n_targets] = view->GetNativeViewAccessible(); |
|
aboxhall
2014/05/07 15:26:30
This will put targets in *targets in chronological
dmazzoni
2014/05/07 15:31:41
I hadn't thought about the order. I'm not even sur
|
| + (*targets)[*n_targets]->AddRef(); |
| + ++(*n_targets); |
| + |
| + if (*n_targets == max_targets) |
| + break; |
| + } |
| + return S_OK; |
| +} |
| + |
| // |
| // IAccessibleText |
| // |
| @@ -1071,11 +1110,12 @@ STDMETHODIMP NativeViewAccessibilityWin::QueryService( |
| if (!view_) |
| return E_FAIL; |
| - if (riid == IID_IAccessible2) |
| + if (riid == IID_IAccessible2 || riid == IID_IAccessible2_2) |
| AccessibleWebViewRegistry::GetInstance()->EnableIAccessible2Support(); |
| if (guidService == IID_IAccessible || |
| guidService == IID_IAccessible2 || |
| + guidService == IID_IAccessible2_2 || |
| guidService == IID_IAccessibleText) { |
| return QueryInterface(riid, object); |
| } |
| @@ -1412,4 +1452,32 @@ void NativeViewAccessibilityWin::PopulateChildWidgetVector( |
| } |
| } |
| +void NativeViewAccessibilityWin::AddAlertTarget() { |
| + ViewStorage* view_storage = ViewStorage::GetInstance(); |
| + for (size_t i = 0; i < alert_target_view_storage_ids_.size(); ++i) { |
| + int view_storage_id = alert_target_view_storage_ids_[i]; |
| + View* view = view_storage->RetrieveView(view_storage_id); |
| + if (view == view_) |
|
aboxhall
2014/05/07 15:26:30
Similarly, do we want to bump up this view in the
|
| + return; |
| + } |
| + int view_storage_id = view_storage->CreateStorageID(); |
| + view_storage->StoreView(view_storage_id, view_); |
| + alert_target_view_storage_ids_.push_back(view_storage_id); |
| +} |
| + |
| +void NativeViewAccessibilityWin::RemoveAlertTarget() { |
| + ViewStorage* view_storage = ViewStorage::GetInstance(); |
| + size_t i = 0; |
| + while (i < alert_target_view_storage_ids_.size()) { |
| + int view_storage_id = alert_target_view_storage_ids_[i]; |
| + View* view = view_storage->RetrieveView(view_storage_id); |
| + if (view == NULL || view == view_) { |
| + alert_target_view_storage_ids_.erase( |
| + alert_target_view_storage_ids_.begin() + i); |
|
aboxhall
2014/05/07 15:26:30
Why don't we want to increment i in this case?
dmazzoni
2014/05/07 15:31:41
We're erasing the ith element, which should shift
|
| + } else { |
| + ++i; |
| + } |
| + } |
| +} |
| + |
| } // namespace views |