Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(575)

Unified Diff: content/browser/accessibility/browser_accessibility_win.cc

Issue 7745035: Add a big grab bag of missing web accessibility functionality... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/accessibility/browser_accessibility_win.cc
===================================================================
--- content/browser/accessibility/browser_accessibility_win.cc (revision 98956)
+++ content/browser/accessibility/browser_accessibility_win.cc (working copy)
@@ -8,6 +8,7 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility_manager_win.h"
+#include "content/common/view_messages.h"
#include "net/base/escape.h"
using webkit_glue::WebAccessibility;
@@ -37,7 +38,8 @@
: ia_role_(0),
ia_state_(0),
ia2_role_(0),
- ia2_state_(0) {
+ ia2_state_(0),
+ first_time_(true) {
}
BrowserAccessibilityWin::~BrowserAccessibilityWin() {
@@ -421,15 +423,13 @@
if (!attributes)
return E_INVALIDARG;
- // Follow Firefox's convention, which is to return a set of key-value pairs
+ // The iaccessible2 attributes are a set of key-value pairs
// separated by semicolons, with a colon between the key and the value.
string16 str;
- for (unsigned int i = 0; i < html_attributes_.size(); i++) {
+ for (unsigned int i = 0; i < ia2_attributes_.size(); ++i) {
if (i != 0)
str += L';';
- str += Escape(html_attributes_[i].first);
- str += L':';
- str += Escape(html_attributes_[i].second);
+ str += ia2_attributes_[i];
}
if (str.empty())
@@ -574,7 +574,8 @@
return S_OK;
}
- return S_FALSE;
+ *accessible = NULL;
+ return E_INVALIDARG;
}
STDMETHODIMP BrowserAccessibilityWin::get_caption(IUnknown** accessible) {
@@ -610,9 +611,16 @@
if (row < 0 || row >= rows || column < 0 || column >= columns)
return E_INVALIDARG;
- *cell_index = row * columns + column;
+ DCHECK_EQ(columns * rows, static_cast<int>(cell_ids_.size()));
+ int cell_id = cell_ids_[row * columns + column];
+ for (size_t i = 0; i < unique_cell_ids_.size(); ++i) {
+ if (unique_cell_ids_[i] == cell_id) {
+ *cell_index = (long)i;
+ return S_OK;
+ }
+ }
- return S_OK;
+ return S_FALSE;
}
STDMETHODIMP BrowserAccessibilityWin::get_columnDescription(
@@ -636,7 +644,7 @@
if (column < 0 || column >= columns)
return E_INVALIDARG;
- for (int i = 0; i < rows; i++) {
+ for (int i = 0; i < rows; ++i) {
int cell_id = cell_ids_[i * columns + column];
BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
manager_->GetFromRendererID(cell_id));
@@ -707,21 +715,24 @@
if (!column_index)
return E_INVALIDARG;
- int columns;
- int rows;
- if (!GetIntAttribute(WebAccessibility::ATTR_TABLE_COLUMN_COUNT, &columns) ||
- !GetIntAttribute(WebAccessibility::ATTR_TABLE_ROW_COUNT, &rows) ||
- columns <= 0 ||
- rows <= 0) {
+ int cell_id_count = static_cast<int>(unique_cell_ids_.size());
+ if (cell_index < 0)
+ return E_INVALIDARG;
+ if (cell_index >= cell_id_count)
return S_FALSE;
+
+ int cell_id = unique_cell_ids_[cell_index];
+ BrowserAccessibilityWin* cell =
+ manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
+ int col_index;
+ if (cell &&
+ cell->GetIntAttribute(
+ WebAccessibility::ATTR_TABLE_CELL_COLUMN_INDEX, &col_index)) {
+ *column_index = col_index;
+ return S_OK;
}
- if (cell_index < 0 || cell_index >= columns * rows)
- return E_INVALIDARG;
-
- *column_index = cell_index % columns;
-
- return S_OK;
+ return S_FALSE;
}
STDMETHODIMP BrowserAccessibilityWin::get_nColumns(
@@ -816,10 +827,10 @@
if (row < 0 || row >= rows)
return E_INVALIDARG;
- for (int i = 0; i < columns; i++) {
+ for (int i = 0; i < columns; ++i) {
int cell_id = cell_ids_[row * columns + i];
- BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFromRendererID(cell_id));
+ BrowserAccessibilityWin* cell =
+ manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
if (cell && cell->role_ == WebAccessibility::ROLE_ROW_HEADER) {
if (cell->name_.size() > 0) {
*description = SysAllocString(cell->name_.c_str());
@@ -857,8 +868,8 @@
return E_INVALIDARG;
int cell_id = cell_ids_[row * columns + column];
- BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFromRendererID(cell_id));
+ BrowserAccessibilityWin* cell =
+ manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
int rowspan;
if (cell &&
cell->GetIntAttribute(
@@ -887,21 +898,24 @@
if (!row_index)
return E_INVALIDARG;
- int columns;
- int rows;
- if (!GetIntAttribute(WebAccessibility::ATTR_TABLE_COLUMN_COUNT, &columns) ||
- !GetIntAttribute(WebAccessibility::ATTR_TABLE_ROW_COUNT, &rows) ||
- columns <= 0 ||
- rows <= 0) {
+ int cell_id_count = static_cast<int>(unique_cell_ids_.size());
+ if (cell_index < 0)
+ return E_INVALIDARG;
+ if (cell_index >= cell_id_count)
return S_FALSE;
+
+ int cell_id = unique_cell_ids_[cell_index];
+ BrowserAccessibilityWin* cell =
+ manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
+ int cell_row_index;
+ if (cell &&
+ cell->GetIntAttribute(
+ WebAccessibility::ATTR_TABLE_CELL_ROW_INDEX, &cell_row_index)) {
+ *row_index = cell_row_index;
+ return S_OK;
}
- if (cell_index < 0 || cell_index >= columns * rows)
- return E_INVALIDARG;
-
- *row_index = cell_index / columns;
-
- return S_OK;
+ return S_FALSE;
}
STDMETHODIMP BrowserAccessibilityWin::get_selectedChildren(
@@ -914,6 +928,7 @@
if (!children || !n_children)
return E_INVALIDARG;
+ // TODO(dmazzoni): Implement this.
*n_children = 0;
return S_OK;
}
@@ -928,6 +943,7 @@
if (!columns || !n_columns)
return E_INVALIDARG;
+ // TODO(dmazzoni): Implement this.
*n_columns = 0;
return S_OK;
}
@@ -942,6 +958,7 @@
if (!rows || !n_rows)
return E_INVALIDARG;
+ // TODO(dmazzoni): Implement this.
*n_rows = 0;
return S_OK;
}
@@ -967,6 +984,7 @@
if (!is_selected)
return E_INVALIDARG;
+ // TODO(dmazzoni): Implement this.
*is_selected = false;
return S_OK;
}
@@ -980,6 +998,7 @@
if (!is_selected)
return E_INVALIDARG;
+ // TODO(dmazzoni): Implement this.
*is_selected = false;
return S_OK;
}
@@ -994,6 +1013,7 @@
if (!is_selected)
return E_INVALIDARG;
+ // TODO(dmazzoni): Implement this.
*is_selected = false;
return S_OK;
}
@@ -1011,23 +1031,15 @@
if (!row || !column || !row_extents || !column_extents || !is_selected)
return E_INVALIDARG;
- int columns;
- int rows;
- if (!GetIntAttribute(WebAccessibility::ATTR_TABLE_COLUMN_COUNT, &columns) ||
- !GetIntAttribute(WebAccessibility::ATTR_TABLE_ROW_COUNT, &rows) ||
- columns <= 0 ||
- rows <= 0) {
+ int cell_id_count = static_cast<int>(unique_cell_ids_.size());
+ if (index < 0)
+ return E_INVALIDARG;
+ if (index >= cell_id_count)
return S_FALSE;
- }
- if (index < 0 || index >= columns * rows)
- return E_INVALIDARG;
-
- *column = index % columns;
- *row = index / columns;
- int cell_id = cell_ids_[index];
- BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFromRendererID(cell_id));
+ int cell_id = unique_cell_ids_[index];
+ BrowserAccessibilityWin* cell =
+ manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
int rowspan;
int colspan;
if (cell &&
@@ -1046,6 +1058,64 @@
}
//
+// IAccessibleTable2 methods.
+//
+
+STDMETHODIMP BrowserAccessibilityWin::get_cellAt(
+ long row,
+ long column,
+ IUnknown** cell) {
+ return get_accessibleAt(row, column, cell);
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_nSelectedCells(long* cell_count) {
+ return get_nSelectedChildren(cell_count);
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_selectedCells(
+ IUnknown*** cells,
+ long* n_selected_cells) {
+ if (!instance_active_)
+ return E_FAIL;
+
+ if (!cells || !n_selected_cells)
+ return E_INVALIDARG;
+
+ // TODO(dmazzoni): Implement this.
+ *n_selected_cells = 0;
+ return S_OK;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_selectedColumns(
+ long** columns,
+ long* n_columns) {
+ if (!instance_active_)
+ return E_FAIL;
+
+ if (!columns || !n_columns)
+ return E_INVALIDARG;
+
+ // TODO(dmazzoni): Implement this.
+ *n_columns = 0;
+ return S_OK;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_selectedRows(
+ long** rows,
+ long* n_rows) {
+ if (!instance_active_)
+ return E_FAIL;
+
+ if (!rows || !n_rows)
+ return E_INVALIDARG;
+
+ // TODO(dmazzoni): Implement this.
+ *n_rows = 0;
+ return S_OK;
+}
+
+
+//
// IAccessibleTableCell methods.
//
@@ -1088,8 +1158,10 @@
BrowserAccessibility* table = parent();
while (table && table->role() != WebAccessibility::ROLE_TABLE)
table = table->parent();
- if (!table)
+ if (!table) {
+ NOTREACHED();
return S_FALSE;
+ }
int columns;
int rows;
@@ -1102,10 +1174,10 @@
if (columns <= 0 || rows <= 0 || column < 0 || column >= columns)
return S_FALSE;
- for (int i = 0; i < rows; i++) {
+ for (int i = 0; i < rows; ++i) {
int cell_id = table->cell_ids()[i * columns + column];
- BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFromRendererID(cell_id));
+ BrowserAccessibilityWin* cell =
+ manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
if (cell && cell->role_ == WebAccessibility::ROLE_COLUMN_HEADER)
(*n_column_header_cells)++;
}
@@ -1113,14 +1185,14 @@
*cell_accessibles = static_cast<IUnknown**>(CoTaskMemAlloc(
(*n_column_header_cells) * sizeof(cell_accessibles[0])));
int index = 0;
- for (int i = 0; i < rows; i++) {
+ for (int i = 0; i < rows; ++i) {
int cell_id = table->cell_ids()[i * columns + column];
- BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFromRendererID(cell_id));
+ BrowserAccessibilityWin* cell =
+ manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
if (cell && cell->role_ == WebAccessibility::ROLE_COLUMN_HEADER) {
(*cell_accessibles)[index] =
static_cast<IAccessible*>(cell->NewReference());
- index++;
+ ++index;
}
}
@@ -1184,8 +1256,10 @@
BrowserAccessibility* table = parent();
while (table && table->role() != WebAccessibility::ROLE_TABLE)
table = table->parent();
- if (!table)
+ if (!table) {
+ NOTREACHED();
return S_FALSE;
+ }
int columns;
int rows;
@@ -1198,10 +1272,10 @@
if (columns <= 0 || rows <= 0 || row < 0 || row >= rows)
return S_FALSE;
- for (int i = 0; i < columns; i++) {
+ for (int i = 0; i < columns; ++i) {
int cell_id = table->cell_ids()[row * columns + i];
- BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFromRendererID(cell_id));
+ BrowserAccessibilityWin* cell =
+ manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
if (cell && cell->role_ == WebAccessibility::ROLE_ROW_HEADER)
(*n_row_header_cells)++;
}
@@ -1209,14 +1283,14 @@
*cell_accessibles = static_cast<IUnknown**>(CoTaskMemAlloc(
(*n_row_header_cells) * sizeof(cell_accessibles[0])));
int index = 0;
- for (int i = 0; i < columns; i++) {
+ for (int i = 0; i < columns; ++i) {
int cell_id = table->cell_ids()[row * columns + i];
- BrowserAccessibilityWin* cell = static_cast<BrowserAccessibilityWin*>(
- manager_->GetFromRendererID(cell_id));
+ BrowserAccessibilityWin* cell =
+ manager_->GetFromRendererID(cell_id)->toBrowserAccessibilityWin();
if (cell && cell->role_ == WebAccessibility::ROLE_ROW_HEADER) {
(*cell_accessibles)[index] =
static_cast<IAccessible*>(cell->NewReference());
- index++;
+ ++index;
}
}
@@ -1298,14 +1372,22 @@
if (!table)
return E_INVALIDARG;
+
+ int row;
+ int column;
+ GetIntAttribute(WebAccessibility::ATTR_TABLE_CELL_ROW_INDEX, &row);
+ GetIntAttribute(WebAccessibility::ATTR_TABLE_CELL_COLUMN_INDEX, &column);
+
BrowserAccessibility* find_table = parent();
while (find_table && find_table->role() != WebAccessibility::ROLE_TABLE)
find_table = find_table->parent();
- if (!find_table)
+ if (!find_table) {
+ NOTREACHED();
return S_FALSE;
+ }
- *table = static_cast<IAccessible*>(
- static_cast<BrowserAccessibilityWin*>(find_table)->NewReference());
+ *table = static_cast<IAccessibleTable*>(
+ find_table->toBrowserAccessibilityWin()->NewReference());
return S_OK;
}
@@ -1526,7 +1608,115 @@
return get_text(*start_offset, *end_offset, text);
}
+STDMETHODIMP BrowserAccessibilityWin::get_newText(IA2TextSegment* new_text) {
+ if (!instance_active_)
+ return E_FAIL;
+
+ if (!new_text)
+ return E_INVALIDARG;
+
+ string16 text = TextForIAccessibleText();
+
+ new_text->text = SysAllocString(text.c_str());
+ new_text->start = 0;
+ new_text->end = static_cast<long>(text.size());
+ return S_OK;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_oldText(IA2TextSegment* old_text) {
+ if (!instance_active_)
+ return E_FAIL;
+
+ if (!old_text)
+ return E_INVALIDARG;
+
+ old_text->text = SysAllocString(old_text_.c_str());
+ old_text->start = 0;
+ old_text->end = static_cast<long>(old_text_.size());
+ return S_OK;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_offsetAtPoint(
+ LONG x, LONG y, enum IA2CoordinateType coord_type, LONG* offset) {
+ if (!instance_active_)
+ return E_FAIL;
+
+ if (!offset)
+ return E_INVALIDARG;
+
+ // TODO(dmazzoni): implement this. We're returning S_OK for now so that
+ // screen readers still return partially accurate results rather than
+ // completely failing.
+ *offset = 0;
+ return S_OK;
+}
+
//
+// IAccessibleValue methods.
+//
+
+STDMETHODIMP BrowserAccessibilityWin::get_currentValue(VARIANT* value) {
+ if (!instance_active_)
+ return E_FAIL;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ float float_val;
+ if (GetFloatAttribute(WebAccessibility::ATTR_VALUE_FOR_RANGE, &float_val)) {
+ value->vt = VT_R8;
+ value->dblVal = float_val;
+ return S_OK;
+ }
+
+ value->vt = VT_EMPTY;
+ return S_FALSE;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_minimumValue(VARIANT* value) {
+ if (!instance_active_)
+ return E_FAIL;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ float float_val;
+ if (GetFloatAttribute(WebAccessibility::ATTR_MIN_VALUE_FOR_RANGE,
+ &float_val)) {
+ value->vt = VT_R8;
+ value->dblVal = float_val;
+ return S_OK;
+ }
+
+ value->vt = VT_EMPTY;
+ return S_FALSE;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::get_maximumValue(VARIANT* value) {
+ if (!instance_active_)
+ return E_FAIL;
+
+ if (!value)
+ return E_INVALIDARG;
+
+ float float_val;
+ if (GetFloatAttribute(WebAccessibility::ATTR_MAX_VALUE_FOR_RANGE,
+ &float_val)) {
+ value->vt = VT_R8;
+ value->dblVal = float_val;
+ return S_OK;
+ }
+
+ value->vt = VT_EMPTY;
+ return S_FALSE;
+}
+
+STDMETHODIMP BrowserAccessibilityWin::setCurrentValue(VARIANT new_value) {
+ // TODO(dmazzoni): Implement this.
+ return E_NOTIMPL;
+}
+
+//
// ISimpleDOMDocument methods.
//
@@ -1707,7 +1897,7 @@
// We only cache a single style property for now: DISPLAY
- for (unsigned short i = 0; i < num_style_properties; i++) {
+ for (unsigned short i = 0; i < num_style_properties; ++i) {
string16 name = (LPCWSTR)style_properties[i];
StringToLowerASCII(&name);
if (name == L"display") {
@@ -1853,19 +2043,14 @@
if (!instance_active_)
return E_FAIL;
- if (guidService == IID_IAccessibleTable) {
- printf("iatable");
- }
- if (guidService == IID_IAccessibleTableCell) {
- printf("iatable");
- }
-
if (guidService == IID_IAccessible ||
guidService == IID_IAccessible2 ||
guidService == IID_IAccessibleImage ||
guidService == IID_IAccessibleTable ||
+ guidService == IID_IAccessibleTable2 ||
guidService == IID_IAccessibleTableCell ||
guidService == IID_IAccessibleText ||
+ guidService == IID_IAccessibleValue ||
guidService == IID_ISimpleDOMDocument ||
guidService == IID_ISimpleDOMNode ||
guidService == IID_ISimpleDOMText ||
@@ -1896,7 +2081,7 @@
*object = NULL;
return E_NOINTERFACE;
}
- } else if (iid == IID_IAccessibleTable) {
+ } else if (iid == IID_IAccessibleTable || iid == IID_IAccessibleTable2) {
if (ia_role_ != ROLE_SYSTEM_TABLE) {
*object = NULL;
return E_NOINTERFACE;
@@ -1906,6 +2091,13 @@
*object = NULL;
return E_NOINTERFACE;
}
+ } else if (iid == IID_IAccessibleValue) {
+ if (ia_role_ != ROLE_SYSTEM_PROGRESSBAR &&
+ ia_role_ != ROLE_SYSTEM_SCROLLBAR &&
+ ia_role_ != ROLE_SYSTEM_SLIDER) {
+ *object = NULL;
+ return E_NOINTERFACE;
+ }
} else if (iid == IID_ISimpleDOMDocument) {
if (ia_role_ != ROLE_SYSTEM_DOCUMENT) {
*object = NULL;
@@ -1927,17 +2119,72 @@
InitRoleAndState();
- // Expose headings levels to NVDA with the "level" object attribute.
+ // Expose headings levels with the "level" attribute.
if (role_ == WebAccessibility::ROLE_HEADING && role_name_.size() == 2 &&
IsAsciiDigit(role_name_[1])) {
- html_attributes_.push_back(std::make_pair(L"level", role_name_.substr(1)));
+ ia2_attributes_.push_back(string16(L"level:") + role_name_.substr(1));
}
- // Expose the "display" object attribute.
- string16 display;
- if (GetStringAttribute(WebAccessibility::ATTR_DISPLAY, &display))
- html_attributes_.push_back(std::make_pair(L"display", display));
+ // Expose the "display" and "tag" attributes.
+ StringAttributeToIA2(WebAccessibility::ATTR_DISPLAY, "display");
+ StringAttributeToIA2(WebAccessibility::ATTR_HTML_TAG, "tag");
+ StringAttributeToIA2(WebAccessibility::ATTR_ROLE, "xml-roles");
+ // Expose "level" attribute for tree nodes.
+ IntAttributeToIA2(WebAccessibility::ATTR_HIERARCHICAL_LEVEL, "level");
+
+ // Expose live region attributes.
+ StringAttributeToIA2(WebAccessibility::ATTR_LIVE_STATUS, "live");
+ StringAttributeToIA2(WebAccessibility::ATTR_LIVE_RELEVANT, "relevant");
+ BoolAttributeToIA2(WebAccessibility::ATTR_LIVE_ATOMIC, "atomic");
+ BoolAttributeToIA2(WebAccessibility::ATTR_LIVE_BUSY, "busy");
+
+ // Expose container live region attributes.
+ StringAttributeToIA2(WebAccessibility::ATTR_CONTAINER_LIVE_STATUS,
+ "container-live");
+ StringAttributeToIA2(WebAccessibility::ATTR_CONTAINER_LIVE_RELEVANT,
+ "container-relevant");
+ BoolAttributeToIA2(WebAccessibility::ATTR_CONTAINER_LIVE_ATOMIC,
+ "container-atomic");
+ BoolAttributeToIA2(WebAccessibility::ATTR_CONTAINER_LIVE_BUSY,
+ "container-busy");
+
+ // Expose slider value.
+ if (ia_role_ == ROLE_SYSTEM_PROGRESSBAR ||
+ ia_role_ == ROLE_SYSTEM_SCROLLBAR ||
+ ia_role_ == ROLE_SYSTEM_SLIDER) {
+ float fval;
+ if (value_.empty() &&
+ GetFloatAttribute(WebAccessibility::ATTR_VALUE_FOR_RANGE, &fval)) {
+ // TODO(dmazzoni): Use ICU to localize this?
+ value_ = UTF8ToUTF16(base::DoubleToString(fval));
+ }
+ ia2_attributes_.push_back(L"valuetext:" + value_);
+ }
+
+ // Expose table cell index.
+ if (ia_role_ == ROLE_SYSTEM_CELL) {
+ BrowserAccessibility* table = parent();
+ while (table && table->role() != WebAccessibility::ROLE_TABLE)
+ table = table->parent();
+ if (table) {
+ const std::vector<int32>& unique_cell_ids = table->unique_cell_ids();
+ int index = -1;
+ for (size_t i = 0; i < unique_cell_ids.size(); ++i) {
+ if (unique_cell_ids[i] == renderer_id_) {
+ index = static_cast<int>(i);
+ break;
+ }
+ }
+ if (index >= 0) {
+ ia2_attributes_.push_back(string16(L"table-cell-index:") +
+ base::IntToString16(index));
+ }
+ } else {
+ NOTREACHED();
+ }
+ }
+
// If this is static text, put the text in the name rather than the value.
if (role_ == WebAccessibility::ROLE_STATIC_TEXT && name_.empty())
name_.swap(value_);
@@ -1955,6 +2202,28 @@
GetStringAttribute(WebAccessibility::ATTR_URL, &value_);
}
+void BrowserAccessibilityWin::SendNodeUpdateEvents() {
+ // Fire an event when an alert first appears.
+ if (role_ == WebAccessibility::ROLE_ALERT && first_time_)
+ manager_->NotifyAccessibilityEvent(ViewHostMsg_AccEvent::ALERT, this);
+
+ // Fire events if text has changed.
+ string16 text = TextForIAccessibleText();
+ if (previous_text_ != text) {
+ if (!previous_text_.empty() && !text.empty()) {
+ manager_->NotifyAccessibilityEvent(
+ ViewHostMsg_AccEvent::OBJECT_SHOW, this);
+ }
+
+ // TODO(dmazzoni): Look into HIDE events, too.
+
+ old_text_ = previous_text_;
+ previous_text_ = text;
+ }
+
+ first_time_ = false;
+}
+
void BrowserAccessibilityWin::NativeAddReference() {
AddRef();
}
@@ -1999,13 +2268,36 @@
return S_OK;
}
+void BrowserAccessibilityWin::StringAttributeToIA2(
+ WebAccessibility::StringAttribute attribute, const char* ia2_attr) {
+ string16 value;
+ if (GetStringAttribute(attribute, &value))
+ ia2_attributes_.push_back(ASCIIToUTF16(ia2_attr) + L":" + value);
+}
+
+void BrowserAccessibilityWin::BoolAttributeToIA2(
+ WebAccessibility::BoolAttribute attribute, const char* ia2_attr) {
+ bool value;
+ if (GetBoolAttribute(attribute, &value)) {
+ ia2_attributes_.push_back((ASCIIToUTF16(ia2_attr) + L":") +
+ (value ? L"true" : L"false"));
+ }
+}
+
+void BrowserAccessibilityWin::IntAttributeToIA2(
+ WebAccessibility::IntAttribute attribute, const char* ia2_attr) {
+ int value;
+ if (GetIntAttribute(attribute, &value))
+ ia2_attributes_.push_back(ASCIIToUTF16(ia2_attr) + L":" +
+ base::IntToString16(value));
+}
+
string16 BrowserAccessibilityWin::Escape(const string16& str) {
return EscapeQueryParamValueUTF8(str, false);
}
const string16& BrowserAccessibilityWin::TextForIAccessibleText() {
- if (role_ == WebAccessibility::ROLE_TEXT_FIELD ||
- role_ == WebAccessibility::ROLE_TEXTAREA) {
+ if (IsEditableText()) {
return value_;
} else {
return name_;
@@ -2041,7 +2333,7 @@
return start_offset;
} else if (boundary == IA2_TEXT_BOUNDARY_LINE) {
if (direction == 1) {
- for (int j = 0; j < static_cast<int>(line_breaks_.size()); j++) {
+ for (int j = 0; j < static_cast<int>(line_breaks_.size()); ++j) {
if (line_breaks_[j] > start_offset)
return line_breaks_[j];
}
@@ -2112,7 +2404,10 @@
void BrowserAccessibilityWin::InitRoleAndState() {
ia_state_ = 0;
ia2_state_ = IA2_STATE_OPAQUE;
+ ia2_attributes_.clear();
+ if ((state_ >> WebAccessibility::STATE_BUSY) & 1)
+ ia_state_|= STATE_SYSTEM_BUSY;
if ((state_ >> WebAccessibility::STATE_CHECKED) & 1)
ia_state_ |= STATE_SYSTEM_CHECKED;
if ((state_ >> WebAccessibility::STATE_COLLAPSED) & 1)
@@ -2140,37 +2435,57 @@
ia_state_|= STATE_SYSTEM_PRESSED;
if ((state_ >> WebAccessibility::STATE_PROTECTED) & 1)
ia_state_|= STATE_SYSTEM_PROTECTED;
+ if ((state_ >> WebAccessibility::STATE_READONLY) & 1)
+ ia_state_|= STATE_SYSTEM_READONLY;
+ if ((state_ >> WebAccessibility::STATE_REQUIRED) & 1)
+ ia2_state_|= IA2_STATE_REQUIRED;
if ((state_ >> WebAccessibility::STATE_SELECTABLE) & 1)
ia_state_|= STATE_SYSTEM_SELECTABLE;
if ((state_ >> WebAccessibility::STATE_SELECTED) & 1)
ia_state_|= STATE_SYSTEM_SELECTED;
- if ((state_ >> WebAccessibility::STATE_READONLY) & 1)
- ia_state_|= STATE_SYSTEM_READONLY;
if ((state_ >> WebAccessibility::STATE_TRAVERSED) & 1)
ia_state_|= STATE_SYSTEM_TRAVERSED;
- if ((state_ >> WebAccessibility::STATE_BUSY) & 1)
- ia_state_|= STATE_SYSTEM_BUSY;
if ((state_ >> WebAccessibility::STATE_UNAVAILABLE) & 1)
ia_state_|= STATE_SYSTEM_UNAVAILABLE;
+ if ((state_ >> WebAccessibility::STATE_VERTICAL) & 1) {
+ ia2_state_|= IA2_STATE_VERTICAL;
+ } else {
+ ia2_state_|= IA2_STATE_HORIZONTAL;
+ }
+ if ((state_ >> WebAccessibility::STATE_VISITED) & 1)
+ ia_state_|= STATE_SYSTEM_TRAVERSED;
+ string16 invalid;
+ if (GetHtmlAttribute("aria-invalid", &invalid))
+ ia2_state_|= IA2_STATE_INVALID_ENTRY;
+
+ bool mixed = false;
+ GetBoolAttribute(WebAccessibility::ATTR_BUTTON_MIXED, &mixed);
+ if (mixed)
+ ia_state_|= STATE_SYSTEM_MIXED;
+
string16 html_tag;
GetStringAttribute(WebAccessibility::ATTR_HTML_TAG, &html_tag);
ia_role_ = 0;
ia2_role_ = 0;
switch (role_) {
case WebAccessibility::ROLE_ALERT:
- case WebAccessibility::ROLE_ALERT_DIALOG:
ia_role_ = ROLE_SYSTEM_ALERT;
break;
+ case WebAccessibility::ROLE_ALERT_DIALOG:
+ ia_role_ = ROLE_SYSTEM_DIALOG;
+ break;
case WebAccessibility::ROLE_APPLICATION:
ia_role_ = ROLE_SYSTEM_APPLICATION;
break;
case WebAccessibility::ROLE_ARTICLE:
ia_role_ = ROLE_SYSTEM_GROUPING;
ia2_role_ = IA2_ROLE_SECTION;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_BUSY_INDICATOR:
ia_role_ = ROLE_SYSTEM_ANIMATION;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_BUTTON:
ia_role_ = ROLE_SYSTEM_PUSHBUTTON;
@@ -2187,9 +2502,11 @@
break;
case WebAccessibility::ROLE_COLUMN:
ia_role_ = ROLE_SYSTEM_COLUMN;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_COLUMN_HEADER:
ia_role_ = ROLE_SYSTEM_COLUMNHEADER;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_COMBO_BOX:
ia_role_ = ROLE_SYSTEM_COMBOBOX;
@@ -2197,15 +2514,19 @@
case WebAccessibility::ROLE_DEFINITION_LIST_DEFINITION:
role_name_ = html_tag;
ia2_role_ = IA2_ROLE_PARAGRAPH;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_DEFINITION_LIST_TERM:
ia_role_ = ROLE_SYSTEM_LISTITEM;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_DIALOG:
ia_role_ = ROLE_SYSTEM_DIALOG;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_DISCLOSURE_TRIANGLE:
ia_role_ = ROLE_SYSTEM_OUTLINEBUTTON;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_DOCUMENT:
case WebAccessibility::ROLE_WEB_AREA:
@@ -2220,10 +2541,17 @@
break;
case WebAccessibility::ROLE_GRID:
ia_role_ = ROLE_SYSTEM_TABLE;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_GROUP:
if (html_tag == L"li") {
ia_role_ = ROLE_SYSTEM_LISTITEM;
+ } else if (html_tag == L"form") {
+ role_name_ = html_tag;
+ ia2_role_ = IA2_ROLE_FORM;
+ } else if (html_tag == L"p") {
+ role_name_ = html_tag;
+ ia2_role_ = IA2_ROLE_PARAGRAPH;
} else {
if (html_tag.empty())
role_name_ = L"div";
@@ -2231,24 +2559,30 @@
role_name_ = html_tag;
ia2_role_ = IA2_ROLE_SECTION;
}
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_GROW_AREA:
ia_role_ = ROLE_SYSTEM_GRIP;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_HEADING:
role_name_ = html_tag;
ia2_role_ = IA2_ROLE_HEADING;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_IMAGE:
ia_role_ = ROLE_SYSTEM_GRAPHIC;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_IMAGE_MAP:
role_name_ = html_tag;
ia2_role_ = IA2_ROLE_IMAGE_MAP;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_IMAGE_MAP_LINK:
ia_role_ = ROLE_SYSTEM_LINK;
ia_state_|= STATE_SYSTEM_LINKED;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_LANDMARK_APPLICATION:
case WebAccessibility::ROLE_LANDMARK_BANNER:
@@ -2259,6 +2593,7 @@
case WebAccessibility::ROLE_LANDMARK_SEARCH:
ia_role_ = ROLE_SYSTEM_GROUPING;
ia2_role_ = IA2_ROLE_SECTION;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_LINK:
case WebAccessibility::ROLE_WEBCORE_LINK:
@@ -2267,17 +2602,25 @@
break;
case WebAccessibility::ROLE_LIST:
ia_role_ = ROLE_SYSTEM_LIST;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_LISTBOX:
ia_role_ = ROLE_SYSTEM_LIST;
break;
case WebAccessibility::ROLE_LISTBOX_OPTION:
+ ia_role_ = ROLE_SYSTEM_LISTITEM;
+ break;
case WebAccessibility::ROLE_LIST_ITEM:
- case WebAccessibility::ROLE_LIST_MARKER:
ia_role_ = ROLE_SYSTEM_LISTITEM;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
+ case WebAccessibility::ROLE_LIST_MARKER:
+ ia_role_ = ROLE_SYSTEM_TEXT;
+ ia_state_|= STATE_SYSTEM_READONLY;
+ break;
case WebAccessibility::ROLE_MATH:
ia_role_ = ROLE_SYSTEM_EQUATION;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_MENU:
case WebAccessibility::ROLE_MENU_BUTTON:
@@ -2296,15 +2639,22 @@
case WebAccessibility::ROLE_NOTE:
ia_role_ = ROLE_SYSTEM_GROUPING;
ia2_role_ = IA2_ROLE_NOTE;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_OUTLINE:
ia_role_ = ROLE_SYSTEM_OUTLINE;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_POPUP_BUTTON:
- ia_role_ = ROLE_SYSTEM_COMBOBOX;
+ if (html_tag == L"select") {
+ ia_role_ = ROLE_SYSTEM_COMBOBOX;
+ } else {
+ ia_role_ = ROLE_SYSTEM_BUTTONMENU;
+ }
break;
case WebAccessibility::ROLE_PROGRESS_INDICATOR:
ia_role_ = ROLE_SYSTEM_PROGRESSBAR;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_RADIO_BUTTON:
ia_role_ = ROLE_SYSTEM_RADIOBUTTON;
@@ -2316,20 +2666,25 @@
case WebAccessibility::ROLE_REGION:
ia_role_ = ROLE_SYSTEM_GROUPING;
ia2_role_ = IA2_ROLE_SECTION;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_ROW:
ia_role_ = ROLE_SYSTEM_ROW;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_ROW_HEADER:
ia_role_ = ROLE_SYSTEM_ROWHEADER;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_RULER:
ia_role_ = ROLE_SYSTEM_CLIENT;
ia2_role_ = IA2_ROLE_RULER;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_SCROLLAREA:
ia_role_ = ROLE_SYSTEM_CLIENT;
ia2_role_ = IA2_ROLE_SCROLL_PANE;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_SCROLLBAR:
ia_role_ = ROLE_SYSTEM_SCROLLBAR;
@@ -2340,13 +2695,16 @@
case WebAccessibility::ROLE_SPLIT_GROUP:
ia_role_ = ROLE_SYSTEM_CLIENT;
ia2_role_ = IA2_ROLE_SPLIT_PANE;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_ANNOTATION:
case WebAccessibility::ROLE_STATIC_TEXT:
ia_role_ = ROLE_SYSTEM_TEXT;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_STATUS:
ia_role_ = ROLE_SYSTEM_STATUSBAR;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_SPLITTER:
ia_role_ = ROLE_SYSTEM_SEPARATOR;
@@ -2356,10 +2714,12 @@
break;
case WebAccessibility::ROLE_TABLE:
ia_role_ = ROLE_SYSTEM_TABLE;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_TABLE_HEADER_CONTAINER:
ia_role_ = ROLE_SYSTEM_GROUPING;
ia2_role_ = IA2_ROLE_SECTION;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_TAB_GROUP:
case WebAccessibility::ROLE_TAB_LIST:
@@ -2380,21 +2740,27 @@
break;
case WebAccessibility::ROLE_TIMER:
ia_role_ = ROLE_SYSTEM_CLOCK;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_TOOLBAR:
ia_role_ = ROLE_SYSTEM_TOOLBAR;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_TOOLTIP:
ia_role_ = ROLE_SYSTEM_TOOLTIP;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_TREE:
ia_role_ = ROLE_SYSTEM_OUTLINE;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_TREE_GRID:
ia_role_ = ROLE_SYSTEM_OUTLINE;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_TREE_ITEM:
ia_role_ = ROLE_SYSTEM_OUTLINEITEM;
+ ia_state_|= STATE_SYSTEM_READONLY;
break;
case WebAccessibility::ROLE_WINDOW:
ia_role_ = ROLE_SYSTEM_WINDOW;

Powered by Google App Engine
This is Rietveld 408576698