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 |