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

Side by Side Diff: content/test/layout_tests/runner/WebAXObjectProxy.cpp

Issue 110533009: Import TestRunner library into chromium. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: updates Created 7 years 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
OLDNEW
(Empty)
1 // Copyright 2013 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 /*
6 * Copyright (C) 2010 Google Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other materials provided with the
17 * distribution.
18 * * Neither the name of Google Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include "content/test/layout_tests/runner/WebAXObjectProxy.h"
36
37 #include "content/test/layout_tests/runner/TestCommon.h"
38 #include "third_party/WebKit/public/platform/WebCString.h"
39 #include "third_party/WebKit/public/platform/WebPoint.h"
40 #include "third_party/WebKit/public/platform/WebRect.h"
41 #include "third_party/WebKit/public/platform/WebString.h"
42
43 using namespace blink;
44 using namespace std;
45
46 namespace WebTestRunner {
47
48 namespace {
49
50 // Map role value to string, matching Safari/Mac platform implementation to
51 // avoid rebaselining layout tests.
52 string roleToString(WebAXRole role)
53 {
54 string result = "AXRole: AX";
55 switch (role) {
56 case WebAXRoleAlertDialog:
57 return result.append("AlertDialog");
58 case WebAXRoleAlert:
59 return result.append("Alert");
60 case WebAXRoleAnnotation:
61 return result.append("Annotation");
62 case WebAXRoleApplication:
63 return result.append("Application");
64 case WebAXRoleArticle:
65 return result.append("Article");
66 case WebAXRoleBanner:
67 return result.append("Banner");
68 case WebAXRoleBrowser:
69 return result.append("Browser");
70 case WebAXRoleBusyIndicator:
71 return result.append("BusyIndicator");
72 case WebAXRoleButton:
73 return result.append("Button");
74 case WebAXRoleCanvas:
75 return result.append("Canvas");
76 case WebAXRoleCell:
77 return result.append("Cell");
78 case WebAXRoleCheckBox:
79 return result.append("CheckBox");
80 case WebAXRoleColorWell:
81 return result.append("ColorWell");
82 case WebAXRoleColumnHeader:
83 return result.append("ColumnHeader");
84 case WebAXRoleColumn:
85 return result.append("Column");
86 case WebAXRoleComboBox:
87 return result.append("ComboBox");
88 case WebAXRoleComplementary:
89 return result.append("Complementary");
90 case WebAXRoleContentInfo:
91 return result.append("ContentInfo");
92 case WebAXRoleDefinition:
93 return result.append("Definition");
94 case WebAXRoleDescriptionListDetail:
95 return result.append("DescriptionListDetail");
96 case WebAXRoleDescriptionListTerm:
97 return result.append("DescriptionListTerm");
98 case WebAXRoleDialog:
99 return result.append("Dialog");
100 case WebAXRoleDirectory:
101 return result.append("Directory");
102 case WebAXRoleDisclosureTriangle:
103 return result.append("DisclosureTriangle");
104 case WebAXRoleDiv:
105 return result.append("Div");
106 case WebAXRoleDocument:
107 return result.append("Document");
108 case WebAXRoleDrawer:
109 return result.append("Drawer");
110 case WebAXRoleEditableText:
111 return result.append("EditableText");
112 case WebAXRoleFooter:
113 return result.append("Footer");
114 case WebAXRoleForm:
115 return result.append("Form");
116 case WebAXRoleGrid:
117 return result.append("Grid");
118 case WebAXRoleGroup:
119 return result.append("Group");
120 case WebAXRoleGrowArea:
121 return result.append("GrowArea");
122 case WebAXRoleHeading:
123 return result.append("Heading");
124 case WebAXRoleHelpTag:
125 return result.append("HelpTag");
126 case WebAXRoleHorizontalRule:
127 return result.append("HorizontalRule");
128 case WebAXRoleIgnored:
129 return result.append("Ignored");
130 case WebAXRoleImageMapLink:
131 return result.append("ImageMapLink");
132 case WebAXRoleImageMap:
133 return result.append("ImageMap");
134 case WebAXRoleImage:
135 return result.append("Image");
136 case WebAXRoleIncrementor:
137 return result.append("Incrementor");
138 case WebAXRoleInlineTextBox:
139 return result.append("InlineTextBox");
140 case WebAXRoleLabel:
141 return result.append("Label");
142 case WebAXRoleLegend:
143 return result.append("Legend");
144 case WebAXRoleLink:
145 return result.append("Link");
146 case WebAXRoleListBoxOption:
147 return result.append("ListBoxOption");
148 case WebAXRoleListBox:
149 return result.append("ListBox");
150 case WebAXRoleListItem:
151 return result.append("ListItem");
152 case WebAXRoleListMarker:
153 return result.append("ListMarker");
154 case WebAXRoleList:
155 return result.append("List");
156 case WebAXRoleLog:
157 return result.append("Log");
158 case WebAXRoleMain:
159 return result.append("Main");
160 case WebAXRoleMarquee:
161 return result.append("Marquee");
162 case WebAXRoleMathElement:
163 return result.append("MathElement");
164 case WebAXRoleMath:
165 return result.append("Math");
166 case WebAXRoleMatte:
167 return result.append("Matte");
168 case WebAXRoleMenuBar:
169 return result.append("MenuBar");
170 case WebAXRoleMenuButton:
171 return result.append("MenuButton");
172 case WebAXRoleMenuItem:
173 return result.append("MenuItem");
174 case WebAXRoleMenuListOption:
175 return result.append("MenuListOption");
176 case WebAXRoleMenuListPopup:
177 return result.append("MenuListPopup");
178 case WebAXRoleMenu:
179 return result.append("Menu");
180 case WebAXRoleNavigation:
181 return result.append("Navigation");
182 case WebAXRoleNote:
183 return result.append("Note");
184 case WebAXRoleOutline:
185 return result.append("Outline");
186 case WebAXRoleParagraph:
187 return result.append("Paragraph");
188 case WebAXRolePopUpButton:
189 return result.append("PopUpButton");
190 case WebAXRolePresentational:
191 return result.append("Presentational");
192 case WebAXRoleProgressIndicator:
193 return result.append("ProgressIndicator");
194 case WebAXRoleRadioButton:
195 return result.append("RadioButton");
196 case WebAXRoleRadioGroup:
197 return result.append("RadioGroup");
198 case WebAXRoleRegion:
199 return result.append("Region");
200 case WebAXRoleRootWebArea:
201 return result.append("RootWebArea");
202 case WebAXRoleRowHeader:
203 return result.append("RowHeader");
204 case WebAXRoleRow:
205 return result.append("Row");
206 case WebAXRoleRulerMarker:
207 return result.append("RulerMarker");
208 case WebAXRoleRuler:
209 return result.append("Ruler");
210 case WebAXRoleSVGRoot:
211 return result.append("SVGRoot");
212 case WebAXRoleScrollArea:
213 return result.append("ScrollArea");
214 case WebAXRoleScrollBar:
215 return result.append("ScrollBar");
216 case WebAXRoleSeamlessWebArea:
217 return result.append("SeamlessWebArea");
218 case WebAXRoleSearch:
219 return result.append("Search");
220 case WebAXRoleSheet:
221 return result.append("Sheet");
222 case WebAXRoleSlider:
223 return result.append("Slider");
224 case WebAXRoleSliderThumb:
225 return result.append("SliderThumb");
226 case WebAXRoleSpinButtonPart:
227 return result.append("SpinButtonPart");
228 case WebAXRoleSpinButton:
229 return result.append("SpinButton");
230 case WebAXRoleSplitGroup:
231 return result.append("SplitGroup");
232 case WebAXRoleSplitter:
233 return result.append("Splitter");
234 case WebAXRoleStaticText:
235 return result.append("StaticText");
236 case WebAXRoleStatus:
237 return result.append("Status");
238 case WebAXRoleSystemWide:
239 return result.append("SystemWide");
240 case WebAXRoleTabGroup:
241 return result.append("TabGroup");
242 case WebAXRoleTabList:
243 return result.append("TabList");
244 case WebAXRoleTabPanel:
245 return result.append("TabPanel");
246 case WebAXRoleTab:
247 return result.append("Tab");
248 case WebAXRoleTableHeaderContainer:
249 return result.append("TableHeaderContainer");
250 case WebAXRoleTable:
251 return result.append("Table");
252 case WebAXRoleTextArea:
253 return result.append("TextArea");
254 case WebAXRoleTextField:
255 return result.append("TextField");
256 case WebAXRoleTimer:
257 return result.append("Timer");
258 case WebAXRoleToggleButton:
259 return result.append("ToggleButton");
260 case WebAXRoleToolbar:
261 return result.append("Toolbar");
262 case WebAXRoleTreeGrid:
263 return result.append("TreeGrid");
264 case WebAXRoleTreeItem:
265 return result.append("TreeItem");
266 case WebAXRoleTree:
267 return result.append("Tree");
268 case WebAXRoleUnknown:
269 return result.append("Unknown");
270 case WebAXRoleUserInterfaceTooltip:
271 return result.append("UserInterfaceTooltip");
272 case WebAXRoleValueIndicator:
273 return result.append("ValueIndicator");
274 case WebAXRoleWebArea:
275 return result.append("WebArea");
276 case WebAXRoleWindow:
277 return result.append("Window");
278 default:
279 return result.append("Unknown");
280 }
281 }
282
283 string getDescription(const WebAXObject& object)
284 {
285 string description = object.accessibilityDescription().utf8();
286 return description.insert(0, "AXDescription: ");
287 }
288
289 string getHelpText(const WebAXObject& object)
290 {
291 string helpText = object.helpText().utf8();
292 return helpText.insert(0, "AXHelp: ");
293 }
294
295 string getStringValue(const WebAXObject& object)
296 {
297 string value;
298 if (object.role() == WebAXRoleColorWell) {
299 int r, g, b;
300 char buffer[100];
301 object.colorValue(r, g, b);
302 snprintf(buffer, sizeof(buffer), "rgb %7.5f %7.5f %7.5f 1", r / 255., g / 255., b / 255.);
303 value = buffer;
304 } else {
305 value = object.stringValue().utf8();
306 }
307 return value.insert(0, "AXValue: ");
308 }
309
310 string getRole(const WebAXObject& object)
311 {
312 string roleString = roleToString(object.role());
313
314 // Special-case canvas with fallback content because Chromium wants to
315 // treat this as essentially a separate role that it can map differently dep ending
316 // on the platform.
317 if (object.role() == WebAXRoleCanvas && object.canvasHasFallbackContent())
318 roleString += "WithFallbackContent";
319
320 return roleString;
321 }
322
323 string getTitle(const WebAXObject& object)
324 {
325 string title = object.title().utf8();
326 return title.insert(0, "AXTitle: ");
327 }
328
329 string getOrientation(const WebAXObject& object)
330 {
331 if (object.isVertical())
332 return "AXOrientation: AXVerticalOrientation";
333
334 return "AXOrientation: AXHorizontalOrientation";
335 }
336
337 string getValueDescription(const WebAXObject& object)
338 {
339 string valueDescription = object.valueDescription().utf8();
340 return valueDescription.insert(0, "AXValueDescription: ");
341 }
342
343 string getAttributes(const WebAXObject& object)
344 {
345 // FIXME: Concatenate all attributes of the AXObject.
346 string attributes(getTitle(object));
347 attributes.append("\n");
348 attributes.append(getRole(object));
349 attributes.append("\n");
350 attributes.append(getDescription(object));
351 return attributes;
352 }
353
354 WebRect boundsForCharacter(const WebAXObject& object, int characterIndex)
355 {
356 BLINK_ASSERT(object.role() == WebAXRoleStaticText);
357 int end = 0;
358 for (unsigned i = 0; i < object.childCount(); i++) {
359 WebAXObject inlineTextBox = object.childAt(i);
360 BLINK_ASSERT(inlineTextBox.role() == WebAXRoleInlineTextBox);
361 int start = end;
362 end += inlineTextBox.stringValue().length();
363 if (end <= characterIndex)
364 continue;
365 WebRect inlineTextBoxRect = inlineTextBox.boundingBoxRect();
366 int localIndex = characterIndex - start;
367 WebVector<int> characterOffsets;
368 inlineTextBox.characterOffsets(characterOffsets);
369 BLINK_ASSERT(characterOffsets.size() > 0 && characterOffsets.size() == i nlineTextBox.stringValue().length());
370 switch (inlineTextBox.textDirection()) {
371 case WebAXTextDirectionLR: {
372 if (localIndex) {
373 int left = inlineTextBoxRect.x + characterOffsets[localIndex - 1 ];
374 int width = characterOffsets[localIndex] - characterOffsets[loca lIndex - 1];
375 return WebRect(left, inlineTextBoxRect.y, width, inlineTextBoxRe ct.height);
376 }
377 return WebRect(inlineTextBoxRect.x, inlineTextBoxRect.y, characterOf fsets[0], inlineTextBoxRect.height);
378 }
379 case WebAXTextDirectionRL: {
380 int right = inlineTextBoxRect.x + inlineTextBoxRect.width;
381
382 if (localIndex) {
383 int left = right - characterOffsets[localIndex];
384 int width = characterOffsets[localIndex] - characterOffsets[loca lIndex - 1];
385 return WebRect(left, inlineTextBoxRect.y, width, inlineTextBoxRe ct.height);
386 }
387 int left = right - characterOffsets[0];
388 return WebRect(left, inlineTextBoxRect.y, characterOffsets[0], inlin eTextBoxRect.height);
389 }
390 case WebAXTextDirectionTB: {
391 if (localIndex) {
392 int top = inlineTextBoxRect.y + characterOffsets[localIndex - 1] ;
393 int height = characterOffsets[localIndex] - characterOffsets[loc alIndex - 1];
394 return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width , height);
395 }
396 return WebRect(inlineTextBoxRect.x, inlineTextBoxRect.y, inlineTextB oxRect.width, characterOffsets[0]);
397 }
398 case WebAXTextDirectionBT: {
399 int bottom = inlineTextBoxRect.y + inlineTextBoxRect.height;
400
401 if (localIndex) {
402 int top = bottom - characterOffsets[localIndex];
403 int height = characterOffsets[localIndex] - characterOffsets[loc alIndex - 1];
404 return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width , height);
405 }
406 int top = bottom - characterOffsets[0];
407 return WebRect(inlineTextBoxRect.x, top, inlineTextBoxRect.width, ch aracterOffsets[0]);
408 }
409 }
410 }
411
412 BLINK_ASSERT(false);
413 return WebRect();
414 }
415
416 void getBoundariesForOneWord(const WebAXObject& object, int characterIndex, int& wordStart, int& wordEnd)
417 {
418 int end = 0;
419 for (unsigned i = 0; i < object.childCount(); i++) {
420 WebAXObject inlineTextBox = object.childAt(i);
421 BLINK_ASSERT(inlineTextBox.role() == WebAXRoleInlineTextBox);
422 int start = end;
423 end += inlineTextBox.stringValue().length();
424 if (end <= characterIndex)
425 continue;
426 int localIndex = characterIndex - start;
427
428 WebVector<int> starts;
429 WebVector<int> ends;
430 inlineTextBox.wordBoundaries(starts, ends);
431 size_t wordCount = starts.size();
432 BLINK_ASSERT(ends.size() == wordCount);
433
434 // If there are no words, use the InlineTextBox boundaries.
435 if (!wordCount) {
436 wordStart = start;
437 wordEnd = end;
438 return;
439 }
440
441 // Look for a character within any word other than the last.
442 for (size_t j = 0; j < wordCount - 1; j++) {
443 if (localIndex <= ends[j]) {
444 wordStart = start + starts[j];
445 wordEnd = start + ends[j];
446 return;
447 }
448 }
449
450 // Return the last word by default.
451 wordStart = start + starts[wordCount - 1];
452 wordEnd = start + ends[wordCount - 1];
453 return;
454 }
455 }
456
457 // Collects attributes into a string, delimited by dashes. Used by all methods
458 // that output lists of attributes: attributesOfLinkedUIElementsCallback,
459 // AttributesOfChildrenCallback, etc.
460 class AttributesCollector {
461 public:
462 void collectAttributes(const WebAXObject& object)
463 {
464 m_attributes.append("\n------------\n");
465 m_attributes.append(getAttributes(object));
466 }
467
468 string attributes() const { return m_attributes; }
469
470 private:
471 string m_attributes;
472 };
473
474 }
475
476 WebAXObjectProxy::WebAXObjectProxy(const WebAXObject& object, Factory* factory)
477 : m_accessibilityObject(object)
478 , m_factory(factory)
479 {
480
481 BLINK_ASSERT(factory);
482
483 //
484 // Properties
485 //
486
487 bindProperty("role", &WebAXObjectProxy::roleGetterCallback);
488 bindProperty("title", &WebAXObjectProxy::titleGetterCallback);
489 bindProperty("description", &WebAXObjectProxy::descriptionGetterCallback);
490 bindProperty("helpText", &WebAXObjectProxy::helpTextGetterCallback);
491 bindProperty("stringValue", &WebAXObjectProxy::stringValueGetterCallback);
492 bindProperty("x", &WebAXObjectProxy::xGetterCallback);
493 bindProperty("y", &WebAXObjectProxy::yGetterCallback);
494 bindProperty("width", &WebAXObjectProxy::widthGetterCallback);
495 bindProperty("height", &WebAXObjectProxy::heightGetterCallback);
496 bindProperty("intValue", &WebAXObjectProxy::intValueGetterCallback);
497 bindProperty("minValue", &WebAXObjectProxy::minValueGetterCallback);
498 bindProperty("maxValue", &WebAXObjectProxy::maxValueGetterCallback);
499 bindProperty("valueDescription", &WebAXObjectProxy::valueDescriptionGetterCa llback);
500 bindProperty("childrenCount", &WebAXObjectProxy::childrenCountGetterCallback );
501 bindProperty("insertionPointLineNumber", &WebAXObjectProxy::insertionPointLi neNumberGetterCallback);
502 bindProperty("selectedTextRange", &WebAXObjectProxy::selectedTextRangeGetter Callback);
503 bindProperty("isEnabled", &WebAXObjectProxy::isEnabledGetterCallback);
504 bindProperty("isRequired", &WebAXObjectProxy::isRequiredGetterCallback);
505 bindProperty("isFocused", &WebAXObjectProxy::isFocusedGetterCallback);
506 bindProperty("isFocusable", &WebAXObjectProxy::isFocusableGetterCallback);
507 bindProperty("isSelected", &WebAXObjectProxy::isSelectedGetterCallback);
508 bindProperty("isSelectable", &WebAXObjectProxy::isSelectableGetterCallback);
509 bindProperty("isMultiSelectable", &WebAXObjectProxy::isMultiSelectableGetter Callback);
510 bindProperty("isSelectedOptionActive", &WebAXObjectProxy::isSelectedOptionAc tiveGetterCallback);
511 bindProperty("isExpanded", &WebAXObjectProxy::isExpandedGetterCallback);
512 bindProperty("isChecked", &WebAXObjectProxy::isCheckedGetterCallback);
513 bindProperty("isVisible", &WebAXObjectProxy::isVisibleGetterCallback);
514 bindProperty("isOffScreen", &WebAXObjectProxy::isOffScreenGetterCallback);
515 bindProperty("isCollapsed", &WebAXObjectProxy::isCollapsedGetterCallback);
516 bindProperty("hasPopup", &WebAXObjectProxy::hasPopupGetterCallback);
517 bindProperty("isValid", &WebAXObjectProxy::isValidGetterCallback);
518 bindProperty("isReadOnly", &WebAXObjectProxy::isReadOnlyGetterCallback);
519 bindProperty("orientation", &WebAXObjectProxy::orientationGetterCallback);
520 bindProperty("clickPointX", &WebAXObjectProxy::clickPointXGetterCallback);
521 bindProperty("clickPointY", &WebAXObjectProxy::clickPointYGetterCallback);
522 bindProperty("rowCount", &WebAXObjectProxy::rowCountGetterCallback);
523 bindProperty("columnCount", &WebAXObjectProxy::columnCountGetterCallback);
524 bindProperty("isClickable", &WebAXObjectProxy::isClickableGetterCallback);
525
526 //
527 // Methods
528 //
529
530 bindMethod("allAttributes", &WebAXObjectProxy::allAttributesCallback);
531 bindMethod("attributesOfChildren", &WebAXObjectProxy::attributesOfChildrenCa llback);
532 bindMethod("lineForIndex", &WebAXObjectProxy::lineForIndexCallback);
533 bindMethod("boundsForRange", &WebAXObjectProxy::boundsForRangeCallback);
534 bindMethod("childAtIndex", &WebAXObjectProxy::childAtIndexCallback);
535 bindMethod("elementAtPoint", &WebAXObjectProxy::elementAtPointCallback);
536 bindMethod("tableHeader", &WebAXObjectProxy::tableHeaderCallback);
537 bindMethod("rowIndexRange", &WebAXObjectProxy::rowIndexRangeCallback);
538 bindMethod("columnIndexRange", &WebAXObjectProxy::columnIndexRangeCallback);
539 bindMethod("cellForColumnAndRow", &WebAXObjectProxy::cellForColumnAndRowCall back);
540 bindMethod("titleUIElement", &WebAXObjectProxy::titleUIElementCallback);
541 bindMethod("setSelectedTextRange", &WebAXObjectProxy::setSelectedTextRangeCa llback);
542 bindMethod("isAttributeSettable", &WebAXObjectProxy::isAttributeSettableCall back);
543 bindMethod("isPressActionSupported", &WebAXObjectProxy::isPressActionSupport edCallback);
544 bindMethod("isIncrementActionSupported", &WebAXObjectProxy::isIncrementActio nSupportedCallback);
545 bindMethod("isDecrementActionSupported", &WebAXObjectProxy::isDecrementActio nSupportedCallback);
546 bindMethod("parentElement", &WebAXObjectProxy::parentElementCallback);
547 bindMethod("increment", &WebAXObjectProxy::incrementCallback);
548 bindMethod("decrement", &WebAXObjectProxy::decrementCallback);
549 bindMethod("showMenu", &WebAXObjectProxy::showMenuCallback);
550 bindMethod("press", &WebAXObjectProxy::pressCallback);
551 bindMethod("isEqual", &WebAXObjectProxy::isEqualCallback);
552 bindMethod("addNotificationListener", &WebAXObjectProxy::addNotificationList enerCallback);
553 bindMethod("removeNotificationListener", &WebAXObjectProxy::removeNotificati onListenerCallback);
554 bindMethod("takeFocus", &WebAXObjectProxy::takeFocusCallback);
555 bindMethod("scrollToMakeVisible", &WebAXObjectProxy::scrollToMakeVisibleCall back);
556 bindMethod("scrollToMakeVisibleWithSubFocus", &WebAXObjectProxy::scrollToMak eVisibleWithSubFocusCallback);
557 bindMethod("scrollToGlobalPoint", &WebAXObjectProxy::scrollToGlobalPointCall back);
558 bindMethod("wordStart", &WebAXObjectProxy::wordStartCallback);
559 bindMethod("wordEnd", &WebAXObjectProxy::wordEndCallback);
560
561 bindFallbackMethod(&WebAXObjectProxy::fallbackCallback);
562 }
563
564 WebAXObjectProxy* WebAXObjectProxy::getChildAtIndex(unsigned index)
565 {
566 return m_factory->getOrCreate(accessibilityObject().childAt(index));
567 }
568
569 bool WebAXObjectProxy::isEqual(const blink::WebAXObject& other)
570 {
571 return accessibilityObject().equals(other);
572 }
573
574 void WebAXObjectProxy::notificationReceived(const char* notificationName)
575 {
576 size_t callbackCount = m_notificationCallbacks.size();
577 for (size_t i = 0; i < callbackCount; i++) {
578 CppVariant notificationNameArgument;
579 notificationNameArgument.set(notificationName);
580 CppVariant invokeResult;
581 m_notificationCallbacks[i].invokeDefault(&notificationNameArgument, 1, i nvokeResult);
582 }
583 }
584
585 //
586 // Properties
587 //
588
589 void WebAXObjectProxy::roleGetterCallback(CppVariant* result)
590 {
591 result->set(getRole(accessibilityObject()));
592 }
593
594 void WebAXObjectProxy::titleGetterCallback(CppVariant* result)
595 {
596 result->set(getTitle(accessibilityObject()));
597 }
598
599 void WebAXObjectProxy::descriptionGetterCallback(CppVariant* result)
600 {
601 result->set(getDescription(accessibilityObject()));
602 }
603
604 void WebAXObjectProxy::helpTextGetterCallback(CppVariant* result)
605 {
606 result->set(getHelpText(accessibilityObject()));
607 }
608
609 void WebAXObjectProxy::stringValueGetterCallback(CppVariant* result)
610 {
611 result->set(getStringValue(accessibilityObject()));
612 }
613
614 void WebAXObjectProxy::xGetterCallback(CppVariant* result)
615 {
616 result->set(accessibilityObject().boundingBoxRect().x);
617 }
618
619 void WebAXObjectProxy::yGetterCallback(CppVariant* result)
620 {
621 result->set(accessibilityObject().boundingBoxRect().y);
622 }
623
624 void WebAXObjectProxy::widthGetterCallback(CppVariant* result)
625 {
626 result->set(accessibilityObject().boundingBoxRect().width);
627 }
628
629 void WebAXObjectProxy::heightGetterCallback(CppVariant* result)
630 {
631 result->set(accessibilityObject().boundingBoxRect().height);
632 }
633
634 void WebAXObjectProxy::intValueGetterCallback(CppVariant* result)
635 {
636 if (accessibilityObject().supportsRangeValue())
637 result->set(accessibilityObject().valueForRange());
638 else if (accessibilityObject().role() == WebAXRoleHeading)
639 result->set(accessibilityObject().headingLevel());
640 else
641 result->set(atoi(accessibilityObject().stringValue().utf8().data()));
642 }
643
644 void WebAXObjectProxy::minValueGetterCallback(CppVariant* result)
645 {
646 result->set(accessibilityObject().minValueForRange());
647 }
648
649 void WebAXObjectProxy::maxValueGetterCallback(CppVariant* result)
650 {
651 result->set(accessibilityObject().maxValueForRange());
652 }
653
654 void WebAXObjectProxy::valueDescriptionGetterCallback(CppVariant* result)
655 {
656 result->set(getValueDescription(accessibilityObject()));
657 }
658
659 void WebAXObjectProxy::childrenCountGetterCallback(CppVariant* result)
660 {
661 int count = 1; // Root object always has only one child, the WebView.
662 if (!isRoot())
663 count = accessibilityObject().childCount();
664 result->set(count);
665 }
666
667 void WebAXObjectProxy::insertionPointLineNumberGetterCallback(CppVariant* result )
668 {
669 if (!accessibilityObject().isFocused()) {
670 result->set(-1);
671 return;
672 }
673
674 int lineNumber = accessibilityObject().selectionEndLineNumber();
675 result->set(lineNumber);
676 }
677
678 void WebAXObjectProxy::selectedTextRangeGetterCallback(CppVariant* result)
679 {
680 unsigned selectionStart = accessibilityObject().selectionStart();
681 unsigned selectionEnd = accessibilityObject().selectionEnd();
682 char buffer[100];
683 snprintf(buffer, sizeof(buffer), "{%d, %d}", selectionStart, selectionEnd - selectionStart);
684
685 result->set(std::string(buffer));
686 }
687
688 void WebAXObjectProxy::isEnabledGetterCallback(CppVariant* result)
689 {
690 result->set(accessibilityObject().isEnabled());
691 }
692
693 void WebAXObjectProxy::isRequiredGetterCallback(CppVariant* result)
694 {
695 result->set(accessibilityObject().isRequired());
696 }
697
698 void WebAXObjectProxy::isFocusedGetterCallback(CppVariant* result)
699 {
700 result->set(accessibilityObject().isFocused());
701 }
702
703 void WebAXObjectProxy::isFocusableGetterCallback(CppVariant* result)
704 {
705 result->set(accessibilityObject().canSetFocusAttribute());
706 }
707
708 void WebAXObjectProxy::isSelectedGetterCallback(CppVariant* result)
709 {
710 result->set(accessibilityObject().isSelected());
711 }
712
713 void WebAXObjectProxy::isSelectableGetterCallback(CppVariant* result)
714 {
715 result->set(accessibilityObject().canSetSelectedAttribute());
716 }
717
718 void WebAXObjectProxy::isMultiSelectableGetterCallback(CppVariant* result)
719 {
720 result->set(accessibilityObject().isMultiSelectable());
721 }
722
723 void WebAXObjectProxy::isSelectedOptionActiveGetterCallback(CppVariant* result)
724 {
725 result->set(accessibilityObject().isSelectedOptionActive());
726 }
727
728 void WebAXObjectProxy::isExpandedGetterCallback(CppVariant* result)
729 {
730 result->set(!accessibilityObject().isCollapsed());
731 }
732
733 void WebAXObjectProxy::isCheckedGetterCallback(CppVariant* result)
734 {
735 result->set(accessibilityObject().isChecked());
736 }
737
738 void WebAXObjectProxy::isVisibleGetterCallback(CppVariant* result)
739 {
740 result->set(accessibilityObject().isVisible());
741 }
742
743 void WebAXObjectProxy::isOffScreenGetterCallback(CppVariant* result)
744 {
745 result->set(accessibilityObject().isOffScreen());
746 }
747
748 void WebAXObjectProxy::isCollapsedGetterCallback(CppVariant* result)
749 {
750 result->set(accessibilityObject().isCollapsed());
751 }
752
753 void WebAXObjectProxy::hasPopupGetterCallback(CppVariant* result)
754 {
755 result->set(accessibilityObject().ariaHasPopup());
756 }
757
758 void WebAXObjectProxy::isValidGetterCallback(CppVariant* result)
759 {
760 result->set(!accessibilityObject().isDetached());
761 }
762
763 void WebAXObjectProxy::isReadOnlyGetterCallback(CppVariant* result)
764 {
765 result->set(accessibilityObject().isReadOnly());
766 }
767
768 void WebAXObjectProxy::orientationGetterCallback(CppVariant* result)
769 {
770 result->set(getOrientation(accessibilityObject()));
771 }
772
773 void WebAXObjectProxy::clickPointXGetterCallback(CppVariant* result)
774 {
775 result->set(accessibilityObject().clickPoint().x);
776 }
777
778 void WebAXObjectProxy::clickPointYGetterCallback(CppVariant* result)
779 {
780 result->set(accessibilityObject().clickPoint().y);
781 }
782
783 void WebAXObjectProxy::rowCountGetterCallback(CppVariant* result)
784 {
785 result->set(static_cast<int32_t>(accessibilityObject().rowCount()));
786 }
787
788 void WebAXObjectProxy::columnCountGetterCallback(CppVariant* result)
789 {
790 result->set(static_cast<int32_t>(accessibilityObject().columnCount()));
791 }
792
793 void WebAXObjectProxy::isClickableGetterCallback(CppVariant* result)
794 {
795 result->set(accessibilityObject().isClickable());
796 }
797
798 //
799 // Methods
800 //
801
802 void WebAXObjectProxy::allAttributesCallback(const CppArgumentList&, CppVariant* result)
803 {
804 result->set(getAttributes(accessibilityObject()));
805 }
806
807 void WebAXObjectProxy::attributesOfChildrenCallback(const CppArgumentList& argum ents, CppVariant* result)
808 {
809 AttributesCollector collector;
810 unsigned size = accessibilityObject().childCount();
811 for (unsigned i = 0; i < size; ++i)
812 collector.collectAttributes(accessibilityObject().childAt(i));
813 result->set(collector.attributes());
814 }
815
816 void WebAXObjectProxy::lineForIndexCallback(const CppArgumentList& arguments, Cp pVariant* result)
817 {
818 if (!arguments.size() || !arguments[0].isNumber()) {
819 result->setNull();
820 return;
821 }
822
823 int index = arguments[0].toInt32();
824
825 WebVector<int> lineBreaks;
826 accessibilityObject().lineBreaks(lineBreaks);
827 int line = 0;
828 int vectorSize = static_cast<int>(lineBreaks.size());
829 while (line < vectorSize && lineBreaks[line] <= index)
830 line++;
831 result->set(line);
832 }
833
834 void WebAXObjectProxy::boundsForRangeCallback(const CppArgumentList& arguments, CppVariant* result)
835 {
836 result->setNull();
837
838 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNum ber())
839 return;
840
841 if (accessibilityObject().role() != WebAXRoleStaticText)
842 return;
843
844 int start = arguments[0].toInt32();
845 int end = arguments[1].toInt32();
846 int len = end - start;
847
848 // Get the bounds for each character and union them into one large rectangle .
849 // This is just for testing so it doesn't need to be efficient.
850 WebRect bounds = boundsForCharacter(accessibilityObject(), start);
851 for (int i = 1; i < len; i++) {
852 WebRect next = boundsForCharacter(accessibilityObject(), start + i);
853 int right = std::max(bounds.x + bounds.width, next.x + next.width);
854 int bottom = std::max(bounds.y + bounds.height, next.y + next.height);
855 bounds.x = std::min(bounds.x, next.x);
856 bounds.y = std::min(bounds.y, next.y);
857 bounds.width = right - bounds.x;
858 bounds.height = bottom - bounds.y;
859 }
860
861 char buffer[100];
862 snprintf(buffer, sizeof(buffer), "{x: %d, y: %d, width: %d, height: %d}", bo unds.x, bounds.y, bounds.width, bounds.height);
863 result->set(string(buffer));
864 }
865
866 void WebAXObjectProxy::childAtIndexCallback(const CppArgumentList& arguments, Cp pVariant* result)
867 {
868 if (!arguments.size() || !arguments[0].isNumber()) {
869 result->setNull();
870 return;
871 }
872
873 WebAXObjectProxy* child = getChildAtIndex(arguments[0].toInt32());
874 if (!child) {
875 result->setNull();
876 return;
877 }
878
879 result->set(*(child->getAsCppVariant()));
880 }
881
882 void WebAXObjectProxy::elementAtPointCallback(const CppArgumentList& arguments, CppVariant* result)
883 {
884 result->setNull();
885
886 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNum ber())
887 return;
888
889 int x = arguments[0].toInt32();
890 int y = arguments[1].toInt32();
891 WebPoint point(x, y);
892 WebAXObject obj = accessibilityObject().hitTest(point);
893 if (obj.isNull())
894 return;
895
896 result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
897 }
898
899 void WebAXObjectProxy::tableHeaderCallback(const CppArgumentList&, CppVariant* r esult)
900 {
901 WebAXObject obj = accessibilityObject().headerContainerObject();
902 if (obj.isNull()) {
903 result->setNull();
904 return;
905 }
906
907 result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
908 }
909
910 void WebAXObjectProxy::rowIndexRangeCallback(const CppArgumentList&, CppVariant* result)
911 {
912 unsigned rowIndex = accessibilityObject().cellRowIndex();
913 unsigned rowSpan = accessibilityObject().cellRowSpan();
914 char buffer[100];
915 snprintf(buffer, sizeof(buffer), "{%d, %d}", rowIndex, rowSpan);
916 string value = buffer;
917 result->set(std::string(buffer));
918 }
919
920 void WebAXObjectProxy::columnIndexRangeCallback(const CppArgumentList&, CppVaria nt* result)
921 {
922 unsigned columnIndex = accessibilityObject().cellColumnIndex();
923 unsigned columnSpan = accessibilityObject().cellColumnSpan();
924 char buffer[100];
925 snprintf(buffer, sizeof(buffer), "{%d, %d}", columnIndex, columnSpan);
926 result->set(std::string(buffer));
927 }
928
929 void WebAXObjectProxy::cellForColumnAndRowCallback(const CppArgumentList& argume nts, CppVariant* result)
930 {
931 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNum ber())
932 return;
933
934 int column = arguments[0].toInt32();
935 int row = arguments[1].toInt32();
936 WebAXObject obj = accessibilityObject().cellForColumnAndRow(column, row);
937 if (obj.isNull()) {
938 result->setNull();
939 return;
940 }
941
942 result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
943 }
944
945 void WebAXObjectProxy::titleUIElementCallback(const CppArgumentList&, CppVariant * result)
946 {
947 WebAXObject obj = accessibilityObject().titleUIElement();
948 if (obj.isNull()) {
949 result->setNull();
950 return;
951 }
952
953 result->set(*(m_factory->getOrCreate(obj)->getAsCppVariant()));
954 }
955
956 void WebAXObjectProxy::setSelectedTextRangeCallback(const CppArgumentList&argume nts, CppVariant* result)
957 {
958 result->setNull();
959 if (arguments.size() != 2 || !arguments[0].isNumber() || !arguments[1].isNum ber())
960 return;
961
962 int selectionStart = arguments[0].toInt32();
963 int selectionEnd = selectionStart + arguments[1].toInt32();
964 accessibilityObject().setSelectedTextRange(selectionStart, selectionEnd);
965 }
966
967 void WebAXObjectProxy::isAttributeSettableCallback(const CppArgumentList& argume nts, CppVariant* result)
968 {
969 if (arguments.size() < 1 && !arguments[0].isString()) {
970 result->setNull();
971 return;
972 }
973
974 string attribute = arguments[0].toString();
975 bool settable = false;
976 if (attribute == "AXValue")
977 settable = accessibilityObject().canSetValueAttribute();
978 result->set(settable);
979 }
980
981 void WebAXObjectProxy::isPressActionSupportedCallback(const CppArgumentList&, Cp pVariant* result)
982 {
983 result->set(accessibilityObject().canPress());
984 }
985
986 void WebAXObjectProxy::isIncrementActionSupportedCallback(const CppArgumentList& , CppVariant* result)
987 {
988 result->set(accessibilityObject().canIncrement());
989 }
990
991 void WebAXObjectProxy::isDecrementActionSupportedCallback(const CppArgumentList& , CppVariant* result)
992 {
993 result->set(accessibilityObject().canDecrement());
994 }
995
996 void WebAXObjectProxy::parentElementCallback(const CppArgumentList&, CppVariant* result)
997 {
998 WebAXObject parentObject = accessibilityObject().parentObject();
999 while (parentObject.accessibilityIsIgnored())
1000 parentObject = parentObject.parentObject();
1001 WebAXObjectProxy* parent = m_factory->getOrCreate(parentObject);
1002 if (!parent) {
1003 result->setNull();
1004 return;
1005 }
1006
1007 result->set(*(parent->getAsCppVariant()));
1008 }
1009
1010 void WebAXObjectProxy::incrementCallback(const CppArgumentList&, CppVariant* res ult)
1011 {
1012 accessibilityObject().increment();
1013 result->setNull();
1014 }
1015
1016 void WebAXObjectProxy::decrementCallback(const CppArgumentList&, CppVariant* res ult)
1017 {
1018 accessibilityObject().decrement();
1019 result->setNull();
1020 }
1021
1022 void WebAXObjectProxy::showMenuCallback(const CppArgumentList&, CppVariant* resu lt)
1023 {
1024 result->setNull();
1025 }
1026
1027 void WebAXObjectProxy::pressCallback(const CppArgumentList&, CppVariant* result)
1028 {
1029 accessibilityObject().press();
1030 result->setNull();
1031 }
1032
1033 void WebAXObjectProxy::isEqualCallback(const CppArgumentList& arguments, CppVari ant* result)
1034 {
1035 if (arguments.size() < 1 || !arguments[0].isObject()) {
1036 result->setNull();
1037 return;
1038 }
1039
1040 result->set(arguments[0].isEqual(*getAsCppVariant()));
1041 }
1042
1043 void WebAXObjectProxy::addNotificationListenerCallback(const CppArgumentList& ar guments, CppVariant* result)
1044 {
1045 if (arguments.size() < 1 || !arguments[0].isObject()) {
1046 result->setNull();
1047 return;
1048 }
1049
1050 m_notificationCallbacks.push_back(arguments[0]);
1051 result->setNull();
1052 }
1053
1054 void WebAXObjectProxy::removeNotificationListenerCallback(const CppArgumentList& , CppVariant* result)
1055 {
1056 // FIXME: Implement this.
1057 result->setNull();
1058 }
1059
1060 void WebAXObjectProxy::takeFocusCallback(const CppArgumentList&, CppVariant* res ult)
1061 {
1062 accessibilityObject().setFocused(true);
1063 result->setNull();
1064 }
1065
1066 void WebAXObjectProxy::scrollToMakeVisibleCallback(const CppArgumentList&, CppVa riant* result)
1067 {
1068 accessibilityObject().scrollToMakeVisible();
1069 result->setNull();
1070 }
1071
1072 void WebAXObjectProxy::scrollToMakeVisibleWithSubFocusCallback(const CppArgument List& arguments, CppVariant* result)
1073 {
1074 result->setNull();
1075
1076 if (arguments.size() != 4
1077 || !arguments[0].isNumber()
1078 || !arguments[1].isNumber()
1079 || !arguments[2].isNumber()
1080 || !arguments[3].isNumber())
1081 return;
1082
1083 int x = arguments[0].toInt32();
1084 int y = arguments[1].toInt32();
1085 int width = arguments[2].toInt32();
1086 int height = arguments[3].toInt32();
1087 accessibilityObject().scrollToMakeVisibleWithSubFocus(WebRect(x, y, width, h eight));
1088 result->setNull();
1089 }
1090
1091 void WebAXObjectProxy::scrollToGlobalPointCallback(const CppArgumentList& argume nts, CppVariant* result)
1092 {
1093 result->setNull();
1094
1095 if (arguments.size() != 2
1096 || !arguments[0].isNumber()
1097 || !arguments[1].isNumber())
1098 return;
1099
1100 int x = arguments[0].toInt32();
1101 int y = arguments[1].toInt32();
1102
1103 accessibilityObject().scrollToGlobalPoint(WebPoint(x, y));
1104 result->setNull();
1105 }
1106
1107 void WebAXObjectProxy::wordStartCallback(const CppArgumentList& arguments, CppVa riant* result)
1108 {
1109 result->setNull();
1110
1111 if (arguments.size() != 1 || !arguments[0].isNumber())
1112 return;
1113
1114 if (accessibilityObject().role() != WebAXRoleStaticText)
1115 return;
1116
1117 int characterIndex = arguments[0].toInt32();
1118 int wordStart, wordEnd;
1119 getBoundariesForOneWord(accessibilityObject(), characterIndex, wordStart, wo rdEnd);
1120 result->set(wordStart);
1121 }
1122
1123 void WebAXObjectProxy::wordEndCallback(const CppArgumentList& arguments, CppVari ant* result)
1124 {
1125 result->setNull();
1126
1127 if (arguments.size() != 1 || !arguments[0].isNumber())
1128 return;
1129
1130 if (accessibilityObject().role() != WebAXRoleStaticText)
1131 return;
1132
1133 int characterIndex = arguments[0].toInt32();
1134 int wordStart, wordEnd;
1135 getBoundariesForOneWord(accessibilityObject(), characterIndex, wordStart, wo rdEnd);
1136 result->set(wordEnd);
1137 }
1138
1139 void WebAXObjectProxy::fallbackCallback(const CppArgumentList &, CppVariant* res ult)
1140 {
1141 result->setNull();
1142 }
1143
1144 RootWebAXObjectProxy::RootWebAXObjectProxy(const WebAXObject &object, Factory *f actory)
1145 : WebAXObjectProxy(object, factory) { }
1146
1147 WebAXObjectProxy* RootWebAXObjectProxy::getChildAtIndex(unsigned index)
1148 {
1149 if (index)
1150 return 0;
1151
1152 return factory()->getOrCreate(accessibilityObject());
1153 }
1154
1155
1156 WebAXObjectProxyList ::~WebAXObjectProxyList()
1157 {
1158 clear();
1159 }
1160
1161 void WebAXObjectProxyList::clear()
1162 {
1163 for (ElementList::iterator i = m_elements.begin(); i != m_elements.end(); ++ i)
1164 delete (*i);
1165 m_elements.clear();
1166 }
1167
1168 WebAXObjectProxy* WebAXObjectProxyList::getOrCreate(const WebAXObject& object)
1169 {
1170 if (object.isNull())
1171 return 0;
1172
1173 size_t elementCount = m_elements.size();
1174 for (size_t i = 0; i < elementCount; i++) {
1175 if (m_elements[i]->isEqual(object))
1176 return m_elements[i];
1177 }
1178
1179 WebAXObjectProxy* element = new WebAXObjectProxy(object, this);
1180 m_elements.push_back(element);
1181 return element;
1182 }
1183
1184 WebAXObjectProxy* WebAXObjectProxyList::createRoot(const WebAXObject& object)
1185 {
1186 WebAXObjectProxy* element = new RootWebAXObjectProxy(object, this);
1187 m_elements.push_back(element);
1188 return element;
1189 }
1190
1191 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698