diff options
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/webaccessibility.cc | 253 | ||||
-rw-r--r-- | webkit/glue/webaccessibility.h | 158 | ||||
-rw-r--r-- | webkit/glue/webaccessibilitymanager.h | 62 | ||||
-rw-r--r-- | webkit/glue/webkit_glue.gypi | 4 |
4 files changed, 387 insertions, 90 deletions
diff --git a/webkit/glue/webaccessibility.cc b/webkit/glue/webaccessibility.cc index 33232ca..1af91d6 100644 --- a/webkit/glue/webaccessibility.cc +++ b/webkit/glue/webaccessibility.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,11 +7,16 @@ #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityCache.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityRole.h" +#include "third_party/WebKit/WebKit/chromium/public/WebPoint.h" +#include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" using WebKit::WebAccessibilityCache; using WebKit::WebAccessibilityRole; using WebKit::WebAccessibilityObject; +using WebKit::WebPoint; +using WebKit::WebRect; +using WebKit::WebString; namespace webkit_glue { @@ -96,82 +101,240 @@ WebAccessibility::Role ConvertRole(WebKit::WebAccessibilityRole role) { } } -uint32 ConvertState(const WebAccessibilityObject& o) { - uint32 state = 0; +long ConvertState(const WebAccessibilityObject& o) { + long state = 0; if (o.isChecked()) - state |= (1 << WebAccessibility::STATE_CHECKED); + state |= static_cast<long>(1 << WebAccessibility::STATE_CHECKED); if (o.canSetFocusAttribute()) - state |= (1 << WebAccessibility::STATE_FOCUSABLE); + state |= static_cast<long>(1 << WebAccessibility::STATE_FOCUSABLE); if (o.isFocused()) - state |= (1 << WebAccessibility::STATE_FOCUSED); + state |= static_cast<long>(1 << WebAccessibility::STATE_FOCUSED); if (o.isHovered()) - state |= (1 << WebAccessibility::STATE_HOTTRACKED); + state |= static_cast<long>(1 << WebAccessibility::STATE_HOTTRACKED); if (o.isIndeterminate()) - state |= (1 << WebAccessibility::STATE_INDETERMINATE); + state |= static_cast<long>(1 << WebAccessibility::STATE_INDETERMINATE); if (o.isAnchor()) - state |= (1 << WebAccessibility::STATE_LINKED); + state |= static_cast<long>(1 << WebAccessibility::STATE_LINKED); if (o.isMultiSelectable()) - state |= (1 << WebAccessibility::STATE_MULTISELECTABLE); + state |= static_cast<long>(1 << WebAccessibility::STATE_MULTISELECTABLE); if (o.isOffScreen()) - state |= (1 << WebAccessibility::STATE_OFFSCREEN); + state |= static_cast<long>(1 << WebAccessibility::STATE_OFFSCREEN); if (o.isPressed()) - state |= (1 << WebAccessibility::STATE_PRESSED); + state |= static_cast<long>(1 << WebAccessibility::STATE_PRESSED); if (o.isPasswordField()) - state |= (1 << WebAccessibility::STATE_PROTECTED); + state |= static_cast<long>(1 << WebAccessibility::STATE_PROTECTED); if (o.isReadOnly()) - state |= (1 << WebAccessibility::STATE_READONLY); + state |= static_cast<long>(1 << WebAccessibility::STATE_READONLY); if (o.isVisited()) - state |= (1 << WebAccessibility::STATE_TRAVERSED); + state |= static_cast<long>(1 << WebAccessibility::STATE_TRAVERSED); if (!o.isEnabled()) - state |= (1 << WebAccessibility::STATE_UNAVAILABLE); + state |= static_cast<long>(1 << WebAccessibility::STATE_UNAVAILABLE); return state; } -WebAccessibility::WebAccessibility() - : id(-1), - role(ROLE_NONE), - state(-1) { -} +int32 WebAccessibility::GetAccObjInfo(WebAccessibilityCache* cache, + const WebAccessibility::InParams& in_params, + WebAccessibility::OutParams* out_params) { + // Find object requested by |object_id|. + WebAccessibilityObject active_acc_obj; -WebAccessibility::WebAccessibility(const WebKit::WebAccessibilityObject& src, - WebKit::WebAccessibilityCache* cache) { - Init(src, cache); -} + // Since ids assigned by Chrome starts at 1000, whereas platform-specific ids + // used to reference a child will be in a wholly different range, we know + // that any id that high should be treated as a non-direct descendant. + bool local_child = false; + if (cache->isValidId(in_params.child_id)) { + // Object is not a direct child, re-map the input parameters accordingly. + // The object to be retrieved is referred to by the |in_params.child_id|, as + // a result of e.g. a focus event. + active_acc_obj = cache->getObjectById(in_params.child_id); + } else { + local_child = true; + + active_acc_obj = cache->getObjectById(in_params.object_id); + if (active_acc_obj.isNull()) + return RETURNCODE_FAIL; + + // child_id == 0 means self. Otherwise, it's a local child - 1. + if (in_params.child_id > 0) { + unsigned index = in_params.child_id - 1; + if (index >= active_acc_obj.childCount()) + return RETURNCODE_FAIL; + + active_acc_obj = active_acc_obj.childAt(index); + } + } + + if (active_acc_obj.isNull()) + return RETURNCODE_FAIL; + + // Temp paramters for holding output information. + WebAccessibilityObject out_acc_obj; + string16 out_string; -void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, - WebKit::WebAccessibilityCache* cache) { - name = src.title(); - value = src.stringValue(); - action = src.actionVerb(); - description = src.accessibilityDescription(); - help = src.helpText(); - shortcut = src.keyboardShortcut(); - role = ConvertRole(src.roleValue()); - state = ConvertState(src); - location = src.boundingBoxRect(); - - // Add the source object to the cache and store its id. - id = cache->addOrGetId(src); - - // Recursively create children. - int child_count = src.childCount(); - children.resize(child_count); - for (int i = 0; i < child_count; i++) { - children[i].Init(src.childAt(i), cache); + switch (in_params.function_id) { + case WebAccessibility::FUNCTION_DODEFAULTACTION: { + if (!active_acc_obj.performDefaultAction()) + return RETURNCODE_FALSE; + break; + } + case WebAccessibility::FUNCTION_HITTEST: { + WebPoint point(in_params.input_long1, in_params.input_long2); + out_acc_obj = active_acc_obj.hitTest(point); + if (out_acc_obj.isNull()) + return RETURNCODE_FALSE; + break; + } + case WebAccessibility::FUNCTION_LOCATION: { + WebRect rect = active_acc_obj.boundingBoxRect(); + out_params->output_long1 = rect.x; + out_params->output_long2 = rect.y; + out_params->output_long3 = rect.width; + out_params->output_long4 = rect.height; + break; + } + case WebAccessibility::FUNCTION_NAVIGATE: { + WebAccessibility::Direction dir = + static_cast<WebAccessibility::Direction>(in_params.input_long1); + switch (dir) { + case WebAccessibility::DIRECTION_DOWN: + case WebAccessibility::DIRECTION_UP: + case WebAccessibility::DIRECTION_LEFT: + case WebAccessibility::DIRECTION_RIGHT: + // These directions are not implemented, matching Mozilla and IE. + return RETURNCODE_FALSE; + case WebAccessibility::DIRECTION_LASTCHILD: + case WebAccessibility::DIRECTION_FIRSTCHILD: + // MSDN states that navigating to first/last child can only be from + // self. + if (!local_child) + return RETURNCODE_FALSE; + + if (dir == WebAccessibility::DIRECTION_FIRSTCHILD) { + out_acc_obj = active_acc_obj.firstChild(); + } else { + out_acc_obj = active_acc_obj.lastChild(); + } + break; + case WebAccessibility::DIRECTION_NEXT: + case WebAccessibility::DIRECTION_PREVIOUS: { + if (dir == WebAccessibility::DIRECTION_NEXT) { + out_acc_obj = active_acc_obj.nextSibling(); + } else { + out_acc_obj = active_acc_obj.previousSibling(); + } + break; + } + default: + return RETURNCODE_FALSE; + } + + if (out_acc_obj.isNull()) + return RETURNCODE_FALSE; + + break; + } + case WebAccessibility::FUNCTION_GETCHILD: { + out_params->object_id = in_params.object_id; + out_acc_obj = active_acc_obj; + break; + } + case WebAccessibility::FUNCTION_CHILDCOUNT: { + out_params->output_long1 = active_acc_obj.childCount(); + break; + } + case WebAccessibility::FUNCTION_DEFAULTACTION: { + out_string = active_acc_obj.actionVerb(); + if (out_string.empty()) + return RETURNCODE_FALSE; + break; + } + case WebAccessibility::FUNCTION_DESCRIPTION: { + out_string = active_acc_obj.accessibilityDescription(); + if (out_string.empty()) + return RETURNCODE_FALSE; + // From the Mozilla MSAA implementation: + // "Signal to screen readers that this description is speakable and is not + // a formatted positional information description. Don't localize the + // 'Description: ' part of this string, it will be parsed out by assistive + // technologies." + out_string = L"Description: " + out_string; + break; + } + case WebAccessibility::FUNCTION_GETFOCUSEDCHILD: { + out_acc_obj = active_acc_obj.focusedChild(); + if (out_acc_obj.isNull()) + return RETURNCODE_FALSE; + break; + } + case WebAccessibility::FUNCTION_HELPTEXT: { + out_string = active_acc_obj.helpText(); + if (out_string.empty()) + return RETURNCODE_FALSE; + break; + } + case WebAccessibility::FUNCTION_KEYBOARDSHORTCUT: { + out_string = active_acc_obj.keyboardShortcut(); + if (out_string.empty()) + return RETURNCODE_FALSE; + break; + } + case WebAccessibility::FUNCTION_NAME: { + out_string = active_acc_obj.title(); + if (out_string.empty()) + return RETURNCODE_FALSE; + break; + } + case WebAccessibility::FUNCTION_GETPARENT: { + out_acc_obj = active_acc_obj.parentObject(); + if (out_acc_obj.isNull()) + return RETURNCODE_FALSE; + break; + } + case WebAccessibility::FUNCTION_ROLE: { + out_params->output_long1 = ConvertRole(active_acc_obj.roleValue()); + break; + } + case WebAccessibility::FUNCTION_STATE: { + out_params->output_long1 = ConvertState(active_acc_obj); + break; + } + case WebAccessibility::FUNCTION_VALUE: { + out_string = active_acc_obj.stringValue(); + if (out_string.empty()) + return RETURNCODE_FALSE; + break; + } + default: + // Non-supported function id. + return RETURNCODE_FAIL; } + + // Output and hashmap assignments, as appropriate. + if (!out_string.empty()) + out_params->output_string = out_string; + + if (out_acc_obj.isNull()) + return RETURNCODE_TRUE; + + int id = cache->addOrGetId(out_acc_obj); + out_params->object_id = id; + out_params->output_long1 = -1; + + // TODO(ctguil): Handle simple objects returned. + return RETURNCODE_TRUE; } } // namespace webkit_glue diff --git a/webkit/glue/webaccessibility.h b/webkit/glue/webaccessibility.h index ea000e7..4bfd7743 100644 --- a/webkit/glue/webaccessibility.h +++ b/webkit/glue/webaccessibility.h @@ -1,16 +1,11 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef WEBKIT_GLUE_WEBACCESSIBILITY_H_ #define WEBKIT_GLUE_WEBACCESSIBILITY_H_ -#include <vector> - #include "base/string16.h" -#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h" -#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityRole.h" -#include "third_party/WebKit/WebKit/chromium/public/WebRect.h" namespace WebKit { class WebAccessibilityCache; @@ -18,15 +13,62 @@ class WebAccessibilityCache; namespace webkit_glue { -// A compact representation of the accessibility information for a -// single web object, in a form that can be serialized and sent from -// the renderer process to the browser process. -struct WebAccessibility { +class WebAccessibility { public: - // An alphabetical enumeration of accessibility roles. - enum Role { - ROLE_NONE = 0, + // This defines an enumeration of IDs that can uniquely identify a call to a + // specific accessibility information function. Should match the support + // implemented in WebKit and GlueAccessibilityObject (functions marked with + // return value E_NOTIMPL in WebKit are also excluded). + enum Function { + FUNCTION_NONE = 0, + + // Supported accessibility information retrieval functions. + FUNCTION_DODEFAULTACTION, + FUNCTION_HITTEST, + FUNCTION_LOCATION, + FUNCTION_NAVIGATE, + FUNCTION_GETCHILD, + FUNCTION_CHILDCOUNT, + FUNCTION_DEFAULTACTION, + FUNCTION_DESCRIPTION, + FUNCTION_GETFOCUSEDCHILD, + FUNCTION_HELPTEXT, + FUNCTION_KEYBOARDSHORTCUT, + FUNCTION_NAME, + FUNCTION_GETPARENT, + FUNCTION_ROLE, + FUNCTION_STATE, + FUNCTION_VALUE + + // The deprecated put_accName and put_accValue (IAccessible) are not + // supported here, nor is accSelect, get_accHelpTopic and get_accSelection + // (matching WebKit's support for IAccessible). + }; + + // This defines an enumeration of navigation directions based on (but + // independent of) the MSAA Navigation Constants. However, to avoid the use of + // COM in our Glue layer, we use this as a substitute with a one-to-one + // conversion between Browser side (has COM) and Glue. + enum Direction { + DIRECTION_NONE = 0, + // Valid directions. + DIRECTION_UP, + DIRECTION_DOWN, + DIRECTION_LEFT, + DIRECTION_RIGHT, + DIRECTION_NEXT, + DIRECTION_PREVIOUS, + DIRECTION_FIRSTCHILD, + DIRECTION_LASTCHILD + }; + + // This defines an enumeration (in alphabetical order) of the supported + // accessibility roles in our Glue layer (used in + // GlueAccessibilityObject::Role). Any interface using roles must provide a + // conversion to its own roles (see e.g. BrowserAccessibility::get_accRole and + // BrowserAccessibility::MSAARole). + enum Role { ROLE_APPLICATION, ROLE_CELL, ROLE_CHECKBUTTON, @@ -57,14 +99,14 @@ struct WebAccessibility { ROLE_TABLE, ROLE_TEXT, ROLE_TOOLBAR, - ROLE_TOOLTIP, - NUM_ROLES + ROLE_TOOLTIP }; - // An alphabetical enumeration of accessibility states. - // A state bitmask is formed by shifting 1 to the left by each state, - // for example: - // int mask = (1 << STATE_CHECKED) | (1 << STATE_FOCUSED); + // This defines an enumeration (in alphabetical order) of the supported + // accessibility states in our Glue layer (used in + // GlueAccessibilityObject::State). Any interface using states must provide a + // conversion to its own states (see e.g. BrowserAccessibility::get_accState + // and BrowserAccessibility::MSAAState). enum State { STATE_CHECKED, STATE_FOCUSABLE, @@ -81,32 +123,58 @@ struct WebAccessibility { STATE_UNAVAILABLE }; - // Empty constructor, for serialization. - WebAccessibility(); - - // Construct from a WebAccessibilityObject. Recursively creates child - // nodes as needed to complete the tree. Adds |src| to |cache| and - // stores its cache ID. - WebAccessibility(const WebKit::WebAccessibilityObject& src, - WebKit::WebAccessibilityCache* cache); - - // Initialize an already-created struct, same as the constructor a - void Init(const WebKit::WebAccessibilityObject& src, - WebKit::WebAccessibilityCache* cache); - - // This is a simple serializable struct. All member variables should be - // copyable. - int32 id; - string16 name; - string16 value; - string16 action; - string16 description; - string16 help; - string16 shortcut; - Role role; - uint32 state; - WebKit::WebRect location; - std::vector<WebAccessibility> children; + enum ReturnCode { + RETURNCODE_TRUE, // MSAA S_OK + RETURNCODE_FALSE, // MSAA S_FALSE + RETURNCODE_FAIL // E_FAIL + }; + + // Parameters structure to hold a union of the possible accessibility function + // INPUT variables, with the unused fields always set to default value. Used + // in ViewMsg_GetAccessibilityInfo, as only parameter. + struct InParams { + // Identifier to uniquely distinguish which instance of accessibility + // information is being called upon on the renderer side. + int object_id; + + // Identifier to resolve which accessibility information retrieval function + // is being called. + int function_id; + + // Id of accessible child, whose information is being requested. + int child_id; + + // LONG input parameters, used differently depending on the function called. + long input_long1; + long input_long2; + }; + + // Parameters structure to hold a union of the possible accessibility function + // OUTPUT variables, with the unused fields always set to default value. Used + // in ViewHostMsg_GetAccessibilityInfoResponse, as only parameter. + struct OutParams { + // Identifier to uniquely distinguish which instance of accessibility + // information is being called upon on the renderer side. + int object_id; + + // LONG output parameters, used differently depending on the function + // called. [output_long1] can in some cases be set to -1 to indicate that + // the child object found by the called IAccessible function is not a simple + // object. + long output_long1; + long output_long2; + long output_long3; + long output_long4; + + // String output parameter. + string16 output_string; + + // Return code of the accessibility function call. + int32 return_code; + }; + + static int32 GetAccObjInfo(WebKit::WebAccessibilityCache* cache, + const InParams& in_params, OutParams* out_params); }; } // namespace webkit_glue diff --git a/webkit/glue/webaccessibilitymanager.h b/webkit/glue/webaccessibilitymanager.h new file mode 100644 index 0000000..2debcb7 --- /dev/null +++ b/webkit/glue/webaccessibilitymanager.h @@ -0,0 +1,62 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_GLUE_WEBACCESSIBILITYMANAGER_H_ +#define WEBKIT_GLUE_WEBACCESSIBILITYMANAGER_H_ + +#include "webkit/glue/webaccessibility.h" + +namespace WebKit { +class WebAccessibilityObject; +class WebView; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// WebAccessibilityManager +// +// Responds to incoming accessibility requests from the browser side. Retrieves +// the requested information from the active AccessibilityObject, through the +// GlueAccessibilityObject. +//////////////////////////////////////////////////////////////////////////////// +namespace webkit_glue { + +class WebAccessibilityManager { + public: + WebAccessibilityManager() {} + virtual ~WebAccessibilityManager() {} + + // Creates a new instance of WebAccessibilityManager. + static WebAccessibilityManager* Create(); + + // Retrieves the accessibility information as requested in in_params, by + // calling into WebKit's AccessibilityObject. Maintains a hashmap of the + // currently active (browser side ref-count non-zero) instances. Returns true + // if successful, false otherwise. + virtual bool GetAccObjInfo(WebKit::WebView* view, + const WebAccessibility::InParams& in_params, + WebAccessibility::OutParams* out_params) = 0; + + // Erases the entry identified by the [acc_obj_id] from the hash maps. If + // [clear_all] is true, all entries are erased. Returns true if successful, + // false otherwise. + virtual bool ClearAccObjMap(int acc_obj_id, bool clear_all) = 0; + + // Retrieves the id of the input AccessibilityObject, due to a focus event. + // Returns an id greater than or equal to 0 if successful, -1 otherwise. + virtual int FocusAccObj(const WebKit::WebAccessibilityObject& object) = 0; + + private: + // Retrieves the RenderObject associated with this WebView, and uses it to + // initialize the root of the GlueAccessibilityObject tree with the + // associated accessibility information. Returns true if successful, false + // otherwise. + virtual bool InitAccObjRoot(WebKit::WebView* view) = 0; + + DISALLOW_COPY_AND_ASSIGN(WebAccessibilityManager); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_WEBACCESSIBILITYMANAGER_H_ diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index aec0904..e6b3a35 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -332,6 +332,10 @@ ['OS!="win"', { 'sources/': [['exclude', '_win\\.cc$']], 'sources!': [ + # These files are Windows-only now but may be ported to other + # platforms. + 'webaccessibility.cc', + 'webaccessibility.h', 'webthemeengine_impl_win.cc', ], }, { # else: OS=="win" |