Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/accessibility/browser_accessibility_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_win.h" |
| 6 | 6 |
| 7 #include "base/string_number_conversions.h" | 7 #include "base/string_number_conversions.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "base/win/scoped_comptr.h" | 10 #include "base/win/scoped_comptr.h" |
| (...skipping 1586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1597 if (!instance_active_) | 1597 if (!instance_active_) |
| 1598 return E_FAIL; | 1598 return E_FAIL; |
| 1599 | 1599 |
| 1600 if (!n_characters) | 1600 if (!n_characters) |
| 1601 return E_INVALIDARG; | 1601 return E_INVALIDARG; |
| 1602 | 1602 |
| 1603 if (role_ == WebAccessibility::ROLE_TEXT_FIELD || | 1603 if (role_ == WebAccessibility::ROLE_TEXT_FIELD || |
| 1604 role_ == WebAccessibility::ROLE_TEXTAREA) { | 1604 role_ == WebAccessibility::ROLE_TEXTAREA) { |
| 1605 *n_characters = value_.length(); | 1605 *n_characters = value_.length(); |
| 1606 } else { | 1606 } else { |
| 1607 *n_characters = name_.length(); | 1607 *n_characters = hypertext_.length(); |
|
dmazzoni
2011/10/28 17:33:53
Can this method use TextForIAccessibleText instead
David Tseng
2011/10/28 18:25:15
Done.
| |
| 1608 } | 1608 } |
| 1609 | 1609 |
| 1610 return S_OK; | 1610 return S_OK; |
| 1611 } | 1611 } |
| 1612 | 1612 |
| 1613 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { | 1613 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { |
| 1614 if (!instance_active_) | 1614 if (!instance_active_) |
| 1615 return E_FAIL; | 1615 return E_FAIL; |
| 1616 | 1616 |
| 1617 if (!offset) | 1617 if (!offset) |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1842 return E_INVALIDARG; | 1842 return E_INVALIDARG; |
| 1843 | 1843 |
| 1844 // TODO(dmazzoni): implement this. We're returning S_OK for now so that | 1844 // TODO(dmazzoni): implement this. We're returning S_OK for now so that |
| 1845 // screen readers still return partially accurate results rather than | 1845 // screen readers still return partially accurate results rather than |
| 1846 // completely failing. | 1846 // completely failing. |
| 1847 *offset = 0; | 1847 *offset = 0; |
| 1848 return S_OK; | 1848 return S_OK; |
| 1849 } | 1849 } |
| 1850 | 1850 |
| 1851 // | 1851 // |
| 1852 // IAccessibleHypertext methods. | |
| 1853 // | |
| 1854 | |
| 1855 STDMETHODIMP BrowserAccessibilityWin::get_nHyperlinks(long* hyperlink_count) { | |
| 1856 if (!instance_active_) | |
| 1857 return E_FAIL; | |
| 1858 | |
| 1859 *hyperlink_count = hyperlink_offset_to_index_.size(); | |
|
dmazzoni
2011/10/28 17:33:53
Need to check all pointer arguments and return E_I
David Tseng
2011/10/28 18:25:15
Done.
| |
| 1860 return S_OK; | |
| 1861 } | |
| 1862 | |
| 1863 STDMETHODIMP BrowserAccessibilityWin::get_hyperlink( | |
| 1864 long index, | |
| 1865 IAccessibleHyperlink** hyperlink) { | |
| 1866 if (!instance_active_) | |
| 1867 return E_FAIL; | |
| 1868 | |
| 1869 if (index < 0 || index >= static_cast<long>(children().size()) || !hyperlink) | |
|
dmazzoni
2011/10/28 17:33:53
You only have an embedded object character for non
David Tseng
2011/10/28 18:25:15
The documentation states that clients are supposed
dmazzoni
2011/11/01 05:08:34
Clients can also call nHyperlinks and iterate over
| |
| 1870 return E_INVALIDARG; | |
| 1871 | |
| 1872 *hyperlink = static_cast<IAccessibleHyperlink*>( | |
| 1873 children_[index]->toBrowserAccessibilityWin()->NewReference()); | |
| 1874 return S_OK; | |
| 1875 } | |
| 1876 | |
| 1877 STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex(long char_index, | |
| 1878 long* hyperlink_index) { | |
| 1879 *hyperlink_index = -1; | |
| 1880 | |
| 1881 if (!instance_active_) | |
| 1882 return E_FAIL; | |
| 1883 | |
| 1884 if (char_index < 0 || char_index >= static_cast<long>(hypertext_.size())) | |
| 1885 return E_INVALIDARG; | |
| 1886 | |
| 1887 std::map<int32, int32>::iterator it = | |
| 1888 hyperlink_offset_to_index_.find(char_index); | |
| 1889 if (it == hyperlink_offset_to_index_.end()) | |
| 1890 return E_FAIL; | |
| 1891 | |
| 1892 *hyperlink_index = it->second; | |
| 1893 return S_OK; | |
| 1894 } | |
| 1895 | |
| 1896 // | |
| 1852 // IAccessibleValue methods. | 1897 // IAccessibleValue methods. |
| 1853 // | 1898 // |
| 1854 | 1899 |
| 1855 STDMETHODIMP BrowserAccessibilityWin::get_currentValue(VARIANT* value) { | 1900 STDMETHODIMP BrowserAccessibilityWin::get_currentValue(VARIANT* value) { |
| 1856 if (!instance_active_) | 1901 if (!instance_active_) |
| 1857 return E_FAIL; | 1902 return E_FAIL; |
| 1858 | 1903 |
| 1859 if (!value) | 1904 if (!value) |
| 1860 return E_INVALIDARG; | 1905 return E_INVALIDARG; |
| 1861 | 1906 |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2235 // IServiceProvider methods. | 2280 // IServiceProvider methods. |
| 2236 // | 2281 // |
| 2237 | 2282 |
| 2238 STDMETHODIMP BrowserAccessibilityWin::QueryService( | 2283 STDMETHODIMP BrowserAccessibilityWin::QueryService( |
| 2239 REFGUID guidService, REFIID riid, void** object) { | 2284 REFGUID guidService, REFIID riid, void** object) { |
| 2240 if (!instance_active_) | 2285 if (!instance_active_) |
| 2241 return E_FAIL; | 2286 return E_FAIL; |
| 2242 | 2287 |
| 2243 if (guidService == IID_IAccessible || | 2288 if (guidService == IID_IAccessible || |
| 2244 guidService == IID_IAccessible2 || | 2289 guidService == IID_IAccessible2 || |
| 2290 guidService == IID_IAccessibleAction || | |
| 2291 guidService == IID_IAccessibleHyperlink || | |
| 2292 guidService == IID_IAccessibleHypertext || | |
| 2245 guidService == IID_IAccessibleImage || | 2293 guidService == IID_IAccessibleImage || |
| 2246 guidService == IID_IAccessibleTable || | 2294 guidService == IID_IAccessibleTable || |
| 2247 guidService == IID_IAccessibleTable2 || | 2295 guidService == IID_IAccessibleTable2 || |
| 2248 guidService == IID_IAccessibleTableCell || | 2296 guidService == IID_IAccessibleTableCell || |
| 2249 guidService == IID_IAccessibleText || | 2297 guidService == IID_IAccessibleText || |
| 2250 guidService == IID_IAccessibleValue || | 2298 guidService == IID_IAccessibleValue || |
| 2251 guidService == IID_ISimpleDOMDocument || | 2299 guidService == IID_ISimpleDOMDocument || |
| 2252 guidService == IID_ISimpleDOMNode || | 2300 guidService == IID_ISimpleDOMNode || |
| 2253 guidService == IID_ISimpleDOMText || | 2301 guidService == IID_ISimpleDOMText || |
| 2254 guidService == GUID_ISimpleDOM) { | 2302 guidService == GUID_ISimpleDOM) { |
| 2255 return QueryInterface(riid, object); | 2303 return QueryInterface(riid, object); |
| 2256 } | 2304 } |
| 2257 | 2305 |
| 2258 *object = NULL; | 2306 *object = NULL; |
| 2259 return E_FAIL; | 2307 return E_FAIL; |
| 2260 } | 2308 } |
| 2261 | 2309 |
| 2262 // | 2310 // |
| 2263 // CComObjectRootEx methods. | 2311 // CComObjectRootEx methods. |
| 2264 // | 2312 // |
| 2265 | 2313 |
| 2266 HRESULT WINAPI BrowserAccessibilityWin::InternalQueryInterface( | 2314 HRESULT WINAPI BrowserAccessibilityWin::InternalQueryInterface( |
| 2267 void* this_ptr, | 2315 void* this_ptr, |
| 2268 const _ATL_INTMAP_ENTRY* entries, | 2316 const _ATL_INTMAP_ENTRY* entries, |
| 2269 REFIID iid, | 2317 REFIID iid, |
| 2270 void** object) { | 2318 void** object) { |
| 2271 if (iid == IID_IAccessibleText) { | 2319 if (iid == IID_IAccessibleImage) { |
| 2272 if (ia_role_ != ROLE_SYSTEM_LINK && ia_role_ != ROLE_SYSTEM_TEXT) { | |
| 2273 *object = NULL; | |
| 2274 return E_NOINTERFACE; | |
| 2275 } | |
| 2276 } else if (iid == IID_IAccessibleImage) { | |
| 2277 if (ia_role_ != ROLE_SYSTEM_GRAPHIC) { | 2320 if (ia_role_ != ROLE_SYSTEM_GRAPHIC) { |
| 2278 *object = NULL; | 2321 *object = NULL; |
| 2279 return E_NOINTERFACE; | 2322 return E_NOINTERFACE; |
| 2280 } | 2323 } |
| 2281 } else if (iid == IID_IAccessibleTable || iid == IID_IAccessibleTable2) { | 2324 } else if (iid == IID_IAccessibleTable || iid == IID_IAccessibleTable2) { |
| 2282 if (ia_role_ != ROLE_SYSTEM_TABLE) { | 2325 if (ia_role_ != ROLE_SYSTEM_TABLE) { |
| 2283 *object = NULL; | 2326 *object = NULL; |
| 2284 return E_NOINTERFACE; | 2327 return E_NOINTERFACE; |
| 2285 } | 2328 } |
| 2286 } else if (iid == IID_IAccessibleTableCell) { | 2329 } else if (iid == IID_IAccessibleTableCell) { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2410 // Add a labelled by relationship. | 2453 // Add a labelled by relationship. |
| 2411 CComObject<BrowserAccessibilityRelation>* relation; | 2454 CComObject<BrowserAccessibilityRelation>* relation; |
| 2412 HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance( | 2455 HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance( |
| 2413 &relation); | 2456 &relation); |
| 2414 DCHECK(SUCCEEDED(hr)); | 2457 DCHECK(SUCCEEDED(hr)); |
| 2415 relation->AddRef(); | 2458 relation->AddRef(); |
| 2416 relation->Initialize(this, IA2_RELATION_LABELLED_BY); | 2459 relation->Initialize(this, IA2_RELATION_LABELLED_BY); |
| 2417 relation->AddTarget(title_elem_id); | 2460 relation->AddTarget(title_elem_id); |
| 2418 relations_.push_back(relation); | 2461 relations_.push_back(relation); |
| 2419 } | 2462 } |
| 2463 | |
| 2464 // Construct the hypertext for this node. | |
| 2465 hyperlink_offset_to_index_.clear(); | |
| 2466 hypertext_.clear(); | |
| 2467 for (unsigned int i = 0; i < children().size(); ++i) { | |
| 2468 BrowserAccessibility* child = children()[i]; | |
| 2469 if (child->role() == WebAccessibility::ROLE_STATIC_TEXT) { | |
| 2470 hypertext_ += child->name(); | |
| 2471 } else { | |
| 2472 hyperlink_offset_to_index_[hypertext_.size()] = i; | |
| 2473 hypertext_ += L"\xfffc"; | |
|
dmazzoni
2011/10/28 17:33:53
Define a constant for this
David Tseng
2011/10/28 18:25:15
Done.
| |
| 2474 } | |
| 2475 } | |
| 2420 } | 2476 } |
| 2421 | 2477 |
| 2422 void BrowserAccessibilityWin::SendNodeUpdateEvents() { | 2478 void BrowserAccessibilityWin::SendNodeUpdateEvents() { |
| 2423 // Fire an event when an alert first appears. | 2479 // Fire an event when an alert first appears. |
| 2424 if (role_ == WebAccessibility::ROLE_ALERT && first_time_) | 2480 if (role_ == WebAccessibility::ROLE_ALERT && first_time_) |
| 2425 manager_->NotifyAccessibilityEvent(ViewHostMsg_AccEvent::ALERT, this); | 2481 manager_->NotifyAccessibilityEvent(ViewHostMsg_AccEvent::ALERT, this); |
| 2426 | 2482 |
| 2427 // Fire events if text has changed. | 2483 // Fire events if text has changed. |
| 2428 string16 text = TextForIAccessibleText(); | 2484 string16 text = TextForIAccessibleText(); |
| 2429 if (previous_text_ != text) { | 2485 if (previous_text_ != text) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2509 base::IntToString16(value)); | 2565 base::IntToString16(value)); |
| 2510 } | 2566 } |
| 2511 | 2567 |
| 2512 string16 BrowserAccessibilityWin::Escape(const string16& str) { | 2568 string16 BrowserAccessibilityWin::Escape(const string16& str) { |
| 2513 return net::EscapeQueryParamValueUTF8(str, false); | 2569 return net::EscapeQueryParamValueUTF8(str, false); |
| 2514 } | 2570 } |
| 2515 | 2571 |
| 2516 const string16& BrowserAccessibilityWin::TextForIAccessibleText() { | 2572 const string16& BrowserAccessibilityWin::TextForIAccessibleText() { |
| 2517 if (IsEditableText()) { | 2573 if (IsEditableText()) { |
| 2518 return value_; | 2574 return value_; |
| 2575 } else if (role_ == WebAccessibility::ROLE_STATIC_TEXT) { | |
| 2576 return name_; | |
| 2519 } else { | 2577 } else { |
| 2520 return name_; | 2578 return hypertext_; |
| 2521 } | 2579 } |
| 2522 } | 2580 } |
| 2523 | 2581 |
| 2524 void BrowserAccessibilityWin::HandleSpecialTextOffset( | 2582 void BrowserAccessibilityWin::HandleSpecialTextOffset( |
| 2525 const string16& text, LONG* offset) { | 2583 const string16& text, LONG* offset) { |
| 2526 if (*offset == IA2_TEXT_OFFSET_LENGTH) { | 2584 if (*offset == IA2_TEXT_OFFSET_LENGTH) { |
| 2527 *offset = static_cast<LONG>(text.size()); | 2585 *offset = static_cast<LONG>(text.size()); |
| 2528 } else if (*offset == IA2_TEXT_OFFSET_CARET) { | 2586 } else if (*offset == IA2_TEXT_OFFSET_CARET) { |
| 2529 get_caretOffset(offset); | 2587 get_caretOffset(offset); |
| 2530 } | 2588 } |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3018 } | 3076 } |
| 3019 | 3077 |
| 3020 // The role should always be set. | 3078 // The role should always be set. |
| 3021 DCHECK(!role_name_.empty() || ia_role_); | 3079 DCHECK(!role_name_.empty() || ia_role_); |
| 3022 | 3080 |
| 3023 // If we didn't explicitly set the IAccessible2 role, make it the same | 3081 // If we didn't explicitly set the IAccessible2 role, make it the same |
| 3024 // as the MSAA role. | 3082 // as the MSAA role. |
| 3025 if (!ia2_role_) | 3083 if (!ia2_role_) |
| 3026 ia2_role_ = ia_role_; | 3084 ia2_role_ = ia_role_; |
| 3027 } | 3085 } |
| OLD | NEW |