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

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: Update another comment. 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
« no previous file with comments | « content/browser/accessibility/browser_accessibility_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
11 #include "content/browser/accessibility/browser_accessibility_manager_win.h" 11 #include "content/browser/accessibility/browser_accessibility_manager_win.h"
12 #include "content/common/view_messages.h" 12 #include "content/common/view_messages.h"
13 #include "net/base/escape.h" 13 #include "net/base/escape.h"
14 14
15 using webkit_glue::WebAccessibility; 15 using webkit_glue::WebAccessibility;
16 16
17 // The GUID for the ISimpleDOM service is not defined in the IDL files. 17 // The GUID for the ISimpleDOM service is not defined in the IDL files.
18 // This is taken directly from the Mozilla sources 18 // This is taken directly from the Mozilla sources
19 // (accessible/src/msaa/nsAccessNodeWrap.cpp) and it's also documented at: 19 // (accessible/src/msaa/nsAccessNodeWrap.cpp) and it's also documented at:
20 // http://developer.mozilla.org/en/Accessibility/AT-APIs/ImplementationFeatures/ MSAA 20 // http://developer.mozilla.org/en/Accessibility/AT-APIs/ImplementationFeatures/ MSAA
21 21
22 const GUID GUID_ISimpleDOM = { 22 const GUID GUID_ISimpleDOM = {
23 0x0c539790, 0x12e4, 0x11cf, 23 0x0c539790, 0x12e4, 0x11cf,
24 0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8}; 24 0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8};
25 25
26 const char16 BrowserAccessibilityWin::kEmbeddedCharacter[] = L"\xfffc";
27
26 // 28 //
27 // BrowserAccessibilityRelation 29 // BrowserAccessibilityRelation
28 // 30 //
29 // A simple implementation of IAccessibleRelation, used to represent 31 // A simple implementation of IAccessibleRelation, used to represent
30 // a relationship between two accessible nodes in the tree. 32 // a relationship between two accessible nodes in the tree.
31 // 33 //
32 34
33 class BrowserAccessibilityRelation 35 class BrowserAccessibilityRelation
34 : public CComObjectRootEx<CComMultiThreadModel>, 36 : public CComObjectRootEx<CComMultiThreadModel>,
35 public IAccessibleRelation { 37 public IAccessibleRelation {
(...skipping 1557 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 // IAccessibleText methods. 1595 // IAccessibleText methods.
1594 // 1596 //
1595 1597
1596 STDMETHODIMP BrowserAccessibilityWin::get_nCharacters(LONG* n_characters) { 1598 STDMETHODIMP BrowserAccessibilityWin::get_nCharacters(LONG* n_characters) {
1597 if (!instance_active_) 1599 if (!instance_active_)
1598 return E_FAIL; 1600 return E_FAIL;
1599 1601
1600 if (!n_characters) 1602 if (!n_characters)
1601 return E_INVALIDARG; 1603 return E_INVALIDARG;
1602 1604
1603 if (role_ == WebAccessibility::ROLE_TEXT_FIELD || 1605 *n_characters = TextForIAccessibleText().length();
1604 role_ == WebAccessibility::ROLE_TEXTAREA) {
1605 *n_characters = value_.length();
1606 } else {
1607 *n_characters = name_.length();
1608 }
1609
1610 return S_OK; 1606 return S_OK;
1611 } 1607 }
1612 1608
1613 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) { 1609 STDMETHODIMP BrowserAccessibilityWin::get_caretOffset(LONG* offset) {
1614 if (!instance_active_) 1610 if (!instance_active_)
1615 return E_FAIL; 1611 return E_FAIL;
1616 1612
1617 if (!offset) 1613 if (!offset)
1618 return E_INVALIDARG; 1614 return E_INVALIDARG;
1619 1615
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 return E_INVALIDARG; 1838 return E_INVALIDARG;
1843 1839
1844 // TODO(dmazzoni): implement this. We're returning S_OK for now so that 1840 // TODO(dmazzoni): implement this. We're returning S_OK for now so that
1845 // screen readers still return partially accurate results rather than 1841 // screen readers still return partially accurate results rather than
1846 // completely failing. 1842 // completely failing.
1847 *offset = 0; 1843 *offset = 0;
1848 return S_OK; 1844 return S_OK;
1849 } 1845 }
1850 1846
1851 // 1847 //
1848 // IAccessibleHypertext methods.
1849 //
1850
1851 STDMETHODIMP BrowserAccessibilityWin::get_nHyperlinks(long* hyperlink_count) {
1852 if (!instance_active_)
1853 return E_FAIL;
1854
1855 if (!hyperlink_count)
1856 return E_INVALIDARG;
1857
1858 *hyperlink_count = hyperlink_offset_to_index_.size();
1859 return S_OK;
1860 }
1861
1862 STDMETHODIMP BrowserAccessibilityWin::get_hyperlink(
1863 long index,
1864 IAccessibleHyperlink** hyperlink) {
1865 if (!instance_active_)
1866 return E_FAIL;
1867
1868 if (!hyperlink ||
1869 index < 0 ||
1870 index >= static_cast<long>(hyperlinks_.size())) {
1871 return E_INVALIDARG;
1872 }
1873
1874 BrowserAccessibilityWin* child =
1875 children_[hyperlinks_[index]]->toBrowserAccessibilityWin();
1876 *hyperlink = static_cast<IAccessibleHyperlink*>(child->NewReference());
1877 return S_OK;
1878 }
1879
1880 STDMETHODIMP BrowserAccessibilityWin::get_hyperlinkIndex(
1881 long char_index,
1882 long* hyperlink_index) {
1883 if (!instance_active_)
1884 return E_FAIL;
1885
1886 if (!hyperlink_index)
1887 return E_INVALIDARG;
1888
1889 *hyperlink_index = -1;
1890
1891 if (char_index < 0 || char_index >= static_cast<long>(hypertext_.size()))
1892 return E_INVALIDARG;
1893
1894 std::map<int32, int32>::iterator it =
1895 hyperlink_offset_to_index_.find(char_index);
1896 if (it == hyperlink_offset_to_index_.end())
1897 return E_FAIL;
1898
1899 *hyperlink_index = it->second;
1900 return S_OK;
1901 }
1902
1903 //
1852 // IAccessibleValue methods. 1904 // IAccessibleValue methods.
1853 // 1905 //
1854 1906
1855 STDMETHODIMP BrowserAccessibilityWin::get_currentValue(VARIANT* value) { 1907 STDMETHODIMP BrowserAccessibilityWin::get_currentValue(VARIANT* value) {
1856 if (!instance_active_) 1908 if (!instance_active_)
1857 return E_FAIL; 1909 return E_FAIL;
1858 1910
1859 if (!value) 1911 if (!value)
1860 return E_INVALIDARG; 1912 return E_INVALIDARG;
1861 1913
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
2235 // IServiceProvider methods. 2287 // IServiceProvider methods.
2236 // 2288 //
2237 2289
2238 STDMETHODIMP BrowserAccessibilityWin::QueryService( 2290 STDMETHODIMP BrowserAccessibilityWin::QueryService(
2239 REFGUID guidService, REFIID riid, void** object) { 2291 REFGUID guidService, REFIID riid, void** object) {
2240 if (!instance_active_) 2292 if (!instance_active_)
2241 return E_FAIL; 2293 return E_FAIL;
2242 2294
2243 if (guidService == IID_IAccessible || 2295 if (guidService == IID_IAccessible ||
2244 guidService == IID_IAccessible2 || 2296 guidService == IID_IAccessible2 ||
2297 guidService == IID_IAccessibleAction ||
2298 guidService == IID_IAccessibleHyperlink ||
2299 guidService == IID_IAccessibleHypertext ||
2245 guidService == IID_IAccessibleImage || 2300 guidService == IID_IAccessibleImage ||
2246 guidService == IID_IAccessibleTable || 2301 guidService == IID_IAccessibleTable ||
2247 guidService == IID_IAccessibleTable2 || 2302 guidService == IID_IAccessibleTable2 ||
2248 guidService == IID_IAccessibleTableCell || 2303 guidService == IID_IAccessibleTableCell ||
2249 guidService == IID_IAccessibleText || 2304 guidService == IID_IAccessibleText ||
2250 guidService == IID_IAccessibleValue || 2305 guidService == IID_IAccessibleValue ||
2251 guidService == IID_ISimpleDOMDocument || 2306 guidService == IID_ISimpleDOMDocument ||
2252 guidService == IID_ISimpleDOMNode || 2307 guidService == IID_ISimpleDOMNode ||
2253 guidService == IID_ISimpleDOMText || 2308 guidService == IID_ISimpleDOMText ||
2254 guidService == GUID_ISimpleDOM) { 2309 guidService == GUID_ISimpleDOM) {
2255 return QueryInterface(riid, object); 2310 return QueryInterface(riid, object);
2256 } 2311 }
2257 2312
2258 *object = NULL; 2313 *object = NULL;
2259 return E_FAIL; 2314 return E_FAIL;
2260 } 2315 }
2261 2316
2262 // 2317 //
2263 // CComObjectRootEx methods. 2318 // CComObjectRootEx methods.
2264 // 2319 //
2265 2320
2266 HRESULT WINAPI BrowserAccessibilityWin::InternalQueryInterface( 2321 HRESULT WINAPI BrowserAccessibilityWin::InternalQueryInterface(
2267 void* this_ptr, 2322 void* this_ptr,
2268 const _ATL_INTMAP_ENTRY* entries, 2323 const _ATL_INTMAP_ENTRY* entries,
2269 REFIID iid, 2324 REFIID iid,
2270 void** object) { 2325 void** object) {
2271 if (iid == IID_IAccessibleText) { 2326 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) { 2327 if (ia_role_ != ROLE_SYSTEM_GRAPHIC) {
2278 *object = NULL; 2328 *object = NULL;
2279 return E_NOINTERFACE; 2329 return E_NOINTERFACE;
2280 } 2330 }
2281 } else if (iid == IID_IAccessibleTable || iid == IID_IAccessibleTable2) { 2331 } else if (iid == IID_IAccessibleTable || iid == IID_IAccessibleTable2) {
2282 if (ia_role_ != ROLE_SYSTEM_TABLE) { 2332 if (ia_role_ != ROLE_SYSTEM_TABLE) {
2283 *object = NULL; 2333 *object = NULL;
2284 return E_NOINTERFACE; 2334 return E_NOINTERFACE;
2285 } 2335 }
2286 } else if (iid == IID_IAccessibleTableCell) { 2336 } else if (iid == IID_IAccessibleTableCell) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 // Add a labelled by relationship. 2460 // Add a labelled by relationship.
2411 CComObject<BrowserAccessibilityRelation>* relation; 2461 CComObject<BrowserAccessibilityRelation>* relation;
2412 HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance( 2462 HRESULT hr = CComObject<BrowserAccessibilityRelation>::CreateInstance(
2413 &relation); 2463 &relation);
2414 DCHECK(SUCCEEDED(hr)); 2464 DCHECK(SUCCEEDED(hr));
2415 relation->AddRef(); 2465 relation->AddRef();
2416 relation->Initialize(this, IA2_RELATION_LABELLED_BY); 2466 relation->Initialize(this, IA2_RELATION_LABELLED_BY);
2417 relation->AddTarget(title_elem_id); 2467 relation->AddTarget(title_elem_id);
2418 relations_.push_back(relation); 2468 relations_.push_back(relation);
2419 } 2469 }
2470
2471 // Construct the hypertext for this node.
2472 hyperlink_offset_to_index_.clear();
2473 hyperlinks_.clear();
2474 hypertext_.clear();
2475 for (unsigned int i = 0; i < children().size(); ++i) {
2476 BrowserAccessibility* child = children()[i];
2477 if (child->role() == WebAccessibility::ROLE_STATIC_TEXT) {
2478 hypertext_ += child->name();
2479 } else {
2480 hyperlink_offset_to_index_[hypertext_.size()] = hyperlinks_.size();
2481 hypertext_ += kEmbeddedCharacter;
2482 hyperlinks_.push_back(i);
2483 }
2484 }
2485 DCHECK_EQ(hyperlink_offset_to_index_.size(), hyperlinks_.size());
2420 } 2486 }
2421 2487
2422 void BrowserAccessibilityWin::SendNodeUpdateEvents() { 2488 void BrowserAccessibilityWin::SendNodeUpdateEvents() {
2423 // Fire an event when an alert first appears. 2489 // Fire an event when an alert first appears.
2424 if (role_ == WebAccessibility::ROLE_ALERT && first_time_) 2490 if (role_ == WebAccessibility::ROLE_ALERT && first_time_)
2425 manager_->NotifyAccessibilityEvent(ViewHostMsg_AccEvent::ALERT, this); 2491 manager_->NotifyAccessibilityEvent(ViewHostMsg_AccEvent::ALERT, this);
2426 2492
2427 // Fire events if text has changed. 2493 // Fire events if text has changed.
2428 string16 text = TextForIAccessibleText(); 2494 string16 text = TextForIAccessibleText();
2429 if (previous_text_ != text) { 2495 if (previous_text_ != text) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2509 base::IntToString16(value)); 2575 base::IntToString16(value));
2510 } 2576 }
2511 2577
2512 string16 BrowserAccessibilityWin::Escape(const string16& str) { 2578 string16 BrowserAccessibilityWin::Escape(const string16& str) {
2513 return net::EscapeQueryParamValueUTF8(str, false); 2579 return net::EscapeQueryParamValueUTF8(str, false);
2514 } 2580 }
2515 2581
2516 const string16& BrowserAccessibilityWin::TextForIAccessibleText() { 2582 const string16& BrowserAccessibilityWin::TextForIAccessibleText() {
2517 if (IsEditableText()) { 2583 if (IsEditableText()) {
2518 return value_; 2584 return value_;
2585 } else if (role_ == WebAccessibility::ROLE_STATIC_TEXT) {
2586 return name_;
2519 } else { 2587 } else {
2520 return name_; 2588 return hypertext_;
2521 } 2589 }
2522 } 2590 }
2523 2591
2524 void BrowserAccessibilityWin::HandleSpecialTextOffset( 2592 void BrowserAccessibilityWin::HandleSpecialTextOffset(
2525 const string16& text, LONG* offset) { 2593 const string16& text, LONG* offset) {
2526 if (*offset == IA2_TEXT_OFFSET_LENGTH) { 2594 if (*offset == IA2_TEXT_OFFSET_LENGTH) {
2527 *offset = static_cast<LONG>(text.size()); 2595 *offset = static_cast<LONG>(text.size());
2528 } else if (*offset == IA2_TEXT_OFFSET_CARET) { 2596 } else if (*offset == IA2_TEXT_OFFSET_CARET) {
2529 get_caretOffset(offset); 2597 get_caretOffset(offset);
2530 } 2598 }
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
3018 } 3086 }
3019 3087
3020 // The role should always be set. 3088 // The role should always be set.
3021 DCHECK(!role_name_.empty() || ia_role_); 3089 DCHECK(!role_name_.empty() || ia_role_);
3022 3090
3023 // If we didn't explicitly set the IAccessible2 role, make it the same 3091 // If we didn't explicitly set the IAccessible2 role, make it the same
3024 // as the MSAA role. 3092 // as the MSAA role.
3025 if (!ia2_role_) 3093 if (!ia2_role_)
3026 ia2_role_ = ia_role_; 3094 ia2_role_ = ia_role_;
3027 } 3095 }
OLDNEW
« no previous file with comments | « content/browser/accessibility/browser_accessibility_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698