[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 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 | |
jochen | 73e711c | 2015-06-03 10:01:46 | [diff] [blame] | 5 | #include "components/test_runner/web_ax_object_proxy.h" |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 6 | |
| 7 | #include "base/strings/stringprintf.h" |
| 8 | #include "gin/handle.h" |
| 9 | #include "third_party/WebKit/public/platform/WebPoint.h" |
| 10 | #include "third_party/WebKit/public/platform/WebRect.h" |
| 11 | #include "third_party/WebKit/public/platform/WebString.h" |
| 12 | #include "third_party/WebKit/public/web/WebFrame.h" |
| 13 | #include "third_party/WebKit/public/web/WebKit.h" |
| 14 | |
jochen | f5f3175 | 2015-06-03 12:06:34 | [diff] [blame] | 15 | namespace test_runner { |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 16 | |
| 17 | namespace { |
| 18 | |
| 19 | // Map role value to string, matching Safari/Mac platform implementation to |
| 20 | // avoid rebaselining layout tests. |
| 21 | std::string RoleToString(blink::WebAXRole role) |
| 22 | { |
| 23 | std::string result = "AXRole: AX"; |
| 24 | switch (role) { |
| 25 | case blink::WebAXRoleAlertDialog: |
| 26 | return result.append("AlertDialog"); |
| 27 | case blink::WebAXRoleAlert: |
| 28 | return result.append("Alert"); |
| 29 | case blink::WebAXRoleAnnotation: |
| 30 | return result.append("Annotation"); |
| 31 | case blink::WebAXRoleApplication: |
| 32 | return result.append("Application"); |
| 33 | case blink::WebAXRoleArticle: |
| 34 | return result.append("Article"); |
| 35 | case blink::WebAXRoleBanner: |
| 36 | return result.append("Banner"); |
je_julie.kim | f337005 | 2014-10-25 02:59:31 | [diff] [blame] | 37 | case blink::WebAXRoleBlockquote: |
| 38 | return result.append("Blockquote"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 39 | case blink::WebAXRoleBusyIndicator: |
| 40 | return result.append("BusyIndicator"); |
| 41 | case blink::WebAXRoleButton: |
| 42 | return result.append("Button"); |
| 43 | case blink::WebAXRoleCanvas: |
| 44 | return result.append("Canvas"); |
ramya.v | 071bb2b | 2015-01-06 09:25:34 | [diff] [blame] | 45 | case blink::WebAXRoleCaption: |
| 46 | return result.append("Caption"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 47 | case blink::WebAXRoleCell: |
| 48 | return result.append("Cell"); |
| 49 | case blink::WebAXRoleCheckBox: |
| 50 | return result.append("CheckBox"); |
| 51 | case blink::WebAXRoleColorWell: |
| 52 | return result.append("ColorWell"); |
| 53 | case blink::WebAXRoleColumnHeader: |
| 54 | return result.append("ColumnHeader"); |
| 55 | case blink::WebAXRoleColumn: |
| 56 | return result.append("Column"); |
| 57 | case blink::WebAXRoleComboBox: |
| 58 | return result.append("ComboBox"); |
| 59 | case blink::WebAXRoleComplementary: |
| 60 | return result.append("Complementary"); |
| 61 | case blink::WebAXRoleContentInfo: |
| 62 | return result.append("ContentInfo"); |
shreeram.k | a89bdd1 | 2014-10-15 12:00:58 | [diff] [blame] | 63 | case blink::WebAXRoleDate: |
| 64 | return result.append("DateField"); |
| 65 | case blink::WebAXRoleDateTime: |
| 66 | return result.append("DateTimeField"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 67 | case blink::WebAXRoleDefinition: |
| 68 | return result.append("Definition"); |
| 69 | case blink::WebAXRoleDescriptionListDetail: |
| 70 | return result.append("DescriptionListDetail"); |
je_julie.kim | 3cbd462 | 2014-10-02 09:04:33 | [diff] [blame] | 71 | case blink::WebAXRoleDescriptionList: |
| 72 | return result.append("DescriptionList"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 73 | case blink::WebAXRoleDescriptionListTerm: |
| 74 | return result.append("DescriptionListTerm"); |
je_julie.kim | dccbae13 | 2015-04-06 06:34:49 | [diff] [blame] | 75 | case blink::WebAXRoleDetails: |
| 76 | return result.append("Details"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 77 | case blink::WebAXRoleDialog: |
| 78 | return result.append("Dialog"); |
| 79 | case blink::WebAXRoleDirectory: |
| 80 | return result.append("Directory"); |
| 81 | case blink::WebAXRoleDisclosureTriangle: |
| 82 | return result.append("DisclosureTriangle"); |
| 83 | case blink::WebAXRoleDiv: |
| 84 | return result.append("Div"); |
| 85 | case blink::WebAXRoleDocument: |
| 86 | return result.append("Document"); |
je_julie.kim | aa536251 | 2014-09-25 17:23:35 | [diff] [blame] | 87 | case blink::WebAXRoleEmbeddedObject: |
| 88 | return result.append("EmbeddedObject"); |
| 89 | case blink::WebAXRoleFigcaption: |
| 90 | return result.append("Figcaption"); |
| 91 | case blink::WebAXRoleFigure: |
| 92 | return result.append("Figure"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 93 | case blink::WebAXRoleFooter: |
| 94 | return result.append("Footer"); |
| 95 | case blink::WebAXRoleForm: |
| 96 | return result.append("Form"); |
| 97 | case blink::WebAXRoleGrid: |
| 98 | return result.append("Grid"); |
| 99 | case blink::WebAXRoleGroup: |
| 100 | return result.append("Group"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 101 | case blink::WebAXRoleHeading: |
| 102 | return result.append("Heading"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 103 | case blink::WebAXRoleIgnored: |
| 104 | return result.append("Ignored"); |
| 105 | case blink::WebAXRoleImageMapLink: |
| 106 | return result.append("ImageMapLink"); |
| 107 | case blink::WebAXRoleImageMap: |
| 108 | return result.append("ImageMap"); |
| 109 | case blink::WebAXRoleImage: |
| 110 | return result.append("Image"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 111 | case blink::WebAXRoleInlineTextBox: |
| 112 | return result.append("InlineTextBox"); |
je_julie.kim | a84659a | 2015-05-27 01:34:43 | [diff] [blame] | 113 | case blink::WebAXRoleInputTime: |
| 114 | return result.append("InputTime"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 115 | case blink::WebAXRoleLabel: |
| 116 | return result.append("Label"); |
| 117 | case blink::WebAXRoleLegend: |
| 118 | return result.append("Legend"); |
| 119 | case blink::WebAXRoleLink: |
| 120 | return result.append("Link"); |
| 121 | case blink::WebAXRoleListBoxOption: |
| 122 | return result.append("ListBoxOption"); |
| 123 | case blink::WebAXRoleListBox: |
| 124 | return result.append("ListBox"); |
| 125 | case blink::WebAXRoleListItem: |
| 126 | return result.append("ListItem"); |
| 127 | case blink::WebAXRoleListMarker: |
| 128 | return result.append("ListMarker"); |
| 129 | case blink::WebAXRoleList: |
| 130 | return result.append("List"); |
| 131 | case blink::WebAXRoleLog: |
| 132 | return result.append("Log"); |
| 133 | case blink::WebAXRoleMain: |
| 134 | return result.append("Main"); |
shreeram.k | cfc36461 | 2015-06-18 16:10:25 | [diff] [blame] | 135 | case blink::WebAXRoleMark: |
| 136 | return result.append("Mark"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 137 | case blink::WebAXRoleMarquee: |
| 138 | return result.append("Marquee"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 139 | case blink::WebAXRoleMath: |
| 140 | return result.append("Math"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 141 | case blink::WebAXRoleMenuBar: |
| 142 | return result.append("MenuBar"); |
| 143 | case blink::WebAXRoleMenuButton: |
| 144 | return result.append("MenuButton"); |
| 145 | case blink::WebAXRoleMenuItem: |
| 146 | return result.append("MenuItem"); |
shreeram.k | 93f1e4e3 | 2014-10-09 04:45:14 | [diff] [blame] | 147 | case blink::WebAXRoleMenuItemCheckBox: |
| 148 | return result.append("MenuItemCheckBox"); |
| 149 | case blink::WebAXRoleMenuItemRadio: |
| 150 | return result.append("MenuItemRadio"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 151 | case blink::WebAXRoleMenuListOption: |
| 152 | return result.append("MenuListOption"); |
| 153 | case blink::WebAXRoleMenuListPopup: |
| 154 | return result.append("MenuListPopup"); |
| 155 | case blink::WebAXRoleMenu: |
| 156 | return result.append("Menu"); |
shreeram.k | e85a773 | 2014-10-16 18:49:34 | [diff] [blame] | 157 | case blink::WebAXRoleMeter: |
| 158 | return result.append("Meter"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 159 | case blink::WebAXRoleNavigation: |
| 160 | return result.append("Navigation"); |
shreeram.k | 7169b5a | 2014-09-24 21:22:57 | [diff] [blame] | 161 | case blink::WebAXRoleNone: |
| 162 | return result.append("None"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 163 | case blink::WebAXRoleNote: |
| 164 | return result.append("Note"); |
| 165 | case blink::WebAXRoleOutline: |
| 166 | return result.append("Outline"); |
| 167 | case blink::WebAXRoleParagraph: |
| 168 | return result.append("Paragraph"); |
| 169 | case blink::WebAXRolePopUpButton: |
| 170 | return result.append("PopUpButton"); |
shreeram.k | c7c5264 | 2014-10-27 06:58:57 | [diff] [blame] | 171 | case blink::WebAXRolePre: |
| 172 | return result.append("Pre"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 173 | case blink::WebAXRolePresentational: |
| 174 | return result.append("Presentational"); |
| 175 | case blink::WebAXRoleProgressIndicator: |
| 176 | return result.append("ProgressIndicator"); |
| 177 | case blink::WebAXRoleRadioButton: |
| 178 | return result.append("RadioButton"); |
| 179 | case blink::WebAXRoleRadioGroup: |
| 180 | return result.append("RadioGroup"); |
| 181 | case blink::WebAXRoleRegion: |
| 182 | return result.append("Region"); |
| 183 | case blink::WebAXRoleRootWebArea: |
| 184 | return result.append("RootWebArea"); |
| 185 | case blink::WebAXRoleRowHeader: |
| 186 | return result.append("RowHeader"); |
| 187 | case blink::WebAXRoleRow: |
| 188 | return result.append("Row"); |
shreeram.k | 3721a0cb | 2014-11-10 18:02:26 | [diff] [blame] | 189 | case blink::WebAXRoleRuby: |
| 190 | return result.append("Ruby"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 191 | case blink::WebAXRoleRuler: |
| 192 | return result.append("Ruler"); |
| 193 | case blink::WebAXRoleSVGRoot: |
| 194 | return result.append("SVGRoot"); |
| 195 | case blink::WebAXRoleScrollArea: |
| 196 | return result.append("ScrollArea"); |
| 197 | case blink::WebAXRoleScrollBar: |
| 198 | return result.append("ScrollBar"); |
| 199 | case blink::WebAXRoleSeamlessWebArea: |
| 200 | return result.append("SeamlessWebArea"); |
| 201 | case blink::WebAXRoleSearch: |
| 202 | return result.append("Search"); |
shreeram.k | b0ec609 | 2015-03-27 10:36:27 | [diff] [blame] | 203 | case blink::WebAXRoleSearchBox: |
| 204 | return result.append("SearchBox"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 205 | case blink::WebAXRoleSlider: |
| 206 | return result.append("Slider"); |
| 207 | case blink::WebAXRoleSliderThumb: |
| 208 | return result.append("SliderThumb"); |
| 209 | case blink::WebAXRoleSpinButtonPart: |
| 210 | return result.append("SpinButtonPart"); |
| 211 | case blink::WebAXRoleSpinButton: |
| 212 | return result.append("SpinButton"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 213 | case blink::WebAXRoleSplitter: |
| 214 | return result.append("Splitter"); |
| 215 | case blink::WebAXRoleStaticText: |
| 216 | return result.append("StaticText"); |
| 217 | case blink::WebAXRoleStatus: |
| 218 | return result.append("Status"); |
shreeram.k | b0ec609 | 2015-03-27 10:36:27 | [diff] [blame] | 219 | case blink::WebAXRoleSwitch: |
| 220 | return result.append("Switch"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 221 | case blink::WebAXRoleTabGroup: |
| 222 | return result.append("TabGroup"); |
| 223 | case blink::WebAXRoleTabList: |
| 224 | return result.append("TabList"); |
| 225 | case blink::WebAXRoleTabPanel: |
| 226 | return result.append("TabPanel"); |
| 227 | case blink::WebAXRoleTab: |
| 228 | return result.append("Tab"); |
| 229 | case blink::WebAXRoleTableHeaderContainer: |
| 230 | return result.append("TableHeaderContainer"); |
| 231 | case blink::WebAXRoleTable: |
| 232 | return result.append("Table"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 233 | case blink::WebAXRoleTextField: |
| 234 | return result.append("TextField"); |
shreeram.k | a89bdd1 | 2014-10-15 12:00:58 | [diff] [blame] | 235 | case blink::WebAXRoleTime: |
| 236 | return result.append("Time"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 237 | case blink::WebAXRoleTimer: |
| 238 | return result.append("Timer"); |
| 239 | case blink::WebAXRoleToggleButton: |
| 240 | return result.append("ToggleButton"); |
| 241 | case blink::WebAXRoleToolbar: |
| 242 | return result.append("Toolbar"); |
| 243 | case blink::WebAXRoleTreeGrid: |
| 244 | return result.append("TreeGrid"); |
| 245 | case blink::WebAXRoleTreeItem: |
| 246 | return result.append("TreeItem"); |
| 247 | case blink::WebAXRoleTree: |
| 248 | return result.append("Tree"); |
| 249 | case blink::WebAXRoleUnknown: |
| 250 | return result.append("Unknown"); |
| 251 | case blink::WebAXRoleUserInterfaceTooltip: |
| 252 | return result.append("UserInterfaceTooltip"); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 253 | case blink::WebAXRoleWebArea: |
| 254 | return result.append("WebArea"); |
| 255 | case blink::WebAXRoleWindow: |
| 256 | return result.append("Window"); |
| 257 | default: |
| 258 | return result.append("Unknown"); |
| 259 | } |
| 260 | } |
| 261 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 262 | std::string GetStringValue(const blink::WebAXObject& object) { |
| 263 | std::string value; |
| 264 | if (object.role() == blink::WebAXRoleColorWell) { |
nektar | d891c76 | 2015-05-13 17:28:05 | [diff] [blame] | 265 | unsigned int color = object.colorValue(); |
| 266 | unsigned int red = (color >> 16) & 0xFF; |
| 267 | unsigned int green = (color >> 8) & 0xFF; |
| 268 | unsigned int blue = color & 0xFF; |
| 269 | value = base::StringPrintf("rgba(%d, %d, %d, 1)", |
| 270 | red, green, blue); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 271 | } else { |
| 272 | value = object.stringValue().utf8(); |
| 273 | } |
| 274 | return value.insert(0, "AXValue: "); |
| 275 | } |
| 276 | |
| 277 | std::string GetRole(const blink::WebAXObject& object) { |
| 278 | std::string role_string = RoleToString(object.role()); |
| 279 | |
| 280 | // Special-case canvas with fallback content because Chromium wants to treat |
| 281 | // this as essentially a separate role that it can map differently depending |
| 282 | // on the platform. |
| 283 | if (object.role() == blink::WebAXRoleCanvas && |
| 284 | object.canvasHasFallbackContent()) { |
| 285 | role_string += "WithFallbackContent"; |
| 286 | } |
| 287 | |
| 288 | return role_string; |
| 289 | } |
| 290 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 291 | std::string GetValueDescription(const blink::WebAXObject& object) { |
| 292 | std::string value_description = object.valueDescription().utf8(); |
| 293 | return value_description.insert(0, "AXValueDescription: "); |
| 294 | } |
| 295 | |
k.czech | 56dbaa5e | 2014-12-08 15:43:54 | [diff] [blame] | 296 | std::string GetLanguage(const blink::WebAXObject& object) { |
| 297 | std::string language = object.language().utf8(); |
| 298 | return language.insert(0, "AXLanguage: "); |
| 299 | } |
| 300 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 301 | std::string GetAttributes(const blink::WebAXObject& object) { |
dmazzoni | 3f6ec08f | 2015-11-10 21:06:40 | [diff] [blame] | 302 | blink::WebAXNameFrom nameFrom; |
| 303 | blink::WebVector<blink::WebAXObject> nameObjects; |
| 304 | std::string attributes(object.name(nameFrom, nameObjects).utf8()); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 305 | attributes.append("\n"); |
| 306 | attributes.append(GetRole(object)); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 307 | return attributes; |
| 308 | } |
| 309 | |
| 310 | blink::WebRect BoundsForCharacter(const blink::WebAXObject& object, |
| 311 | int characterIndex) { |
| 312 | DCHECK_EQ(object.role(), blink::WebAXRoleStaticText); |
| 313 | int end = 0; |
| 314 | for (unsigned i = 0; i < object.childCount(); i++) { |
| 315 | blink::WebAXObject inline_text_box = object.childAt(i); |
| 316 | DCHECK_EQ(inline_text_box.role(), blink::WebAXRoleInlineTextBox); |
| 317 | int start = end; |
| 318 | end += inline_text_box.stringValue().length(); |
[email protected] | 2c64c3b0 | 2014-03-27 05:58:54 | [diff] [blame] | 319 | if (characterIndex < start || characterIndex >= end) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 320 | continue; |
| 321 | blink::WebRect inline_text_box_rect = inline_text_box.boundingBoxRect(); |
| 322 | int localIndex = characterIndex - start; |
| 323 | blink::WebVector<int> character_offsets; |
| 324 | inline_text_box.characterOffsets(character_offsets); |
| 325 | DCHECK(character_offsets.size() > 0 && |
| 326 | character_offsets.size() == inline_text_box.stringValue().length()); |
| 327 | switch (inline_text_box.textDirection()) { |
| 328 | case blink::WebAXTextDirectionLR: { |
| 329 | if (localIndex) { |
| 330 | int left = inline_text_box_rect.x + character_offsets[localIndex - 1]; |
| 331 | int width = character_offsets[localIndex] - |
| 332 | character_offsets[localIndex - 1]; |
| 333 | return blink::WebRect(left, inline_text_box_rect.y, |
| 334 | width, inline_text_box_rect.height); |
| 335 | } |
| 336 | return blink::WebRect( |
| 337 | inline_text_box_rect.x, inline_text_box_rect.y, |
| 338 | character_offsets[0], inline_text_box_rect.height); |
| 339 | } |
| 340 | case blink::WebAXTextDirectionRL: { |
| 341 | int right = inline_text_box_rect.x + inline_text_box_rect.width; |
| 342 | |
| 343 | if (localIndex) { |
| 344 | int left = right - character_offsets[localIndex]; |
| 345 | int width = character_offsets[localIndex] - |
| 346 | character_offsets[localIndex - 1]; |
| 347 | return blink::WebRect(left, inline_text_box_rect.y, |
| 348 | width, inline_text_box_rect.height); |
| 349 | } |
| 350 | int left = right - character_offsets[0]; |
| 351 | return blink::WebRect( |
| 352 | left, inline_text_box_rect.y, |
| 353 | character_offsets[0], inline_text_box_rect.height); |
| 354 | } |
| 355 | case blink::WebAXTextDirectionTB: { |
| 356 | if (localIndex) { |
| 357 | int top = inline_text_box_rect.y + character_offsets[localIndex - 1]; |
| 358 | int height = character_offsets[localIndex] - |
| 359 | character_offsets[localIndex - 1]; |
| 360 | return blink::WebRect(inline_text_box_rect.x, top, |
| 361 | inline_text_box_rect.width, height); |
| 362 | } |
| 363 | return blink::WebRect(inline_text_box_rect.x, inline_text_box_rect.y, |
| 364 | inline_text_box_rect.width, character_offsets[0]); |
| 365 | } |
| 366 | case blink::WebAXTextDirectionBT: { |
| 367 | int bottom = inline_text_box_rect.y + inline_text_box_rect.height; |
| 368 | |
| 369 | if (localIndex) { |
| 370 | int top = bottom - character_offsets[localIndex]; |
| 371 | int height = character_offsets[localIndex] - |
| 372 | character_offsets[localIndex - 1]; |
| 373 | return blink::WebRect(inline_text_box_rect.x, top, |
| 374 | inline_text_box_rect.width, height); |
| 375 | } |
| 376 | int top = bottom - character_offsets[0]; |
| 377 | return blink::WebRect(inline_text_box_rect.x, top, |
| 378 | inline_text_box_rect.width, character_offsets[0]); |
| 379 | } |
| 380 | } |
| 381 | } |
| 382 | |
| 383 | DCHECK(false); |
| 384 | return blink::WebRect(); |
| 385 | } |
| 386 | |
| 387 | void GetBoundariesForOneWord(const blink::WebAXObject& object, |
| 388 | int character_index, |
| 389 | int& word_start, |
| 390 | int& word_end) { |
| 391 | int end = 0; |
| 392 | for (unsigned i = 0; i < object.childCount(); i++) { |
| 393 | blink::WebAXObject inline_text_box = object.childAt(i); |
| 394 | DCHECK_EQ(inline_text_box.role(), blink::WebAXRoleInlineTextBox); |
| 395 | int start = end; |
| 396 | end += inline_text_box.stringValue().length(); |
| 397 | if (end <= character_index) |
| 398 | continue; |
| 399 | int localIndex = character_index - start; |
| 400 | |
| 401 | blink::WebVector<int> starts; |
| 402 | blink::WebVector<int> ends; |
| 403 | inline_text_box.wordBoundaries(starts, ends); |
| 404 | size_t word_count = starts.size(); |
| 405 | DCHECK_EQ(ends.size(), word_count); |
| 406 | |
| 407 | // If there are no words, use the InlineTextBox boundaries. |
| 408 | if (!word_count) { |
| 409 | word_start = start; |
| 410 | word_end = end; |
| 411 | return; |
| 412 | } |
| 413 | |
| 414 | // Look for a character within any word other than the last. |
| 415 | for (size_t j = 0; j < word_count - 1; j++) { |
| 416 | if (localIndex <= ends[j]) { |
| 417 | word_start = start + starts[j]; |
| 418 | word_end = start + ends[j]; |
| 419 | return; |
| 420 | } |
| 421 | } |
| 422 | |
| 423 | // Return the last word by default. |
| 424 | word_start = start + starts[word_count - 1]; |
| 425 | word_end = start + ends[word_count - 1]; |
| 426 | return; |
| 427 | } |
| 428 | } |
| 429 | |
| 430 | // Collects attributes into a string, delimited by dashes. Used by all methods |
| 431 | // that output lists of attributes: attributesOfLinkedUIElementsCallback, |
| 432 | // AttributesOfChildrenCallback, etc. |
| 433 | class AttributesCollector { |
| 434 | public: |
| 435 | AttributesCollector() {} |
| 436 | ~AttributesCollector() {} |
| 437 | |
| 438 | void CollectAttributes(const blink::WebAXObject& object) { |
| 439 | attributes_.append("\n------------\n"); |
| 440 | attributes_.append(GetAttributes(object)); |
| 441 | } |
| 442 | |
| 443 | std::string attributes() const { return attributes_; } |
| 444 | |
| 445 | private: |
| 446 | std::string attributes_; |
| 447 | |
| 448 | DISALLOW_COPY_AND_ASSIGN(AttributesCollector); |
| 449 | }; |
| 450 | |
| 451 | } // namespace |
| 452 | |
| 453 | gin::WrapperInfo WebAXObjectProxy::kWrapperInfo = { |
| 454 | gin::kEmbedderNativeGin}; |
| 455 | |
| 456 | WebAXObjectProxy::WebAXObjectProxy(const blink::WebAXObject& object, |
| 457 | WebAXObjectProxy::Factory* factory) |
| 458 | : accessibility_object_(object), |
| 459 | factory_(factory) { |
| 460 | } |
| 461 | |
| 462 | WebAXObjectProxy::~WebAXObjectProxy() {} |
| 463 | |
| 464 | gin::ObjectTemplateBuilder |
| 465 | WebAXObjectProxy::GetObjectTemplateBuilder(v8::Isolate* isolate) { |
| 466 | return gin::Wrappable<WebAXObjectProxy>::GetObjectTemplateBuilder(isolate) |
| 467 | .SetProperty("role", &WebAXObjectProxy::Role) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 468 | .SetProperty("stringValue", &WebAXObjectProxy::StringValue) |
k.czech | 56dbaa5e | 2014-12-08 15:43:54 | [diff] [blame] | 469 | .SetProperty("language", &WebAXObjectProxy::Language) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 470 | .SetProperty("x", &WebAXObjectProxy::X) |
| 471 | .SetProperty("y", &WebAXObjectProxy::Y) |
| 472 | .SetProperty("width", &WebAXObjectProxy::Width) |
| 473 | .SetProperty("height", &WebAXObjectProxy::Height) |
| 474 | .SetProperty("intValue", &WebAXObjectProxy::IntValue) |
| 475 | .SetProperty("minValue", &WebAXObjectProxy::MinValue) |
| 476 | .SetProperty("maxValue", &WebAXObjectProxy::MaxValue) |
| 477 | .SetProperty("valueDescription", &WebAXObjectProxy::ValueDescription) |
| 478 | .SetProperty("childrenCount", &WebAXObjectProxy::ChildrenCount) |
nektar | 8ff878a | 2015-08-07 16:56:57 | [diff] [blame] | 479 | .SetProperty("selectionAnchorObject", |
| 480 | &WebAXObjectProxy::SelectionAnchorObject) |
| 481 | .SetProperty("selectionAnchorOffset", |
| 482 | &WebAXObjectProxy::SelectionAnchorOffset) |
| 483 | .SetProperty("selectionFocusObject", |
| 484 | &WebAXObjectProxy::SelectionFocusObject) |
| 485 | .SetProperty("selectionFocusOffset", |
| 486 | &WebAXObjectProxy::SelectionFocusOffset) |
nektar | 02feadf6 | 2015-04-09 21:29:06 | [diff] [blame] | 487 | .SetProperty("selectionStart", &WebAXObjectProxy::SelectionStart) |
| 488 | .SetProperty("selectionEnd", &WebAXObjectProxy::SelectionEnd) |
nektar | f44560c | 2015-04-13 19:30:55 | [diff] [blame] | 489 | .SetProperty("selectionStartLineNumber", |
| 490 | &WebAXObjectProxy::SelectionStartLineNumber) |
| 491 | .SetProperty("selectionEndLineNumber", |
| 492 | &WebAXObjectProxy::SelectionEndLineNumber) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 493 | .SetProperty("isEnabled", &WebAXObjectProxy::IsEnabled) |
| 494 | .SetProperty("isRequired", &WebAXObjectProxy::IsRequired) |
nektar | 76e1a77 | 2015-09-18 01:24:49 | [diff] [blame] | 495 | .SetProperty("isEditable", &WebAXObjectProxy::IsEditable) |
nektar | f57a948 | 2015-06-10 00:00:43 | [diff] [blame] | 496 | .SetProperty("isRichlyEditable", &WebAXObjectProxy::IsRichlyEditable) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 497 | .SetProperty("isFocused", &WebAXObjectProxy::IsFocused) |
| 498 | .SetProperty("isFocusable", &WebAXObjectProxy::IsFocusable) |
| 499 | .SetProperty("isSelected", &WebAXObjectProxy::IsSelected) |
| 500 | .SetProperty("isSelectable", &WebAXObjectProxy::IsSelectable) |
| 501 | .SetProperty("isMultiSelectable", &WebAXObjectProxy::IsMultiSelectable) |
| 502 | .SetProperty("isSelectedOptionActive", |
| 503 | &WebAXObjectProxy::IsSelectedOptionActive) |
| 504 | .SetProperty("isExpanded", &WebAXObjectProxy::IsExpanded) |
| 505 | .SetProperty("isChecked", &WebAXObjectProxy::IsChecked) |
| 506 | .SetProperty("isVisible", &WebAXObjectProxy::IsVisible) |
| 507 | .SetProperty("isOffScreen", &WebAXObjectProxy::IsOffScreen) |
| 508 | .SetProperty("isCollapsed", &WebAXObjectProxy::IsCollapsed) |
| 509 | .SetProperty("hasPopup", &WebAXObjectProxy::HasPopup) |
| 510 | .SetProperty("isValid", &WebAXObjectProxy::IsValid) |
| 511 | .SetProperty("isReadOnly", &WebAXObjectProxy::IsReadOnly) |
nektar | d891c76 | 2015-05-13 17:28:05 | [diff] [blame] | 512 | .SetProperty("backgroundColor", &WebAXObjectProxy::BackgroundColor) |
| 513 | .SetProperty("color", &WebAXObjectProxy::Color) |
| 514 | .SetProperty("colorValue", &WebAXObjectProxy::ColorValue) |
| 515 | .SetProperty("fontSize", &WebAXObjectProxy::FontSize) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 516 | .SetProperty("orientation", &WebAXObjectProxy::Orientation) |
shreeram.k | deec21d2 | 2015-04-23 06:02:24 | [diff] [blame] | 517 | .SetProperty("posInSet", &WebAXObjectProxy::PosInSet) |
| 518 | .SetProperty("setSize", &WebAXObjectProxy::SetSize) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 519 | .SetProperty("clickPointX", &WebAXObjectProxy::ClickPointX) |
| 520 | .SetProperty("clickPointY", &WebAXObjectProxy::ClickPointY) |
| 521 | .SetProperty("rowCount", &WebAXObjectProxy::RowCount) |
k.czech | 48d2eb6 | 2015-01-20 09:38:48 | [diff] [blame] | 522 | .SetProperty("rowHeadersCount", &WebAXObjectProxy::RowHeadersCount) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 523 | .SetProperty("columnCount", &WebAXObjectProxy::ColumnCount) |
k.czech | 48d2eb6 | 2015-01-20 09:38:48 | [diff] [blame] | 524 | .SetProperty("columnHeadersCount", &WebAXObjectProxy::ColumnHeadersCount) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 525 | .SetProperty("isClickable", &WebAXObjectProxy::IsClickable) |
k.czech | 0027a48 | 2014-12-06 08:40:15 | [diff] [blame] | 526 | .SetProperty("isButtonStateMixed", &WebAXObjectProxy::IsButtonStateMixed) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 527 | .SetMethod("allAttributes", &WebAXObjectProxy::AllAttributes) |
| 528 | .SetMethod("attributesOfChildren", |
| 529 | &WebAXObjectProxy::AttributesOfChildren) |
k.czech | 510b04c6 | 2015-01-07 12:44:30 | [diff] [blame] | 530 | .SetMethod("ariaControlsElementAtIndex", |
| 531 | &WebAXObjectProxy::AriaControlsElementAtIndex) |
| 532 | .SetMethod("ariaFlowToElementAtIndex", |
| 533 | &WebAXObjectProxy::AriaFlowToElementAtIndex) |
| 534 | .SetMethod("ariaOwnsElementAtIndex", |
| 535 | &WebAXObjectProxy::AriaOwnsElementAtIndex) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 536 | .SetMethod("lineForIndex", &WebAXObjectProxy::LineForIndex) |
| 537 | .SetMethod("boundsForRange", &WebAXObjectProxy::BoundsForRange) |
| 538 | .SetMethod("childAtIndex", &WebAXObjectProxy::ChildAtIndex) |
| 539 | .SetMethod("elementAtPoint", &WebAXObjectProxy::ElementAtPoint) |
| 540 | .SetMethod("tableHeader", &WebAXObjectProxy::TableHeader) |
k.czech | aaddbff | 2014-12-30 11:55:09 | [diff] [blame] | 541 | .SetMethod("rowHeaderAtIndex", &WebAXObjectProxy::RowHeaderAtIndex) |
| 542 | .SetMethod("columnHeaderAtIndex", &WebAXObjectProxy::ColumnHeaderAtIndex) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 543 | .SetMethod("rowIndexRange", &WebAXObjectProxy::RowIndexRange) |
| 544 | .SetMethod("columnIndexRange", &WebAXObjectProxy::ColumnIndexRange) |
| 545 | .SetMethod("cellForColumnAndRow", &WebAXObjectProxy::CellForColumnAndRow) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 546 | .SetMethod("setSelectedTextRange", |
| 547 | &WebAXObjectProxy::SetSelectedTextRange) |
nektar | a2a22b89 | 2015-08-28 22:39:01 | [diff] [blame] | 548 | .SetMethod("setSelection", |
| 549 | &WebAXObjectProxy::SetSelection) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 550 | .SetMethod("isAttributeSettable", &WebAXObjectProxy::IsAttributeSettable) |
| 551 | .SetMethod("isPressActionSupported", |
| 552 | &WebAXObjectProxy::IsPressActionSupported) |
| 553 | .SetMethod("isIncrementActionSupported", |
| 554 | &WebAXObjectProxy::IsIncrementActionSupported) |
| 555 | .SetMethod("isDecrementActionSupported", |
| 556 | &WebAXObjectProxy::IsDecrementActionSupported) |
| 557 | .SetMethod("parentElement", &WebAXObjectProxy::ParentElement) |
| 558 | .SetMethod("increment", &WebAXObjectProxy::Increment) |
| 559 | .SetMethod("decrement", &WebAXObjectProxy::Decrement) |
| 560 | .SetMethod("showMenu", &WebAXObjectProxy::ShowMenu) |
| 561 | .SetMethod("press", &WebAXObjectProxy::Press) |
dmazzoni | a5bd1795 | 2015-09-11 17:41:27 | [diff] [blame] | 562 | .SetMethod("setValue", &WebAXObjectProxy::SetValue) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 563 | .SetMethod("isEqual", &WebAXObjectProxy::IsEqual) |
| 564 | .SetMethod("setNotificationListener", |
| 565 | &WebAXObjectProxy::SetNotificationListener) |
| 566 | .SetMethod("unsetNotificationListener", |
| 567 | &WebAXObjectProxy::UnsetNotificationListener) |
| 568 | .SetMethod("takeFocus", &WebAXObjectProxy::TakeFocus) |
| 569 | .SetMethod("scrollToMakeVisible", &WebAXObjectProxy::ScrollToMakeVisible) |
| 570 | .SetMethod("scrollToMakeVisibleWithSubFocus", |
| 571 | &WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus) |
| 572 | .SetMethod("scrollToGlobalPoint", &WebAXObjectProxy::ScrollToGlobalPoint) |
| 573 | .SetMethod("wordStart", &WebAXObjectProxy::WordStart) |
| 574 | .SetMethod("wordEnd", &WebAXObjectProxy::WordEnd) |
dmazzoni | 7873d25 | 2015-05-06 15:41:13 | [diff] [blame] | 575 | .SetMethod("nextOnLine", &WebAXObjectProxy::NextOnLine) |
| 576 | .SetMethod("previousOnLine", &WebAXObjectProxy::PreviousOnLine) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 577 | // TODO(hajimehoshi): This is for backward compatibility. Remove them. |
| 578 | .SetMethod("addNotificationListener", |
| 579 | &WebAXObjectProxy::SetNotificationListener) |
| 580 | .SetMethod("removeNotificationListener", |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 581 | &WebAXObjectProxy::UnsetNotificationListener) |
| 582 | // |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 583 | // NEW accessible name and description accessors |
| 584 | // |
| 585 | .SetProperty("name", &WebAXObjectProxy::Name) |
| 586 | .SetProperty("nameFrom", &WebAXObjectProxy::NameFrom) |
| 587 | .SetMethod("nameElementCount", &WebAXObjectProxy::NameElementCount) |
dmazzoni | 372420c | 2015-11-02 19:36:53 | [diff] [blame] | 588 | .SetMethod("nameElementAtIndex", &WebAXObjectProxy::NameElementAtIndex) |
| 589 | .SetProperty("description", &WebAXObjectProxy::Description) |
| 590 | .SetProperty("descriptionFrom", &WebAXObjectProxy::DescriptionFrom) |
| 591 | .SetMethod("descriptionElementCount", |
| 592 | &WebAXObjectProxy::DescriptionElementCount) |
| 593 | .SetMethod("descriptionElementAtIndex", |
| 594 | &WebAXObjectProxy::DescriptionElementAtIndex); |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 595 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 596 | } |
| 597 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 598 | v8::Local<v8::Object> WebAXObjectProxy::GetChildAtIndex(unsigned index) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 599 | return factory_->GetOrCreate(accessibility_object_.childAt(index)); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 600 | } |
| 601 | |
| 602 | bool WebAXObjectProxy::IsRoot() const { |
| 603 | return false; |
| 604 | } |
| 605 | |
| 606 | bool WebAXObjectProxy::IsEqualToObject(const blink::WebAXObject& other) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 607 | return accessibility_object_.equals(other); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 608 | } |
| 609 | |
| 610 | void WebAXObjectProxy::NotificationReceived( |
| 611 | blink::WebFrame* frame, |
| 612 | const std::string& notification_name) { |
| 613 | if (notification_callback_.IsEmpty()) |
| 614 | return; |
| 615 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 616 | v8::Local<v8::Context> context = frame->mainWorldScriptContext(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 617 | if (context.IsEmpty()) |
| 618 | return; |
| 619 | |
| 620 | v8::Isolate* isolate = blink::mainThreadIsolate(); |
| 621 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 622 | v8::Local<v8::Value> argv[] = { |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 623 | v8::String::NewFromUtf8(isolate, notification_name.data(), |
| 624 | v8::String::kNormalString, |
| 625 | notification_name.size()), |
| 626 | }; |
| 627 | frame->callFunctionEvenIfScriptDisabled( |
| 628 | v8::Local<v8::Function>::New(isolate, notification_callback_), |
| 629 | context->Global(), |
| 630 | arraysize(argv), |
| 631 | argv); |
| 632 | } |
| 633 | |
[email protected] | 4748a66 | 2014-07-04 00:27:17 | [diff] [blame] | 634 | void WebAXObjectProxy::Reset() { |
| 635 | notification_callback_.Reset(); |
| 636 | } |
| 637 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 638 | std::string WebAXObjectProxy::Role() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 639 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 640 | return GetRole(accessibility_object_); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 641 | } |
| 642 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 643 | std::string WebAXObjectProxy::StringValue() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 644 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 645 | return GetStringValue(accessibility_object_); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 646 | } |
| 647 | |
k.czech | 56dbaa5e | 2014-12-08 15:43:54 | [diff] [blame] | 648 | std::string WebAXObjectProxy::Language() { |
| 649 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 650 | return GetLanguage(accessibility_object_); |
| 651 | } |
| 652 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 653 | int WebAXObjectProxy::X() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 654 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 655 | return accessibility_object_.boundingBoxRect().x; |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 656 | } |
| 657 | |
| 658 | int WebAXObjectProxy::Y() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 659 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 660 | return accessibility_object_.boundingBoxRect().y; |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 661 | } |
| 662 | |
| 663 | int WebAXObjectProxy::Width() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 664 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 665 | return accessibility_object_.boundingBoxRect().width; |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 666 | } |
| 667 | |
| 668 | int WebAXObjectProxy::Height() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 669 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 670 | return accessibility_object_.boundingBoxRect().height; |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 671 | } |
| 672 | |
| 673 | int WebAXObjectProxy::IntValue() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 674 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 675 | if (accessibility_object_.supportsRangeValue()) |
| 676 | return accessibility_object_.valueForRange(); |
| 677 | else if (accessibility_object_.role() == blink::WebAXRoleHeading) |
| 678 | return accessibility_object_.headingLevel(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 679 | else |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 680 | return atoi(accessibility_object_.stringValue().utf8().data()); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 681 | } |
| 682 | |
| 683 | int WebAXObjectProxy::MinValue() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 684 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 685 | return accessibility_object_.minValueForRange(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 686 | } |
| 687 | |
| 688 | int WebAXObjectProxy::MaxValue() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 689 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 690 | return accessibility_object_.maxValueForRange(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 691 | } |
| 692 | |
| 693 | std::string WebAXObjectProxy::ValueDescription() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 694 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 695 | return GetValueDescription(accessibility_object_); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 696 | } |
| 697 | |
| 698 | int WebAXObjectProxy::ChildrenCount() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 699 | accessibility_object_.updateLayoutAndCheckValidity(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 700 | int count = 1; // Root object always has only one child, the WebView. |
| 701 | if (!IsRoot()) |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 702 | count = accessibility_object_.childCount(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 703 | return count; |
| 704 | } |
| 705 | |
nektar | 8ff878a | 2015-08-07 16:56:57 | [diff] [blame] | 706 | v8::Local<v8::Value> WebAXObjectProxy::SelectionAnchorObject() { |
| 707 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 708 | |
| 709 | blink::WebAXObject anchorObject; |
| 710 | int anchorOffset = -1; |
| 711 | blink::WebAXObject focusObject; |
| 712 | int focusOffset = -1; |
| 713 | accessibility_object_.selection(anchorObject, anchorOffset, |
| 714 | focusObject, focusOffset); |
| 715 | if (anchorObject.isNull()) |
| 716 | return v8::Null(blink::mainThreadIsolate()); |
| 717 | |
| 718 | return factory_->GetOrCreate(anchorObject); |
| 719 | } |
| 720 | |
| 721 | int WebAXObjectProxy::SelectionAnchorOffset() { |
| 722 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 723 | |
| 724 | blink::WebAXObject anchorObject; |
| 725 | int anchorOffset = -1; |
| 726 | blink::WebAXObject focusObject; |
| 727 | int focusOffset = -1; |
| 728 | accessibility_object_.selection(anchorObject, anchorOffset, |
| 729 | focusObject, focusOffset); |
| 730 | if (anchorOffset < 0) |
| 731 | return -1; |
| 732 | |
| 733 | return anchorOffset; |
| 734 | } |
| 735 | |
| 736 | v8::Local<v8::Value> WebAXObjectProxy::SelectionFocusObject() { |
| 737 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 738 | |
| 739 | blink::WebAXObject anchorObject; |
| 740 | int anchorOffset = -1; |
| 741 | blink::WebAXObject focusObject; |
| 742 | int focusOffset = -1; |
| 743 | accessibility_object_.selection(anchorObject, anchorOffset, |
| 744 | focusObject, focusOffset); |
| 745 | if (focusObject.isNull()) |
| 746 | return v8::Null(blink::mainThreadIsolate()); |
| 747 | |
| 748 | return factory_->GetOrCreate(focusObject); |
| 749 | } |
| 750 | |
| 751 | int WebAXObjectProxy::SelectionFocusOffset() { |
| 752 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 753 | |
| 754 | blink::WebAXObject anchorObject; |
| 755 | int anchorOffset = -1; |
| 756 | blink::WebAXObject focusObject; |
| 757 | int focusOffset = -1; |
| 758 | accessibility_object_.selection(anchorObject, anchorOffset, |
| 759 | focusObject, focusOffset); |
| 760 | if (focusOffset < 0) |
| 761 | return -1; |
| 762 | |
| 763 | return focusOffset; |
| 764 | } |
| 765 | |
nektar | 02feadf6 | 2015-04-09 21:29:06 | [diff] [blame] | 766 | int WebAXObjectProxy::SelectionStart() { |
| 767 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 768 | return accessibility_object_.selectionStart(); |
| 769 | } |
| 770 | |
| 771 | int WebAXObjectProxy::SelectionEnd() { |
| 772 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 773 | return accessibility_object_.selectionEnd(); |
| 774 | } |
| 775 | |
nektar | f44560c | 2015-04-13 19:30:55 | [diff] [blame] | 776 | int WebAXObjectProxy::SelectionStartLineNumber() { |
| 777 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 778 | return accessibility_object_.selectionStartLineNumber(); |
| 779 | } |
| 780 | |
| 781 | int WebAXObjectProxy::SelectionEndLineNumber() { |
| 782 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 783 | return accessibility_object_.selectionEndLineNumber(); |
| 784 | } |
| 785 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 786 | bool WebAXObjectProxy::IsEnabled() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 787 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 788 | return accessibility_object_.isEnabled(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 789 | } |
| 790 | |
| 791 | bool WebAXObjectProxy::IsRequired() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 792 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 793 | return accessibility_object_.isRequired(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 794 | } |
| 795 | |
nektar | 76e1a77 | 2015-09-18 01:24:49 | [diff] [blame] | 796 | bool WebAXObjectProxy::IsEditable() { |
| 797 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 798 | return accessibility_object_.isEditable(); |
| 799 | } |
| 800 | |
nektar | f57a948 | 2015-06-10 00:00:43 | [diff] [blame] | 801 | bool WebAXObjectProxy::IsRichlyEditable() { |
| 802 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 803 | return accessibility_object_.isRichlyEditable(); |
| 804 | } |
| 805 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 806 | bool WebAXObjectProxy::IsFocused() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 807 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 808 | return accessibility_object_.isFocused(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 809 | } |
| 810 | |
| 811 | bool WebAXObjectProxy::IsFocusable() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 812 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 813 | return accessibility_object_.canSetFocusAttribute(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 814 | } |
| 815 | |
| 816 | bool WebAXObjectProxy::IsSelected() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 817 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 818 | return accessibility_object_.isSelected(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 819 | } |
| 820 | |
| 821 | bool WebAXObjectProxy::IsSelectable() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 822 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 823 | return accessibility_object_.canSetSelectedAttribute(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 824 | } |
| 825 | |
| 826 | bool WebAXObjectProxy::IsMultiSelectable() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 827 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 828 | return accessibility_object_.isMultiSelectable(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 829 | } |
| 830 | |
| 831 | bool WebAXObjectProxy::IsSelectedOptionActive() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 832 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 833 | return accessibility_object_.isSelectedOptionActive(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 834 | } |
| 835 | |
| 836 | bool WebAXObjectProxy::IsExpanded() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 837 | accessibility_object_.updateLayoutAndCheckValidity(); |
je_julie.kim | 1f7fa9c | 2014-10-30 16:09:32 | [diff] [blame] | 838 | return accessibility_object_.isExpanded() == blink::WebAXExpandedExpanded; |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 839 | } |
| 840 | |
| 841 | bool WebAXObjectProxy::IsChecked() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 842 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 843 | return accessibility_object_.isChecked(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 844 | } |
| 845 | |
je_julie.kim | 1f7fa9c | 2014-10-30 16:09:32 | [diff] [blame] | 846 | bool WebAXObjectProxy::IsCollapsed() { |
| 847 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 848 | return accessibility_object_.isExpanded() == blink::WebAXExpandedCollapsed; |
| 849 | } |
| 850 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 851 | bool WebAXObjectProxy::IsVisible() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 852 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 853 | return accessibility_object_.isVisible(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 854 | } |
| 855 | |
| 856 | bool WebAXObjectProxy::IsOffScreen() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 857 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 858 | return accessibility_object_.isOffScreen(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 859 | } |
| 860 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 861 | bool WebAXObjectProxy::HasPopup() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 862 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 863 | return accessibility_object_.ariaHasPopup(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 864 | } |
| 865 | |
| 866 | bool WebAXObjectProxy::IsValid() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 867 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 868 | return !accessibility_object_.isDetached(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 869 | } |
| 870 | |
| 871 | bool WebAXObjectProxy::IsReadOnly() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 872 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 873 | return accessibility_object_.isReadOnly(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 874 | } |
| 875 | |
nektar | d891c76 | 2015-05-13 17:28:05 | [diff] [blame] | 876 | unsigned int WebAXObjectProxy::BackgroundColor() { |
| 877 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 878 | return accessibility_object_.backgroundColor(); |
| 879 | } |
| 880 | |
| 881 | unsigned int WebAXObjectProxy::Color() { |
| 882 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 883 | unsigned int color = accessibility_object_.color(); |
| 884 | // Remove the alpha because it's always 1 and thus not informative. |
| 885 | return color & 0xFFFFFF; |
| 886 | } |
| 887 | |
| 888 | // For input elements of type color. |
| 889 | unsigned int WebAXObjectProxy::ColorValue() { |
| 890 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 891 | return accessibility_object_.colorValue(); |
| 892 | } |
| 893 | |
| 894 | float WebAXObjectProxy::FontSize() { |
| 895 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 896 | return accessibility_object_.fontSize(); |
| 897 | } |
| 898 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 899 | std::string WebAXObjectProxy::Orientation() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 900 | accessibility_object_.updateLayoutAndCheckValidity(); |
shreeram.k | c562d1d | 2014-12-01 06:00:01 | [diff] [blame] | 901 | if (accessibility_object_.orientation() == blink::WebAXOrientationVertical) |
| 902 | return "AXOrientation: AXVerticalOrientation"; |
| 903 | else if (accessibility_object_.orientation() |
| 904 | == blink::WebAXOrientationHorizontal) |
| 905 | return "AXOrientation: AXHorizontalOrientation"; |
| 906 | |
| 907 | return std::string(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 908 | } |
| 909 | |
shreeram.k | deec21d2 | 2015-04-23 06:02:24 | [diff] [blame] | 910 | int WebAXObjectProxy::PosInSet() { |
| 911 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 912 | return accessibility_object_.posInSet(); |
| 913 | } |
| 914 | |
| 915 | int WebAXObjectProxy::SetSize() { |
| 916 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 917 | return accessibility_object_.setSize(); |
| 918 | } |
| 919 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 920 | int WebAXObjectProxy::ClickPointX() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 921 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 922 | return accessibility_object_.clickPoint().x; |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 923 | } |
| 924 | |
| 925 | int WebAXObjectProxy::ClickPointY() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 926 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 927 | return accessibility_object_.clickPoint().y; |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 928 | } |
| 929 | |
| 930 | int32_t WebAXObjectProxy::RowCount() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 931 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 932 | return static_cast<int32_t>(accessibility_object_.rowCount()); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 933 | } |
| 934 | |
k.czech | 48d2eb6 | 2015-01-20 09:38:48 | [diff] [blame] | 935 | int32_t WebAXObjectProxy::RowHeadersCount() { |
| 936 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 937 | blink::WebVector<blink::WebAXObject> headers; |
| 938 | accessibility_object_.rowHeaders(headers); |
| 939 | return static_cast<int32_t>(headers.size()); |
| 940 | } |
| 941 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 942 | int32_t WebAXObjectProxy::ColumnCount() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 943 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 944 | return static_cast<int32_t>(accessibility_object_.columnCount()); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 945 | } |
| 946 | |
k.czech | 48d2eb6 | 2015-01-20 09:38:48 | [diff] [blame] | 947 | int32_t WebAXObjectProxy::ColumnHeadersCount() |
| 948 | { |
| 949 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 950 | blink::WebVector<blink::WebAXObject> headers; |
| 951 | accessibility_object_.columnHeaders(headers); |
| 952 | return static_cast<int32_t>(headers.size()); |
| 953 | } |
| 954 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 955 | bool WebAXObjectProxy::IsClickable() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 956 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 957 | return accessibility_object_.isClickable(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 958 | } |
| 959 | |
k.czech | 0027a48 | 2014-12-06 08:40:15 | [diff] [blame] | 960 | bool WebAXObjectProxy::IsButtonStateMixed() { |
| 961 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 962 | return accessibility_object_.isButtonStateMixed(); |
| 963 | } |
| 964 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 965 | v8::Local<v8::Object> WebAXObjectProxy::AriaControlsElementAtIndex( |
k.czech | 510b04c6 | 2015-01-07 12:44:30 | [diff] [blame] | 966 | unsigned index) |
| 967 | { |
| 968 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 969 | blink::WebVector<blink::WebAXObject> elements; |
| 970 | accessibility_object_.ariaControls(elements); |
| 971 | size_t elementCount = elements.size(); |
| 972 | if (index >= elementCount) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 973 | return v8::Local<v8::Object>(); |
k.czech | 510b04c6 | 2015-01-07 12:44:30 | [diff] [blame] | 974 | |
| 975 | return factory_->GetOrCreate(elements[index]); |
| 976 | } |
| 977 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 978 | v8::Local<v8::Object> WebAXObjectProxy::AriaFlowToElementAtIndex( |
k.czech | 510b04c6 | 2015-01-07 12:44:30 | [diff] [blame] | 979 | unsigned index) |
| 980 | { |
| 981 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 982 | blink::WebVector<blink::WebAXObject> elements; |
| 983 | accessibility_object_.ariaFlowTo(elements); |
| 984 | size_t elementCount = elements.size(); |
| 985 | if (index >= elementCount) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 986 | return v8::Local<v8::Object>(); |
k.czech | 510b04c6 | 2015-01-07 12:44:30 | [diff] [blame] | 987 | |
| 988 | return factory_->GetOrCreate(elements[index]); |
| 989 | } |
| 990 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 991 | v8::Local<v8::Object> WebAXObjectProxy::AriaOwnsElementAtIndex(unsigned index) |
k.czech | 510b04c6 | 2015-01-07 12:44:30 | [diff] [blame] | 992 | { |
| 993 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 994 | blink::WebVector<blink::WebAXObject> elements; |
| 995 | accessibility_object_.ariaOwns(elements); |
| 996 | size_t elementCount = elements.size(); |
| 997 | if (index >= elementCount) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 998 | return v8::Local<v8::Object>(); |
k.czech | 510b04c6 | 2015-01-07 12:44:30 | [diff] [blame] | 999 | |
| 1000 | return factory_->GetOrCreate(elements[index]); |
| 1001 | } |
| 1002 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1003 | std::string WebAXObjectProxy::AllAttributes() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1004 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1005 | return GetAttributes(accessibility_object_); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1006 | } |
| 1007 | |
| 1008 | std::string WebAXObjectProxy::AttributesOfChildren() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1009 | accessibility_object_.updateLayoutAndCheckValidity(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1010 | AttributesCollector collector; |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1011 | unsigned size = accessibility_object_.childCount(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1012 | for (unsigned i = 0; i < size; ++i) |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1013 | collector.CollectAttributes(accessibility_object_.childAt(i)); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1014 | return collector.attributes(); |
| 1015 | } |
| 1016 | |
| 1017 | int WebAXObjectProxy::LineForIndex(int index) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1018 | accessibility_object_.updateLayoutAndCheckValidity(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1019 | blink::WebVector<int> line_breaks; |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1020 | accessibility_object_.lineBreaks(line_breaks); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1021 | int line = 0; |
| 1022 | int vector_size = static_cast<int>(line_breaks.size()); |
| 1023 | while (line < vector_size && line_breaks[line] <= index) |
| 1024 | line++; |
| 1025 | return line; |
| 1026 | } |
| 1027 | |
| 1028 | std::string WebAXObjectProxy::BoundsForRange(int start, int end) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1029 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1030 | if (accessibility_object_.role() != blink::WebAXRoleStaticText) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1031 | return std::string(); |
| 1032 | |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1033 | if (!accessibility_object_.updateLayoutAndCheckValidity()) |
[email protected] | e5a0930 | 2014-04-04 19:04:50 | [diff] [blame] | 1034 | return std::string(); |
| 1035 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1036 | int len = end - start; |
| 1037 | |
| 1038 | // Get the bounds for each character and union them into one large rectangle. |
| 1039 | // This is just for testing so it doesn't need to be efficient. |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1040 | blink::WebRect bounds = BoundsForCharacter(accessibility_object_, start); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1041 | for (int i = 1; i < len; i++) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1042 | blink::WebRect next = BoundsForCharacter(accessibility_object_, start + i); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1043 | int right = std::max(bounds.x + bounds.width, next.x + next.width); |
| 1044 | int bottom = std::max(bounds.y + bounds.height, next.y + next.height); |
| 1045 | bounds.x = std::min(bounds.x, next.x); |
| 1046 | bounds.y = std::min(bounds.y, next.y); |
| 1047 | bounds.width = right - bounds.x; |
| 1048 | bounds.height = bottom - bounds.y; |
| 1049 | } |
| 1050 | |
| 1051 | return base::StringPrintf("{x: %d, y: %d, width: %d, height: %d}", |
| 1052 | bounds.x, bounds.y, bounds.width, bounds.height); |
| 1053 | } |
| 1054 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1055 | v8::Local<v8::Object> WebAXObjectProxy::ChildAtIndex(int index) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1056 | accessibility_object_.updateLayoutAndCheckValidity(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1057 | return GetChildAtIndex(index); |
| 1058 | } |
| 1059 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1060 | v8::Local<v8::Object> WebAXObjectProxy::ElementAtPoint(int x, int y) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1061 | accessibility_object_.updateLayoutAndCheckValidity(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1062 | blink::WebPoint point(x, y); |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1063 | blink::WebAXObject obj = accessibility_object_.hitTest(point); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1064 | if (obj.isNull()) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1065 | return v8::Local<v8::Object>(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1066 | |
| 1067 | return factory_->GetOrCreate(obj); |
| 1068 | } |
| 1069 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1070 | v8::Local<v8::Object> WebAXObjectProxy::TableHeader() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1071 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1072 | blink::WebAXObject obj = accessibility_object_.headerContainerObject(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1073 | if (obj.isNull()) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1074 | return v8::Local<v8::Object>(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1075 | |
| 1076 | return factory_->GetOrCreate(obj); |
| 1077 | } |
| 1078 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1079 | v8::Local<v8::Object> WebAXObjectProxy::RowHeaderAtIndex(unsigned index) { |
k.czech | aaddbff | 2014-12-30 11:55:09 | [diff] [blame] | 1080 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1081 | blink::WebVector<blink::WebAXObject> headers; |
| 1082 | accessibility_object_.rowHeaders(headers); |
| 1083 | size_t headerCount = headers.size(); |
| 1084 | if (index >= headerCount) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1085 | return v8::Local<v8::Object>(); |
k.czech | aaddbff | 2014-12-30 11:55:09 | [diff] [blame] | 1086 | |
| 1087 | return factory_->GetOrCreate(headers[index]); |
| 1088 | } |
| 1089 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1090 | v8::Local<v8::Object> WebAXObjectProxy::ColumnHeaderAtIndex(unsigned index) { |
k.czech | aaddbff | 2014-12-30 11:55:09 | [diff] [blame] | 1091 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1092 | blink::WebVector<blink::WebAXObject> headers; |
| 1093 | accessibility_object_.columnHeaders(headers); |
| 1094 | size_t headerCount = headers.size(); |
| 1095 | if (index >= headerCount) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1096 | return v8::Local<v8::Object>(); |
k.czech | aaddbff | 2014-12-30 11:55:09 | [diff] [blame] | 1097 | |
| 1098 | return factory_->GetOrCreate(headers[index]); |
| 1099 | } |
| 1100 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1101 | std::string WebAXObjectProxy::RowIndexRange() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1102 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1103 | unsigned row_index = accessibility_object_.cellRowIndex(); |
| 1104 | unsigned row_span = accessibility_object_.cellRowSpan(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1105 | return base::StringPrintf("{%d, %d}", row_index, row_span); |
| 1106 | } |
| 1107 | |
| 1108 | std::string WebAXObjectProxy::ColumnIndexRange() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1109 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1110 | unsigned column_index = accessibility_object_.cellColumnIndex(); |
| 1111 | unsigned column_span = accessibility_object_.cellColumnSpan(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1112 | return base::StringPrintf("{%d, %d}", column_index, column_span); |
| 1113 | } |
| 1114 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1115 | v8::Local<v8::Object> WebAXObjectProxy::CellForColumnAndRow( |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1116 | int column, int row) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1117 | accessibility_object_.updateLayoutAndCheckValidity(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1118 | blink::WebAXObject obj = |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1119 | accessibility_object_.cellForColumnAndRow(column, row); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1120 | if (obj.isNull()) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1121 | return v8::Local<v8::Object>(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1122 | |
| 1123 | return factory_->GetOrCreate(obj); |
| 1124 | } |
| 1125 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1126 | void WebAXObjectProxy::SetSelectedTextRange(int selection_start, |
| 1127 | int length) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1128 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1129 | accessibility_object_.setSelectedTextRange(selection_start, |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1130 | selection_start + length); |
| 1131 | } |
| 1132 | |
nektar | a2a22b89 | 2015-08-28 22:39:01 | [diff] [blame] | 1133 | void WebAXObjectProxy::SetSelection( |
| 1134 | v8::Local<v8::Value> anchor_object, int anchor_offset, |
| 1135 | v8::Local<v8::Value> focus_object, int focus_offset) { |
| 1136 | if (anchor_object.IsEmpty() || focus_object.IsEmpty() || |
| 1137 | !anchor_object->IsObject() || !focus_object->IsObject() || |
| 1138 | anchor_offset < 0 || focus_offset < 0) { |
| 1139 | return; |
| 1140 | } |
| 1141 | |
| 1142 | WebAXObjectProxy* web_ax_anchor = nullptr; |
| 1143 | if (!gin::ConvertFromV8( |
| 1144 | blink::mainThreadIsolate(), anchor_object, &web_ax_anchor)) { |
| 1145 | return; |
| 1146 | } |
| 1147 | DCHECK(web_ax_anchor); |
| 1148 | |
| 1149 | WebAXObjectProxy* web_ax_focus = nullptr; |
| 1150 | if (!gin::ConvertFromV8( |
| 1151 | blink::mainThreadIsolate(), focus_object, &web_ax_focus)) { |
| 1152 | return; |
| 1153 | } |
| 1154 | DCHECK(web_ax_focus); |
| 1155 | |
| 1156 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1157 | accessibility_object_.setSelection( |
| 1158 | web_ax_anchor->accessibility_object_, anchor_offset, |
| 1159 | web_ax_focus->accessibility_object_, focus_offset); |
| 1160 | } |
| 1161 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1162 | bool WebAXObjectProxy::IsAttributeSettable(const std::string& attribute) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1163 | accessibility_object_.updateLayoutAndCheckValidity(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1164 | bool settable = false; |
| 1165 | if (attribute == "AXValue") |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1166 | settable = accessibility_object_.canSetValueAttribute(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1167 | return settable; |
| 1168 | } |
| 1169 | |
| 1170 | bool WebAXObjectProxy::IsPressActionSupported() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1171 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1172 | return accessibility_object_.canPress(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1173 | } |
| 1174 | |
| 1175 | bool WebAXObjectProxy::IsIncrementActionSupported() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1176 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1177 | return accessibility_object_.canIncrement(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1178 | } |
| 1179 | |
| 1180 | bool WebAXObjectProxy::IsDecrementActionSupported() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1181 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1182 | return accessibility_object_.canDecrement(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1183 | } |
| 1184 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1185 | v8::Local<v8::Object> WebAXObjectProxy::ParentElement() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1186 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1187 | blink::WebAXObject parent_object = accessibility_object_.parentObject(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1188 | while (parent_object.accessibilityIsIgnored()) |
| 1189 | parent_object = parent_object.parentObject(); |
| 1190 | return factory_->GetOrCreate(parent_object); |
| 1191 | } |
| 1192 | |
| 1193 | void WebAXObjectProxy::Increment() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1194 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1195 | accessibility_object_.increment(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1196 | } |
| 1197 | |
| 1198 | void WebAXObjectProxy::Decrement() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1199 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1200 | accessibility_object_.decrement(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1201 | } |
| 1202 | |
| 1203 | void WebAXObjectProxy::ShowMenu() { |
dmazzoni | 1915812c | 2015-05-18 20:32:40 | [diff] [blame] | 1204 | accessibility_object_.showContextMenu(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1205 | } |
| 1206 | |
| 1207 | void WebAXObjectProxy::Press() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1208 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1209 | accessibility_object_.press(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1210 | } |
| 1211 | |
dmazzoni | a5bd1795 | 2015-09-11 17:41:27 | [diff] [blame] | 1212 | bool WebAXObjectProxy::SetValue(const std::string& value) { |
| 1213 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1214 | if (!accessibility_object_.canSetValueAttribute()) |
| 1215 | return false; |
| 1216 | |
| 1217 | accessibility_object_.setValue(blink::WebString::fromUTF8(value)); |
| 1218 | return true; |
| 1219 | } |
| 1220 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1221 | bool WebAXObjectProxy::IsEqual(v8::Local<v8::Object> proxy) { |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1222 | WebAXObjectProxy* unwrapped_proxy = NULL; |
| 1223 | if (!gin::ConvertFromV8(blink::mainThreadIsolate(), proxy, &unwrapped_proxy)) |
| 1224 | return false; |
| 1225 | return unwrapped_proxy->IsEqualToObject(accessibility_object_); |
| 1226 | } |
| 1227 | |
| 1228 | void WebAXObjectProxy::SetNotificationListener( |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1229 | v8::Local<v8::Function> callback) { |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1230 | v8::Isolate* isolate = blink::mainThreadIsolate(); |
| 1231 | notification_callback_.Reset(isolate, callback); |
| 1232 | } |
| 1233 | |
| 1234 | void WebAXObjectProxy::UnsetNotificationListener() { |
| 1235 | notification_callback_.Reset(); |
| 1236 | } |
| 1237 | |
| 1238 | void WebAXObjectProxy::TakeFocus() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1239 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1240 | accessibility_object_.setFocused(true); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1241 | } |
| 1242 | |
| 1243 | void WebAXObjectProxy::ScrollToMakeVisible() { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1244 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1245 | accessibility_object_.scrollToMakeVisible(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1246 | } |
| 1247 | |
| 1248 | void WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus(int x, int y, |
| 1249 | int width, int height) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1250 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1251 | accessibility_object_.scrollToMakeVisibleWithSubFocus( |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1252 | blink::WebRect(x, y, width, height)); |
| 1253 | } |
| 1254 | |
| 1255 | void WebAXObjectProxy::ScrollToGlobalPoint(int x, int y) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1256 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1257 | accessibility_object_.scrollToGlobalPoint(blink::WebPoint(x, y)); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1258 | } |
| 1259 | |
| 1260 | int WebAXObjectProxy::WordStart(int character_index) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1261 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1262 | if (accessibility_object_.role() != blink::WebAXRoleStaticText) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1263 | return -1; |
| 1264 | |
dmazzoni | b5237c0 | 2015-04-16 21:43:25 | [diff] [blame] | 1265 | int word_start = 0, word_end = 0; |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1266 | GetBoundariesForOneWord(accessibility_object_, character_index, |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1267 | word_start, word_end); |
| 1268 | return word_start; |
| 1269 | } |
| 1270 | |
| 1271 | int WebAXObjectProxy::WordEnd(int character_index) { |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1272 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1273 | if (accessibility_object_.role() != blink::WebAXRoleStaticText) |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1274 | return -1; |
| 1275 | |
dmazzoni | b5237c0 | 2015-04-16 21:43:25 | [diff] [blame] | 1276 | int word_start = 0, word_end = 0; |
[email protected] | bb2076f | 2014-08-20 18:59:50 | [diff] [blame] | 1277 | GetBoundariesForOneWord(accessibility_object_, character_index, |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1278 | word_start, word_end); |
| 1279 | return word_end; |
| 1280 | } |
| 1281 | |
dmazzoni | 7873d25 | 2015-05-06 15:41:13 | [diff] [blame] | 1282 | v8::Local<v8::Object> WebAXObjectProxy::NextOnLine() { |
| 1283 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1284 | blink::WebAXObject obj = accessibility_object_.nextOnLine(); |
| 1285 | if (obj.isNull()) |
| 1286 | return v8::Local<v8::Object>(); |
| 1287 | |
| 1288 | return factory_->GetOrCreate(obj); |
| 1289 | } |
| 1290 | |
| 1291 | v8::Local<v8::Object> WebAXObjectProxy::PreviousOnLine() { |
| 1292 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1293 | blink::WebAXObject obj = accessibility_object_.previousOnLine(); |
| 1294 | if (obj.isNull()) |
| 1295 | return v8::Local<v8::Object>(); |
| 1296 | |
| 1297 | return factory_->GetOrCreate(obj); |
| 1298 | } |
| 1299 | |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 1300 | std::string WebAXObjectProxy::Name() { |
| 1301 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1302 | blink::WebAXNameFrom nameFrom; |
| 1303 | blink::WebVector<blink::WebAXObject> nameObjects; |
| 1304 | return accessibility_object_.name(nameFrom, nameObjects).utf8(); |
| 1305 | } |
| 1306 | |
| 1307 | std::string WebAXObjectProxy::NameFrom() { |
| 1308 | accessibility_object_.updateLayoutAndCheckValidity(); |
dmazzoni | 372420c | 2015-11-02 19:36:53 | [diff] [blame] | 1309 | blink::WebAXNameFrom nameFrom = blink::WebAXNameFromUninitialized; |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 1310 | blink::WebVector<blink::WebAXObject> nameObjects; |
| 1311 | accessibility_object_.name(nameFrom, nameObjects); |
| 1312 | switch(nameFrom) { |
dmazzoni | 372420c | 2015-11-02 19:36:53 | [diff] [blame] | 1313 | case blink::WebAXNameFromUninitialized: |
| 1314 | return ""; |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 1315 | case blink::WebAXNameFromAttribute: |
| 1316 | return "attribute"; |
dmazzoni | 372420c | 2015-11-02 19:36:53 | [diff] [blame] | 1317 | case blink::WebAXNameFromCaption: |
| 1318 | return "caption"; |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 1319 | case blink::WebAXNameFromContents: |
| 1320 | return "contents"; |
| 1321 | case blink::WebAXNameFromPlaceholder: |
| 1322 | return "placeholder"; |
| 1323 | case blink::WebAXNameFromRelatedElement: |
| 1324 | return "relatedElement"; |
dmazzoni | 372420c | 2015-11-02 19:36:53 | [diff] [blame] | 1325 | case blink::WebAXNameFromValue: |
| 1326 | return "value"; |
| 1327 | case blink::WebAXNameFromTitle: |
| 1328 | return "title"; |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 1329 | } |
dmazzoni | 372420c | 2015-11-02 19:36:53 | [diff] [blame] | 1330 | |
| 1331 | NOTREACHED(); |
| 1332 | return std::string(); |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 1333 | } |
| 1334 | |
| 1335 | int WebAXObjectProxy::NameElementCount() { |
| 1336 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1337 | blink::WebAXNameFrom nameFrom; |
| 1338 | blink::WebVector<blink::WebAXObject> nameObjects; |
| 1339 | accessibility_object_.name(nameFrom, nameObjects); |
| 1340 | return static_cast<int>(nameObjects.size()); |
| 1341 | } |
| 1342 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1343 | v8::Local<v8::Object> WebAXObjectProxy::NameElementAtIndex(unsigned index) { |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 1344 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1345 | blink::WebAXNameFrom nameFrom; |
| 1346 | blink::WebVector<blink::WebAXObject> nameObjects; |
| 1347 | accessibility_object_.name(nameFrom, nameObjects); |
| 1348 | if (index >= nameObjects.size()) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1349 | return v8::Local<v8::Object>(); |
dmazzoni | ffb5943 | 2015-04-11 01:53:13 | [diff] [blame] | 1350 | return factory_->GetOrCreate(nameObjects[index]); |
| 1351 | } |
| 1352 | |
dmazzoni | 372420c | 2015-11-02 19:36:53 | [diff] [blame] | 1353 | std::string WebAXObjectProxy::Description() { |
| 1354 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1355 | blink::WebAXNameFrom nameFrom; |
| 1356 | blink::WebVector<blink::WebAXObject> nameObjects; |
| 1357 | accessibility_object_.name(nameFrom, nameObjects); |
| 1358 | blink::WebAXDescriptionFrom descriptionFrom; |
| 1359 | blink::WebVector<blink::WebAXObject> descriptionObjects; |
| 1360 | return accessibility_object_.description( |
| 1361 | nameFrom, descriptionFrom, descriptionObjects).utf8(); |
| 1362 | } |
| 1363 | |
| 1364 | std::string WebAXObjectProxy::DescriptionFrom() { |
| 1365 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1366 | blink::WebAXNameFrom nameFrom; |
| 1367 | blink::WebVector<blink::WebAXObject> nameObjects; |
| 1368 | accessibility_object_.name(nameFrom, nameObjects); |
| 1369 | blink::WebAXDescriptionFrom descriptionFrom = |
| 1370 | blink::WebAXDescriptionFromUninitialized; |
| 1371 | blink::WebVector<blink::WebAXObject> descriptionObjects; |
| 1372 | accessibility_object_.description( |
| 1373 | nameFrom, descriptionFrom, descriptionObjects); |
| 1374 | switch(descriptionFrom) { |
| 1375 | case blink::WebAXDescriptionFromUninitialized: |
| 1376 | return ""; |
| 1377 | case blink::WebAXDescriptionFromAttribute: |
| 1378 | return "attribute"; |
| 1379 | case blink::WebAXDescriptionFromContents: |
| 1380 | return "contents"; |
| 1381 | case blink::WebAXDescriptionFromPlaceholder: |
| 1382 | return "placeholder"; |
| 1383 | case blink::WebAXDescriptionFromRelatedElement: |
| 1384 | return "relatedElement"; |
| 1385 | } |
| 1386 | |
| 1387 | NOTREACHED(); |
| 1388 | return std::string(); |
| 1389 | } |
| 1390 | |
| 1391 | int WebAXObjectProxy::DescriptionElementCount() { |
| 1392 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1393 | blink::WebAXNameFrom nameFrom; |
| 1394 | blink::WebVector<blink::WebAXObject> nameObjects; |
| 1395 | accessibility_object_.name(nameFrom, nameObjects); |
| 1396 | blink::WebAXDescriptionFrom descriptionFrom; |
| 1397 | blink::WebVector<blink::WebAXObject> descriptionObjects; |
| 1398 | accessibility_object_.description( |
| 1399 | nameFrom, descriptionFrom, descriptionObjects); |
| 1400 | return static_cast<int>(descriptionObjects.size()); |
| 1401 | } |
| 1402 | |
| 1403 | v8::Local<v8::Object> WebAXObjectProxy::DescriptionElementAtIndex( |
| 1404 | unsigned index) { |
| 1405 | accessibility_object_.updateLayoutAndCheckValidity(); |
| 1406 | blink::WebAXNameFrom nameFrom; |
| 1407 | blink::WebVector<blink::WebAXObject> nameObjects; |
| 1408 | accessibility_object_.name(nameFrom, nameObjects); |
| 1409 | blink::WebAXDescriptionFrom descriptionFrom; |
| 1410 | blink::WebVector<blink::WebAXObject> descriptionObjects; |
| 1411 | accessibility_object_.description( |
| 1412 | nameFrom, descriptionFrom, descriptionObjects); |
| 1413 | if (index >= descriptionObjects.size()) |
| 1414 | return v8::Local<v8::Object>(); |
| 1415 | return factory_->GetOrCreate(descriptionObjects[index]); |
| 1416 | } |
| 1417 | |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1418 | RootWebAXObjectProxy::RootWebAXObjectProxy( |
| 1419 | const blink::WebAXObject &object, Factory *factory) |
| 1420 | : WebAXObjectProxy(object, factory) { |
| 1421 | } |
| 1422 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1423 | v8::Local<v8::Object> RootWebAXObjectProxy::GetChildAtIndex(unsigned index) { |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1424 | if (index) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1425 | return v8::Local<v8::Object>(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1426 | |
| 1427 | return factory()->GetOrCreate(accessibility_object()); |
| 1428 | } |
| 1429 | |
| 1430 | bool RootWebAXObjectProxy::IsRoot() const { |
| 1431 | return true; |
| 1432 | } |
| 1433 | |
[email protected] | 40384bb | 2014-04-07 23:29:44 | [diff] [blame] | 1434 | WebAXObjectProxyList::WebAXObjectProxyList() |
| 1435 | : elements_(blink::mainThreadIsolate()) { |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1436 | } |
| 1437 | |
| 1438 | WebAXObjectProxyList::~WebAXObjectProxyList() { |
| 1439 | Clear(); |
| 1440 | } |
| 1441 | |
| 1442 | void WebAXObjectProxyList::Clear() { |
[email protected] | 4748a66 | 2014-07-04 00:27:17 | [diff] [blame] | 1443 | v8::Isolate* isolate = blink::mainThreadIsolate(); |
| 1444 | v8::HandleScope handle_scope(isolate); |
| 1445 | size_t elementCount = elements_.Size(); |
| 1446 | for (size_t i = 0; i < elementCount; i++) { |
| 1447 | WebAXObjectProxy* unwrapped_object = NULL; |
| 1448 | bool result = gin::ConvertFromV8(isolate, elements_.Get(i), |
| 1449 | &unwrapped_object); |
| 1450 | DCHECK(result); |
| 1451 | DCHECK(unwrapped_object); |
| 1452 | unwrapped_object->Reset(); |
| 1453 | } |
[email protected] | 40384bb | 2014-04-07 23:29:44 | [diff] [blame] | 1454 | elements_.Clear(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1455 | } |
| 1456 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1457 | v8::Local<v8::Object> WebAXObjectProxyList::GetOrCreate( |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1458 | const blink::WebAXObject& object) { |
| 1459 | if (object.isNull()) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1460 | return v8::Local<v8::Object>(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1461 | |
| 1462 | v8::Isolate* isolate = blink::mainThreadIsolate(); |
| 1463 | |
[email protected] | 40384bb | 2014-04-07 23:29:44 | [diff] [blame] | 1464 | size_t elementCount = elements_.Size(); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1465 | for (size_t i = 0; i < elementCount; i++) { |
| 1466 | WebAXObjectProxy* unwrapped_object = NULL; |
[email protected] | 40384bb | 2014-04-07 23:29:44 | [diff] [blame] | 1467 | bool result = gin::ConvertFromV8(isolate, elements_.Get(i), |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1468 | &unwrapped_object); |
| 1469 | DCHECK(result); |
| 1470 | DCHECK(unwrapped_object); |
| 1471 | if (unwrapped_object->IsEqualToObject(object)) |
[email protected] | 40384bb | 2014-04-07 23:29:44 | [diff] [blame] | 1472 | return elements_.Get(i); |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1473 | } |
| 1474 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1475 | v8::Local<v8::Value> value_handle = gin::CreateHandle( |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1476 | isolate, new WebAXObjectProxy(object, this)).ToV8(); |
| 1477 | if (value_handle.IsEmpty()) |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 1478 | return v8::Local<v8::Object>(); |
| 1479 | v8::Local<v8::Object> handle = value_handle->ToObject(isolate); |
[email protected] | 40384bb | 2014-04-07 23:29:44 | [diff] [blame] | 1480 | elements_.Append(handle); |
| 1481 | return handle; |
[email protected] | fa6a8f4 | 2014-03-06 14:20:18 | [diff] [blame] | 1482 | } |
| 1483 | |
jochen | f5f3175 | 2015-06-03 12:06:34 | [diff] [blame] | 1484 | } // namespace test_runner |