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 |