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

Side by Side Diff: content/shell/renderer/test_runner/web_ax_object_proxy.cc

Issue 172263002: Move WebAXObjectProxy and AccessibleController from CppBoundClass to gin::Wrappable (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: (rebasing) Created 6 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/shell/renderer/test_runner/web_ax_object_proxy.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // TODO(hajimehoshi): Remove this when UnsafePersistent is removed.
6 #define V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
7
8 #include "content/shell/renderer/test_runner/web_ax_object_proxy.h"
9
10 #include "base/strings/stringprintf.h"
11 #include "gin/handle.h"
12 #include "third_party/WebKit/public/platform/WebPoint.h"
13 #include "third_party/WebKit/public/platform/WebRect.h"
14 #include "third_party/WebKit/public/platform/WebString.h"
15 #include "third_party/WebKit/public/web/WebFrame.h"
16 #include "third_party/WebKit/public/web/WebKit.h"
17
18 namespace content {
19
20 namespace {
21
22 // Map role value to string, matching Safari/Mac platform implementation to
23 // avoid rebaselining layout tests.
24 std::string RoleToString(blink::WebAXRole role)
25 {
26 std::string result = "AXRole: AX";
27 switch (role) {
28 case blink::WebAXRoleAlertDialog:
29 return result.append("AlertDialog");
30 case blink::WebAXRoleAlert:
31 return result.append("Alert");
32 case blink::WebAXRoleAnnotation:
33 return result.append("Annotation");
34 case blink::WebAXRoleApplication:
35 return result.append("Application");
36 case blink::WebAXRoleArticle:
37 return result.append("Article");
38 case blink::WebAXRoleBanner:
39 return result.append("Banner");
40 case blink::WebAXRoleBrowser:
41 return result.append("Browser");
42 case blink::WebAXRoleBusyIndicator:
43 return result.append("BusyIndicator");
44 case blink::WebAXRoleButton:
45 return result.append("Button");
46 case blink::WebAXRoleCanvas:
47 return result.append("Canvas");
48 case blink::WebAXRoleCell:
49 return result.append("Cell");
50 case blink::WebAXRoleCheckBox:
51 return result.append("CheckBox");
52 case blink::WebAXRoleColorWell:
53 return result.append("ColorWell");
54 case blink::WebAXRoleColumnHeader:
55 return result.append("ColumnHeader");
56 case blink::WebAXRoleColumn:
57 return result.append("Column");
58 case blink::WebAXRoleComboBox:
59 return result.append("ComboBox");
60 case blink::WebAXRoleComplementary:
61 return result.append("Complementary");
62 case blink::WebAXRoleContentInfo:
63 return result.append("ContentInfo");
64 case blink::WebAXRoleDefinition:
65 return result.append("Definition");
66 case blink::WebAXRoleDescriptionListDetail:
67 return result.append("DescriptionListDetail");
68 case blink::WebAXRoleDescriptionListTerm:
69 return result.append("DescriptionListTerm");
70 case blink::WebAXRoleDialog:
71 return result.append("Dialog");
72 case blink::WebAXRoleDirectory:
73 return result.append("Directory");
74 case blink::WebAXRoleDisclosureTriangle:
75 return result.append("DisclosureTriangle");
76 case blink::WebAXRoleDiv:
77 return result.append("Div");
78 case blink::WebAXRoleDocument:
79 return result.append("Document");
80 case blink::WebAXRoleDrawer:
81 return result.append("Drawer");
82 case blink::WebAXRoleEditableText:
83 return result.append("EditableText");
84 case blink::WebAXRoleFooter:
85 return result.append("Footer");
86 case blink::WebAXRoleForm:
87 return result.append("Form");
88 case blink::WebAXRoleGrid:
89 return result.append("Grid");
90 case blink::WebAXRoleGroup:
91 return result.append("Group");
92 case blink::WebAXRoleGrowArea:
93 return result.append("GrowArea");
94 case blink::WebAXRoleHeading:
95 return result.append("Heading");
96 case blink::WebAXRoleHelpTag:
97 return result.append("HelpTag");
98 case blink::WebAXRoleHorizontalRule:
99 return result.append("HorizontalRule");
100 case blink::WebAXRoleIgnored:
101 return result.append("Ignored");
102 case blink::WebAXRoleImageMapLink:
103 return result.append("ImageMapLink");
104 case blink::WebAXRoleImageMap:
105 return result.append("ImageMap");
106 case blink::WebAXRoleImage:
107 return result.append("Image");
108 case blink::WebAXRoleIncrementor:
109 return result.append("Incrementor");
110 case blink::WebAXRoleInlineTextBox:
111 return result.append("InlineTextBox");
112 case blink::WebAXRoleLabel:
113 return result.append("Label");
114 case blink::WebAXRoleLegend:
115 return result.append("Legend");
116 case blink::WebAXRoleLink:
117 return result.append("Link");
118 case blink::WebAXRoleListBoxOption:
119 return result.append("ListBoxOption");
120 case blink::WebAXRoleListBox:
121 return result.append("ListBox");
122 case blink::WebAXRoleListItem:
123 return result.append("ListItem");
124 case blink::WebAXRoleListMarker:
125 return result.append("ListMarker");
126 case blink::WebAXRoleList:
127 return result.append("List");
128 case blink::WebAXRoleLog:
129 return result.append("Log");
130 case blink::WebAXRoleMain:
131 return result.append("Main");
132 case blink::WebAXRoleMarquee:
133 return result.append("Marquee");
134 case blink::WebAXRoleMathElement:
135 return result.append("MathElement");
136 case blink::WebAXRoleMath:
137 return result.append("Math");
138 case blink::WebAXRoleMatte:
139 return result.append("Matte");
140 case blink::WebAXRoleMenuBar:
141 return result.append("MenuBar");
142 case blink::WebAXRoleMenuButton:
143 return result.append("MenuButton");
144 case blink::WebAXRoleMenuItem:
145 return result.append("MenuItem");
146 case blink::WebAXRoleMenuListOption:
147 return result.append("MenuListOption");
148 case blink::WebAXRoleMenuListPopup:
149 return result.append("MenuListPopup");
150 case blink::WebAXRoleMenu:
151 return result.append("Menu");
152 case blink::WebAXRoleNavigation:
153 return result.append("Navigation");
154 case blink::WebAXRoleNote:
155 return result.append("Note");
156 case blink::WebAXRoleOutline:
157 return result.append("Outline");
158 case blink::WebAXRoleParagraph:
159 return result.append("Paragraph");
160 case blink::WebAXRolePopUpButton:
161 return result.append("PopUpButton");
162 case blink::WebAXRolePresentational:
163 return result.append("Presentational");
164 case blink::WebAXRoleProgressIndicator:
165 return result.append("ProgressIndicator");
166 case blink::WebAXRoleRadioButton:
167 return result.append("RadioButton");
168 case blink::WebAXRoleRadioGroup:
169 return result.append("RadioGroup");
170 case blink::WebAXRoleRegion:
171 return result.append("Region");
172 case blink::WebAXRoleRootWebArea:
173 return result.append("RootWebArea");
174 case blink::WebAXRoleRowHeader:
175 return result.append("RowHeader");
176 case blink::WebAXRoleRow:
177 return result.append("Row");
178 case blink::WebAXRoleRulerMarker:
179 return result.append("RulerMarker");
180 case blink::WebAXRoleRuler:
181 return result.append("Ruler");
182 case blink::WebAXRoleSVGRoot:
183 return result.append("SVGRoot");
184 case blink::WebAXRoleScrollArea:
185 return result.append("ScrollArea");
186 case blink::WebAXRoleScrollBar:
187 return result.append("ScrollBar");
188 case blink::WebAXRoleSeamlessWebArea:
189 return result.append("SeamlessWebArea");
190 case blink::WebAXRoleSearch:
191 return result.append("Search");
192 case blink::WebAXRoleSheet:
193 return result.append("Sheet");
194 case blink::WebAXRoleSlider:
195 return result.append("Slider");
196 case blink::WebAXRoleSliderThumb:
197 return result.append("SliderThumb");
198 case blink::WebAXRoleSpinButtonPart:
199 return result.append("SpinButtonPart");
200 case blink::WebAXRoleSpinButton:
201 return result.append("SpinButton");
202 case blink::WebAXRoleSplitGroup:
203 return result.append("SplitGroup");
204 case blink::WebAXRoleSplitter:
205 return result.append("Splitter");
206 case blink::WebAXRoleStaticText:
207 return result.append("StaticText");
208 case blink::WebAXRoleStatus:
209 return result.append("Status");
210 case blink::WebAXRoleSystemWide:
211 return result.append("SystemWide");
212 case blink::WebAXRoleTabGroup:
213 return result.append("TabGroup");
214 case blink::WebAXRoleTabList:
215 return result.append("TabList");
216 case blink::WebAXRoleTabPanel:
217 return result.append("TabPanel");
218 case blink::WebAXRoleTab:
219 return result.append("Tab");
220 case blink::WebAXRoleTableHeaderContainer:
221 return result.append("TableHeaderContainer");
222 case blink::WebAXRoleTable:
223 return result.append("Table");
224 case blink::WebAXRoleTextArea:
225 return result.append("TextArea");
226 case blink::WebAXRoleTextField:
227 return result.append("TextField");
228 case blink::WebAXRoleTimer:
229 return result.append("Timer");
230 case blink::WebAXRoleToggleButton:
231 return result.append("ToggleButton");
232 case blink::WebAXRoleToolbar:
233 return result.append("Toolbar");
234 case blink::WebAXRoleTreeGrid:
235 return result.append("TreeGrid");
236 case blink::WebAXRoleTreeItem:
237 return result.append("TreeItem");
238 case blink::WebAXRoleTree:
239 return result.append("Tree");
240 case blink::WebAXRoleUnknown:
241 return result.append("Unknown");
242 case blink::WebAXRoleUserInterfaceTooltip:
243 return result.append("UserInterfaceTooltip");
244 case blink::WebAXRoleValueIndicator:
245 return result.append("ValueIndicator");
246 case blink::WebAXRoleWebArea:
247 return result.append("WebArea");
248 case blink::WebAXRoleWindow:
249 return result.append("Window");
250 default:
251 return result.append("Unknown");
252 }
253 }
254
255 std::string GetDescription(const blink::WebAXObject& object) {
256 std::string description = object.accessibilityDescription().utf8();
257 return description.insert(0, "AXDescription: ");
258 }
259
260 std::string GetHelpText(const blink::WebAXObject& object) {
261 std::string help_text = object.helpText().utf8();
262 return help_text.insert(0, "AXHelp: ");
263 }
264
265 std::string GetStringValue(const blink::WebAXObject& object) {
266 std::string value;
267 if (object.role() == blink::WebAXRoleColorWell) {
268 int r, g, b;
269 object.colorValue(r, g, b);
270 value = base::StringPrintf("rgb %7.5f %7.5f %7.5f 1",
271 r / 255., g / 255., b / 255.);
272 } else {
273 value = object.stringValue().utf8();
274 }
275 return value.insert(0, "AXValue: ");
276 }
277
278 std::string GetRole(const blink::WebAXObject& object) {
279 std::string role_string = RoleToString(object.role());
280
281 // Special-case canvas with fallback content because Chromium wants to treat
282 // this as essentially a separate role that it can map differently depending
283 // on the platform.
284 if (object.role() == blink::WebAXRoleCanvas &&
285 object.canvasHasFallbackContent()) {
286 role_string += "WithFallbackContent";
287 }
288
289 return role_string;
290 }
291
292 std::string GetTitle(const blink::WebAXObject& object) {
293 std::string title = object.title().utf8();
294 return title.insert(0, "AXTitle: ");
295 }
296
297 std::string GetOrientation(const blink::WebAXObject& object) {
298 if (object.isVertical())
299 return "AXOrientation: AXVerticalOrientation";
300
301 return "AXOrientation: AXHorizontalOrientation";
302 }
303
304 std::string GetValueDescription(const blink::WebAXObject& object) {
305 std::string value_description = object.valueDescription().utf8();
306 return value_description.insert(0, "AXValueDescription: ");
307 }
308
309 std::string GetAttributes(const blink::WebAXObject& object) {
310 // FIXME: Concatenate all attributes of the AXObject.
311 std::string attributes(GetTitle(object));
312 attributes.append("\n");
313 attributes.append(GetRole(object));
314 attributes.append("\n");
315 attributes.append(GetDescription(object));
316 return attributes;
317 }
318
319 blink::WebRect BoundsForCharacter(const blink::WebAXObject& object,
320 int characterIndex) {
321 DCHECK_EQ(object.role(), blink::WebAXRoleStaticText);
322 int end = 0;
323 for (unsigned i = 0; i < object.childCount(); i++) {
324 blink::WebAXObject inline_text_box = object.childAt(i);
325 DCHECK_EQ(inline_text_box.role(), blink::WebAXRoleInlineTextBox);
326 int start = end;
327 end += inline_text_box.stringValue().length();
328 if (end <= characterIndex)
329 continue;
330 blink::WebRect inline_text_box_rect = inline_text_box.boundingBoxRect();
331 int localIndex = characterIndex - start;
332 blink::WebVector<int> character_offsets;
333 inline_text_box.characterOffsets(character_offsets);
334 DCHECK(character_offsets.size() > 0 &&
335 character_offsets.size() == inline_text_box.stringValue().length());
336 switch (inline_text_box.textDirection()) {
337 case blink::WebAXTextDirectionLR: {
338 if (localIndex) {
339 int left = inline_text_box_rect.x + character_offsets[localIndex - 1];
340 int width = character_offsets[localIndex] -
341 character_offsets[localIndex - 1];
342 return blink::WebRect(left, inline_text_box_rect.y,
343 width, inline_text_box_rect.height);
344 }
345 return blink::WebRect(
346 inline_text_box_rect.x, inline_text_box_rect.y,
347 character_offsets[0], inline_text_box_rect.height);
348 }
349 case blink::WebAXTextDirectionRL: {
350 int right = inline_text_box_rect.x + inline_text_box_rect.width;
351
352 if (localIndex) {
353 int left = right - character_offsets[localIndex];
354 int width = character_offsets[localIndex] -
355 character_offsets[localIndex - 1];
356 return blink::WebRect(left, inline_text_box_rect.y,
357 width, inline_text_box_rect.height);
358 }
359 int left = right - character_offsets[0];
360 return blink::WebRect(
361 left, inline_text_box_rect.y,
362 character_offsets[0], inline_text_box_rect.height);
363 }
364 case blink::WebAXTextDirectionTB: {
365 if (localIndex) {
366 int top = inline_text_box_rect.y + character_offsets[localIndex - 1];
367 int height = character_offsets[localIndex] -
368 character_offsets[localIndex - 1];
369 return blink::WebRect(inline_text_box_rect.x, top,
370 inline_text_box_rect.width, height);
371 }
372 return blink::WebRect(inline_text_box_rect.x, inline_text_box_rect.y,
373 inline_text_box_rect.width, character_offsets[0]);
374 }
375 case blink::WebAXTextDirectionBT: {
376 int bottom = inline_text_box_rect.y + inline_text_box_rect.height;
377
378 if (localIndex) {
379 int top = bottom - character_offsets[localIndex];
380 int height = character_offsets[localIndex] -
381 character_offsets[localIndex - 1];
382 return blink::WebRect(inline_text_box_rect.x, top,
383 inline_text_box_rect.width, height);
384 }
385 int top = bottom - character_offsets[0];
386 return blink::WebRect(inline_text_box_rect.x, top,
387 inline_text_box_rect.width, character_offsets[0]);
388 }
389 }
390 }
391
392 DCHECK(false);
393 return blink::WebRect();
394 }
395
396 void GetBoundariesForOneWord(const blink::WebAXObject& object,
397 int character_index,
398 int& word_start,
399 int& word_end) {
400 int end = 0;
401 for (unsigned i = 0; i < object.childCount(); i++) {
402 blink::WebAXObject inline_text_box = object.childAt(i);
403 DCHECK_EQ(inline_text_box.role(), blink::WebAXRoleInlineTextBox);
404 int start = end;
405 end += inline_text_box.stringValue().length();
406 if (end <= character_index)
407 continue;
408 int localIndex = character_index - start;
409
410 blink::WebVector<int> starts;
411 blink::WebVector<int> ends;
412 inline_text_box.wordBoundaries(starts, ends);
413 size_t word_count = starts.size();
414 DCHECK_EQ(ends.size(), word_count);
415
416 // If there are no words, use the InlineTextBox boundaries.
417 if (!word_count) {
418 word_start = start;
419 word_end = end;
420 return;
421 }
422
423 // Look for a character within any word other than the last.
424 for (size_t j = 0; j < word_count - 1; j++) {
425 if (localIndex <= ends[j]) {
426 word_start = start + starts[j];
427 word_end = start + ends[j];
428 return;
429 }
430 }
431
432 // Return the last word by default.
433 word_start = start + starts[word_count - 1];
434 word_end = start + ends[word_count - 1];
435 return;
436 }
437 }
438
439 // Collects attributes into a string, delimited by dashes. Used by all methods
440 // that output lists of attributes: attributesOfLinkedUIElementsCallback,
441 // AttributesOfChildrenCallback, etc.
442 class AttributesCollector {
443 public:
444 AttributesCollector() {}
445 ~AttributesCollector() {}
446
447 void CollectAttributes(const blink::WebAXObject& object) {
448 attributes_.append("\n------------\n");
449 attributes_.append(GetAttributes(object));
450 }
451
452 std::string attributes() const { return attributes_; }
453
454 private:
455 std::string attributes_;
456
457 DISALLOW_COPY_AND_ASSIGN(AttributesCollector);
458 };
459
460 } // namespace
461
462 gin::WrapperInfo WebAXObjectProxy::kWrapperInfo = {
463 gin::kEmbedderNativeGin};
464
465 WebAXObjectProxy::WebAXObjectProxy(const blink::WebAXObject& object,
466 WebAXObjectProxy::Factory* factory)
467 : accessibility_object_(object),
468 factory_(factory) {
469 }
470
471 WebAXObjectProxy::~WebAXObjectProxy() {}
472
473 gin::ObjectTemplateBuilder
474 WebAXObjectProxy::GetObjectTemplateBuilder(v8::Isolate* isolate) {
475 return gin::Wrappable<WebAXObjectProxy>::GetObjectTemplateBuilder(isolate)
476 .SetProperty("role", &WebAXObjectProxy::Role)
477 .SetProperty("title", &WebAXObjectProxy::Title)
478 .SetProperty("description", &WebAXObjectProxy::Description)
479 .SetProperty("helpText", &WebAXObjectProxy::HelpText)
480 .SetProperty("stringValue", &WebAXObjectProxy::StringValue)
481 .SetProperty("x", &WebAXObjectProxy::X)
482 .SetProperty("y", &WebAXObjectProxy::Y)
483 .SetProperty("width", &WebAXObjectProxy::Width)
484 .SetProperty("height", &WebAXObjectProxy::Height)
485 .SetProperty("intValue", &WebAXObjectProxy::IntValue)
486 .SetProperty("minValue", &WebAXObjectProxy::MinValue)
487 .SetProperty("maxValue", &WebAXObjectProxy::MaxValue)
488 .SetProperty("valueDescription", &WebAXObjectProxy::ValueDescription)
489 .SetProperty("childrenCount", &WebAXObjectProxy::ChildrenCount)
490 .SetProperty("insertionPointLineNumber",
491 &WebAXObjectProxy::InsertionPointLineNumber)
492 .SetProperty("selectedTextRange", &WebAXObjectProxy::SelectedTextRange)
493 .SetProperty("isEnabled", &WebAXObjectProxy::IsEnabled)
494 .SetProperty("isRequired", &WebAXObjectProxy::IsRequired)
495 .SetProperty("isFocused", &WebAXObjectProxy::IsFocused)
496 .SetProperty("isFocusable", &WebAXObjectProxy::IsFocusable)
497 .SetProperty("isSelected", &WebAXObjectProxy::IsSelected)
498 .SetProperty("isSelectable", &WebAXObjectProxy::IsSelectable)
499 .SetProperty("isMultiSelectable", &WebAXObjectProxy::IsMultiSelectable)
500 .SetProperty("isSelectedOptionActive",
501 &WebAXObjectProxy::IsSelectedOptionActive)
502 .SetProperty("isExpanded", &WebAXObjectProxy::IsExpanded)
503 .SetProperty("isChecked", &WebAXObjectProxy::IsChecked)
504 .SetProperty("isVisible", &WebAXObjectProxy::IsVisible)
505 .SetProperty("isOffScreen", &WebAXObjectProxy::IsOffScreen)
506 .SetProperty("isCollapsed", &WebAXObjectProxy::IsCollapsed)
507 .SetProperty("hasPopup", &WebAXObjectProxy::HasPopup)
508 .SetProperty("isValid", &WebAXObjectProxy::IsValid)
509 .SetProperty("isReadOnly", &WebAXObjectProxy::IsReadOnly)
510 .SetProperty("orientation", &WebAXObjectProxy::Orientation)
511 .SetProperty("clickPointX", &WebAXObjectProxy::ClickPointX)
512 .SetProperty("clickPointY", &WebAXObjectProxy::ClickPointY)
513 .SetProperty("rowCount", &WebAXObjectProxy::RowCount)
514 .SetProperty("columnCount", &WebAXObjectProxy::ColumnCount)
515 .SetProperty("isClickable", &WebAXObjectProxy::IsClickable)
516 .SetMethod("allAttributes", &WebAXObjectProxy::AllAttributes)
517 .SetMethod("attributesOfChildren",
518 &WebAXObjectProxy::AttributesOfChildren)
519 .SetMethod("lineForIndex", &WebAXObjectProxy::LineForIndex)
520 .SetMethod("boundsForRange", &WebAXObjectProxy::BoundsForRange)
521 .SetMethod("childAtIndex", &WebAXObjectProxy::ChildAtIndex)
522 .SetMethod("elementAtPoint", &WebAXObjectProxy::ElementAtPoint)
523 .SetMethod("tableHeader", &WebAXObjectProxy::TableHeader)
524 .SetMethod("rowIndexRange", &WebAXObjectProxy::RowIndexRange)
525 .SetMethod("columnIndexRange", &WebAXObjectProxy::ColumnIndexRange)
526 .SetMethod("cellForColumnAndRow", &WebAXObjectProxy::CellForColumnAndRow)
527 .SetMethod("titleUIElement", &WebAXObjectProxy::TitleUIElement)
528 .SetMethod("setSelectedTextRange",
529 &WebAXObjectProxy::SetSelectedTextRange)
530 .SetMethod("isAttributeSettable", &WebAXObjectProxy::IsAttributeSettable)
531 .SetMethod("isPressActionSupported",
532 &WebAXObjectProxy::IsPressActionSupported)
533 .SetMethod("isIncrementActionSupported",
534 &WebAXObjectProxy::IsIncrementActionSupported)
535 .SetMethod("isDecrementActionSupported",
536 &WebAXObjectProxy::IsDecrementActionSupported)
537 .SetMethod("parentElement", &WebAXObjectProxy::ParentElement)
538 .SetMethod("increment", &WebAXObjectProxy::Increment)
539 .SetMethod("decrement", &WebAXObjectProxy::Decrement)
540 .SetMethod("showMenu", &WebAXObjectProxy::ShowMenu)
541 .SetMethod("press", &WebAXObjectProxy::Press)
542 .SetMethod("isEqual", &WebAXObjectProxy::IsEqual)
543 .SetMethod("setNotificationListener",
544 &WebAXObjectProxy::SetNotificationListener)
545 .SetMethod("unsetNotificationListener",
546 &WebAXObjectProxy::UnsetNotificationListener)
547 .SetMethod("takeFocus", &WebAXObjectProxy::TakeFocus)
548 .SetMethod("scrollToMakeVisible", &WebAXObjectProxy::ScrollToMakeVisible)
549 .SetMethod("scrollToMakeVisibleWithSubFocus",
550 &WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus)
551 .SetMethod("scrollToGlobalPoint", &WebAXObjectProxy::ScrollToGlobalPoint)
552 .SetMethod("wordStart", &WebAXObjectProxy::WordStart)
553 .SetMethod("wordEnd", &WebAXObjectProxy::WordEnd)
554 // TODO(hajimehoshi): This is for backward compatibility. Remove them.
555 .SetMethod("addNotificationListener",
556 &WebAXObjectProxy::SetNotificationListener)
557 .SetMethod("removeNotificationListener",
558 &WebAXObjectProxy::UnsetNotificationListener);
559 }
560
561 v8::Handle<v8::Object> WebAXObjectProxy::GetChildAtIndex(unsigned index) {
562 return factory_->GetOrCreate(accessibility_object().childAt(index));
563 }
564
565 bool WebAXObjectProxy::IsRoot() const {
566 return false;
567 }
568
569 bool WebAXObjectProxy::IsEqualToObject(const blink::WebAXObject& other) {
570 return accessibility_object().equals(other);
571 }
572
573 void WebAXObjectProxy::NotificationReceived(
574 blink::WebFrame* frame,
575 const std::string& notification_name) {
576 if (notification_callback_.IsEmpty())
577 return;
578
579 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
580 if (context.IsEmpty())
581 return;
582
583 v8::Isolate* isolate = blink::mainThreadIsolate();
584
585 v8::Handle<v8::Value> argv[] = {
586 v8::String::NewFromUtf8(isolate, notification_name.data(),
587 v8::String::kNormalString,
588 notification_name.size()),
589 };
590 frame->callFunctionEvenIfScriptDisabled(
591 v8::Local<v8::Function>::New(isolate, notification_callback_),
592 context->Global(),
593 arraysize(argv),
594 argv);
595 }
596
597 std::string WebAXObjectProxy::Role() {
598 return GetRole(accessibility_object());
599 }
600
601 std::string WebAXObjectProxy::Title() {
602 return GetTitle(accessibility_object());
603 }
604
605 std::string WebAXObjectProxy::Description() {
606 return GetDescription(accessibility_object());
607 }
608
609 std::string WebAXObjectProxy::HelpText() {
610 return GetHelpText(accessibility_object());
611 }
612
613 std::string WebAXObjectProxy::StringValue() {
614 return GetStringValue(accessibility_object());
615 }
616
617 int WebAXObjectProxy::X() {
618 return accessibility_object().boundingBoxRect().x;
619 }
620
621 int WebAXObjectProxy::Y() {
622 return accessibility_object().boundingBoxRect().y;
623 }
624
625 int WebAXObjectProxy::Width() {
626 return accessibility_object().boundingBoxRect().width;
627 }
628
629 int WebAXObjectProxy::Height() {
630 return accessibility_object().boundingBoxRect().height;
631 }
632
633 int WebAXObjectProxy::IntValue() {
634 if (accessibility_object().supportsRangeValue())
635 return accessibility_object().valueForRange();
636 else if (accessibility_object().role() == blink::WebAXRoleHeading)
637 return accessibility_object().headingLevel();
638 else
639 return atoi(accessibility_object().stringValue().utf8().data());
640 }
641
642 int WebAXObjectProxy::MinValue() {
643 return accessibility_object().minValueForRange();
644 }
645
646 int WebAXObjectProxy::MaxValue() {
647 return accessibility_object().maxValueForRange();
648 }
649
650 std::string WebAXObjectProxy::ValueDescription() {
651 return GetValueDescription(accessibility_object());
652 }
653
654 int WebAXObjectProxy::ChildrenCount() {
655 int count = 1; // Root object always has only one child, the WebView.
656 if (!IsRoot())
657 count = accessibility_object().childCount();
658 return count;
659 }
660
661 int WebAXObjectProxy::InsertionPointLineNumber() {
662 if (!accessibility_object().isFocused())
663 return -1;
664 return accessibility_object().selectionEndLineNumber();
665 }
666
667 std::string WebAXObjectProxy::SelectedTextRange() {
668 unsigned selection_start = accessibility_object().selectionStart();
669 unsigned selection_end = accessibility_object().selectionEnd();
670 return base::StringPrintf("{%d, %d}",
671 selection_start, selection_end - selection_start);
672 }
673
674 bool WebAXObjectProxy::IsEnabled() {
675 return accessibility_object().isEnabled();
676 }
677
678 bool WebAXObjectProxy::IsRequired() {
679 return accessibility_object().isRequired();
680 }
681
682 bool WebAXObjectProxy::IsFocused() {
683 return accessibility_object().isFocused();
684 }
685
686 bool WebAXObjectProxy::IsFocusable() {
687 return accessibility_object().canSetFocusAttribute();
688 }
689
690 bool WebAXObjectProxy::IsSelected() {
691 return accessibility_object().isSelected();
692 }
693
694 bool WebAXObjectProxy::IsSelectable() {
695 return accessibility_object().canSetSelectedAttribute();
696 }
697
698 bool WebAXObjectProxy::IsMultiSelectable() {
699 return accessibility_object().isMultiSelectable();
700 }
701
702 bool WebAXObjectProxy::IsSelectedOptionActive() {
703 return accessibility_object().isSelectedOptionActive();
704 }
705
706 bool WebAXObjectProxy::IsExpanded() {
707 return !accessibility_object().isCollapsed();
708 }
709
710 bool WebAXObjectProxy::IsChecked() {
711 return accessibility_object().isChecked();
712 }
713
714 bool WebAXObjectProxy::IsVisible() {
715 return accessibility_object().isVisible();
716 }
717
718 bool WebAXObjectProxy::IsOffScreen() {
719 return accessibility_object().isOffScreen();
720 }
721
722 bool WebAXObjectProxy::IsCollapsed() {
723 return accessibility_object().isCollapsed();
724 }
725
726 bool WebAXObjectProxy::HasPopup() {
727 return accessibility_object().ariaHasPopup();
728 }
729
730 bool WebAXObjectProxy::IsValid() {
731 return !accessibility_object().isDetached();
732 }
733
734 bool WebAXObjectProxy::IsReadOnly() {
735 return accessibility_object().isReadOnly();
736 }
737
738 std::string WebAXObjectProxy::Orientation() {
739 return GetOrientation(accessibility_object());
740 }
741
742 int WebAXObjectProxy::ClickPointX() {
743 return accessibility_object().clickPoint().x;
744 }
745
746 int WebAXObjectProxy::ClickPointY() {
747 return accessibility_object().clickPoint().y;
748 }
749
750 int32_t WebAXObjectProxy::RowCount() {
751 return static_cast<int32_t>(accessibility_object().rowCount());
752 }
753
754 int32_t WebAXObjectProxy::ColumnCount() {
755 return static_cast<int32_t>(accessibility_object().columnCount());
756 }
757
758 bool WebAXObjectProxy::IsClickable() {
759 return accessibility_object().isClickable();
760 }
761
762 std::string WebAXObjectProxy::AllAttributes() {
763 return GetAttributes(accessibility_object());
764 }
765
766 std::string WebAXObjectProxy::AttributesOfChildren() {
767 AttributesCollector collector;
768 unsigned size = accessibility_object().childCount();
769 for (unsigned i = 0; i < size; ++i)
770 collector.CollectAttributes(accessibility_object().childAt(i));
771 return collector.attributes();
772 }
773
774 int WebAXObjectProxy::LineForIndex(int index) {
775 blink::WebVector<int> line_breaks;
776 accessibility_object().lineBreaks(line_breaks);
777 int line = 0;
778 int vector_size = static_cast<int>(line_breaks.size());
779 while (line < vector_size && line_breaks[line] <= index)
780 line++;
781 return line;
782 }
783
784 std::string WebAXObjectProxy::BoundsForRange(int start, int end) {
785 if (accessibility_object().role() != blink::WebAXRoleStaticText)
786 return std::string();
787
788 int len = end - start;
789
790 // Get the bounds for each character and union them into one large rectangle.
791 // This is just for testing so it doesn't need to be efficient.
792 blink::WebRect bounds = BoundsForCharacter(accessibility_object(), start);
793 for (int i = 1; i < len; i++) {
794 blink::WebRect next = BoundsForCharacter(accessibility_object(), start + i);
795 int right = std::max(bounds.x + bounds.width, next.x + next.width);
796 int bottom = std::max(bounds.y + bounds.height, next.y + next.height);
797 bounds.x = std::min(bounds.x, next.x);
798 bounds.y = std::min(bounds.y, next.y);
799 bounds.width = right - bounds.x;
800 bounds.height = bottom - bounds.y;
801 }
802
803 return base::StringPrintf("{x: %d, y: %d, width: %d, height: %d}",
804 bounds.x, bounds.y, bounds.width, bounds.height);
805 }
806
807 v8::Handle<v8::Object> WebAXObjectProxy::ChildAtIndex(int index) {
808 return GetChildAtIndex(index);
809 }
810
811 v8::Handle<v8::Object> WebAXObjectProxy::ElementAtPoint(int x, int y) {
812 blink::WebPoint point(x, y);
813 blink::WebAXObject obj = accessibility_object().hitTest(point);
814 if (obj.isNull())
815 return v8::Handle<v8::Object>();
816
817 return factory_->GetOrCreate(obj);
818 }
819
820 v8::Handle<v8::Object> WebAXObjectProxy::TableHeader() {
821 blink::WebAXObject obj = accessibility_object().headerContainerObject();
822 if (obj.isNull())
823 return v8::Handle<v8::Object>();
824
825 return factory_->GetOrCreate(obj);
826 }
827
828 std::string WebAXObjectProxy::RowIndexRange() {
829 unsigned row_index = accessibility_object().cellRowIndex();
830 unsigned row_span = accessibility_object().cellRowSpan();
831 return base::StringPrintf("{%d, %d}", row_index, row_span);
832 }
833
834 std::string WebAXObjectProxy::ColumnIndexRange() {
835 unsigned column_index = accessibility_object().cellColumnIndex();
836 unsigned column_span = accessibility_object().cellColumnSpan();
837 return base::StringPrintf("{%d, %d}", column_index, column_span);
838 }
839
840 v8::Handle<v8::Object> WebAXObjectProxy::CellForColumnAndRow(
841 int column, int row) {
842 blink::WebAXObject obj =
843 accessibility_object().cellForColumnAndRow(column, row);
844 if (obj.isNull())
845 return v8::Handle<v8::Object>();
846
847 return factory_->GetOrCreate(obj);
848 }
849
850 v8::Handle<v8::Object> WebAXObjectProxy::TitleUIElement() {
851 blink::WebAXObject obj = accessibility_object().titleUIElement();
852 if (obj.isNull())
853 return v8::Handle<v8::Object>();
854
855 return factory_->GetOrCreate(obj);
856 }
857
858 void WebAXObjectProxy::SetSelectedTextRange(int selection_start,
859 int length) {
860 accessibility_object().setSelectedTextRange(selection_start,
861 selection_start + length);
862 }
863
864 bool WebAXObjectProxy::IsAttributeSettable(const std::string& attribute) {
865 bool settable = false;
866 if (attribute == "AXValue")
867 settable = accessibility_object().canSetValueAttribute();
868 return settable;
869 }
870
871 bool WebAXObjectProxy::IsPressActionSupported() {
872 return accessibility_object().canPress();
873 }
874
875 bool WebAXObjectProxy::IsIncrementActionSupported() {
876 return accessibility_object().canIncrement();
877 }
878
879 bool WebAXObjectProxy::IsDecrementActionSupported() {
880 return accessibility_object().canDecrement();
881 }
882
883 v8::Handle<v8::Object> WebAXObjectProxy::ParentElement() {
884 blink::WebAXObject parent_object = accessibility_object().parentObject();
885 while (parent_object.accessibilityIsIgnored())
886 parent_object = parent_object.parentObject();
887 return factory_->GetOrCreate(parent_object);
888 }
889
890 void WebAXObjectProxy::Increment() {
891 accessibility_object().increment();
892 }
893
894 void WebAXObjectProxy::Decrement() {
895 accessibility_object().decrement();
896 }
897
898 void WebAXObjectProxy::ShowMenu() {
899 }
900
901 void WebAXObjectProxy::Press() {
902 accessibility_object().press();
903 }
904
905 bool WebAXObjectProxy::IsEqual(v8::Handle<v8::Object> proxy) {
906 WebAXObjectProxy* unwrapped_proxy = NULL;
907 if (!gin::ConvertFromV8(blink::mainThreadIsolate(), proxy, &unwrapped_proxy))
908 return false;
909 return unwrapped_proxy->IsEqualToObject(accessibility_object_);
910 }
911
912 void WebAXObjectProxy::SetNotificationListener(
913 v8::Handle<v8::Function> callback) {
914 v8::Isolate* isolate = blink::mainThreadIsolate();
915 notification_callback_.Reset(isolate, callback);
916 }
917
918 void WebAXObjectProxy::UnsetNotificationListener() {
919 notification_callback_.Reset();
920 }
921
922 void WebAXObjectProxy::TakeFocus() {
923 accessibility_object().setFocused(true);
924 }
925
926 void WebAXObjectProxy::ScrollToMakeVisible() {
927 accessibility_object().scrollToMakeVisible();
928 }
929
930 void WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus(int x, int y,
931 int width, int height) {
932 accessibility_object().scrollToMakeVisibleWithSubFocus(
933 blink::WebRect(x, y, width, height));
934 }
935
936 void WebAXObjectProxy::ScrollToGlobalPoint(int x, int y) {
937 accessibility_object().scrollToGlobalPoint(blink::WebPoint(x, y));
938 }
939
940 int WebAXObjectProxy::WordStart(int character_index) {
941 if (accessibility_object().role() != blink::WebAXRoleStaticText)
942 return -1;
943
944 int word_start, word_end;
945 GetBoundariesForOneWord(accessibility_object(), character_index,
946 word_start, word_end);
947 return word_start;
948 }
949
950 int WebAXObjectProxy::WordEnd(int character_index) {
951 if (accessibility_object().role() != blink::WebAXRoleStaticText)
952 return -1;
953
954 int word_start, word_end;
955 GetBoundariesForOneWord(accessibility_object(), character_index,
956 word_start, word_end);
957 return word_end;
958 }
959
960 RootWebAXObjectProxy::RootWebAXObjectProxy(
961 const blink::WebAXObject &object, Factory *factory)
962 : WebAXObjectProxy(object, factory) {
963 }
964
965 v8::Handle<v8::Object> RootWebAXObjectProxy::GetChildAtIndex(unsigned index) {
966 if (index)
967 return v8::Handle<v8::Object>();
968
969 return factory()->GetOrCreate(accessibility_object());
970 }
971
972 bool RootWebAXObjectProxy::IsRoot() const {
973 return true;
974 }
975
976 WebAXObjectProxyList::WebAXObjectProxyList() {
977 }
978
979 WebAXObjectProxyList::~WebAXObjectProxyList() {
980 Clear();
981 }
982
983 void WebAXObjectProxyList::Clear() {
984 for (ElementList::iterator i = elements_.begin(); i != elements_.end(); ++i)
985 i->Dispose();
986 elements_.clear();
987 }
988
989 v8::Handle<v8::Object> WebAXObjectProxyList::GetOrCreate(
990 const blink::WebAXObject& object) {
991 if (object.isNull())
992 return v8::Handle<v8::Object>();
993
994 v8::Isolate* isolate = blink::mainThreadIsolate();
995
996 size_t elementCount = elements_.size();
997 for (size_t i = 0; i < elementCount; i++) {
998 WebAXObjectProxy* unwrapped_object = NULL;
999 bool result = gin::ConvertFromV8(isolate, elements_[i].NewLocal(isolate),
1000 &unwrapped_object);
1001 DCHECK(result);
1002 DCHECK(unwrapped_object);
1003 if (unwrapped_object->IsEqualToObject(object))
1004 return elements_[i].NewLocal(isolate);
1005 }
1006
1007 v8::Handle<v8::Value> value_handle = gin::CreateHandle(
1008 isolate, new WebAXObjectProxy(object, this)).ToV8();
1009 if (value_handle.IsEmpty())
1010 return v8::Handle<v8::Object>();
1011 v8::Handle<v8::Object> handle = value_handle->ToObject();
1012 UnsafePersistent<v8::Object> unsafe_handle(isolate, handle);
1013 elements_.push_back(unsafe_handle);
1014 return unsafe_handle.NewLocal(isolate);
1015 }
1016
1017 v8::Handle<v8::Object> WebAXObjectProxyList::CreateRoot(
1018 const blink::WebAXObject& object) {
1019 v8::Isolate* isolate = blink::mainThreadIsolate();
1020 v8::Handle<v8::Value> value_handle = gin::CreateHandle(
1021 isolate, new RootWebAXObjectProxy(object, this)).ToV8();
1022 if (value_handle.IsEmpty())
1023 return v8::Handle<v8::Object>();
1024 v8::Handle<v8::Object> handle = value_handle->ToObject();
1025 UnsafePersistent<v8::Object> unsafe_handle(isolate, handle);
1026 elements_.push_back(unsafe_handle);
1027 return unsafe_handle.NewLocal(isolate);
1028 }
1029
1030 } // namespace content
OLDNEW
« no previous file with comments | « content/shell/renderer/test_runner/web_ax_object_proxy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698