diff options
author | ctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-03 19:10:00 +0000 |
---|---|---|
committer | ctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-03 19:10:00 +0000 |
commit | 02747d4e2fcd7211cf2fe0851d15d7c8a9341b54 (patch) | |
tree | 9f3db8a5df43293cb5ac1f8612d48273009ff641 | |
parent | 604890c160d3f9383907b80585491fa282abbbd8 (diff) | |
download | chromium_src-02747d4e2fcd7211cf2fe0851d15d7c8a9341b54.zip chromium_src-02747d4e2fcd7211cf2fe0851d15d7c8a9341b54.tar.gz chromium_src-02747d4e2fcd7211cf2fe0851d15d7c8a9341b54.tar.bz2 |
Add basic support for accessibility hit testing within web contents.
BUG=59890
TEST=Manual. Inspect32.
Review URL: http://codereview.chromium.org/4292001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64943 0039d316-1c4b-4281-b951-d872f2087c98
8 files changed, 124 insertions, 57 deletions
diff --git a/chrome/browser/accessibility/browser_accessibility.cc b/chrome/browser/accessibility/browser_accessibility.cc index 21a1dc0..42cc878 100644 --- a/chrome/browser/accessibility/browser_accessibility.cc +++ b/chrome/browser/accessibility/browser_accessibility.cc @@ -5,6 +5,7 @@ #include "chrome/browser/accessibility/browser_accessibility.h" #include "base/logging.h" +#include "base/string_number_conversions.h" #include "chrome/browser/accessibility/browser_accessibility_manager.h" BrowserAccessibility::BrowserAccessibility() @@ -110,3 +111,65 @@ BrowserAccessibility* BrowserAccessibility::GetNextSibling() { return NULL; } + +gfx::Rect BrowserAccessibility::GetBoundsRect() { + gfx::Rect bounds = location_; + + // Adjust the bounds by the top left corner of the containing view's bounds + // in screen coordinates. + gfx::Point top_left = manager_->GetViewBounds().origin(); + bounds.Offset(top_left); + + // Adjust top left position by the root document's scroll offset. + BrowserAccessibility* root = manager_->GetRoot(); + int scroll_x = 0; + int scroll_y = 0; + root->GetAttributeAsInt( + WebAccessibility::ATTR_DOC_SCROLLX, &scroll_x); + root->GetAttributeAsInt( + WebAccessibility::ATTR_DOC_SCROLLY, &scroll_y); + bounds.Offset(-scroll_x, -scroll_y); + + return bounds; +} + +BrowserAccessibility* BrowserAccessibility::BrowserAccessibilityForPoint( + const gfx::Point& point) { + // Walk the children recursively looking for the BrowserAccessibility that + // most tightly encloses the specified point. + for (int i = children_.size() - 1; i >= 0; --i) { + BrowserAccessibility* child = children_[i]; + if (child->GetBoundsRect().Contains(point)) + return child->BrowserAccessibilityForPoint(point); + } + return this; +} + +bool BrowserAccessibility::HasAttribute( + WebAccessibility::Attribute attribute) { + return (attributes_.find(attribute) != attributes_.end()); +} + +bool BrowserAccessibility::GetAttribute( + WebAccessibility::Attribute attribute, string16* value) { + std::map<int32, string16>::iterator iter = attributes_.find(attribute); + if (iter != attributes_.end()) { + *value = iter->second; + return true; + } + + return false; +} + +bool BrowserAccessibility::GetAttributeAsInt( + WebAccessibility::Attribute attribute, int* value_int) { + string16 value_str; + + if (!GetAttribute(attribute, &value_str)) + return false; + + if (!base::StringToInt(value_str, value_int)) + return false; + + return true; +} diff --git a/chrome/browser/accessibility/browser_accessibility.h b/chrome/browser/accessibility/browser_accessibility.h index 2e39ba0..7bd4a63 100644 --- a/chrome/browser/accessibility/browser_accessibility.h +++ b/chrome/browser/accessibility/browser_accessibility.h @@ -90,6 +90,12 @@ class BrowserAccessibility { // of its parent. BrowserAccessibility* GetNextSibling(); + // Returns the bounds of this object in screen coordinates. + gfx::Rect GetBoundsRect(); + + // Returns the deepest descendant that contains the specified point. + BrowserAccessibility* BrowserAccessibilityForPoint(const gfx::Point& point); + // Accessors const std::map<int32, string16>& attributes() const { return attributes_; } int32 child_id() const { return child_id_; } @@ -118,6 +124,20 @@ class BrowserAccessibility { protected: BrowserAccessibility(); + // Return true if this attribute is in the attributes map. + bool HasAttribute(WebAccessibility::Attribute attribute); + + // Retrieve the string value of an attribute from the attribute map and + // returns true if found. + bool GetAttribute(WebAccessibility::Attribute attribute, string16* value); + + // Retrieve the value of an attribute from the attribute map and + // if found and nonempty, try to convert it to an integer. + // Returns true only if both the attribute was found and it was successfully + // converted to an integer. + bool GetAttributeAsInt( + WebAccessibility::Attribute attribute, int* value_int); + // The manager of this tree of accessibility objects; needed for // global operations like focus tracking. BrowserAccessibilityManager* manager_; diff --git a/chrome/browser/accessibility/browser_accessibility_manager.cc b/chrome/browser/accessibility/browser_accessibility_manager.cc index eb17e6e..c53d77a 100644 --- a/chrome/browser/accessibility/browser_accessibility_manager.cc +++ b/chrome/browser/accessibility/browser_accessibility_manager.cc @@ -226,6 +226,12 @@ void BrowserAccessibilityManager::DoDefaultAction( delegate_->AccessibilityDoDefaultAction(node.renderer_id()); } +gfx::Rect BrowserAccessibilityManager::GetViewBounds() { + if (delegate_) + return delegate_->GetViewBounds(); + return gfx::Rect(); +} + bool BrowserAccessibilityManager::CanModifyTreeInPlace( BrowserAccessibility* current_root, const WebAccessibility& new_root) { diff --git a/chrome/browser/accessibility/browser_accessibility_manager.h b/chrome/browser/accessibility/browser_accessibility_manager.h index ff96e56..23c1948 100644 --- a/chrome/browser/accessibility/browser_accessibility_manager.h +++ b/chrome/browser/accessibility/browser_accessibility_manager.h @@ -15,7 +15,6 @@ #include "gfx/native_widget_types.h" #include "webkit/glue/webaccessibility.h" - class BrowserAccessibility; #if defined(OS_WIN) class BrowserAccessibilityManagerWin; @@ -30,6 +29,7 @@ class BrowserAccessibilityDelegate { virtual void SetAccessibilityFocus(int acc_obj_id) = 0; virtual void AccessibilityDoDefaultAction(int acc_obj_id) = 0; virtual bool HasFocus() = 0; + virtual gfx::Rect GetViewBounds() const = 0; }; class BrowserAccessibilityFactory { @@ -81,6 +81,9 @@ class BrowserAccessibilityManager { // Tell the renderer to do the default action for this node. void DoDefaultAction(const BrowserAccessibility& node); + // Retrieve the bounds of the parent View in screen coordinates. + gfx::Rect GetViewBounds(); + // Called when the renderer process has notified us of about tree changes. // Send a notification to MSAA clients of the change. void OnAccessibilityNotifications( diff --git a/chrome/browser/accessibility/browser_accessibility_win.cc b/chrome/browser/accessibility/browser_accessibility_win.cc index 8817dfa..63d2408 100644 --- a/chrome/browser/accessibility/browser_accessibility_win.cc +++ b/chrome/browser/accessibility/browser_accessibility_win.cc @@ -53,15 +53,31 @@ HRESULT BrowserAccessibilityWin::accDoDefaultAction(VARIANT var_id) { return S_OK; } -STDMETHODIMP BrowserAccessibilityWin::accHitTest(LONG x_left, LONG y_top, - VARIANT* child) { +STDMETHODIMP BrowserAccessibilityWin::accHitTest( + LONG x_left, LONG y_top, VARIANT* child) { if (!instance_active_) return E_FAIL; if (!child) return E_INVALIDARG; - return E_NOTIMPL; + gfx::Point point(x_left, y_top); + if (!GetBoundsRect().Contains(point)) { + // Return S_FALSE and VT_EMPTY when the outside the object's boundaries. + child->vt = VT_EMPTY; + return S_FALSE; + } + + BrowserAccessibility* result = BrowserAccessibilityForPoint(point); + if (result == this) { + // Point is within this object. + child->vt = VT_I4; + child->lVal = CHILDID_SELF; + } else { + child->vt = VT_DISPATCH; + child->pdispVal = result->toBrowserAccessibilityWin()->NewReference(); + } + return S_OK; } STDMETHODIMP BrowserAccessibilityWin::accLocation(LONG* x_left, LONG* y_top, @@ -77,16 +93,11 @@ STDMETHODIMP BrowserAccessibilityWin::accLocation(LONG* x_left, LONG* y_top, if (!target) return E_INVALIDARG; - // Find the top left corner of the containing window in screen coords, and - // adjust the output position by this amount. - HWND parent_hwnd = manager_->GetParentView(); - POINT top_left = {0, 0}; - ::ClientToScreen(parent_hwnd, &top_left); - - *x_left = target->location_.x + top_left.x; - *y_top = target->location_.y + top_left.y; - *width = target->location_.width; - *height = target->location_.height; + gfx::Rect bounds = target->GetBoundsRect(); + *x_left = bounds.x(); + *y_top = bounds.y(); + *width = bounds.width(); + *height = bounds.height(); return S_OK; } @@ -1156,22 +1167,6 @@ BrowserAccessibilityWin* BrowserAccessibilityWin::GetTargetFromChildID( return manager_->GetFromChildID(child_id)->toBrowserAccessibilityWin(); } -bool BrowserAccessibilityWin::HasAttribute( - WebAccessibility::Attribute attribute) { - return (attributes_.find(attribute) != attributes_.end()); -} - -bool BrowserAccessibilityWin::GetAttribute( - WebAccessibility::Attribute attribute, string16* value) { - std::map<int32, string16>::iterator iter = attributes_.find(attribute); - if (iter != attributes_.end()) { - *value = iter->second; - return true; - } - - return false; -} - HRESULT BrowserAccessibilityWin::GetAttributeAsBstr( WebAccessibility::Attribute attribute, BSTR* value_bstr) { string16 str; @@ -1188,19 +1183,6 @@ HRESULT BrowserAccessibilityWin::GetAttributeAsBstr( return S_OK; } -bool BrowserAccessibilityWin::GetAttributeAsInt( - WebAccessibility::Attribute attribute, int* value_int) { - string16 value_str; - - if (!GetAttribute(attribute, &value_str)) - return false; - - if (!base::StringToInt(value_str, value_int)) - return false; - - return true; -} - string16 BrowserAccessibilityWin::Escape(string16 str) { return EscapeQueryParamValueUTF8(str, false); } diff --git a/chrome/browser/accessibility/browser_accessibility_win.h b/chrome/browser/accessibility/browser_accessibility_win.h index 16ea136..6352b98 100644 --- a/chrome/browser/accessibility/browser_accessibility_win.h +++ b/chrome/browser/accessibility/browser_accessibility_win.h @@ -457,26 +457,12 @@ class BrowserAccessibilityWin // bitmasks defined in webkit/glue/webaccessibility.h. void InitRoleAndState(); - // Return true if this attribute is in the attributes map. - bool HasAttribute(WebAccessibility::Attribute attribute); - - // Retrieve the string value of an attribute from the attribute map and - // returns true if found. - bool GetAttribute(WebAccessibility::Attribute attribute, string16* value); - // Retrieve the string value of an attribute from the attribute map and // if found and nonempty, allocate a new BSTR (with SysAllocString) // and return S_OK. If not found or empty, return S_FALSE. HRESULT GetAttributeAsBstr( WebAccessibility::Attribute attribute, BSTR* value_bstr); - // Retrieve the value of an attribute from the attribute map and - // if found and nonempty, try to convert it to an integer. - // Returns true only if both the attribute was found and it was successfully - // converted to an integer. - bool GetAttributeAsInt( - WebAccessibility::Attribute attribute, int* value_int); - // Escape a string like it would be escaped for a URL or HTML form. string16 Escape(string16 str); diff --git a/webkit/glue/webaccessibility.cc b/webkit/glue/webaccessibility.cc index 70827c1..f405331 100644 --- a/webkit/glue/webaccessibility.cc +++ b/webkit/glue/webaccessibility.cc @@ -19,6 +19,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebInputElement.h" #include "third_party/WebKit/WebKit/chromium/public/WebNamedNodeMap.h" #include "third_party/WebKit/WebKit/chromium/public/WebNode.h" +#include "third_party/WebKit/WebKit/chromium/public/WebSize.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" using WebKit::WebAccessibilityCache; @@ -366,6 +367,10 @@ void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, const WebKit::WebDocumentType& doctype = document.doctype(); if (!doctype.isNull()) attributes[ATTR_DOC_DOCTYPE] = doctype.name(); + + const gfx::Size& scroll_offset = document.frame()->scrollOffset(); + attributes[ATTR_DOC_SCROLLX] = base::IntToString16(scroll_offset.width()); + attributes[ATTR_DOC_SCROLLY] = base::IntToString16(scroll_offset.height()); } // Add the source object to the cache and store its id. diff --git a/webkit/glue/webaccessibility.h b/webkit/glue/webaccessibility.h index cc92939..9d661eb 100644 --- a/webkit/glue/webaccessibility.h +++ b/webkit/glue/webaccessibility.h @@ -162,6 +162,8 @@ struct WebAccessibility { ATTR_DOC_TITLE, ATTR_DOC_MIMETYPE, ATTR_DOC_DOCTYPE, + ATTR_DOC_SCROLLX, + ATTR_DOC_SCROLLY, // Editable text attributes ATTR_TEXT_SEL_START, |