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

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js

Issue 2943193002: Run clang-format on .js files in c/b/r/chromeos/chromevox (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview Provides output services for ChromeVox. 6 * @fileoverview Provides output services for ChromeVox.
7 */ 7 */
8 8
9 goog.provide('Output'); 9 goog.provide('Output');
10 goog.provide('Output.EventType'); 10 goog.provide('Output.EventType');
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 * earconId: (string|undefined), 108 * earconId: (string|undefined),
109 * inherits: (string|undefined), 109 * inherits: (string|undefined),
110 * outputContextFirst: (boolean|undefined)}>} 110 * outputContextFirst: (boolean|undefined)}>}
111 * msgId: the message id of the role. 111 * msgId: the message id of the role.
112 * earconId: an optional earcon to play when encountering the role. 112 * earconId: an optional earcon to play when encountering the role.
113 * inherits: inherits rules from this role. 113 * inherits: inherits rules from this role.
114 * outputContextFirst: where to place the context output. 114 * outputContextFirst: where to place the context output.
115 * @private 115 * @private
116 */ 116 */
117 Output.ROLE_INFO_ = { 117 Output.ROLE_INFO_ = {
118 alert: { 118 alert: {msgId: 'role_alert'},
119 msgId: 'role_alert' 119 alertDialog: {msgId: 'role_alertdialog', outputContextFirst: true},
120 }, 120 article: {msgId: 'role_article', inherits: 'abstractContainer'},
121 alertDialog: { 121 application: {msgId: 'role_application', inherits: 'abstractContainer'},
122 msgId: 'role_alertdialog', 122 banner: {msgId: 'role_banner', inherits: 'abstractContainer'},
123 outputContextFirst: true 123 button: {msgId: 'role_button', earconId: 'BUTTON'},
124 }, 124 buttonDropDown: {msgId: 'role_button', earconId: 'BUTTON'},
125 article: { 125 checkBox: {msgId: 'role_checkbox'},
126 msgId: 'role_article', 126 columnHeader: {msgId: 'role_columnheader', inherits: 'cell'},
127 inherits: 'abstractContainer' 127 comboBox: {msgId: 'role_combobox', earconId: 'LISTBOX'},
128 }, 128 complementary: {msgId: 'role_complementary', inherits: 'abstractContainer'},
129 application: { 129 contentInfo: {msgId: 'role_contentinfo', inherits: 'abstractContainer'},
130 msgId: 'role_application', 130 date: {msgId: 'input_type_date', inherits: 'abstractContainer'},
131 inherits: 'abstractContainer' 131 definition: {msgId: 'role_definition', inherits: 'abstractContainer'},
132 }, 132 dialog: {msgId: 'role_dialog', outputContextFirst: true},
133 banner: { 133 directory: {msgId: 'role_directory', inherits: 'abstractContainer'},
134 msgId: 'role_banner', 134 document: {msgId: 'role_document', inherits: 'abstractContainer'},
135 inherits: 'abstractContainer' 135 form: {msgId: 'role_form', inherits: 'abstractContainer'},
136 }, 136 grid: {msgId: 'role_grid'},
137 button: { 137 group: {msgId: 'role_group', inherits: 'abstractContainer'},
138 msgId: 'role_button',
139 earconId: 'BUTTON'
140 },
141 buttonDropDown: {
142 msgId: 'role_button',
143 earconId: 'BUTTON'
144 },
145 checkBox: {
146 msgId: 'role_checkbox'
147 },
148 columnHeader: {
149 msgId: 'role_columnheader',
150 inherits: 'cell'
151 },
152 comboBox: {
153 msgId: 'role_combobox',
154 earconId: 'LISTBOX'
155 },
156 complementary: {
157 msgId: 'role_complementary',
158 inherits: 'abstractContainer'
159 },
160 contentInfo: {
161 msgId: 'role_contentinfo',
162 inherits: 'abstractContainer'
163 },
164 date: {
165 msgId: 'input_type_date',
166 inherits: 'abstractContainer'
167 },
168 definition: {
169 msgId: 'role_definition',
170 inherits: 'abstractContainer'
171 },
172 dialog: {
173 msgId: 'role_dialog',
174 outputContextFirst: true
175 },
176 directory: {
177 msgId: 'role_directory',
178 inherits: 'abstractContainer'
179 },
180 document: {
181 msgId: 'role_document',
182 inherits: 'abstractContainer'
183 },
184 form: {
185 msgId: 'role_form',
186 inherits: 'abstractContainer'
187 },
188 grid: {
189 msgId: 'role_grid'
190 },
191 group: {
192 msgId: 'role_group',
193 inherits: 'abstractContainer'
194 },
195 heading: { 138 heading: {
196 msgId: 'role_heading', 139 msgId: 'role_heading',
197 }, 140 },
198 image: { 141 image: {
199 msgId: 'role_img', 142 msgId: 'role_img',
200 }, 143 },
201 inputTime: { 144 inputTime: {msgId: 'input_type_time', inherits: 'abstractContainer'},
202 msgId: 'input_type_time', 145 link: {msgId: 'role_link', earconId: 'LINK'},
203 inherits: 'abstractContainer' 146 listBox: {msgId: 'role_listbox', earconId: 'LISTBOX'},
204 }, 147 listBoxOption: {msgId: 'role_listitem', earconId: 'LIST_ITEM'},
205 link: { 148 listItem: {msgId: 'role_listitem', earconId: 'LIST_ITEM'},
206 msgId: 'role_link',
207 earconId: 'LINK'
208 },
209 listBox: {
210 msgId: 'role_listbox',
211 earconId: 'LISTBOX'
212 },
213 listBoxOption: {
214 msgId: 'role_listitem',
215 earconId: 'LIST_ITEM'
216 },
217 listItem: {
218 msgId: 'role_listitem',
219 earconId: 'LIST_ITEM'
220 },
221 log: { 149 log: {
222 msgId: 'role_log', 150 msgId: 'role_log',
223 }, 151 },
224 main: { 152 main: {msgId: 'role_main', inherits: 'abstractContainer'},
225 msgId: 'role_main',
226 inherits: 'abstractContainer'
227 },
228 marquee: { 153 marquee: {
229 msgId: 'role_marquee', 154 msgId: 'role_marquee',
230 }, 155 },
231 math: { 156 math: {msgId: 'role_math', inherits: 'abstractContainer'},
232 msgId: 'role_math', 157 menu: {msgId: 'role_menu', outputContextFirst: true},
233 inherits: 'abstractContainer'
234 },
235 menu: {
236 msgId: 'role_menu',
237 outputContextFirst: true
238 },
239 menuBar: { 158 menuBar: {
240 msgId: 'role_menubar', 159 msgId: 'role_menubar',
241 }, 160 },
242 menuItem: { 161 menuItem: {msgId: 'role_menuitem'},
243 msgId: 'role_menuitem' 162 menuItemCheckBox: {msgId: 'role_menuitemcheckbox'},
244 }, 163 menuItemRadio: {msgId: 'role_menuitemradio'},
245 menuItemCheckBox: { 164 menuListOption: {msgId: 'role_menuitem'},
246 msgId: 'role_menuitemcheckbox' 165 menuListPopup: {msgId: 'role_menu'},
247 }, 166 meter: {msgId: 'role_meter', inherits: 'abstractRange'},
248 menuItemRadio: { 167 navigation: {msgId: 'role_navigation', inherits: 'abstractContainer'},
249 msgId: 'role_menuitemradio' 168 note: {msgId: 'role_note', inherits: 'abstractContainer'},
250 }, 169 progressIndicator:
251 menuListOption: { 170 {msgId: 'role_progress_indicator', inherits: 'abstractRange'},
252 msgId: 'role_menuitem' 171 popUpButton: {msgId: 'role_button', earconId: 'POP_UP_BUTTON'},
253 }, 172 radioButton: {msgId: 'role_radio'},
254 menuListPopup: {
255 msgId: 'role_menu'
256 },
257 meter: {
258 msgId: 'role_meter',
259 inherits: 'abstractRange'
260 },
261 navigation: {
262 msgId: 'role_navigation',
263 inherits: 'abstractContainer'
264 },
265 note: {
266 msgId: 'role_note',
267 inherits: 'abstractContainer'
268 },
269 progressIndicator: {
270 msgId: 'role_progress_indicator',
271 inherits: 'abstractRange'
272 },
273 popUpButton: {
274 msgId: 'role_button',
275 earconId: 'POP_UP_BUTTON'
276 },
277 radioButton: {
278 msgId: 'role_radio'
279 },
280 radioGroup: { 173 radioGroup: {
281 msgId: 'role_radiogroup', 174 msgId: 'role_radiogroup',
282 }, 175 },
283 rootWebArea: { 176 rootWebArea: {outputContextFirst: true},
284 outputContextFirst: true 177 row: {msgId: 'role_row', inherits: 'abstractContainer'},
285 }, 178 rowHeader: {msgId: 'role_rowheader', inherits: 'cell'},
286 row: { 179 scrollBar: {msgId: 'role_scrollbar', inherits: 'abstractRange'},
287 msgId: 'role_row', 180 search: {msgId: 'role_search', inherits: 'abstractContainer'},
288 inherits: 'abstractContainer' 181 separator: {msgId: 'role_separator', inherits: 'abstractContainer'},
289 }, 182 slider: {msgId: 'role_slider', inherits: 'abstractRange', earconId: 'SLIDER'},
290 rowHeader: {
291 msgId: 'role_rowheader',
292 inherits: 'cell'
293 },
294 scrollBar: {
295 msgId: 'role_scrollbar',
296 inherits: 'abstractRange'
297 },
298 search: {
299 msgId: 'role_search',
300 inherits: 'abstractContainer'
301 },
302 separator: {
303 msgId: 'role_separator',
304 inherits: 'abstractContainer'
305 },
306 slider: {
307 msgId: 'role_slider',
308 inherits: 'abstractRange',
309 earconId: 'SLIDER'
310 },
311 spinButton: { 183 spinButton: {
312 msgId: 'role_spinbutton', 184 msgId: 'role_spinbutton',
313 inherits: 'abstractRange', 185 inherits: 'abstractRange',
314 earconId: 'LISTBOX' 186 earconId: 'LISTBOX'
315 }, 187 },
316 status: { 188 status: {msgId: 'role_status'},
317 msgId: 'role_status' 189 tab: {msgId: 'role_tab'},
318 }, 190 tabList: {msgId: 'role_tablist'},
319 tab: { 191 tabPanel: {msgId: 'role_tabpanel'},
320 msgId: 'role_tab' 192 textBox: {msgId: 'input_type_text', earconId: 'EDITABLE_TEXT'},
321 }, 193 textField: {msgId: 'input_type_text', earconId: 'EDITABLE_TEXT'},
322 tabList: { 194 time: {msgId: 'tag_time', inherits: 'abstractContainer'},
323 msgId: 'role_tablist' 195 timer: {msgId: 'role_timer'},
324 }, 196 toolbar: {msgId: 'role_toolbar'},
325 tabPanel: { 197 toggleButton: {msgId: 'role_button', inherits: 'checkBox'},
326 msgId: 'role_tabpanel' 198 tree: {msgId: 'role_tree'},
327 }, 199 treeItem: {msgId: 'role_treeitem'}
328 textBox: {
329 msgId: 'input_type_text',
330 earconId: 'EDITABLE_TEXT'
331 },
332 textField: {
333 msgId: 'input_type_text',
334 earconId: 'EDITABLE_TEXT'
335 },
336 time: {
337 msgId: 'tag_time',
338 inherits: 'abstractContainer'
339 },
340 timer: {
341 msgId: 'role_timer'
342 },
343 toolbar: {
344 msgId: 'role_toolbar'
345 },
346 toggleButton: {
347 msgId: 'role_button',
348 inherits: 'checkBox'
349 },
350 tree: {
351 msgId: 'role_tree'
352 },
353 treeItem: {
354 msgId: 'role_treeitem'
355 }
356 }; 200 };
357 201
358 /** 202 /**
359 * Metadata about supported automation states. 203 * Metadata about supported automation states.
360 * @const {!Object<string, {on: {msgId: string, earconId: string}, 204 * @const {!Object<string, {on: {msgId: string, earconId: string},
361 * off: {msgId: string, earconId: string}, 205 * off: {msgId: string, earconId: string},
362 * isRoleSpecific: (boolean|undefined)}>} 206 * isRoleSpecific: (boolean|undefined)}>}
363 * on: info used to describe a state that is set to true. 207 * on: info used to describe a state that is set to true.
364 * off: info used to describe a state that is set to undefined. 208 * off: info used to describe a state that is set to undefined.
365 * isRoleSpecific: info used for specific roles. 209 * isRoleSpecific: info used for specific roles.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 'false': 'aria_pressed_false', 257 'false': 'aria_pressed_false',
414 'mixed': 'aria_pressed_mixed' 258 'mixed': 'aria_pressed_mixed'
415 }; 259 };
416 260
417 /** 261 /**
418 * Rules specifying format of AutomationNodes for output. 262 * Rules specifying format of AutomationNodes for output.
419 * @type {!Object<Object<Object<string>>>} 263 * @type {!Object<Object<Object<string>>>}
420 */ 264 */
421 Output.RULES = { 265 Output.RULES = {
422 navigate: { 266 navigate: {
423 'default': { 267 'default': {speak: '$name $value $state $role $description', braille: ''},
424 speak: '$name $value $state $role $description',
425 braille: ''
426 },
427 abstractContainer: { 268 abstractContainer: {
428 enter: '$nameFromNode $role $state $description', 269 enter: '$nameFromNode $role $state $description',
429 leave: '@exited_container($role)' 270 leave: '@exited_container($role)'
430 }, 271 },
431 abstractRange: { 272 abstractRange: {
432 speak: 273 speak: '$if($valueForRange, $valueForRange, $value) ' +
433 '$if($valueForRange, $valueForRange, $value) ' +
434 '$if($minValueForRange, @aria_value_min($minValueForRange)) ' + 274 '$if($minValueForRange, @aria_value_min($minValueForRange)) ' +
435 '$if($maxValueForRange, @aria_value_max($maxValueForRange)) ' + 275 '$if($maxValueForRange, @aria_value_max($maxValueForRange)) ' +
436 '$name $role $description $state' 276 '$name $role $description $state'
437 }, 277 },
438 alert: { 278 alert: {
439 enter: '$name $role $state', 279 enter: '$name $role $state',
440 speak: '$earcon(ALERT_NONMODAL) $role $nameOrTextContent $state' 280 speak: '$earcon(ALERT_NONMODAL) $role $nameOrTextContent $state'
441 }, 281 },
442 alertDialog: { 282 alertDialog: {
443 enter: '$earcon(ALERT_MODAL) $name $state', 283 enter: '$earcon(ALERT_MODAL) $name $state',
444 speak: '$earcon(ALERT_MODAL) $name $nameOrTextContent $state $role' 284 speak: '$earcon(ALERT_MODAL) $name $nameOrTextContent $state $role'
445 }, 285 },
446 cell: { 286 cell: {
447 enter: '@cell_summary($if($ariaCellRowIndex, $ariaCellRowIndex, ' + 287 enter: '@cell_summary($if($ariaCellRowIndex, $ariaCellRowIndex, ' +
448 '$tableCellRowIndex), ' + 288 '$tableCellRowIndex), ' +
449 '$if($ariaCellColumnIndex, $ariaCellColumnIndex, ' + 289 '$if($ariaCellColumnIndex, $ariaCellColumnIndex, ' +
450 '$tableCellColumnIndex)) $node(tableColumnHeader)', 290 '$tableCellColumnIndex)) $node(tableColumnHeader)',
451 speak: '$name @cell_summary($if($ariaCellRowIndex, $ariaCellRowIndex, ' + 291 speak: '$name @cell_summary($if($ariaCellRowIndex, $ariaCellRowIndex, ' +
452 '$tableCellRowIndex), ' + 292 '$tableCellRowIndex), ' +
453 '$if($ariaCellColumnIndex, $ariaCellColumnIndex, ' + 293 '$if($ariaCellColumnIndex, $ariaCellColumnIndex, ' +
454 '$tableCellColumnIndex)) $node(tableColumnHeader) $state' 294 '$tableCellColumnIndex)) $node(tableColumnHeader) $state'
455 }, 295 },
456 checkBox: { 296 checkBox: {
457 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' + 297 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' +
458 '$name $role $checked $description $state' 298 '$name $role $checked $description $state'
459 }, 299 },
460 client: { 300 client: {speak: '$name'},
461 speak: '$name' 301 date: {enter: '$nameFromNode $role $description'},
462 }, 302 dialog: {enter: '$nameFromNode $role $description'},
463 date: { 303 genericContainer:
464 enter: '$nameFromNode $role $description' 304 {enter: '$nameFromNode', speak: '$nameOrTextContent $description'},
465 }, 305 embeddedObject: {speak: '$name'},
466 dialog: { 306 grid: {enter: '$nameFromNode $role $description'},
467 enter: '$nameFromNode $role $description'
468 },
469 genericContainer: {
470 enter: '$nameFromNode',
471 speak: '$nameOrTextContent $description'
472 },
473 embeddedObject: {
474 speak: '$name'
475 },
476 grid: {
477 enter: '$nameFromNode $role $description'
478 },
479 group: { 307 group: {
480 enter: '$nameFromNode $state $description', 308 enter: '$nameFromNode $state $description',
481 speak: '$nameOrDescendants $value $state $description', 309 speak: '$nameOrDescendants $value $state $description',
482 leave: '' 310 leave: ''
483 }, 311 },
484 heading: { 312 heading: {
485 enter: '!relativePitch(hierarchicalLevel) ' + 313 enter: '!relativePitch(hierarchicalLevel) ' +
486 '$nameFromNode= ' + 314 '$nameFromNode= ' +
487 '$if($hierarchicalLevel, @tag_h+$hierarchicalLevel, $role) $state', 315 '$if($hierarchicalLevel, @tag_h+$hierarchicalLevel, $role) $state',
488 speak: '!relativePitch(hierarchicalLevel) ' + 316 speak: '!relativePitch(hierarchicalLevel) ' +
489 '$nameOrDescendants= ' + 317 '$nameOrDescendants= ' +
490 '$if($hierarchicalLevel, @tag_h+$hierarchicalLevel, $role) $state' 318 '$if($hierarchicalLevel, @tag_h+$hierarchicalLevel, $role) $state'
491 }, 319 },
492 image: { 320 image: {
493 speak: '$if($name, $name, $urlFilename) ' + 321 speak: '$if($name, $name, $urlFilename) ' +
494 '$value $state $role $description', 322 '$value $state $role $description',
495 }, 323 },
496 inlineTextBox: { 324 inlineTextBox: {speak: '$name='},
497 speak: '$name=' 325 inputTime: {enter: '$nameFromNode $role $description'},
498 },
499 inputTime: {
500 enter: '$nameFromNode $role $description'
501 },
502 link: { 326 link: {
503 enter: '$nameFromNode= $role $state', 327 enter: '$nameFromNode= $role $state',
504 speak: '$name $value $state ' + 328 speak: '$name $value $state ' +
505 '$if($inPageLinkTarget, @internal_link, $role) $description', 329 '$if($inPageLinkTarget, @internal_link, $role) $description',
506 }, 330 },
507 list: { 331 list: {
508 enter: '$role @@list_with_items($countChildren(listItem))', 332 enter: '$role @@list_with_items($countChildren(listItem))',
509 speak: '$descendants $role @@list_with_items($countChildren(listItem))' 333 speak: '$descendants $role @@list_with_items($countChildren(listItem))'
510 }, 334 },
511 listBox: { 335 listBox: {
(...skipping 26 matching lines...) Expand all
538 menuItemRadio: { 362 menuItemRadio: {
539 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' + 363 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' +
540 '$if($checked, @describe_radio_selected($name), ' + 364 '$if($checked, @describe_radio_selected($name), ' +
541 '@describe_radio_unselected($name)) $description ' + 365 '@describe_radio_unselected($name)) $description ' +
542 '@describe_index($indexInParent, $parentChildCount) ' 366 '@describe_index($indexInParent, $parentChildCount) '
543 }, 367 },
544 menuListOption: { 368 menuListOption: {
545 speak: '$name @role_menuitem ' + 369 speak: '$name @role_menuitem ' +
546 '@describe_index($indexInParent, $parentChildCount) $description' 370 '@describe_index($indexInParent, $parentChildCount) $description'
547 }, 371 },
548 paragraph: { 372 paragraph: {speak: '$descendants'},
549 speak: '$descendants'
550 },
551 popUpButton: { 373 popUpButton: {
552 speak: '$value $name $role @aria_has_popup ' + 374 speak: '$value $name $role @aria_has_popup ' +
553 '$state $description' 375 '$state $description'
554 }, 376 },
555 radioButton: { 377 radioButton: {
556 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' + 378 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' +
557 '$if($checked, @describe_radio_selected($name), ' + 379 '$if($checked, @describe_radio_selected($name), ' +
558 '@describe_radio_unselected($name)) $description' 380 '@describe_radio_unselected($name)) $description'
559 }, 381 },
560 radioGroup: { 382 radioGroup: {enter: '$name $role $description'},
561 enter: '$name $role $description' 383 rootWebArea: {enter: '$name', speak: '$if($name, $name, $docUrl)'},
562 }, 384 region: {speak: '$nameOrTextContent'},
563 rootWebArea: { 385 row: {enter: '$node(tableRowHeader)'},
564 enter: '$name', 386 rowHeader: {speak: '$nameOrTextContent $state'},
565 speak: '$if($name, $name, $docUrl)' 387 staticText: {speak: '$name='},
566 },
567 region: {
568 speak: '$nameOrTextContent'
569 },
570 row: {
571 enter: '$node(tableRowHeader)'
572 },
573 rowHeader: {
574 speak: '$nameOrTextContent $state'
575 },
576 staticText: {
577 speak: '$name='
578 },
579 switch: { 388 switch: {
580 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' + 389 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' +
581 '$if($checked, @describe_switch_on($name), ' + 390 '$if($checked, @describe_switch_on($name), ' +
582 '@describe_switch_off($name)) $description $state' 391 '@describe_switch_off($name)) $description $state'
583 }, 392 },
584 tab: { 393 tab: {
585 speak: '@describe_tab($name) $state $description ' + 394 speak: '@describe_tab($name) $state $description ' +
586 '$if($setSize, @describe_index($posInSet, $setSize))', 395 '$if($setSize, @describe_index($posInSet, $setSize))',
587 }, 396 },
588 table: { 397 table: {
589 enter: '@table_summary($name, ' + 398 enter: '@table_summary($name, ' +
590 '$if($ariaRowCount, $ariaRowCount, $tableRowCount), ' + 399 '$if($ariaRowCount, $ariaRowCount, $tableRowCount), ' +
591 '$if($ariaColumnCount, $ariaColumnCount, $tableColumnCount)) ' + 400 '$if($ariaColumnCount, $ariaColumnCount, $tableColumnCount)) ' +
592 '$node(tableHeader)' 401 '$node(tableHeader)'
593 }, 402 },
594 tableHeaderContainer: { 403 tableHeaderContainer: {speak: '$nameOrTextContent $state $description'},
595 speak: '$nameOrTextContent $state $description'
596 },
597 textField: { 404 textField: {
598 speak: '$name $value $if($multiline, @tag_textarea, $if(' + 405 speak: '$name $value $if($multiline, @tag_textarea, $if(' +
599 '$inputType, $inputType, $role)) $description $state', 406 '$inputType, $inputType, $role)) $description $state',
600 braille: '' 407 braille: ''
601 }, 408 },
602 timer: { 409 timer: {speak: '$nameFromNode $descendants $value $state $description'},
603 speak: '$nameFromNode $descendants $value $state $description'
604 },
605 toggleButton: { 410 toggleButton: {
606 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' + 411 speak: '$if($checked, $earcon(CHECK_ON), $earcon(CHECK_OFF)) ' +
607 '$name $role $pressed $description $state' 412 '$name $role $pressed $description $state'
608 }, 413 },
609 toolbar: { 414 toolbar: {enter: '$name $role $description'},
610 enter: '$name $role $description' 415 tree: {enter: '$name $role @@list_with_items($countChildren(treeItem))'},
611 },
612 tree: {
613 enter: '$name $role @@list_with_items($countChildren(treeItem))'
614 },
615 treeItem: { 416 treeItem: {
616 enter: '$role $expanded $collapsed ' + 417 enter: '$role $expanded $collapsed ' +
617 '@describe_index($indexInParent, $parentChildCount) ' + 418 '@describe_index($indexInParent, $parentChildCount) ' +
618 '@describe_depth($hierarchicalLevel)', 419 '@describe_depth($hierarchicalLevel)',
619 speak: '$name ' + 420 speak: '$name ' +
620 '$role $state ' + 421 '$role $state ' +
621 '@describe_index($indexInParent, $parentChildCount) ' + 422 '@describe_index($indexInParent, $parentChildCount) ' +
622 '@describe_depth($hierarchicalLevel)' 423 '@describe_depth($hierarchicalLevel)'
623 }, 424 },
624 window: { 425 window: {
625 enter: '@describe_window($name)', 426 enter: '@describe_window($name)',
626 speak: '@describe_window($name) $earcon(OBJECT_OPEN)' 427 speak: '@describe_window($name) $earcon(OBJECT_OPEN)'
627 } 428 }
628 }, 429 },
629 menuStart: { 430 menuStart:
630 'default': { 431 {'default': {speak: '@chrome_menu_opened($name) $earcon(OBJECT_OPEN)'}},
631 speak: '@chrome_menu_opened($name) $earcon(OBJECT_OPEN)' 432 menuEnd: {'default': {speak: '@chrome_menu_closed $earcon(OBJECT_CLOSE)'}},
632 }
633 },
634 menuEnd: {
635 'default': {
636 speak: '@chrome_menu_closed $earcon(OBJECT_CLOSE)'
637 }
638 },
639 menuListValueChanged: { 433 menuListValueChanged: {
640 'default': { 434 'default': {
641 speak: '$value $name ' + 435 speak: '$value $name ' +
642 '$find({"state": {"selected": true, "invisible": false}}, ' + 436 '$find({"state": {"selected": true, "invisible": false}}, ' +
643 '@describe_index($indexInParent, $parentChildCount)) ' 437 '@describe_index($indexInParent, $parentChildCount)) '
644 } 438 }
645 }, 439 },
646 alert: { 440 alert: {
647 default: { 441 default: {
648 speak: '$earcon(ALERT_NONMODAL) @role_alert ' + 442 speak: '$earcon(ALERT_NONMODAL) @role_alert ' +
649 '$nameOrTextContent $description' 443 '$nameOrTextContent $description'
650 } 444 }
651 } 445 }
652 }; 446 };
653 447
654 /** 448 /**
655 * Used to annotate utterances with speech properties. 449 * Used to annotate utterances with speech properties.
656 * @constructor 450 * @constructor
657 */ 451 */
658 Output.SpeechProperties = function() {}; 452 Output.SpeechProperties = function() {};
659 453
660 /** 454 /**
661 * Custom actions performed while rendering an output string. 455 * Custom actions performed while rendering an output string.
662 * @constructor 456 * @constructor
663 */ 457 */
664 Output.Action = function() { 458 Output.Action = function() {};
665 };
666 459
667 Output.Action.prototype = { 460 Output.Action.prototype = {
668 run: function() { 461 run: function() {}
669 }
670 }; 462 };
671 463
672 /** 464 /**
673 * Action to play an earcon. 465 * Action to play an earcon.
674 * @param {string} earconId 466 * @param {string} earconId
675 * @param {chrome.automation.Rect=} opt_location 467 * @param {chrome.automation.Rect=} opt_location
676 * @constructor 468 * @constructor
677 * @extends {Output.Action} 469 * @extends {Output.Action}
678 */ 470 */
679 Output.EarconAction = function(earconId, opt_location) { 471 Output.EarconAction = function(earconId, opt_location) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 * queueing mode. 529 * queueing mode.
738 * @type {cvox.QueueMode|undefined} 530 * @type {cvox.QueueMode|undefined}
739 * @private 531 * @private
740 */ 532 */
741 Output.forceModeForNextSpeechUtterance_; 533 Output.forceModeForNextSpeechUtterance_;
742 534
743 /** 535 /**
744 * Calling this will make the next speech utterance use |mode| even if it would 536 * Calling this will make the next speech utterance use |mode| even if it would
745 * normally queue or do a category flush. This differs from the |withQueueMode| 537 * normally queue or do a category flush. This differs from the |withQueueMode|
746 * instance method as it can apply to future output. 538 * instance method as it can apply to future output.
747 * @param {cvox.QueueMode} mode 539 * @param {cvox.QueueMode} mode
748 */ 540 */
749 Output.forceModeForNextSpeechUtterance = function(mode) { 541 Output.forceModeForNextSpeechUtterance = function(mode) {
750 Output.forceModeForNextSpeechUtterance_ = mode; 542 Output.forceModeForNextSpeechUtterance_ = mode;
751 }; 543 };
752 544
753 /** 545 /**
754 * For a given automation property, return true if the value 546 * For a given automation property, return true if the value
755 * represents something 'truthy', e.g.: for checked: 547 * represents something 'truthy', e.g.: for checked:
756 * 'true'|'mixed' -> true 548 * 'true'|'mixed' -> true
757 * 'false'|undefined -> false 549 * 'false'|undefined -> false
758 */ 550 */
759 Output.isTruthy = function(node, attrib) { 551 Output.isTruthy = function(node, attrib) {
760 switch(attrib) { 552 switch (attrib) {
761 case 'checked': 553 case 'checked':
762 return node.checked && node.checked !== 'false'; 554 return node.checked && node.checked !== 'false';
763 default: 555 default:
764 return node[attrib] !== undefined || node.state[attrib]; 556 return node[attrib] !== undefined || node.state[attrib];
765 } 557 }
766 }; 558 };
767 559
768 Output.prototype = { 560 Output.prototype = {
769 /** 561 /**
770 * @return {boolean} True if there's any speech that will be output. 562 * @return {boolean} True if there's any speech that will be output.
(...skipping 12 matching lines...) Expand all
783 * @param {cursors.Range} prevRange 575 * @param {cursors.Range} prevRange
784 * @param {EventType|Output.EventType} type 576 * @param {EventType|Output.EventType} type
785 * @return {!Output} 577 * @return {!Output}
786 */ 578 */
787 withSpeech: function(range, prevRange, type) { 579 withSpeech: function(range, prevRange, type) {
788 this.formatOptions_ = {speech: true, braille: false, auralStyle: false}; 580 this.formatOptions_ = {speech: true, braille: false, auralStyle: false};
789 this.render_(range, prevRange, type, this.speechBuffer_); 581 this.render_(range, prevRange, type, this.speechBuffer_);
790 return this; 582 return this;
791 }, 583 },
792 584
793 /** 585 /**
794 * Specify ranges for aurally styled speech. 586 * Specify ranges for aurally styled speech.
795 * @param {!cursors.Range} range 587 * @param {!cursors.Range} range
796 * @param {cursors.Range} prevRange 588 * @param {cursors.Range} prevRange
797 * @param {EventType|Output.EventType} type 589 * @param {EventType|Output.EventType} type
798 * @return {!Output} 590 * @return {!Output}
799 */ 591 */
800 withRichSpeech: function(range, prevRange, type) { 592 withRichSpeech: function(range, prevRange, type) {
801 this.formatOptions_ = {speech: true, braille: false, auralStyle: true}; 593 this.formatOptions_ = {speech: true, braille: false, auralStyle: true};
802 this.render_(range, prevRange, type, this.speechBuffer_); 594 this.render_(range, prevRange, type, this.speechBuffer_);
803 return this; 595 return this;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 * @param {cursors.Range} prevRange 627 * @param {cursors.Range} prevRange
836 * @param {EventType|Output.EventType} type 628 * @param {EventType|Output.EventType} type
837 * @return {!Output} 629 * @return {!Output}
838 */ 630 */
839 withSpeechAndBraille: function(range, prevRange, type) { 631 withSpeechAndBraille: function(range, prevRange, type) {
840 this.withSpeech(range, prevRange, type); 632 this.withSpeech(range, prevRange, type);
841 this.withBraille(range, prevRange, type); 633 this.withBraille(range, prevRange, type);
842 return this; 634 return this;
843 }, 635 },
844 636
845 /** 637 /**
846 * Specify the same ranges for aurally styled speech and braille. 638 * Specify the same ranges for aurally styled speech and braille.
847 * @param {!cursors.Range} range 639 * @param {!cursors.Range} range
848 * @param {cursors.Range} prevRange 640 * @param {cursors.Range} prevRange
849 * @param {EventType|Output.EventType} type 641 * @param {EventType|Output.EventType} type
850 * @return {!Output} 642 * @return {!Output}
851 */ 643 */
852 withRichSpeechAndBraille: function(range, prevRange, type) { 644 withRichSpeechAndBraille: function(range, prevRange, type) {
853 this.withRichSpeech(range, prevRange, type); 645 this.withRichSpeech(range, prevRange, type);
854 this.withBraille(range, prevRange, type); 646 this.withBraille(range, prevRange, type);
855 return this; 647 return this;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 690
899 /** 691 /**
900 * Apply a format string directly to the output buffer. This lets you 692 * Apply a format string directly to the output buffer. This lets you
901 * output a message directly to the buffer using the format syntax. 693 * output a message directly to the buffer using the format syntax.
902 * @param {string} formatStr 694 * @param {string} formatStr
903 * @param {!AutomationNode=} opt_node An optional node to apply the 695 * @param {!AutomationNode=} opt_node An optional node to apply the
904 * formatting to. 696 * formatting to.
905 * @return {!Output} |this| for chaining 697 * @return {!Output} |this| for chaining
906 */ 698 */
907 format: function(formatStr, opt_node) { 699 format: function(formatStr, opt_node) {
908 return this 700 return this.formatForSpeech(formatStr, opt_node)
909 .formatForSpeech(formatStr, opt_node)
910 .formatForBraille(formatStr, opt_node); 701 .formatForBraille(formatStr, opt_node);
911 }, 702 },
912 703
913 /** 704 /**
914 * Apply a format string directly to the speech output buffer. This lets you 705 * Apply a format string directly to the speech output buffer. This lets you
915 * output a message directly to the buffer using the format syntax. 706 * output a message directly to the buffer using the format syntax.
916 * @param {string} formatStr 707 * @param {string} formatStr
917 * @param {!AutomationNode=} opt_node An optional node to apply the 708 * @param {!AutomationNode=} opt_node An optional node to apply the
918 * formatting to. 709 * formatting to.
919 * @return {!Output} |this| for chaining 710 * @return {!Output} |this| for chaining
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 if (Output.forceModeForNextSpeechUtterance_ !== undefined) 756 if (Output.forceModeForNextSpeechUtterance_ !== undefined)
966 queueMode = Output.forceModeForNextSpeechUtterance_; 757 queueMode = Output.forceModeForNextSpeechUtterance_;
967 else if (this.queueMode_ !== undefined) 758 else if (this.queueMode_ !== undefined)
968 queueMode = this.queueMode_; 759 queueMode = this.queueMode_;
969 760
970 if (this.speechBuffer_.length > 0) 761 if (this.speechBuffer_.length > 0)
971 Output.forceModeForNextSpeechUtterance_ = undefined; 762 Output.forceModeForNextSpeechUtterance_ = undefined;
972 763
973 for (var i = 0; i < this.speechBuffer_.length; i++) { 764 for (var i = 0; i < this.speechBuffer_.length; i++) {
974 var buff = this.speechBuffer_[i]; 765 var buff = this.speechBuffer_[i];
975 var speechProps = /** @type {Object} */( 766 var speechProps = /** @type {Object} */ (
976 buff.getSpanInstanceOf(Output.SpeechProperties)) || {}; 767 buff.getSpanInstanceOf(Output.SpeechProperties)) ||
768 {};
977 769
978 speechProps.category = this.speechCategory_; 770 speechProps.category = this.speechCategory_;
979 771
980 (function() { 772 (function() {
981 var scopedBuff = buff; 773 var scopedBuff = buff;
982 speechProps['startCallback'] = function() { 774 speechProps['startCallback'] = function() {
983 var actions = scopedBuff.getSpansInstanceOf(Output.Action); 775 var actions = scopedBuff.getSpansInstanceOf(Output.Action);
984 if (actions) { 776 if (actions) {
985 actions.forEach(function(a) { 777 actions.forEach(function(a) {
986 a.run(); 778 a.run();
987 }); 779 });
988 } 780 }
989 }; 781 };
990 }()); 782 }());
991 783
992 if (i == this.speechBuffer_.length - 1) 784 if (i == this.speechBuffer_.length - 1)
993 speechProps['endCallback'] = this.speechEndCallback_; 785 speechProps['endCallback'] = this.speechEndCallback_;
994 786
995 cvox.ChromeVox.tts.speak( 787 cvox.ChromeVox.tts.speak(buff.toString(), queueMode, speechProps);
996 buff.toString(), queueMode, speechProps);
997 queueMode = cvox.QueueMode.QUEUE; 788 queueMode = cvox.QueueMode.QUEUE;
998 } 789 }
999 790
1000 // Braille. 791 // Braille.
1001 if (this.brailleBuffer_.length) { 792 if (this.brailleBuffer_.length) {
1002 var buff = this.mergeBraille_(this.brailleBuffer_); 793 var buff = this.mergeBraille_(this.brailleBuffer_);
1003 var selSpan = 794 var selSpan = buff.getSpanInstanceOf(Output.SelectionSpan);
1004 buff.getSpanInstanceOf(Output.SelectionSpan);
1005 var startIndex = -1, endIndex = -1; 795 var startIndex = -1, endIndex = -1;
1006 if (selSpan) { 796 if (selSpan) {
1007 var valueStart = buff.getSpanStart(selSpan); 797 var valueStart = buff.getSpanStart(selSpan);
1008 var valueEnd = buff.getSpanEnd(selSpan); 798 var valueEnd = buff.getSpanEnd(selSpan);
1009 startIndex = valueStart + selSpan.startIndex; 799 startIndex = valueStart + selSpan.startIndex;
1010 endIndex = valueStart + selSpan.endIndex; 800 endIndex = valueStart + selSpan.endIndex;
1011 buff.setSpan(new cvox.ValueSpan(0), valueStart, valueEnd); 801 buff.setSpan(new cvox.ValueSpan(0), valueStart, valueEnd);
1012 buff.setSpan(new cvox.ValueSelectionSpan(), startIndex, endIndex); 802 buff.setSpan(new cvox.ValueSelectionSpan(), startIndex, endIndex);
1013 } 803 }
1014 804
1015 var output = new cvox.NavBraille({ 805 var output = new cvox.NavBraille(
1016 text: buff, 806 {text: buff, startIndex: startIndex, endIndex: endIndex});
1017 startIndex: startIndex,
1018 endIndex: endIndex
1019 });
1020 807
1021 cvox.ChromeVox.braille.write(output); 808 cvox.ChromeVox.braille.write(output);
1022 } 809 }
1023 810
1024 // Display. 811 // Display.
1025 if (this.speechCategory_ != cvox.TtsCategory.LIVE) 812 if (this.speechCategory_ != cvox.TtsCategory.LIVE)
1026 chrome.accessibilityPrivate.setFocusRing(this.locations_); 813 chrome.accessibilityPrivate.setFocusRing(this.locations_);
1027 }, 814 },
1028 815
1029 /** 816 /**
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 // All possible tokens based on prefix. 899 // All possible tokens based on prefix.
1113 if (prefix == '$') { 900 if (prefix == '$') {
1114 if (token == 'value') { 901 if (token == 'value') {
1115 var text = node.value || ''; 902 var text = node.value || '';
1116 if (!node.state[StateType.EDITABLE] && node.name == text) 903 if (!node.state[StateType.EDITABLE] && node.name == text)
1117 return; 904 return;
1118 905
1119 var selectedText = ''; 906 var selectedText = '';
1120 if (node.textSelStart !== undefined) { 907 if (node.textSelStart !== undefined) {
1121 options.annotation.push(new Output.SelectionSpan( 908 options.annotation.push(new Output.SelectionSpan(
1122 node.textSelStart || 0, 909 node.textSelStart || 0, node.textSelEnd || 0));
1123 node.textSelEnd || 0));
1124 910
1125 selectedText = 911 selectedText = node.value.substring(
1126 node.value.substring(node.textSelStart || 0, 912 node.textSelStart || 0, node.textSelEnd || 0);
1127 node.textSelEnd || 0);
1128 } 913 }
1129 options.annotation.push(token); 914 options.annotation.push(token);
1130 if (selectedText && !this.formatOptions_.braille) { 915 if (selectedText && !this.formatOptions_.braille) {
1131 this.append_(buff, selectedText, options); 916 this.append_(buff, selectedText, options);
1132 this.append_(buff, Msgs.getMsg('selected')); 917 this.append_(buff, Msgs.getMsg('selected'));
1133 } else { 918 } else {
1134 this.append_(buff, text, options); 919 this.append_(buff, text, options);
1135 } 920 }
1136 } else if (token == 'name') { 921 } else if (token == 'name') {
1137 options.annotation.push(token); 922 options.annotation.push(token);
(...skipping 10 matching lines...) Expand all
1148 } else if (token == 'urlFilename') { 933 } else if (token == 'urlFilename') {
1149 options.annotation.push('name'); 934 options.annotation.push('name');
1150 var url = node.url || ''; 935 var url = node.url || '';
1151 var filename = ''; 936 var filename = '';
1152 if (url.substring(0, 4) != 'data') { 937 if (url.substring(0, 4) != 'data') {
1153 filename = 938 filename =
1154 url.substring(url.lastIndexOf('/') + 1, url.lastIndexOf('.')); 939 url.substring(url.lastIndexOf('/') + 1, url.lastIndexOf('.'));
1155 940
1156 // Hack to not speak the filename if it's ridiculously long. 941 // Hack to not speak the filename if it's ridiculously long.
1157 if (filename.length >= 30) 942 if (filename.length >= 30)
1158 filename = filename.substring(0, 16) + '...'; 943 filename = filename.substring(0, 16) + '...';
1159 } 944 }
1160 this.append_(buff, filename, options); 945 this.append_(buff, filename, options);
1161 } else if (token == 'nameFromNode') { 946 } else if (token == 'nameFromNode') {
1162 if (node.nameFrom == chrome.automation.NameFromType.CONTENTS) 947 if (node.nameFrom == chrome.automation.NameFromType.CONTENTS)
1163 return; 948 return;
1164 949
1165 options.annotation.push('name'); 950 options.annotation.push('name');
1166 this.append_(buff, node.name || '', options); 951 this.append_(buff, node.name || '', options);
1167 } else if (token == 'nameOrDescendants') { 952 } else if (token == 'nameOrDescendants') {
1168 options.annotation.push(token); 953 options.annotation.push(token);
(...skipping 14 matching lines...) Expand all
1183 if (node.role == child.role) 968 if (node.role == child.role)
1184 count++; 969 count++;
1185 if (node === child) 970 if (node === child)
1186 break; 971 break;
1187 } 972 }
1188 this.append_(buff, String(count)); 973 this.append_(buff, String(count));
1189 } 974 }
1190 } else if (token == 'parentChildCount') { 975 } else if (token == 'parentChildCount') {
1191 if (node.parent) { 976 if (node.parent) {
1192 options.annotation.push(token); 977 options.annotation.push(token);
1193 var count = node.parent.children.filter(function(child) { 978 var count = node.parent.children
1194 return node.role == child.role; 979 .filter(function(child) {
1195 }).length; 980 return node.role == child.role;
981 })
982 .length;
1196 this.append_(buff, String(count)); 983 this.append_(buff, String(count));
1197 } 984 }
1198 } else if (token == 'checked') { 985 } else if (token == 'checked') {
1199 var msg = Output.CHECKED_STATE_MAP[node.checked]; 986 var msg = Output.CHECKED_STATE_MAP[node.checked];
1200 if (msg) { 987 if (msg) {
1201 this.format_(node, '@' + msg, buff); 988 this.format_(node, '@' + msg, buff);
1202 } 989 }
1203 } else if (token == 'pressed') { 990 } else if (token == 'pressed') {
1204 var msg = Output.PRESSED_STATE_MAP[node.checked]; 991 var msg = Output.PRESSED_STATE_MAP[node.checked];
1205 if (msg) { 992 if (msg) {
1206 this.format_(node, '@' + msg, buff); 993 this.format_(node, '@' + msg, buff);
1207 } 994 }
1208 } else if (token == 'state') { 995 } else if (token == 'state') {
1209 if (node.state) { 996 if (node.state) {
1210 Object.getOwnPropertyNames(node.state).forEach(function(s) { 997 Object.getOwnPropertyNames(node.state).forEach(function(s) {
1211 var stateInfo = Output.STATE_INFO_[s]; 998 var stateInfo = Output.STATE_INFO_[s];
1212 if (stateInfo && !stateInfo.isRoleSpecific && stateInfo.on) 999 if (stateInfo && !stateInfo.isRoleSpecific && stateInfo.on)
1213 this.format_(node, '@' + stateInfo.on.msgId, buff); 1000 this.format_(node, '@' + stateInfo.on.msgId, buff);
1214 }.bind(this)); 1001 }.bind(this));
1215 } 1002 }
1216 } else if (token == 'find') { 1003 } else if (token == 'find') {
1217 // Find takes two arguments: JSON query string and format string. 1004 // Find takes two arguments: JSON query string and format string.
1218 if (tree.firstChild) { 1005 if (tree.firstChild) {
1219 var jsonQuery = tree.firstChild.value; 1006 var jsonQuery = tree.firstChild.value;
1220 node = node.find( 1007 node = node.find(
1221 /** @type {chrome.automation.FindParams}*/( 1008 /** @type {chrome.automation.FindParams}*/ (
1222 JSON.parse(jsonQuery))); 1009 JSON.parse(jsonQuery)));
1223 var formatString = tree.firstChild.nextSibling; 1010 var formatString = tree.firstChild.nextSibling;
1224 if (node) 1011 if (node)
1225 this.format_(node, formatString, buff); 1012 this.format_(node, formatString, buff);
1226 } 1013 }
1227 } else if (token == 'descendants') { 1014 } else if (token == 'descendants') {
1228 if (!node || AutomationPredicate.leafOrStaticText(node)) 1015 if (!node || AutomationPredicate.leafOrStaticText(node))
1229 return; 1016 return;
1230 1017
1231 // Construct a range to the leftmost and rightmost leaves. 1018 // Construct a range to the leftmost and rightmost leaves.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 this.append_(buff, msg || '', options); 1058 this.append_(buff, msg || '', options);
1272 } else if (token == 'inputType') { 1059 } else if (token == 'inputType') {
1273 if (!node.inputType) 1060 if (!node.inputType)
1274 return; 1061 return;
1275 options.annotation.push(token); 1062 options.annotation.push(token);
1276 var msgId = Output.INPUT_TYPE_MESSAGE_IDS_[node.inputType] || 1063 var msgId = Output.INPUT_TYPE_MESSAGE_IDS_[node.inputType] ||
1277 'input_type_text'; 1064 'input_type_text';
1278 if (this.formatOptions_.braille) 1065 if (this.formatOptions_.braille)
1279 msgId = msgId + '_brl'; 1066 msgId = msgId + '_brl';
1280 this.append_(buff, Msgs.getMsg(msgId), options); 1067 this.append_(buff, Msgs.getMsg(msgId), options);
1281 } else if (token == 'tableCellRowIndex' || 1068 } else if (
1282 token == 'tableCellColumnIndex') { 1069 token == 'tableCellRowIndex' || token == 'tableCellColumnIndex') {
1283 var value = node[token]; 1070 var value = node[token];
1284 if (value == undefined) 1071 if (value == undefined)
1285 return; 1072 return;
1286 value = String(value + 1); 1073 value = String(value + 1);
1287 options.annotation.push(token); 1074 options.annotation.push(token);
1288 this.append_(buff, value, options); 1075 this.append_(buff, value, options);
1289 } else if (token == 'node') { 1076 } else if (token == 'node') {
1290 if (!tree.firstChild || !node[tree.firstChild.value]) 1077 if (!tree.firstChild || !node[tree.firstChild.value])
1291 return; 1078 return;
1292 var related = node[tree.firstChild.value]; 1079 var related = node[tree.firstChild.value];
1293 this.node_(related, related, Output.EventType.NAVIGATE, buff); 1080 this.node_(related, related, Output.EventType.NAVIGATE, buff);
1294 } else if (token == 'nameOrTextContent') { 1081 } else if (token == 'nameOrTextContent') {
1295 if (node.name) { 1082 if (node.name) {
1296 this.format_(node, '$name', buff); 1083 this.format_(node, '$name', buff);
1297 } else { 1084 } else {
1298 var walker = new AutomationTreeWalker(node, 1085 var walker = new AutomationTreeWalker(node, Dir.FORWARD, {
1299 Dir.FORWARD, 1086 visit: AutomationPredicate.leafOrStaticText,
1300 {visit: AutomationPredicate.leafOrStaticText, 1087 leaf: AutomationPredicate.leafOrStaticText
1301 leaf: AutomationPredicate.leafOrStaticText}); 1088 });
1302 var outputStrings = []; 1089 var outputStrings = [];
1303 while (walker.next().node && 1090 while (walker.next().node &&
1304 walker.phase == AutomationTreeWalkerPhase.DESCENDANT) { 1091 walker.phase == AutomationTreeWalkerPhase.DESCENDANT) {
1305 if (walker.node.name) 1092 if (walker.node.name)
1306 outputStrings.push(walker.node.name); 1093 outputStrings.push(walker.node.name);
1307 } 1094 }
1308 var joinedOutput = outputStrings.join(' '); 1095 var joinedOutput = outputStrings.join(' ');
1309 this.append_(buff, joinedOutput, options); 1096 this.append_(buff, joinedOutput, options);
1310 } 1097 }
1311 } else if (node[token] !== undefined) { 1098 } else if (node[token] !== undefined) {
1312 options.annotation.push(token); 1099 options.annotation.push(token);
1313 var value = node[token]; 1100 var value = node[token];
1314 if (typeof value == 'number') 1101 if (typeof value == 'number')
1315 value = String(value); 1102 value = String(value);
1316 this.append_(buff, value, options); 1103 this.append_(buff, value, options);
1317 } else if (Output.STATE_INFO_[token]) { 1104 } else if (Output.STATE_INFO_[token]) {
1318 options.annotation.push('state'); 1105 options.annotation.push('state');
1319 var stateInfo = Output.STATE_INFO_[token]; 1106 var stateInfo = Output.STATE_INFO_[token];
1320 var resolvedInfo = {}; 1107 var resolvedInfo = {};
1321 resolvedInfo = node.state[token] ? stateInfo.on : stateInfo.off; 1108 resolvedInfo = node.state[token] ? stateInfo.on : stateInfo.off;
1322 if (!resolvedInfo) 1109 if (!resolvedInfo)
1323 return; 1110 return;
1324 if (this.formatOptions_.speech && resolvedInfo.earconId) { 1111 if (this.formatOptions_.speech && resolvedInfo.earconId) {
1325 options.annotation.push( 1112 options.annotation.push(
1326 new Output.EarconAction(resolvedInfo.earconId), 1113 new Output.EarconAction(resolvedInfo.earconId),
1327 node.location || undefined); 1114 node.location || undefined);
1328 } 1115 }
1329 var msgId = 1116 var msgId = this.formatOptions_.braille ?
1330 this.formatOptions_.braille ? resolvedInfo.msgId + '_brl' : 1117 resolvedInfo.msgId + '_brl' :
1331 resolvedInfo.msgId; 1118 resolvedInfo.msgId;
1332 var msg = Msgs.getMsg(msgId); 1119 var msg = Msgs.getMsg(msgId);
1333 this.append_(buff, msg, options); 1120 this.append_(buff, msg, options);
1334 } else if (tree.firstChild) { 1121 } else if (tree.firstChild) {
1335 // Custom functions. 1122 // Custom functions.
1336 if (token == 'if') { 1123 if (token == 'if') {
1337 var cond = tree.firstChild; 1124 var cond = tree.firstChild;
1338 var attrib = cond.value.slice(1); 1125 var attrib = cond.value.slice(1);
1339 if (Output.isTruthy(node, attrib)) 1126 if (Output.isTruthy(node, attrib))
1340 this.format_(node, cond.nextSibling, buff); 1127 this.format_(node, cond.nextSibling, buff);
1341 else 1128 else
1342 this.format_(node, cond.nextSibling.nextSibling, buff); 1129 this.format_(node, cond.nextSibling.nextSibling, buff);
1343 } else if (token == 'earcon') { 1130 } else if (token == 'earcon') {
1344 // Ignore unless we're generating speech output. 1131 // Ignore unless we're generating speech output.
1345 if (!this.formatOptions_.speech) 1132 if (!this.formatOptions_.speech)
1346 return; 1133 return;
1347 1134
1348 options.annotation.push( 1135 options.annotation.push(new Output.EarconAction(
1349 new Output.EarconAction(tree.firstChild.value, 1136 tree.firstChild.value, node.location || undefined));
1350 node.location || undefined));
1351 this.append_(buff, '', options); 1137 this.append_(buff, '', options);
1352 } else if (token == 'countChildren') { 1138 } else if (token == 'countChildren') {
1353 var role = tree.firstChild.value; 1139 var role = tree.firstChild.value;
1354 var count = node.children.filter(function(e) { 1140 var count = node.children
1355 return e.role == role; 1141 .filter(function(e) {
1356 }).length; 1142 return e.role == role;
1143 })
1144 .length;
1357 this.append_(buff, String(count)); 1145 this.append_(buff, String(count));
1358 } 1146 }
1359 } 1147 }
1360 } else if (prefix == '@') { 1148 } else if (prefix == '@') {
1361 if (this.formatOptions_.auralStyle) { 1149 if (this.formatOptions_.auralStyle) {
1362 speechProps = new Output.SpeechProperties(); 1150 speechProps = new Output.SpeechProperties();
1363 speechProps['relativePitch'] = -0.2; 1151 speechProps['relativePitch'] = -0.2;
1364 } 1152 }
1365 var isPluralized = (token[0] == '@'); 1153 var isPluralized = (token[0] == '@');
1366 if (isPluralized) 1154 if (isPluralized)
(...skipping 21 matching lines...) Expand all
1388 if (!msgBuff.length) 1176 if (!msgBuff.length)
1389 msgBuff = ['']; 1177 msgBuff = [''];
1390 msgArgs = msgArgs.concat(msgBuff); 1178 msgArgs = msgArgs.concat(msgBuff);
1391 curArg = curArg.nextSibling; 1179 curArg = curArg.nextSibling;
1392 } 1180 }
1393 } 1181 }
1394 var msg = Msgs.getMsg(msgId, msgArgs); 1182 var msg = Msgs.getMsg(msgId, msgArgs);
1395 try { 1183 try {
1396 if (this.formatOptions_.braille) 1184 if (this.formatOptions_.braille)
1397 msg = Msgs.getMsg(msgId + '_brl', msgArgs) || msg; 1185 msg = Msgs.getMsg(msgId + '_brl', msgArgs) || msg;
1398 } catch(e) {} 1186 } catch (e) {
1187 }
1399 1188
1400 if (!msg) { 1189 if (!msg) {
1401 console.error('Could not get message ' + msgId); 1190 console.error('Could not get message ' + msgId);
1402 return; 1191 return;
1403 } 1192 }
1404 1193
1405 if (isPluralized) { 1194 if (isPluralized) {
1406 var arg = tree.firstChild; 1195 var arg = tree.firstChild;
1407 if (!arg || arg.nextSibling) { 1196 if (!arg || arg.nextSibling) {
1408 console.error('Pluralized messages take exactly one argument'); 1197 console.error('Pluralized messages take exactly one argument');
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 this.ancestry_(node, prevNode, type, buff); 1263 this.ancestry_(node, prevNode, type, buff);
1475 this.node_(node, prevNode, type, buff); 1264 this.node_(node, prevNode, type, buff);
1476 if (!this.outputContextFirst_) 1265 if (!this.outputContextFirst_)
1477 this.ancestry_(node, prevNode, type, buff); 1266 this.ancestry_(node, prevNode, type, buff);
1478 if (node.location) 1267 if (node.location)
1479 this.locations_.push(node.location); 1268 this.locations_.push(node.location);
1480 return buff; 1269 return buff;
1481 }.bind(this); 1270 }.bind(this);
1482 1271
1483 var unit = range.isInlineText() ? cursors.Unit.TEXT : cursors.Unit.NODE; 1272 var unit = range.isInlineText() ? cursors.Unit.TEXT : cursors.Unit.NODE;
1484 while (cursor.node && 1273 while (cursor.node && range.end.node &&
1485 range.end.node && 1274 AutomationUtil.getDirection(cursor.node, range.end.node) ==
1486 AutomationUtil.getDirection(cursor.node, range.end.node) == 1275 Dir.FORWARD) {
1487 Dir.FORWARD) {
1488 var node = cursor.node; 1276 var node = cursor.node;
1489 rangeBuff.push.apply(rangeBuff, formatNodeAndAncestors(node, prevNode)); 1277 rangeBuff.push.apply(rangeBuff, formatNodeAndAncestors(node, prevNode));
1490 prevNode = node; 1278 prevNode = node;
1491 cursor = cursor.move(unit, 1279 cursor = cursor.move(unit, cursors.Movement.DIRECTIONAL, Dir.FORWARD);
1492 cursors.Movement.DIRECTIONAL,
1493 Dir.FORWARD);
1494 1280
1495 // Reached a boundary. 1281 // Reached a boundary.
1496 if (cursor.node == prevNode) 1282 if (cursor.node == prevNode)
1497 break; 1283 break;
1498 } 1284 }
1499 }, 1285 },
1500 1286
1501 /** 1287 /**
1502 * @param {!AutomationNode} node 1288 * @param {!AutomationNode} node
1503 * @param {!AutomationNode} prevNode 1289 * @param {!AutomationNode} prevNode
(...skipping 14 matching lines...) Expand all
1518 contextFirst = []; 1304 contextFirst = [];
1519 rest = []; 1305 rest = [];
1520 } 1306 }
1521 if ((Output.ROLE_INFO_[node.role] || {}).outputContextFirst) 1307 if ((Output.ROLE_INFO_[node.role] || {}).outputContextFirst)
1522 contextFirst.push(node); 1308 contextFirst.push(node);
1523 else 1309 else
1524 rest.push(node); 1310 rest.push(node);
1525 } 1311 }
1526 return rest.concat(contextFirst.reverse()); 1312 return rest.concat(contextFirst.reverse());
1527 } 1313 }
1528 var prevUniqueAncestors = byContextFirst(AutomationUtil.getUniqueAncestors( 1314 var prevUniqueAncestors =
1529 node, prevNode)); 1315 byContextFirst(AutomationUtil.getUniqueAncestors(node, prevNode));
1530 var uniqueAncestors = byContextFirst(AutomationUtil.getUniqueAncestors( 1316 var uniqueAncestors =
1531 prevNode, node)); 1317 byContextFirst(AutomationUtil.getUniqueAncestors(prevNode, node));
1532 1318
1533 // First, look up the event type's format block. 1319 // First, look up the event type's format block.
1534 // Navigate is the default event. 1320 // Navigate is the default event.
1535 var eventBlock = Output.RULES[type] || Output.RULES['navigate']; 1321 var eventBlock = Output.RULES[type] || Output.RULES['navigate'];
1536 1322
1537 var getMergedRoleBlock = function(role) { 1323 var getMergedRoleBlock = function(role) {
1538 var parentRole = (Output.ROLE_INFO_[role] || {}).inherits; 1324 var parentRole = (Output.ROLE_INFO_[role] || {}).inherits;
1539 var roleBlock = eventBlock[role] || eventBlock['default']; 1325 var roleBlock = eventBlock[role] || eventBlock['default'];
1540 var parentRoleBlock = parentRole ? eventBlock[parentRole] : {}; 1326 var parentRoleBlock = parentRole ? eventBlock[parentRole] : {};
1541 var mergedRoleBlock = {}; 1327 var mergedRoleBlock = {};
1542 for (var key in parentRoleBlock) 1328 for (var key in parentRoleBlock)
1543 mergedRoleBlock[key] = parentRoleBlock[key]; 1329 mergedRoleBlock[key] = parentRoleBlock[key];
1544 for (var key in roleBlock) 1330 for (var key in roleBlock)
1545 mergedRoleBlock[key] = roleBlock[key]; 1331 mergedRoleBlock[key] = roleBlock[key];
1546 return mergedRoleBlock; 1332 return mergedRoleBlock;
1547 }; 1333 };
1548 1334
1549 // Hash the roles we've entered. 1335 // Hash the roles we've entered.
1550 var enteredRoleSet = {}; 1336 var enteredRoleSet = {};
1551 for (var j = uniqueAncestors.length - 1, hashNode; 1337 for (var j = uniqueAncestors.length - 1, hashNode;
1552 (hashNode = uniqueAncestors[j]); 1338 (hashNode = uniqueAncestors[j]); j--)
1553 j--)
1554 enteredRoleSet[hashNode.role] = true; 1339 enteredRoleSet[hashNode.role] = true;
1555 1340
1556 for (var i = 0, formatPrevNode; 1341 for (var i = 0, formatPrevNode; (formatPrevNode = prevUniqueAncestors[i]);
1557 (formatPrevNode = prevUniqueAncestors[i]);
1558 i++) { 1342 i++) {
1559 // This prevents very repetitive announcements. 1343 // This prevents very repetitive announcements.
1560 if (enteredRoleSet[formatPrevNode.role] || 1344 if (enteredRoleSet[formatPrevNode.role] ||
1561 node.role == formatPrevNode.role || 1345 node.role == formatPrevNode.role ||
1562 localStorage['useVerboseMode'] == 'false') 1346 localStorage['useVerboseMode'] == 'false')
1563 continue; 1347 continue;
1564 1348
1565 var roleBlock = getMergedRoleBlock(formatPrevNode.role); 1349 var roleBlock = getMergedRoleBlock(formatPrevNode.role);
1566 if (roleBlock.leave && localStorage['useVerboseMode'] == 'true') 1350 if (roleBlock.leave && localStorage['useVerboseMode'] == 'true')
1567 this.format_(formatPrevNode, roleBlock.leave, buff, prevNode); 1351 this.format_(formatPrevNode, roleBlock.leave, buff, prevNode);
1568 } 1352 }
1569 1353
1570 // Customize for braille node annotations. 1354 // Customize for braille node annotations.
1571 var originalBuff = buff; 1355 var originalBuff = buff;
1572 var enterRole = {}; 1356 var enterRole = {};
1573 for (var j = uniqueAncestors.length - 1, formatNode; 1357 for (var j = uniqueAncestors.length - 1, formatNode;
1574 (formatNode = uniqueAncestors[j]); 1358 (formatNode = uniqueAncestors[j]); j--) {
1575 j--) {
1576 var roleBlock = getMergedRoleBlock(formatNode.role); 1359 var roleBlock = getMergedRoleBlock(formatNode.role);
1577 if (roleBlock.enter) { 1360 if (roleBlock.enter) {
1578 if (enterRole[formatNode.role]) 1361 if (enterRole[formatNode.role])
1579 continue; 1362 continue;
1580 1363
1581 if (this.formatOptions_.braille) 1364 if (this.formatOptions_.braille)
1582 buff = []; 1365 buff = [];
1583 1366
1584 enterRole[formatNode.role] = true; 1367 enterRole[formatNode.role] = true;
1585 this.format_(formatNode, roleBlock.enter, buff, prevNode); 1368 this.format_(formatNode, roleBlock.enter, buff, prevNode);
(...skipping 18 matching lines...) Expand all
1604 var originalBuff = buff; 1387 var originalBuff = buff;
1605 1388
1606 if (this.formatOptions_.braille) 1389 if (this.formatOptions_.braille)
1607 buff = []; 1390 buff = [];
1608 1391
1609 // Navigate is the default event. 1392 // Navigate is the default event.
1610 var eventBlock = Output.RULES[type] || Output.RULES['navigate']; 1393 var eventBlock = Output.RULES[type] || Output.RULES['navigate'];
1611 var roleBlock = eventBlock[node.role] || {}; 1394 var roleBlock = eventBlock[node.role] || {};
1612 var parentRole = (Output.ROLE_INFO_[node.role] || {}).inherits; 1395 var parentRole = (Output.ROLE_INFO_[node.role] || {}).inherits;
1613 var parentRoleBlock = eventBlock[parentRole || ''] || {}; 1396 var parentRoleBlock = eventBlock[parentRole || ''] || {};
1614 var speakFormat = roleBlock.speak || 1397 var speakFormat =
1615 parentRoleBlock.speak || 1398 roleBlock.speak || parentRoleBlock.speak || eventBlock['default'].speak;
1616 eventBlock['default'].speak;
1617 1399
1618 this.format_(node, speakFormat, buff, prevNode); 1400 this.format_(node, speakFormat, buff, prevNode);
1619 1401
1620 // Restore braille and add an annotation for this node. 1402 // Restore braille and add an annotation for this node.
1621 if (this.formatOptions_.braille) { 1403 if (this.formatOptions_.braille) {
1622 var nodeSpan = this.mergeBraille_(buff); 1404 var nodeSpan = this.mergeBraille_(buff);
1623 nodeSpan.setSpan(new Output.NodeSpan(node), 0, nodeSpan.length); 1405 nodeSpan.setSpan(new Output.NodeSpan(node), 0, nodeSpan.length);
1624 originalBuff.push(nodeSpan); 1406 originalBuff.push(nodeSpan);
1625 } 1407 }
1626 }, 1408 },
(...skipping 15 matching lines...) Expand all
1642 return; 1424 return;
1643 1425
1644 var options = {annotation: ['name'], isUnique: true}; 1426 var options = {annotation: ['name'], isUnique: true};
1645 var rangeStart = range.start.index; 1427 var rangeStart = range.start.index;
1646 var rangeEnd = range.end.index; 1428 var rangeEnd = range.end.index;
1647 if (this.formatOptions_.braille) { 1429 if (this.formatOptions_.braille) {
1648 options.annotation.push(new Output.NodeSpan(node)); 1430 options.annotation.push(new Output.NodeSpan(node));
1649 var selStart = node.textSelStart; 1431 var selStart = node.textSelStart;
1650 var selEnd = node.textSelEnd; 1432 var selEnd = node.textSelEnd;
1651 1433
1652 if (selStart !== undefined && 1434 if (selStart !== undefined && selEnd >= rangeStart &&
1653 selEnd >= rangeStart && selStart <= rangeEnd) { 1435 selStart <= rangeEnd) {
1654 // Editable text selection. 1436 // Editable text selection.
1655 1437
1656 // |rangeStart| and |rangeEnd| are indices set by the caller and are 1438 // |rangeStart| and |rangeEnd| are indices set by the caller and are
1657 // assumed to be inside of the range. In braille, we only ever expect to 1439 // assumed to be inside of the range. In braille, we only ever expect to
1658 // get ranges surrounding a line as anything smaller doesn't make sense. 1440 // get ranges surrounding a line as anything smaller doesn't make sense.
1659 1441
1660 // |selStart| and |selEnd| reflect the editable selection. The relative 1442 // |selStart| and |selEnd| reflect the editable selection. The relative
1661 // selStart and relative selEnd for the current line are then just the 1443 // selStart and relative selEnd for the current line are then just the
1662 // difference between |selStart|, |selEnd| with |rangeStart|. 1444 // difference between |selStart|, |selEnd| with |rangeStart|.
1663 // See editing_test.js for examples. 1445 // See editing_test.js for examples.
(...skipping 21 matching lines...) Expand all
1685 } else { 1467 } else {
1686 // This is output for speech or editable braille. 1468 // This is output for speech or editable braille.
1687 text = range.start.getText().substring(rangeStart, rangeEnd); 1469 text = range.start.getText().substring(rangeStart, rangeEnd);
1688 } 1470 }
1689 1471
1690 this.append_(buff, text, options); 1472 this.append_(buff, text, options);
1691 1473
1692 if (!this.outputContextFirst_) 1474 if (!this.outputContextFirst_)
1693 this.ancestry_(node, prevNode, type, buff); 1475 this.ancestry_(node, prevNode, type, buff);
1694 1476
1695 var loc = 1477 var loc = range.start.node.boundsForRange(rangeStart, rangeEnd);
1696 range.start.node.boundsForRange(rangeStart, rangeEnd);
1697 if (loc) 1478 if (loc)
1698 this.locations_.push(loc); 1479 this.locations_.push(loc);
1699 }, 1480 },
1700 1481
1701 /** 1482 /**
1702 * Appends output to the |buff|. 1483 * Appends output to the |buff|.
1703 * @param {!Array<Spannable>} buff 1484 * @param {!Array<Spannable>} buff
1704 * @param {string|!Spannable} value 1485 * @param {string|!Spannable} value
1705 * @param {{isUnique: (boolean|undefined), 1486 * @param {{isUnique: (boolean|undefined),
1706 * annotation: !Array<*>}=} opt_options 1487 * annotation: !Array<*>}=} opt_options
1707 */ 1488 */
1708 append_: function(buff, value, opt_options) { 1489 append_: function(buff, value, opt_options) {
1709 opt_options = opt_options || {isUnique: false, annotation: []}; 1490 opt_options = opt_options || {isUnique: false, annotation: []};
1710 1491
1711 // Reject empty values without meaningful annotations. 1492 // Reject empty values without meaningful annotations.
1712 if ((!value || value.length == 0) && opt_options.annotation.every( 1493 if ((!value || value.length == 0) &&
1713 function(a) { 1494 opt_options.annotation.every(function(a) {
1714 return !(a instanceof Output.Action) && 1495 return !(a instanceof Output.Action) &&
1715 !(a instanceof Output.SelectionSpan); 1496 !(a instanceof Output.SelectionSpan);
1716 1497
1717 })) 1498 }))
1718 return; 1499 return;
1719 1500
1720 var spannableToAdd = new Spannable(value); 1501 var spannableToAdd = new Spannable(value);
1721 opt_options.annotation.forEach(function(a) { 1502 opt_options.annotation.forEach(function(a) {
1722 spannableToAdd.setSpan(a, 0, spannableToAdd.length); 1503 spannableToAdd.setSpan(a, 0, spannableToAdd.length);
1723 }); 1504 });
1724 1505
1725 // |isUnique| specifies an annotation that cannot be duplicated. 1506 // |isUnique| specifies an annotation that cannot be duplicated.
1726 if (opt_options.isUnique) { 1507 if (opt_options.isUnique) {
1727 var annotationSansNodes = opt_options.annotation.filter( 1508 var annotationSansNodes =
1728 function(annotation) { 1509 opt_options.annotation.filter(function(annotation) {
1729 return !(annotation instanceof Output.NodeSpan); 1510 return !(annotation instanceof Output.NodeSpan);
1730 }); 1511 });
1731 1512
1732 var alreadyAnnotated = buff.some(function(s) { 1513 var alreadyAnnotated = buff.some(function(s) {
1733 return annotationSansNodes.some(function(annotation) { 1514 return annotationSansNodes.some(function(annotation) {
1734 if (!s.hasSpan(annotation)) 1515 if (!s.hasSpan(annotation))
1735 return false; 1516 return false;
1736 var start = s.getSpanStart(annotation); 1517 var start = s.getSpanStart(annotation);
1737 var end = s.getSpanEnd(annotation); 1518 var end = s.getSpanEnd(annotation);
1738 var substr = s.substring(start, end); 1519 var substr = s.substring(start, end);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1809 // showing the braille cursor. 1590 // showing the braille cursor.
1810 if (cur.length == 0 && hasSelection) { 1591 if (cur.length == 0 && hasSelection) {
1811 result.append(cur); 1592 result.append(cur);
1812 result.append(Output.SPACE); 1593 result.append(Output.SPACE);
1813 separator = ''; 1594 separator = '';
1814 return result; 1595 return result;
1815 } 1596 }
1816 1597
1817 // Keep track of if there's an inline node associated with 1598 // Keep track of if there's an inline node associated with
1818 // |cur|. 1599 // |cur|.
1819 var hasInlineNode = cur.getSpansInstanceOf(Output.NodeSpan) 1600 var hasInlineNode =
1820 .some(function(s) { 1601 cur.getSpansInstanceOf(Output.NodeSpan).some(function(s) {
1821 if (!s.node) 1602 if (!s.node)
1822 return false; 1603 return false;
1823 return s.node.display == 'inline' || 1604 return s.node.display == 'inline' ||
1824 s.node.role == RoleType.INLINE_TEXT_BOX; 1605 s.node.role == RoleType.INLINE_TEXT_BOX;
1825 }); 1606 });
1826 1607
1827 var isName = cur.hasSpan('name'); 1608 var isName = cur.hasSpan('name');
1828 1609
1829 // Now, decide whether we should include separators between the previous 1610 // Now, decide whether we should include separators between the previous
1830 // span and |cur|. 1611 // span and |cur|.
1831 // Never separate chunks without something already there at this point. 1612 // Never separate chunks without something already there at this point.
1832 1613
1833 // The only case where we know for certain that a separator is not needed 1614 // The only case where we know for certain that a separator is not needed
1834 // is when the previous and current values are in-lined and part of the 1615 // is when the previous and current values are in-lined and part of the
1835 // node's name. In all other cases, use the surrounding whitespace to 1616 // node's name. In all other cases, use the surrounding whitespace to
1836 // ensure we only have one separator between the node text. 1617 // ensure we only have one separator between the node text.
1837 if (result.length == 0 || 1618 if (result.length == 0 ||
1838 (hasInlineNode && prevHasInlineNode && isName && prevIsName)) 1619 (hasInlineNode && prevHasInlineNode && isName && prevIsName))
1839 separator = ''; 1620 separator = '';
1840 else if (result.toString()[result.length - 1] == Output.SPACE || 1621 else if (
1622 result.toString()[result.length - 1] == Output.SPACE ||
1841 cur.toString()[0] == Output.SPACE) 1623 cur.toString()[0] == Output.SPACE)
1842 separator = ''; 1624 separator = '';
1843 else 1625 else
1844 separator = Output.SPACE; 1626 separator = Output.SPACE;
1845 1627
1846 prevHasInlineNode = hasInlineNode; 1628 prevHasInlineNode = hasInlineNode;
1847 prevIsName = isName; 1629 prevIsName = isName;
1848 result.append(separator); 1630 result.append(separator);
1849 result.append(cur); 1631 result.append(cur);
1850 return result; 1632 return result;
(...skipping 14 matching lines...) Expand all
1865 var earconFinder = node; 1647 var earconFinder = node;
1866 var ancestors; 1648 var ancestors;
1867 if (opt_prevNode) 1649 if (opt_prevNode)
1868 ancestors = AutomationUtil.getUniqueAncestors(opt_prevNode, node); 1650 ancestors = AutomationUtil.getUniqueAncestors(opt_prevNode, node);
1869 else 1651 else
1870 ancestors = AutomationUtil.getAncestors(node); 1652 ancestors = AutomationUtil.getAncestors(node);
1871 1653
1872 while (earconFinder = ancestors.pop()) { 1654 while (earconFinder = ancestors.pop()) {
1873 var info = Output.ROLE_INFO_[earconFinder.role]; 1655 var info = Output.ROLE_INFO_[earconFinder.role];
1874 if (info && info.earconId) { 1656 if (info && info.earconId) {
1875 return new Output.EarconAction(info.earconId, 1657 return new Output.EarconAction(
1876 node.location || undefined); 1658 info.earconId, node.location || undefined);
1877 break; 1659 break;
1878 } 1660 }
1879 earconFinder = earconFinder.parent; 1661 earconFinder = earconFinder.parent;
1880 } 1662 }
1881 } 1663 }
1882 return null; 1664 return null;
1883 }, 1665 },
1884 1666
1885 /** 1667 /**
1886 * Gets a human friendly string with the contents of output. 1668 * Gets a human friendly string with the contents of output.
(...skipping 25 matching lines...) Expand all
1912 /** 1694 /**
1913 * Gets the output buffer for braille. 1695 * Gets the output buffer for braille.
1914 * @return {!Spannable} 1696 * @return {!Spannable}
1915 */ 1697 */
1916 get brailleOutputForTest() { 1698 get brailleOutputForTest() {
1917 return this.mergeBraille_(this.brailleBuffer_); 1699 return this.mergeBraille_(this.brailleBuffer_);
1918 } 1700 }
1919 }; 1701 };
1920 1702
1921 }); // goog.scope 1703 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698