diff options
author | klink@chromium.org <klink@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-20 00:53:06 +0000 |
---|---|---|
committer | klink@chromium.org <klink@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-20 00:53:06 +0000 |
commit | e846d0dba2bf9506a929c9e16294997e37014039 (patch) | |
tree | 5ac70d2216fd450b3d4f164a26f752504c8cb220 /webkit/glue | |
parent | fabd89f6aa700cb0e59b04e92ce54e729cbd0c66 (diff) | |
download | chromium_src-e846d0dba2bf9506a929c9e16294997e37014039.zip chromium_src-e846d0dba2bf9506a929c9e16294997e37014039.tar.gz chromium_src-e846d0dba2bf9506a929c9e16294997e37014039.tar.bz2 |
Adds propagation and handling of render-side focus events, for the benefit of assistive technologies (accessibility). Also cleans up the handling of WM_GETOBJECT in RenderWidgetHostViewWin and WidgetWin, as well as in BrowserAccessibilityManager.
Review URL: http://codereview.chromium.org/115374
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16449 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/chrome_client_impl.cc | 33 | ||||
-rw-r--r-- | webkit/glue/chrome_client_impl.h | 5 | ||||
-rw-r--r-- | webkit/glue/glue_accessibility_object.cc | 2 | ||||
-rw-r--r-- | webkit/glue/glue_accessibility_object.h | 3 | ||||
-rw-r--r-- | webkit/glue/webaccessibility.h | 4 | ||||
-rw-r--r-- | webkit/glue/webaccessibilitymanager.h | 11 | ||||
-rw-r--r-- | webkit/glue/webaccessibilitymanager_impl.cc | 79 | ||||
-rw-r--r-- | webkit/glue/webaccessibilitymanager_impl.h | 26 | ||||
-rw-r--r-- | webkit/glue/webview_delegate.h | 11 | ||||
-rw-r--r-- | webkit/glue/webview_impl.h | 6 |
10 files changed, 136 insertions, 44 deletions
diff --git a/webkit/glue/chrome_client_impl.cc b/webkit/glue/chrome_client_impl.cc index b235d35..9553e93 100644 --- a/webkit/glue/chrome_client_impl.cc +++ b/webkit/glue/chrome_client_impl.cc @@ -7,8 +7,11 @@ #include "base/compiler_specific.h" MSVC_PUSH_WARNING_LEVEL(0); +#include "AccessibilityObject.h" +#include "AXObjectCache.h" #include "Console.h" #include "Cursor.h" +#include "Document.h" #include "DocumentLoader.h" #include "FloatRect.h" #include "FileChooser.h" @@ -16,6 +19,7 @@ MSVC_PUSH_WARNING_LEVEL(0); #include "FrameView.h" #include "HitTestResult.h" #include "IntRect.h" +#include "Node.h" #include "Page.h" #include "PopupMenuChromium.h" #include "ScriptController.h" @@ -29,7 +33,6 @@ MSVC_POP_WARNING(); #include "webkit/glue/chrome_client_impl.h" -#include "base/logging.h" #include "base/gfx/rect.h" #include "googleurl/src/gurl.h" #include "webkit/api/public/WebInputEvent.h" @@ -141,6 +144,28 @@ void ChromeClientImpl::focus() { WebViewDelegate* delegate = webview_->delegate(); if (delegate) delegate->Focus(webview_); + + // If accessibility is enabled, we should notify assistive technology that the + // active AccessibilityObject changed. + WebCore::Document* doc = webview_->GetFocusedWebCoreFrame()->document(); + + if (doc && doc->axObjectCache()->accessibilityEnabled()) { + WebCore::Node* focused_node = webview_->GetFocusedNode(); + + if (!focused_node) { + // Could not retrieve focused Node. + return; + } + + // Retrieve the focused AccessibilityObject. + WebCore::AccessibilityObject* focused_acc_obj = + doc->axObjectCache()->getOrCreate(focused_node->renderer()); + + // Alert assistive technology that focus changed. + if (focused_acc_obj) { + delegate->FocusAccessibilityObject(focused_acc_obj); + } + } } void ChromeClientImpl::unfocus() { @@ -201,7 +226,8 @@ static inline bool CurrentEventShouldCauseBackgroundTab( if (input_event->type != WebInputEvent::MouseUp) return false; - const WebMouseEvent* mouse_event = static_cast<const WebMouseEvent*>(input_event); + const WebMouseEvent* mouse_event = + static_cast<const WebMouseEvent*>(input_event); return (mouse_event->button == WebMouseEvent::ButtonMiddle); } @@ -294,7 +320,8 @@ void ChromeClientImpl::addMessageToConsole(WebCore::MessageSource source, } WebDevToolsAgentImpl* devtools_agent = webview_->GetWebDevToolsAgentImpl(); if (devtools_agent) { - devtools_agent->AddMessageToConsole(source, level, message, line_no, source_id); + devtools_agent->AddMessageToConsole(source, level, message, line_no, + source_id); } } diff --git a/webkit/glue/chrome_client_impl.h b/webkit/glue/chrome_client_impl.h index e372f7c..3a3fdc5 100644 --- a/webkit/glue/chrome_client_impl.h +++ b/webkit/glue/chrome_client_impl.h @@ -24,7 +24,7 @@ struct WindowFeatures; // Handles window-level notifications from WebCore on behalf of a WebView. class ChromeClientImpl : public WebCore::ChromeClientChromium { public: - ChromeClientImpl(WebViewImpl* webview); + explicit ChromeClientImpl(WebViewImpl* webview); virtual ~ChromeClientImpl(); WebViewImpl* webview() const { return webview_; } @@ -67,7 +67,8 @@ class ChromeClientImpl : public WebCore::ChromeClientChromium { virtual void setResizable(bool); virtual void addMessageToConsole(WebCore::MessageSource source, - WebCore::MessageLevel level, const WebCore::String& message, + WebCore::MessageLevel level, + const WebCore::String& message, unsigned int lineNumber, const WebCore::String& sourceID); diff --git a/webkit/glue/glue_accessibility_object.cc b/webkit/glue/glue_accessibility_object.cc index 17a693e..8c056eb 100644 --- a/webkit/glue/glue_accessibility_object.cc +++ b/webkit/glue/glue_accessibility_object.cc @@ -134,7 +134,7 @@ GlueAccessibilityObject* GlueAccessibilityObject::Navigate( GlueAccessibilityObject* GlueAccessibilityObject::GetChild(int child_id) { AccessibilityObject* child_obj; if (!GetAccessibilityObjectForChild(child_id, child_obj)) - return false; + return NULL; // TODO(klink): simple object child? ToWrapper(child_obj)->ref(); diff --git a/webkit/glue/glue_accessibility_object.h b/webkit/glue/glue_accessibility_object.h index 137a7e3..f94f9a1 100644 --- a/webkit/glue/glue_accessibility_object.h +++ b/webkit/glue/glue_accessibility_object.h @@ -27,6 +27,8 @@ class GlueAccessibilityObject : public WebCore::AccessibilityObjectWrapper { public: static GlueAccessibilityObject* CreateInstance(WebCore::AccessibilityObject*); + virtual ~GlueAccessibilityObject() {} + // Performs the default action on a given object. bool DoDefaultAction(int child_id); @@ -91,7 +93,6 @@ class GlueAccessibilityObject : public WebCore::AccessibilityObjectWrapper { protected: explicit GlueAccessibilityObject(WebCore::AccessibilityObject*); - virtual ~GlueAccessibilityObject() {} // Helper functions. WebCore::String name() const; diff --git a/webkit/glue/webaccessibility.h b/webkit/glue/webaccessibility.h index 538e612..250c665 100644 --- a/webkit/glue/webaccessibility.h +++ b/webkit/glue/webaccessibility.h @@ -117,6 +117,10 @@ class WebAccessibility { // Id of accessible child, whose information is being requested. int child_id; + // Indicates if the |child_id| refers to a direct child of the active + // accessibility object (true) or not (false). + bool direct_descendant; + // LONG input parameters, used differently depending on the function called. long input_long1; long input_long2; diff --git a/webkit/glue/webaccessibilitymanager.h b/webkit/glue/webaccessibilitymanager.h index cebe94c..c94fbb9 100644 --- a/webkit/glue/webaccessibilitymanager.h +++ b/webkit/glue/webaccessibilitymanager.h @@ -7,6 +7,10 @@ #include "webkit/glue/webaccessibility.h" +namespace WebCore { +class AccessibilityObject; +} + class WebView; //////////////////////////////////////////////////////////////////////////////// @@ -24,6 +28,7 @@ class WebAccessibilityManager { WebAccessibilityManager() {} virtual ~WebAccessibilityManager() {} + // Creates a new instance of WebAccessibilityManager. static WebAccessibilityManager* Create(); // Retrieves the accessibility information as requested in in_params, by @@ -39,13 +44,17 @@ class WebAccessibilityManager { // 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(WebCore::AccessibilityObject* acc_obj) = 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(WebView* view) = 0; - private: DISALLOW_COPY_AND_ASSIGN(WebAccessibilityManager); }; diff --git a/webkit/glue/webaccessibilitymanager_impl.cc b/webkit/glue/webaccessibilitymanager_impl.cc index 57ac0c7..f765127 100644 --- a/webkit/glue/webaccessibilitymanager_impl.cc +++ b/webkit/glue/webaccessibilitymanager_impl.cc @@ -34,7 +34,13 @@ WebAccessibilityManager* WebAccessibilityManager::Create() { // class WebAccessibilityManagerImpl WebAccessibilityManagerImpl::WebAccessibilityManagerImpl() - : root_(new GlueAccessibilityObjectRoot) { + : root_(new GlueAccessibilityObjectRoot), + acc_obj_id_(0) { +} + +WebAccessibilityManagerImpl::~WebAccessibilityManagerImpl() { + int_to_glue_acc_obj_map_.clear(); + acc_obj_to_int_map_.clear(); } bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view, @@ -45,18 +51,28 @@ bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view, return false; } - // Find GlueAccessibilityObject requested by [in_params.object_id]. - IntToAccObjMap::iterator it = - int_to_acc_obj_map_.find(in_params.object_id); - if (it == int_to_acc_obj_map_.end() || !it->second) { + // Function input parameters. + int object_id = in_params.object_id; + int child_id = in_params.child_id; + + if (!in_params.direct_descendant) { + // 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. The local |child_id| is set to 0, to + // indicate that any function call should refer to the object itself. + object_id = in_params.child_id; + child_id = 0; + } + + // Find GlueAccessibilityObject requested by |object_id|. + IntToGlueAccObjMap::iterator it = + int_to_glue_acc_obj_map_.find(object_id); + if (it == int_to_glue_acc_obj_map_.end() || !it->second) { // Map did not contain a valid instance of the data requested. return false; } RefPtr<GlueAccessibilityObject> active_acc_obj = it->second; - // Function input parameters. - int child_id = in_params.child_id; - // Temp paramters for holding output information. RefPtr<GlueAccessibilityObject> out_acc_obj = NULL; WebCore::String out_string; @@ -156,7 +172,8 @@ bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view, out_params->output_string = StringToString16(out_string); if (out_acc_obj) { - AccObjToIntMap::iterator it = acc_obj_to_int_map_.find(out_acc_obj.get()); + AccObjToIntMap::iterator it = + acc_obj_to_int_map_.find(out_acc_obj->accessibilityObject()); if (it != acc_obj_to_int_map_.end()) { // Data already present in map, return previously assigned id. @@ -164,8 +181,8 @@ bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view, out_params->output_long1 = -1; } else { // Insert new GlueAccessibilityObject in hashmaps. - int_to_acc_obj_map_[acc_obj_id_] = out_acc_obj.get(); - acc_obj_to_int_map_[out_acc_obj.get()] = acc_obj_id_; + int_to_glue_acc_obj_map_[acc_obj_id_] = out_acc_obj.get(); + acc_obj_to_int_map_[out_acc_obj->accessibilityObject()] = acc_obj_id_; out_params->object_id = acc_obj_id_++; out_params->output_long1 = -1; } @@ -175,9 +192,6 @@ bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view, } bool WebAccessibilityManagerImpl::InitAccObjRoot(WebView* view) { - // Root id is always 0. - acc_obj_id_ = 0; - // Enable accessibility and retrieve Document. WebCore::AXObjectCache::enableAccessibility(); WebFrameImpl* main_frame_impl = @@ -199,8 +213,9 @@ bool WebAccessibilityManagerImpl::InitAccObjRoot(WebView* view) { axObjectCache()->getOrCreate(doc->renderer())); } // Insert root in hashmaps. - int_to_acc_obj_map_[acc_obj_id_] = root_->acc_obj_root_.get(); - acc_obj_to_int_map_[root_->acc_obj_root_.get()] = acc_obj_id_++; + int_to_glue_acc_obj_map_[acc_obj_id_] = root_->acc_obj_root_.get(); + acc_obj_to_int_map_[root_->acc_obj_root_->accessibilityObject()] = + acc_obj_id_++; return true; } @@ -209,27 +224,28 @@ bool WebAccessibilityManagerImpl::ClearAccObjMap(int acc_obj_id, bool clear_all) { if (clear_all) { // Clear maps and invalidate root. - int_to_acc_obj_map_.clear(); + int_to_glue_acc_obj_map_.clear(); acc_obj_to_int_map_.clear(); root_->acc_obj_root_ = 0; return true; } - IntToAccObjMap::iterator it = int_to_acc_obj_map_.find(acc_obj_id); + IntToGlueAccObjMap::iterator it = int_to_glue_acc_obj_map_.find(acc_obj_id); - if (it == int_to_acc_obj_map_.end()) { + if (it == int_to_glue_acc_obj_map_.end()) { // Element not found. return false; } if (it->second) { // Erase element from reverse hashmap. - AccObjToIntMap::iterator it2 = acc_obj_to_int_map_.find(it->second); + AccObjToIntMap::iterator it2 = + acc_obj_to_int_map_.find(it->second->accessibilityObject()); if (it2 != acc_obj_to_int_map_.end()) acc_obj_to_int_map_.erase(it2); } - int_to_acc_obj_map_.erase(it); + int_to_glue_acc_obj_map_.erase(it); if (acc_obj_id == 0) { // Invalidate root. @@ -238,4 +254,25 @@ bool WebAccessibilityManagerImpl::ClearAccObjMap(int acc_obj_id, return true; } +int WebAccessibilityManagerImpl::FocusAccObj( + WebCore::AccessibilityObject* acc_obj) { + if (!acc_obj) { + // Return with failure. + return -1; + } + + AccObjToIntMap::iterator it = acc_obj_to_int_map_.find(acc_obj); + + if (it != acc_obj_to_int_map_.end()) + return it->second; + + // Insert new accessibility object in hashmaps and return its newly + // assigned accessibility object id. + int_to_glue_acc_obj_map_[acc_obj_id_] = + GlueAccessibilityObject::CreateInstance(acc_obj); + acc_obj_to_int_map_[acc_obj] = acc_obj_id_; + + return acc_obj_id_++; +} + } // namespace webkit_glue diff --git a/webkit/glue/webaccessibilitymanager_impl.h b/webkit/glue/webaccessibilitymanager_impl.h index fe28e4e..1bc0607 100644 --- a/webkit/glue/webaccessibilitymanager_impl.h +++ b/webkit/glue/webaccessibilitymanager_impl.h @@ -10,10 +10,6 @@ class GlueAccessibilityObject; -namespace webkit_glue { -typedef base::hash_map<int, GlueAccessibilityObject*> IntToAccObjMap; -typedef base::hash_map<GlueAccessibilityObject*, int> AccObjToIntMap; - //////////////////////////////////////////////////////////////////////////////// // // WebAccessibilityManagerImpl @@ -24,21 +20,23 @@ typedef base::hash_map<GlueAccessibilityObject*, int> AccObjToIntMap; // the requested information from the active AccessibilityObject, through the // GlueAccessibilityObject. //////////////////////////////////////////////////////////////////////////////// + +namespace webkit_glue { + class WebAccessibilityManagerImpl : public WebAccessibilityManager { public: // From WebAccessibilityManager. bool GetAccObjInfo(WebView* view, const WebAccessibility::InParams& in_params, WebAccessibility::OutParams* out_params); - - // From WebAccessibilityManager. bool ClearAccObjMap(int acc_obj_id, bool clear_all); + int FocusAccObj(WebCore::AccessibilityObject* acc_obj); protected: // Needed so WebAccessibilityManager::Create can call our constructor. friend class WebAccessibilityManager; WebAccessibilityManagerImpl(); - ~WebAccessibilityManagerImpl() {} + ~WebAccessibilityManagerImpl(); private: // From WebAccessibilityManager. @@ -49,17 +47,21 @@ class WebAccessibilityManagerImpl : public WebAccessibilityManager { struct GlueAccessibilityObjectRoot; GlueAccessibilityObjectRoot* root_; + typedef base::hash_map<int, GlueAccessibilityObject*> IntToGlueAccObjMap; + typedef base::hash_map<WebCore::AccessibilityObject*, int> AccObjToIntMap; + // Hashmap for cashing of elements in use by the AT, mapping id (int) to a // GlueAccessibilityObject pointer. - IntToAccObjMap int_to_acc_obj_map_; + IntToGlueAccObjMap int_to_glue_acc_obj_map_; // Hashmap for cashing of elements in use by the AT, mapping a - // GlueAccessibilityObject pointer to its id (int). Needed for reverse lookup, + // AccessibilityObject pointer to its id (int). Needed for reverse lookup, // to ensure unnecessary duplicate entries are not created in the - // IntToAccObjMap (above). + // IntToGlueAccObjMap (above) and for focus changes in WebKit. AccObjToIntMap acc_obj_to_int_map_; - // Unique identifier for retrieving a GlueAccessibilityObject from the page's - // hashmaps. + // Unique identifier for retrieving an accessibility object from the page's + // hashmaps. Id is always 0 for the root of the accessibility object + // hierarchy (on a per-renderer process basis). int acc_obj_id_; DISALLOW_COPY_AND_ASSIGN(WebAccessibilityManagerImpl); diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h index 525f745..7d503ad 100644 --- a/webkit/glue/webview_delegate.h +++ b/webkit/glue/webview_delegate.h @@ -37,6 +37,10 @@ namespace webkit_glue { class WebMediaPlayerDelegate; } +namespace WebCore { +class AccessibilityObject; +} + namespace WebKit { class WebDragData; class WebWorker; @@ -169,6 +173,13 @@ class WebViewDelegate : virtual public WebWidgetDelegate { return true; } + // Called by ChromeClientImpl::focus() if accessibility on the renderer side + // is enabled, and a focus change has occurred. Will retrieve the id of the + // input AccessibilityObject and send it through IPC for handling on the + // browser side. + virtual void FocusAccessibilityObject(WebCore::AccessibilityObject* acc_obj) { + } + // FrameLoaderClient ------------------------------------------------------- // Notifies the delegate that a load has begun. diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h index ae26890..caac1c8 100644 --- a/webkit/glue/webview_impl.h +++ b/webkit/glue/webview_impl.h @@ -138,6 +138,9 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { WebCore::Frame* GetFocusedWebCoreFrame(); + // Returns the currently focused Node or NULL if no node has focus. + WebCore::Node* GetFocusedNode(); + static WebViewImpl* FromPage(WebCore::Page* page); WebViewDelegate* delegate() { @@ -285,9 +288,6 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { WebCore::HitTestResult HitTestResultForWindowPos( const WebCore::IntPoint& pos); - // Returns the currently focused Node or NULL if no node has focus. - WebCore::Node* GetFocusedNode(); - // ImageResourceFetchers schedule via DownloadImage. std::set<ImageResourceFetcher*> image_fetchers_; |