| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 Handles automation from a desktop automation node. | 6 * @fileoverview Handles automation from a desktop automation node. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 goog.provide('DesktopAutomationHandler'); | 9 goog.provide('DesktopAutomationHandler'); |
| 10 | 10 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 */ | 36 */ |
| 37 this.textEditHandler_ = null; | 37 this.textEditHandler_ = null; |
| 38 | 38 |
| 39 /** | 39 /** |
| 40 * The last time we handled a value changed event. | 40 * The last time we handled a value changed event. |
| 41 * @type {!Date} | 41 * @type {!Date} |
| 42 * @private | 42 * @private |
| 43 */ | 43 */ |
| 44 this.lastValueChanged_ = new Date(0); | 44 this.lastValueChanged_ = new Date(0); |
| 45 | 45 |
| 46 this.addListener_(EventType.ACTIVEDESCENDANTCHANGED, | 46 this.addListener_( |
| 47 this.onActiveDescendantChanged); | 47 EventType.ACTIVEDESCENDANTCHANGED, this.onActiveDescendantChanged); |
| 48 this.addListener_(EventType.ALERT, | 48 this.addListener_(EventType.ALERT, this.onAlert); |
| 49 this.onAlert); | 49 this.addListener_( |
| 50 this.addListener_(EventType.ARIA_ATTRIBUTE_CHANGED, | 50 EventType.ARIA_ATTRIBUTE_CHANGED, this.onAriaAttributeChanged); |
| 51 this.onAriaAttributeChanged); | 51 this.addListener_(EventType.AUTOCORRECTION_OCCURED, this.onEventIfInRange); |
| 52 this.addListener_(EventType.AUTOCORRECTION_OCCURED, | 52 this.addListener_(EventType.BLUR, this.onBlur); |
| 53 this.onEventIfInRange); | 53 this.addListener_( |
| 54 this.addListener_(EventType.BLUR, | 54 EventType.CHECKED_STATE_CHANGED, this.onCheckedStateChanged); |
| 55 this.onBlur); | 55 this.addListener_(EventType.CHILDREN_CHANGED, this.onChildrenChanged); |
| 56 this.addListener_(EventType.CHECKED_STATE_CHANGED, | 56 this.addListener_(EventType.EXPANDED_CHANGED, this.onEventIfInRange); |
| 57 this.onCheckedStateChanged); | 57 this.addListener_(EventType.FOCUS, this.onFocus); |
| 58 this.addListener_(EventType.CHILDREN_CHANGED, | 58 this.addListener_(EventType.HOVER, this.onHover); |
| 59 this.onChildrenChanged); | 59 this.addListener_(EventType.INVALID_STATUS_CHANGED, this.onEventIfInRange); |
| 60 this.addListener_(EventType.EXPANDED_CHANGED, | 60 this.addListener_(EventType.LOAD_COMPLETE, this.onLoadComplete); |
| 61 this.onEventIfInRange); | 61 this.addListener_(EventType.MENU_END, this.onMenuEnd); |
| 62 this.addListener_(EventType.FOCUS, | 62 this.addListener_(EventType.MENU_LIST_ITEM_SELECTED, this.onEventIfSelected); |
| 63 this.onFocus); | 63 this.addListener_(EventType.MENU_START, this.onMenuStart); |
| 64 this.addListener_(EventType.HOVER, | 64 this.addListener_(EventType.ROW_COLLAPSED, this.onEventIfInRange); |
| 65 this.onHover); | 65 this.addListener_(EventType.ROW_EXPANDED, this.onEventIfInRange); |
| 66 this.addListener_(EventType.INVALID_STATUS_CHANGED, | 66 this.addListener_( |
| 67 this.onEventIfInRange); | 67 EventType.SCROLL_POSITION_CHANGED, this.onScrollPositionChanged); |
| 68 this.addListener_(EventType.LOAD_COMPLETE, | 68 this.addListener_(EventType.SELECTION, this.onSelection); |
| 69 this.onLoadComplete); | 69 this.addListener_(EventType.TEXT_CHANGED, this.onTextChanged); |
| 70 this.addListener_(EventType.MENU_END, | 70 this.addListener_( |
| 71 this.onMenuEnd); | 71 EventType.TEXT_SELECTION_CHANGED, this.onTextSelectionChanged); |
| 72 this.addListener_(EventType.MENU_LIST_ITEM_SELECTED, | 72 this.addListener_(EventType.VALUE_CHANGED, this.onValueChanged); |
| 73 this.onEventIfSelected); | |
| 74 this.addListener_(EventType.MENU_START, | |
| 75 this.onMenuStart); | |
| 76 this.addListener_(EventType.ROW_COLLAPSED, | |
| 77 this.onEventIfInRange); | |
| 78 this.addListener_(EventType.ROW_EXPANDED, | |
| 79 this.onEventIfInRange); | |
| 80 this.addListener_(EventType.SCROLL_POSITION_CHANGED, | |
| 81 this.onScrollPositionChanged); | |
| 82 this.addListener_(EventType.SELECTION, | |
| 83 this.onSelection); | |
| 84 this.addListener_(EventType.TEXT_CHANGED, | |
| 85 this.onTextChanged); | |
| 86 this.addListener_(EventType.TEXT_SELECTION_CHANGED, | |
| 87 this.onTextSelectionChanged); | |
| 88 this.addListener_(EventType.VALUE_CHANGED, | |
| 89 this.onValueChanged); | |
| 90 | 73 |
| 91 AutomationObjectConstructorInstaller.init(node, function() { | 74 AutomationObjectConstructorInstaller.init(node, function() { |
| 92 chrome.automation.getFocus((function(focus) { | 75 chrome.automation.getFocus( |
| 93 if (ChromeVoxState.instance.mode != ChromeVoxMode.FORCE_NEXT) | 76 (function(focus) { |
| 94 return; | 77 if (ChromeVoxState.instance.mode != ChromeVoxMode.FORCE_NEXT) |
| 78 return; |
| 95 | 79 |
| 96 if (focus) { | 80 if (focus) { |
| 97 var event = new CustomAutomationEvent(EventType.FOCUS, focus, 'page'); | 81 var event = |
| 98 this.onFocus(event); | 82 new CustomAutomationEvent(EventType.FOCUS, focus, 'page'); |
| 99 } | 83 this.onFocus(event); |
| 100 }).bind(this)); | 84 } |
| 85 }).bind(this)); |
| 101 }.bind(this)); | 86 }.bind(this)); |
| 102 }; | 87 }; |
| 103 | 88 |
| 104 /** | 89 /** |
| 105 * Time to wait until processing more value changed events. | 90 * Time to wait until processing more value changed events. |
| 106 * @const {number} | 91 * @const {number} |
| 107 */ | 92 */ |
| 108 DesktopAutomationHandler.VMIN_VALUE_CHANGE_DELAY_MS = 500; | 93 DesktopAutomationHandler.VMIN_VALUE_CHANGE_DELAY_MS = 500; |
| 109 | 94 |
| 110 /** | 95 /** |
| (...skipping 24 matching lines...) Expand all Loading... |
| 135 return; | 120 return; |
| 136 | 121 |
| 137 var prevRange = ChromeVoxState.instance.currentRange; | 122 var prevRange = ChromeVoxState.instance.currentRange; |
| 138 | 123 |
| 139 ChromeVoxState.instance.setCurrentRange(cursors.Range.fromNode(node)); | 124 ChromeVoxState.instance.setCurrentRange(cursors.Range.fromNode(node)); |
| 140 | 125 |
| 141 if (!this.shouldOutput_(evt)) | 126 if (!this.shouldOutput_(evt)) |
| 142 return; | 127 return; |
| 143 | 128 |
| 144 // Don't output if focused node hasn't changed. | 129 // Don't output if focused node hasn't changed. |
| 145 if (prevRange && | 130 if (prevRange && evt.type == 'focus' && |
| 146 evt.type == 'focus' && | |
| 147 ChromeVoxState.instance.currentRange.equals(prevRange)) | 131 ChromeVoxState.instance.currentRange.equals(prevRange)) |
| 148 return; | 132 return; |
| 149 | 133 |
| 150 var output = new Output(); | 134 var output = new Output(); |
| 151 output.withRichSpeech( | 135 output.withRichSpeech( |
| 152 ChromeVoxState.instance.currentRange, prevRange, evt.type); | 136 ChromeVoxState.instance.currentRange, prevRange, evt.type); |
| 153 if (!this.textEditHandler_) { | 137 if (!this.textEditHandler_) { |
| 154 output.withBraille( | 138 output.withBraille( |
| 155 ChromeVoxState.instance.currentRange, prevRange, evt.type); | 139 ChromeVoxState.instance.currentRange, prevRange, evt.type); |
| 156 } else { | 140 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 169 | 153 |
| 170 var prev = ChromeVoxState.instance.currentRange; | 154 var prev = ChromeVoxState.instance.currentRange; |
| 171 if (prev.contentEquals(cursors.Range.fromNode(evt.target)) || | 155 if (prev.contentEquals(cursors.Range.fromNode(evt.target)) || |
| 172 evt.target.state.focused) { | 156 evt.target.state.focused) { |
| 173 // Category flush here since previous focus events via navigation can | 157 // Category flush here since previous focus events via navigation can |
| 174 // cause double speak. | 158 // cause double speak. |
| 175 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH); | 159 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH); |
| 176 | 160 |
| 177 // Intentionally skip setting range. | 161 // Intentionally skip setting range. |
| 178 new Output() | 162 new Output() |
| 179 .withRichSpeechAndBraille(cursors.Range.fromNode(evt.target), | 163 .withRichSpeechAndBraille( |
| 180 prev, | 164 cursors.Range.fromNode(evt.target), prev, |
| 181 Output.EventType.NAVIGATE) | 165 Output.EventType.NAVIGATE) |
| 182 .go(); | 166 .go(); |
| 183 } | 167 } |
| 184 }, | 168 }, |
| 185 | 169 |
| 186 /** | 170 /** |
| 187 * @param {!AutomationEvent} evt | 171 * @param {!AutomationEvent} evt |
| 188 */ | 172 */ |
| 189 onEventIfSelected: function(evt) { | 173 onEventIfSelected: function(evt) { |
| 190 if (evt.target.state.selected) | 174 if (evt.target.state.selected) |
| 191 this.onEventDefault(evt); | 175 this.onEventDefault(evt); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 return; | 267 return; |
| 284 } | 268 } |
| 285 | 269 |
| 286 if (!this.shouldOutput_(evt)) | 270 if (!this.shouldOutput_(evt)) |
| 287 return; | 271 return; |
| 288 | 272 |
| 289 var curRange = ChromeVoxState.instance.currentRange; | 273 var curRange = ChromeVoxState.instance.currentRange; |
| 290 | 274 |
| 291 // Always refresh the braille contents. | 275 // Always refresh the braille contents. |
| 292 if (curRange && curRange.equals(cursors.Range.fromNode(evt.target))) { | 276 if (curRange && curRange.equals(cursors.Range.fromNode(evt.target))) { |
| 293 new Output().withBraille(curRange, curRange, Output.EventType.NAVIGATE) | 277 new Output() |
| 278 .withBraille(curRange, curRange, Output.EventType.NAVIGATE) |
| 294 .go(); | 279 .go(); |
| 295 } | 280 } |
| 296 | 281 |
| 297 this.onActiveDescendantChanged(evt); | 282 this.onActiveDescendantChanged(evt); |
| 298 }, | 283 }, |
| 299 | 284 |
| 300 /** | 285 /** |
| 301 * Provides all feedback once a focus event fires. | 286 * Provides all feedback once a focus event fires. |
| 302 * @param {!AutomationEvent} evt | 287 * @param {!AutomationEvent} evt |
| 303 */ | 288 */ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 318 if (evt.eventFrom == '') | 303 if (evt.eventFrom == '') |
| 319 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH); | 304 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.CATEGORY_FLUSH); |
| 320 if (!node.root) | 305 if (!node.root) |
| 321 return; | 306 return; |
| 322 | 307 |
| 323 var root = AutomationUtil.getTopLevelRoot(node.root); | 308 var root = AutomationUtil.getTopLevelRoot(node.root); |
| 324 // If we're crossing out of a root, save it in case it needs recovering. | 309 // If we're crossing out of a root, save it in case it needs recovering. |
| 325 var prevRange = ChromeVoxState.instance.currentRange; | 310 var prevRange = ChromeVoxState.instance.currentRange; |
| 326 var prevNode = prevRange ? prevRange.start.node : null; | 311 var prevNode = prevRange ? prevRange.start.node : null; |
| 327 if (prevNode) { | 312 if (prevNode) { |
| 328 var prevRoot = AutomationUtil.getTopLevelRoot(prevNode); | 313 var prevRoot = AutomationUtil.getTopLevelRoot(prevNode); |
| 329 if (prevRoot && prevRoot !== root) | 314 if (prevRoot && prevRoot !== root) |
| 330 ChromeVoxState.instance.focusRecoveryMap.set(prevRoot, prevRange); | 315 ChromeVoxState.instance.focusRecoveryMap.set(prevRoot, prevRange); |
| 331 } | 316 } |
| 332 // If a previous node was saved for this focus, restore it. | 317 // If a previous node was saved for this focus, restore it. |
| 333 var savedRange = ChromeVoxState.instance.focusRecoveryMap.get(root); | 318 var savedRange = ChromeVoxState.instance.focusRecoveryMap.get(root); |
| 334 ChromeVoxState.instance.focusRecoveryMap.delete(root); | 319 ChromeVoxState.instance.focusRecoveryMap.delete(root); |
| 335 if (savedRange) { | 320 if (savedRange) { |
| 336 ChromeVoxState.instance.navigateToRange(savedRange, false); | 321 ChromeVoxState.instance.navigateToRange(savedRange, false); |
| 337 return; | 322 return; |
| 338 } | 323 } |
| 339 var event = new CustomAutomationEvent(EventType.FOCUS, node, evt.eventFrom); | 324 var event = new CustomAutomationEvent(EventType.FOCUS, node, evt.eventFrom); |
| 340 this.onEventDefault(event); | 325 this.onEventDefault(event); |
| 341 }, | 326 }, |
| 342 | 327 |
| 343 /** | 328 /** |
| 344 * Provides all feedback once a load complete event fires. | 329 * Provides all feedback once a load complete event fires. |
| 345 * @param {!AutomationEvent} evt | 330 * @param {!AutomationEvent} evt |
| 346 */ | 331 */ |
| 347 onLoadComplete: function(evt) { | 332 onLoadComplete: function(evt) { |
| 348 chrome.automation.getFocus(function(focus) { | 333 chrome.automation.getFocus(function(focus) { |
| 349 if (!focus || !AutomationUtil.isDescendantOf(focus, evt.target)) | 334 if (!focus || !AutomationUtil.isDescendantOf(focus, evt.target)) |
| 350 return; | 335 return; |
| 351 | 336 |
| 352 // Create text edit handler, if needed, now in order not to miss initial | 337 // Create text edit handler, if needed, now in order not to miss initial |
| 353 // value change if text field has already been focused when initializing | 338 // value change if text field has already been focused when initializing |
| 354 // ChromeVox. | 339 // ChromeVox. |
| 355 this.createTextEditHandlerIfNeeded_(focus); | 340 this.createTextEditHandlerIfNeeded_(focus); |
| 356 | 341 |
| 357 // If auto read is set, skip focus recovery and start reading from the top
. | 342 // If auto read is set, skip focus recovery and start reading from the |
| 343 // top. |
| 358 if (localStorage['autoRead'] == 'true' && | 344 if (localStorage['autoRead'] == 'true' && |
| 359 AutomationUtil.getTopLevelRoot(evt.target) == evt.target) { | 345 AutomationUtil.getTopLevelRoot(evt.target) == evt.target) { |
| 360 ChromeVoxState.instance.setCurrentRange(cursors.Range.fromNode(evt.targe
t)); | 346 ChromeVoxState.instance.setCurrentRange( |
| 347 cursors.Range.fromNode(evt.target)); |
| 361 cvox.ChromeVox.tts.stop(); | 348 cvox.ChromeVox.tts.stop(); |
| 362 CommandHandler.onCommand('readFromHere'); | 349 CommandHandler.onCommand('readFromHere'); |
| 363 return; | 350 return; |
| 364 } | 351 } |
| 365 | 352 |
| 366 // If initial focus was already placed on this page (e.g. if a user starts | 353 // If initial focus was already placed on this page (e.g. if a user starts |
| 367 // tabbing before load complete), then don't move ChromeVox's position on | 354 // tabbing before load complete), then don't move ChromeVox's position on |
| 368 // the page. | 355 // the page. |
| 369 if (ChromeVoxState.instance.currentRange && | 356 if (ChromeVoxState.instance.currentRange && |
| 370 ChromeVoxState.instance.currentRange.start.node.root == focus.root) | 357 ChromeVoxState.instance.currentRange.start.node.root == focus.root) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 381 if (focus != focus.root) | 368 if (focus != focus.root) |
| 382 o.format('$name', focus.root); | 369 o.format('$name', focus.root); |
| 383 } | 370 } |
| 384 } | 371 } |
| 385 ChromeVoxState.instance.setCurrentRange(cursors.Range.fromNode(focus)); | 372 ChromeVoxState.instance.setCurrentRange(cursors.Range.fromNode(focus)); |
| 386 if (!this.shouldOutput_(evt)) | 373 if (!this.shouldOutput_(evt)) |
| 387 return; | 374 return; |
| 388 | 375 |
| 389 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH); | 376 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH); |
| 390 o.withRichSpeechAndBraille( | 377 o.withRichSpeechAndBraille( |
| 391 ChromeVoxState.instance.currentRange, null, evt.type).go(); | 378 ChromeVoxState.instance.currentRange, null, evt.type) |
| 379 .go(); |
| 392 }.bind(this)); | 380 }.bind(this)); |
| 393 }, | 381 }, |
| 394 | 382 |
| 395 /** | 383 /** |
| 396 * Provides all feedback once a text changed event fires. | 384 * Provides all feedback once a text changed event fires. |
| 397 * @param {!AutomationEvent} evt | 385 * @param {!AutomationEvent} evt |
| 398 */ | 386 */ |
| 399 onTextChanged: function(evt) { | 387 onTextChanged: function(evt) { |
| 400 if (evt.target.state.editable) | 388 if (evt.target.state.editable) |
| 401 this.onEditableChanged_(evt); | 389 this.onEditableChanged_(evt); |
| 402 }, | 390 }, |
| 403 | 391 |
| 404 /** | 392 /** |
| 405 * Provides all feedback once a text selection changed event fires. | 393 * Provides all feedback once a text selection changed event fires. |
| 406 * @param {!AutomationEvent} evt | 394 * @param {!AutomationEvent} evt |
| 407 */ | 395 */ |
| 408 onTextSelectionChanged: function(evt) { | 396 onTextSelectionChanged: function(evt) { |
| 409 if (evt.target.state.editable) | 397 if (evt.target.state.editable) |
| 410 this.onEditableChanged_(evt); | 398 this.onEditableChanged_(evt); |
| 411 }, | 399 }, |
| 412 | 400 |
| 413 /** | 401 /** |
| 414 * Provides all feedback once a change event in a text field fires. | 402 * Provides all feedback once a change event in a text field fires. |
| 415 * @param {!AutomationEvent} evt | 403 * @param {!AutomationEvent} evt |
| 416 * @private | 404 * @private |
| 417 */ | 405 */ |
| 418 onEditableChanged_: function(evt) { | 406 onEditableChanged_: function(evt) { |
| 419 var topRoot = AutomationUtil.getTopLevelRoot(evt.target); | 407 var topRoot = AutomationUtil.getTopLevelRoot(evt.target); |
| 420 if (!evt.target.state.focused || | 408 if (!evt.target.state.focused || |
| 421 (topRoot && | 409 (topRoot && topRoot.parent && !topRoot.parent.state.focused)) |
| 422 topRoot.parent && | |
| 423 !topRoot.parent.state.focused)) | |
| 424 return; | 410 return; |
| 425 | 411 |
| 426 if (!ChromeVoxState.instance.currentRange) { | 412 if (!ChromeVoxState.instance.currentRange) { |
| 427 this.onEventDefault(evt); | 413 this.onEventDefault(evt); |
| 428 ChromeVoxState.instance.setCurrentRange( | 414 ChromeVoxState.instance.setCurrentRange( |
| 429 cursors.Range.fromNode(evt.target)); | 415 cursors.Range.fromNode(evt.target)); |
| 430 } | 416 } |
| 431 | 417 |
| 432 this.createTextEditHandlerIfNeeded_(evt.target); | 418 this.createTextEditHandlerIfNeeded_(evt.target); |
| 433 | 419 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 459 // Delegate to the edit text handler if this is an editable. | 445 // Delegate to the edit text handler if this is an editable. |
| 460 if (evt.target.state.editable) { | 446 if (evt.target.state.editable) { |
| 461 this.onEditableChanged_(evt); | 447 this.onEditableChanged_(evt); |
| 462 return; | 448 return; |
| 463 } | 449 } |
| 464 | 450 |
| 465 if (!this.shouldOutput_(evt)) | 451 if (!this.shouldOutput_(evt)) |
| 466 return; | 452 return; |
| 467 | 453 |
| 468 var t = evt.target; | 454 var t = evt.target; |
| 469 if (t.state.focused || | 455 if (t.state.focused || t.root.role == RoleType.DESKTOP || |
| 470 t.root.role == RoleType.DESKTOP || | |
| 471 AutomationUtil.isDescendantOf( | 456 AutomationUtil.isDescendantOf( |
| 472 ChromeVoxState.instance.currentRange.start.node, t)) { | 457 ChromeVoxState.instance.currentRange.start.node, t)) { |
| 473 if (new Date() - this.lastValueChanged_ <= | 458 if (new Date() - this.lastValueChanged_ <= |
| 474 DesktopAutomationHandler.VMIN_VALUE_CHANGE_DELAY_MS) | 459 DesktopAutomationHandler.VMIN_VALUE_CHANGE_DELAY_MS) |
| 475 return; | 460 return; |
| 476 | 461 |
| 477 this.lastValueChanged_ = new Date(); | 462 this.lastValueChanged_ = new Date(); |
| 478 | 463 |
| 479 var output = new Output(); | 464 var output = new Output(); |
| 480 | 465 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 510 if (focus.role == RoleType.WEB_VIEW && evt.target.role == RoleType.TAB) { | 495 if (focus.role == RoleType.WEB_VIEW && evt.target.role == RoleType.TAB) { |
| 511 ChromeVoxState.instance.setCurrentRange( | 496 ChromeVoxState.instance.setCurrentRange( |
| 512 cursors.Range.fromNode(focus.firstChild)); | 497 cursors.Range.fromNode(focus.firstChild)); |
| 513 return; | 498 return; |
| 514 } | 499 } |
| 515 | 500 |
| 516 // Some cases (e.g. in overview mode), require overriding the assumption | 501 // Some cases (e.g. in overview mode), require overriding the assumption |
| 517 // that focus is an ancestor of a selection target. | 502 // that focus is an ancestor of a selection target. |
| 518 var override = evt.target.role == RoleType.MENU_ITEM || | 503 var override = evt.target.role == RoleType.MENU_ITEM || |
| 519 (evt.target.root == focus.root && | 504 (evt.target.root == focus.root && |
| 520 focus.root.role == RoleType.DESKTOP); | 505 focus.root.role == RoleType.DESKTOP); |
| 521 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH); | 506 Output.forceModeForNextSpeechUtterance(cvox.QueueMode.FLUSH); |
| 522 if (override || AutomationUtil.isDescendantOf(evt.target, focus)) | 507 if (override || AutomationUtil.isDescendantOf(evt.target, focus)) |
| 523 this.onEventDefault(evt); | 508 this.onEventDefault(evt); |
| 524 }.bind(this)); | 509 }.bind(this)); |
| 525 }, | 510 }, |
| 526 | 511 |
| 527 /** | 512 /** |
| 528 * Provides all feedback once a menu start event fires. | 513 * Provides all feedback once a menu start event fires. |
| 529 * @param {!AutomationEvent} evt | 514 * @param {!AutomationEvent} evt |
| 530 */ | 515 */ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 548 this.onFocus(event); | 533 this.onFocus(event); |
| 549 } | 534 } |
| 550 }.bind(this)); | 535 }.bind(this)); |
| 551 }, | 536 }, |
| 552 | 537 |
| 553 /** | 538 /** |
| 554 * Create an editable text handler for the given node if needed. | 539 * Create an editable text handler for the given node if needed. |
| 555 * @param {!AutomationNode} node | 540 * @param {!AutomationNode} node |
| 556 */ | 541 */ |
| 557 createTextEditHandlerIfNeeded_: function(node) { | 542 createTextEditHandlerIfNeeded_: function(node) { |
| 558 if (!this.textEditHandler_ || | 543 if (!this.textEditHandler_ || this.textEditHandler_.node !== node) { |
| 559 this.textEditHandler_.node !== node) { | |
| 560 this.textEditHandler_ = editing.TextEditHandler.createForNode(node); | 544 this.textEditHandler_ = editing.TextEditHandler.createForNode(node); |
| 561 } | 545 } |
| 562 }, | 546 }, |
| 563 | 547 |
| 564 /** | 548 /** |
| 565 * Once an event handler updates ChromeVox's range based on |evt| | 549 * Once an event handler updates ChromeVox's range based on |evt| |
| 566 * which updates mode, returns whether |evt| should be outputted. | 550 * which updates mode, returns whether |evt| should be outputted. |
| 567 * @return {boolean} | 551 * @return {boolean} |
| 568 */ | 552 */ |
| 569 shouldOutput_: function(evt) { | 553 shouldOutput_: function(evt) { |
| 570 var mode = ChromeVoxState.instance.mode; | 554 var mode = ChromeVoxState.instance.mode; |
| 571 // Only output desktop rooted nodes or web nodes for next engine modes. | 555 // Only output desktop rooted nodes or web nodes for next engine modes. |
| 572 return evt.target.root.role == RoleType.DESKTOP || | 556 return evt.target.root.role == RoleType.DESKTOP || |
| 573 (mode == ChromeVoxMode.NEXT || | 557 (mode == ChromeVoxMode.NEXT || mode == ChromeVoxMode.FORCE_NEXT || |
| 574 mode == ChromeVoxMode.FORCE_NEXT || | |
| 575 mode == ChromeVoxMode.CLASSIC_COMPAT); | 558 mode == ChromeVoxMode.CLASSIC_COMPAT); |
| 576 } | 559 } |
| 577 }; | 560 }; |
| 578 | 561 |
| 579 /** | 562 /** |
| 580 * Initializes global state for DesktopAutomationHandler. | 563 * Initializes global state for DesktopAutomationHandler. |
| 581 * @private | 564 * @private |
| 582 */ | 565 */ |
| 583 DesktopAutomationHandler.init_ = function() { | 566 DesktopAutomationHandler.init_ = function() { |
| 584 chrome.automation.getDesktop(function(desktop) { | 567 chrome.automation.getDesktop(function(desktop) { |
| 585 ChromeVoxState.desktopAutomationHandler = | 568 ChromeVoxState.desktopAutomationHandler = |
| 586 new DesktopAutomationHandler(desktop); | 569 new DesktopAutomationHandler(desktop); |
| 587 }); | 570 }); |
| 588 }; | 571 }; |
| 589 | 572 |
| 590 DesktopAutomationHandler.init_(); | 573 DesktopAutomationHandler.init_(); |
| 591 | 574 |
| 592 }); // goog.scope | 575 }); // goog.scope |
| OLD | NEW |