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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_WIN_H_
6#define CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_WIN_H_
7#pragma once
8
9#include <atlbase.h>
10#include <atlcom.h>
11#include <oleacc.h>
12
13#include <vector>
14
15#include "chrome/browser/accessibility/browser_accessibility.h"
16#include "ia2_api_all.h"  // Generated
17#include "ISimpleDOMDocument.h"  // Generated
18#include "ISimpleDOMNode.h"  // Generated
19#include "ISimpleDOMText.h"  // Generated
20#include "webkit/glue/webaccessibility.h"
21
22class BrowserAccessibilityManagerWin;
23
24using webkit_glue::WebAccessibility;
25
26////////////////////////////////////////////////////////////////////////////////
27//
28// BrowserAccessibilityWin
29//
30// Class implementing the windows accessible interface for the Browser-Renderer
31// communication of accessibility information, providing accessibility
32// to be used by screen readers and other assistive technology (AT).
33//
34////////////////////////////////////////////////////////////////////////////////
35class BrowserAccessibilityWin
36    : public BrowserAccessibility,
37      public CComObjectRootEx<CComMultiThreadModel>,
38      public IDispatchImpl<IAccessible2, &IID_IAccessible2,
39                           &LIBID_IAccessible2Lib>,
40      public IAccessibleImage,
41      public IAccessibleText,
42      public IServiceProvider,
43      public ISimpleDOMDocument,
44      public ISimpleDOMNode,
45      public ISimpleDOMText {
46 public:
47  BEGIN_COM_MAP(BrowserAccessibilityWin)
48    COM_INTERFACE_ENTRY2(IDispatch, IAccessible2)
49    COM_INTERFACE_ENTRY2(IAccessible, IAccessible2)
50    COM_INTERFACE_ENTRY(IAccessible2)
51    COM_INTERFACE_ENTRY(IAccessibleImage)
52    COM_INTERFACE_ENTRY(IAccessibleText)
53    COM_INTERFACE_ENTRY(IServiceProvider)
54    COM_INTERFACE_ENTRY(ISimpleDOMDocument)
55    COM_INTERFACE_ENTRY(ISimpleDOMNode)
56    COM_INTERFACE_ENTRY(ISimpleDOMText)
57  END_COM_MAP()
58
59  BrowserAccessibilityWin();
60
61  virtual ~BrowserAccessibilityWin();
62
63  //
64  // BrowserAccessibility methods.
65  //
66  virtual void Initialize();
67  virtual void NativeAddReference();
68  virtual void NativeReleaseReference();
69
70  //
71  // IAccessible methods.
72  //
73
74  // Performs the default action on a given object.
75  STDMETHODIMP accDoDefaultAction(VARIANT var_id);
76
77  // Retrieves the child element or child object at a given point on the screen.
78  STDMETHODIMP accHitTest(LONG x_left, LONG y_top, VARIANT* child);
79
80  // Retrieves the specified object's current screen location.
81  STDMETHODIMP accLocation(LONG* x_left,
82                           LONG* y_top,
83                           LONG* width,
84                           LONG* height,
85                           VARIANT var_id);
86
87  // Traverses to another UI element and retrieves the object.
88  STDMETHODIMP accNavigate(LONG nav_dir, VARIANT start, VARIANT* end);
89
90  // Retrieves an IDispatch interface pointer for the specified child.
91  STDMETHODIMP get_accChild(VARIANT var_child, IDispatch** disp_child);
92
93  // Retrieves the number of accessible children.
94  STDMETHODIMP get_accChildCount(LONG* child_count);
95
96  // Retrieves a string that describes the object's default action.
97  STDMETHODIMP get_accDefaultAction(VARIANT var_id, BSTR* default_action);
98
99  // Retrieves the object's description.
100  STDMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc);
101
102  // Retrieves the object that has the keyboard focus.
103  STDMETHODIMP get_accFocus(VARIANT* focus_child);
104
105  // Retrieves the help information associated with the object.
106  STDMETHODIMP get_accHelp(VARIANT var_id, BSTR* help);
107
108  // Retrieves the specified object's shortcut.
109  STDMETHODIMP get_accKeyboardShortcut(VARIANT var_id, BSTR* access_key);
110
111  // Retrieves the name of the specified object.
112  STDMETHODIMP get_accName(VARIANT var_id, BSTR* name);
113
114  // Retrieves the IDispatch interface of the object's parent.
115  STDMETHODIMP get_accParent(IDispatch** disp_parent);
116
117  // Retrieves information describing the role of the specified object.
118  STDMETHODIMP get_accRole(VARIANT var_id, VARIANT* role);
119
120  // Retrieves the current state of the specified object.
121  STDMETHODIMP get_accState(VARIANT var_id, VARIANT* state);
122
123  // Returns the value associated with the object.
124  STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value);
125
126  // Make an object take focus or extend the selection.
127  STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id);
128
129  STDMETHODIMP get_accHelpTopic(BSTR* help_file,
130                                VARIANT var_id,
131                                LONG* topic_id);
132
133  STDMETHODIMP get_accSelection(VARIANT* selected);
134
135  // Deprecated methods, not implemented.
136  STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name) {
137    return E_NOTIMPL;
138  }
139  STDMETHODIMP put_accValue(VARIANT var_id, BSTR put_val) {
140    return E_NOTIMPL;
141  }
142
143  //
144  // IAccessible2 methods.
145  //
146
147  // Returns role from a longer list of possible roles.
148  STDMETHODIMP role(LONG* role);
149
150  // Returns the state bitmask from a larger set of possible states.
151  STDMETHODIMP get_states(AccessibleStates* states);
152
153  // Returns the attributes specific to this IAccessible2 object,
154  // such as a cell's formula.
155  STDMETHODIMP get_attributes(BSTR* attributes);
156
157  // Get the unique ID of this object so that the client knows if it's
158  // been encountered previously.
159  STDMETHODIMP get_uniqueID(LONG* unique_id);
160
161  // Get the window handle of the enclosing window.
162  STDMETHODIMP get_windowHandle(HWND* window_handle);
163
164  // Get this object's index in its parent object.
165  STDMETHODIMP get_indexInParent(LONG* index_in_parent);
166
167  // IAccessible2 methods not implemented.
168  STDMETHODIMP get_extendedRole(BSTR* extended_role) {
169    return E_NOTIMPL;
170  }
171  STDMETHODIMP get_nRelations(LONG* n_relations) {
172    return E_NOTIMPL;
173  }
174  STDMETHODIMP get_relation(LONG relation_index,
175                            IAccessibleRelation** relation) {
176    return E_NOTIMPL;
177  }
178  STDMETHODIMP get_relations(LONG max_relations,
179                             IAccessibleRelation** relations,
180                             LONG* n_relations) {
181    return E_NOTIMPL;
182  }
183  STDMETHODIMP scrollTo(enum IA2ScrollType scroll_type) {
184    return E_NOTIMPL;
185  }
186  STDMETHODIMP scrollToPoint(enum IA2CoordinateType coordinate_type,
187                             LONG x,
188                             LONG y) {
189    return E_NOTIMPL;
190  }
191  STDMETHODIMP get_groupPosition(LONG* group_level,
192                                 LONG* similar_items_in_group,
193                                 LONG* position_in_group) {
194    return E_NOTIMPL;
195  }
196  STDMETHODIMP get_localizedExtendedRole(BSTR* localized_extended_role) {
197    return E_NOTIMPL;
198  }
199  STDMETHODIMP get_nExtendedStates(LONG* n_extended_states) {
200    return E_NOTIMPL;
201  }
202  STDMETHODIMP get_extendedStates(LONG max_extended_states,
203                                  BSTR** extended_states,
204                                  LONG* n_extended_states) {
205    return E_NOTIMPL;
206  }
207  STDMETHODIMP get_localizedExtendedStates(LONG max_localized_extended_states,
208                                           BSTR** localized_extended_states,
209                                           LONG* n_localized_extended_states) {
210    return E_NOTIMPL;
211  }
212  STDMETHODIMP get_locale(IA2Locale* locale) {
213    return E_NOTIMPL;
214  }
215
216  //
217  // IAccessibleImage methods.
218  //
219
220  STDMETHODIMP get_description(BSTR* description);
221
222  STDMETHODIMP get_imagePosition(enum IA2CoordinateType coordinate_type,
223                                 LONG* x, LONG* y);
224
225  STDMETHODIMP get_imageSize(LONG* height, LONG* width);
226
227  //
228  // IAccessibleText methods.
229  //
230
231  STDMETHODIMP get_nCharacters(LONG* n_characters);
232
233  STDMETHODIMP get_caretOffset(LONG* offset);
234
235  STDMETHODIMP get_nSelections(LONG* n_selections);
236
237  STDMETHODIMP get_selection(LONG selection_index,
238                             LONG* start_offset,
239                             LONG* end_offset);
240
241  STDMETHODIMP get_text(LONG start_offset, LONG end_offset, BSTR* text);
242
243  STDMETHODIMP get_textAtOffset(LONG offset,
244                                enum IA2TextBoundaryType boundary_type,
245                                LONG* start_offset, LONG* end_offset,
246                                BSTR* text);
247
248  STDMETHODIMP get_textBeforeOffset(LONG offset,
249                                    enum IA2TextBoundaryType boundary_type,
250                                    LONG* start_offset, LONG* end_offset,
251                                    BSTR* text);
252
253  STDMETHODIMP get_textAfterOffset(LONG offset,
254                                   enum IA2TextBoundaryType boundary_type,
255                                   LONG* start_offset, LONG* end_offset,
256                                   BSTR* text);
257
258  // IAccessibleText methods not implemented.
259  STDMETHODIMP addSelection(LONG start_offset, LONG end_offset) {
260    return E_NOTIMPL;
261  }
262  STDMETHODIMP get_attributes(LONG offset, LONG* start_offset, LONG* end_offset,
263                              BSTR* text_attributes) {
264    return E_NOTIMPL;
265  }
266  STDMETHODIMP get_characterExtents(LONG offset,
267                                    enum IA2CoordinateType coord_type,
268                                    LONG* x, LONG* y,
269                                    LONG* width, LONG* height) {
270    return E_NOTIMPL;
271  }
272  STDMETHODIMP get_offsetAtPoint(LONG x, LONG y,
273                                 enum IA2CoordinateType coord_type,
274                                 LONG* offset) {
275    return E_NOTIMPL;
276  }
277  STDMETHODIMP removeSelection(LONG selection_index) {
278    return E_NOTIMPL;
279  }
280  STDMETHODIMP setCaretOffset(LONG offset) {
281    return E_NOTIMPL;
282  }
283  STDMETHODIMP setSelection(LONG selection_index,
284                            LONG start_offset,
285                            LONG end_offset) {
286    return E_NOTIMPL;
287  }
288  STDMETHODIMP scrollSubstringTo(LONG start_index,
289                                 LONG end_index,
290                                 enum IA2ScrollType scroll_type) {
291    return E_NOTIMPL;
292  }
293  STDMETHODIMP scrollSubstringToPoint(LONG start_index, LONG end_index,
294                                      enum IA2CoordinateType coordinate_type,
295                                      LONG x, LONG y) {
296    return E_NOTIMPL;
297  }
298  STDMETHODIMP get_newText(IA2TextSegment* new_text) {
299    return E_NOTIMPL;
300  }
301  STDMETHODIMP get_oldText(IA2TextSegment* old_text) {
302    return E_NOTIMPL;
303  }
304
305  //
306  // ISimpleDOMDocument methods.
307  //
308
309  STDMETHODIMP get_URL(BSTR* url);
310
311  STDMETHODIMP get_title(BSTR* title);
312
313  STDMETHODIMP get_mimeType(BSTR* mime_type);
314
315  STDMETHODIMP get_docType(BSTR* doc_type);
316
317  STDMETHODIMP get_nameSpaceURIForID(
318      short name_space_id, BSTR *name_space_uri) {
319    return E_NOTIMPL;
320  }
321  STDMETHODIMP put_alternateViewMediaTypes(
322      BSTR *comma_separated_media_types) {
323    return E_NOTIMPL;
324  }
325
326  //
327  // ISimpleDOMNode methods.
328  //
329
330  STDMETHODIMP get_nodeInfo(
331      BSTR* node_name,
332      short* name_space_id,
333      BSTR* node_value,
334      unsigned int* num_children,
335      unsigned int* unique_id,
336      unsigned short* node_type);
337
338  STDMETHODIMP get_attributes(
339      unsigned short max_attribs,
340      BSTR* attrib_names,
341      short* name_space_id,
342      BSTR* attrib_values,
343      unsigned short* num_attribs);
344
345  STDMETHODIMP get_attributesForNames(
346      unsigned short num_attribs,
347      BSTR* attrib_names,
348      short* name_space_id,
349      BSTR* attrib_values);
350
351  STDMETHODIMP get_computedStyle(
352      unsigned short max_style_properties,
353      boolean use_alternate_view,
354      BSTR *style_properties,
355      BSTR *style_values,
356      unsigned short *num_style_properties);
357
358  STDMETHODIMP get_computedStyleForProperties(
359      unsigned short num_style_properties,
360      boolean use_alternate_view,
361      BSTR* style_properties,
362      BSTR* style_values);
363
364  STDMETHODIMP scrollTo(boolean placeTopLeft);
365
366  STDMETHODIMP get_parentNode(ISimpleDOMNode** node);
367
368  STDMETHODIMP get_firstChild(ISimpleDOMNode** node);
369
370  STDMETHODIMP get_lastChild(ISimpleDOMNode** node);
371
372  STDMETHODIMP get_previousSibling(ISimpleDOMNode** node);
373
374  STDMETHODIMP get_nextSibling(ISimpleDOMNode** node);
375
376  STDMETHODIMP get_childAt(
377      unsigned int child_index,
378      ISimpleDOMNode** node);
379
380  STDMETHODIMP get_innerHTML(BSTR* innerHTML) {
381    return E_NOTIMPL;
382  }
383
384  STDMETHODIMP get_localInterface(void** local_interface) {
385    return E_NOTIMPL;
386  }
387
388  STDMETHODIMP get_language(BSTR* language) {
389    return E_NOTIMPL;
390  }
391
392  //
393  // ISimpleDOMText methods.
394  //
395
396  STDMETHODIMP get_domText(BSTR* dom_text);
397
398  STDMETHODIMP get_clippedSubstringBounds(
399      unsigned int start_index,
400      unsigned int end_index,
401      int* x,
402      int* y,
403      int* width,
404      int* height) {
405    return E_NOTIMPL;
406  }
407
408  STDMETHODIMP get_unclippedSubstringBounds(
409      unsigned int start_index,
410      unsigned int end_index,
411      int* x,
412      int* y,
413      int* width,
414      int* height) {
415    return E_NOTIMPL;
416  }
417
418  STDMETHODIMP scrollToSubstring(
419      unsigned int start_index,
420      unsigned int end_index)  {
421    return E_NOTIMPL;
422  }
423
424  STDMETHODIMP get_fontFamily(BSTR *font_family)  {
425    return E_NOTIMPL;
426  }
427
428  //
429  // IServiceProvider methods.
430  //
431
432  STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void** object);
433
434  //
435  // CComObjectRootEx methods.
436  //
437
438  HRESULT WINAPI InternalQueryInterface(void* this_ptr,
439                                        const _ATL_INTMAP_ENTRY* entries,
440                                        REFIID iid,
441                                        void** object);
442
443 private:
444  // Add one to the reference count and return the same object. Always
445  // use this method when returning a BrowserAccessibilityWin object as
446  // an output parameter to a COM interface, never use it otherwise.
447  BrowserAccessibilityWin* NewReference();
448
449  // Many MSAA methods take a var_id parameter indicating that the operation
450  // should be performed on a particular child ID, rather than this object.
451  // This method tries to figure out the target object from |var_id| and
452  // returns a pointer to the target object if it exists, otherwise NULL.
453  // Does not return a new reference.
454  BrowserAccessibilityWin* GetTargetFromChildID(const VARIANT& var_id);
455
456  // Initialize the role and state metadata from the role enum and state
457  // bitmasks defined in webkit/glue/webaccessibility.h.
458  void InitRoleAndState();
459
460  // Retrieve the string value of an attribute from the attribute map and
461  // if found and nonempty, allocate a new BSTR (with SysAllocString)
462  // and return S_OK. If not found or empty, return S_FALSE.
463  HRESULT GetAttributeAsBstr(
464      WebAccessibility::Attribute attribute, BSTR* value_bstr);
465
466  // Escape a string like it would be escaped for a URL or HTML form.
467  string16 Escape(const string16& str);
468
469  // Get the text of this node for the purposes of IAccessibleText - it may
470  // be the name, it may be the value, etc. depending on the role.
471  const string16& TextForIAccessibleText();
472
473  // Search forwards (direction == 1) or backwards (direction == -1) from
474  // the given offset until the given IAccessible2 boundary (like word,
475  // sentence) is found, and return its offset.
476  LONG FindBoundary(const string16& text,
477                    IA2TextBoundaryType boundary,
478                    LONG start_offset,
479                    LONG direction);
480
481  // IAccessible role and state.
482  int32 ia_role_;
483  int32 ia_state_;
484
485  // IAccessible2 role and state.
486  int32 ia2_role_;
487  int32 ia2_state_;
488
489  // Give BrowserAccessibility::Create access to our constructor.
490  friend class BrowserAccessibility;
491
492  DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityWin);
493};
494
495#endif  // CHROME_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_WIN_H_
496