summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-03 19:10:00 +0000
committerctguil@chromium.org <ctguil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-03 19:10:00 +0000
commit02747d4e2fcd7211cf2fe0851d15d7c8a9341b54 (patch)
tree9f3db8a5df43293cb5ac1f8612d48273009ff641
parent604890c160d3f9383907b80585491fa282abbbd8 (diff)
downloadchromium_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
-rw-r--r--chrome/browser/accessibility/browser_accessibility.cc63
-rw-r--r--chrome/browser/accessibility/browser_accessibility.h20
-rw-r--r--chrome/browser/accessibility/browser_accessibility_manager.cc6
-rw-r--r--chrome/browser/accessibility/browser_accessibility_manager.h5
-rw-r--r--chrome/browser/accessibility/browser_accessibility_win.cc66
-rw-r--r--chrome/browser/accessibility/browser_accessibility_win.h14
-rw-r--r--webkit/glue/webaccessibility.cc5
-rw-r--r--webkit/glue/webaccessibility.h2
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,