Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(934)

Side by Side Diff: content/browser/accessibility/browser_accessibility_win.cc

Issue 8416034: Support IAccessibleHypertext. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Initial patch. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698