| 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 14 matching lines...) Expand all Loading... |
| 25 * @param {!AutomationNode} node | 25 * @param {!AutomationNode} node |
| 26 * @constructor | 26 * @constructor |
| 27 * @extends {BaseAutomationHandler} | 27 * @extends {BaseAutomationHandler} |
| 28 */ | 28 */ |
| 29 DesktopAutomationHandler = function(node) { | 29 DesktopAutomationHandler = function(node) { |
| 30 BaseAutomationHandler.call(this, node); | 30 BaseAutomationHandler.call(this, node); |
| 31 | 31 |
| 32 /** | 32 /** |
| 33 * The object that speaks changes to an editable text field. | 33 * The object that speaks changes to an editable text field. |
| 34 * @type {editing.TextEditHandler} | 34 * @type {editing.TextEditHandler} |
| 35 * @private |
| 35 */ | 36 */ |
| 36 this.textEditHandler_ = null; | 37 this.textEditHandler_ = null; |
| 37 | 38 |
| 38 /** | 39 /** |
| 39 * The last time we handled a value changed event. | 40 * The last time we handled a value changed event. |
| 40 * @type {!Date} | 41 * @type {!Date} |
| 41 * @private | 42 * @private |
| 42 */ | 43 */ |
| 43 this.lastValueChanged_ = new Date(0); | 44 this.lastValueChanged_ = new Date(0); |
| 44 | 45 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 65 this.addListener_(e.textSelectionChanged, this.onTextSelectionChanged); | 66 this.addListener_(e.textSelectionChanged, this.onTextSelectionChanged); |
| 66 this.addListener_(e.valueChanged, this.onValueChanged); | 67 this.addListener_(e.valueChanged, this.onValueChanged); |
| 67 | 68 |
| 68 AutomationObjectConstructorInstaller.init(node, function() { | 69 AutomationObjectConstructorInstaller.init(node, function() { |
| 69 chrome.automation.getFocus((function(focus) { | 70 chrome.automation.getFocus((function(focus) { |
| 70 if (ChromeVoxState.instance.mode != ChromeVoxMode.FORCE_NEXT) | 71 if (ChromeVoxState.instance.mode != ChromeVoxMode.FORCE_NEXT) |
| 71 return; | 72 return; |
| 72 | 73 |
| 73 if (focus) { | 74 if (focus) { |
| 74 this.onFocus( | 75 this.onFocus( |
| 75 new chrome.automation.AutomationEvent(EventType.focus, focus)); | 76 new chrome.automation.AutomationEvent( |
| 77 EventType.focus, focus, 'page')); |
| 76 } | 78 } |
| 77 }).bind(this)); | 79 }).bind(this)); |
| 78 }.bind(this)); | 80 }.bind(this)); |
| 79 }; | 81 }; |
| 80 | 82 |
| 81 /** | 83 /** |
| 82 * Time to wait until processing more value changed events. | 84 * Time to wait until processing more value changed events. |
| 83 * @const {number} | 85 * @const {number} |
| 84 */ | 86 */ |
| 85 DesktopAutomationHandler.VMIN_VALUE_CHANGE_DELAY_MS = 500; | 87 DesktopAutomationHandler.VMIN_VALUE_CHANGE_DELAY_MS = 500; |
| 86 | 88 |
| 89 /** |
| 90 * Controls announcement of non-user-initiated events. |
| 91 * @type {boolean} |
| 92 */ |
| 93 DesktopAutomationHandler.announceActions = false; |
| 94 |
| 87 DesktopAutomationHandler.prototype = { | 95 DesktopAutomationHandler.prototype = { |
| 88 __proto__: BaseAutomationHandler.prototype, | 96 __proto__: BaseAutomationHandler.prototype, |
| 89 | 97 |
| 90 /** @override */ | 98 /** @override */ |
| 91 willHandleEvent_: function(evt) { | 99 willHandleEvent_: function(evt) { |
| 92 return !cvox.ChromeVox.isActive; | 100 return !cvox.ChromeVox.isActive; |
| 93 }, | 101 }, |
| 94 | 102 |
| 95 /** | 103 /** |
| 96 * Provides all feedback once ChromeVox's focus changes. | 104 * Provides all feedback once ChromeVox's focus changes. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 111 chrome.accessibilityPrivate.setFocusRing([]); | 119 chrome.accessibilityPrivate.setFocusRing([]); |
| 112 return; | 120 return; |
| 113 } | 121 } |
| 114 | 122 |
| 115 // Don't output if focused node hasn't changed. | 123 // Don't output if focused node hasn't changed. |
| 116 if (prevRange && | 124 if (prevRange && |
| 117 evt.type == 'focus' && | 125 evt.type == 'focus' && |
| 118 ChromeVoxState.instance.currentRange.equals(prevRange)) | 126 ChromeVoxState.instance.currentRange.equals(prevRange)) |
| 119 return; | 127 return; |
| 120 | 128 |
| 129 // Decide whether to announce this event. |
| 130 if (!DesktopAutomationHandler.announceActions && evt.eventFrom == 'action') |
| 131 return; |
| 132 |
| 121 var output = new Output(); | 133 var output = new Output(); |
| 122 output.withRichSpeech( | 134 output.withRichSpeech( |
| 123 ChromeVoxState.instance.currentRange, prevRange, evt.type); | 135 ChromeVoxState.instance.currentRange, prevRange, evt.type); |
| 124 if (!this.textEditHandler_) { | 136 if (!this.textEditHandler_) { |
| 125 output.withBraille( | 137 output.withBraille( |
| 126 ChromeVoxState.instance.currentRange, prevRange, evt.type); | 138 ChromeVoxState.instance.currentRange, prevRange, evt.type); |
| 127 } else { | 139 } else { |
| 128 // Delegate event handling to the text edit handler for braille. | 140 // Delegate event handling to the text edit handler for braille. |
| 129 this.textEditHandler_.onEvent(evt); | 141 this.textEditHandler_.onEvent(evt); |
| 130 } | 142 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 }, | 192 }, |
| 181 | 193 |
| 182 /** | 194 /** |
| 183 * Makes an announcement without changing focus. | 195 * Makes an announcement without changing focus. |
| 184 * @param {!AutomationEvent} evt | 196 * @param {!AutomationEvent} evt |
| 185 */ | 197 */ |
| 186 onActiveDescendantChanged: function(evt) { | 198 onActiveDescendantChanged: function(evt) { |
| 187 if (!evt.target.activeDescendant || !evt.target.state.focused) | 199 if (!evt.target.activeDescendant || !evt.target.state.focused) |
| 188 return; | 200 return; |
| 189 this.onEventDefault(new chrome.automation.AutomationEvent( | 201 this.onEventDefault(new chrome.automation.AutomationEvent( |
| 190 EventType.focus, evt.target.activeDescendant)); | 202 EventType.focus, evt.target.activeDescendant, evt.eventFrom)); |
| 191 }, | 203 }, |
| 192 | 204 |
| 193 /** | 205 /** |
| 194 * Makes an announcement without changing focus. | 206 * Makes an announcement without changing focus. |
| 195 * @param {!AutomationEvent} evt | 207 * @param {!AutomationEvent} evt |
| 196 */ | 208 */ |
| 197 onAlert: function(evt) { | 209 onAlert: function(evt) { |
| 198 var node = evt.target; | 210 var node = evt.target; |
| 199 if (!node) | 211 if (!node) |
| 200 return; | 212 return; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 213 /** | 225 /** |
| 214 * Provides all feedback once a checked state changed event fires. | 226 * Provides all feedback once a checked state changed event fires. |
| 215 * @param {!AutomationEvent} evt | 227 * @param {!AutomationEvent} evt |
| 216 */ | 228 */ |
| 217 onCheckedStateChanged: function(evt) { | 229 onCheckedStateChanged: function(evt) { |
| 218 if (!AutomationPredicate.checkable(evt.target)) | 230 if (!AutomationPredicate.checkable(evt.target)) |
| 219 return; | 231 return; |
| 220 | 232 |
| 221 this.onEventIfInRange( | 233 this.onEventIfInRange( |
| 222 new chrome.automation.AutomationEvent( | 234 new chrome.automation.AutomationEvent( |
| 223 EventType.checkedStateChanged, evt.target)); | 235 EventType.checkedStateChanged, evt.target, evt.eventFrom)); |
| 224 }, | 236 }, |
| 225 | 237 |
| 226 /** | 238 /** |
| 227 * Provides all feedback once a focus event fires. | 239 * Provides all feedback once a focus event fires. |
| 228 * @param {!AutomationEvent} evt | 240 * @param {!AutomationEvent} evt |
| 229 */ | 241 */ |
| 230 onFocus: function(evt) { | 242 onFocus: function(evt) { |
| 231 // Invalidate any previous editable text handler state. | 243 // Invalidate any previous editable text handler state. |
| 232 this.textEditHandler_ = null; | 244 this.textEditHandler_ = null; |
| 233 | 245 |
| 234 var node = evt.target; | 246 var node = evt.target; |
| 235 | 247 |
| 236 // Discard focus events on embeddedObject and client nodes. | 248 // Discard focus events on embeddedObject and client nodes. |
| 237 if (node.role == RoleType.embeddedObject || node.role == RoleType.client) | 249 if (node.role == RoleType.embeddedObject || node.role == RoleType.client) |
| 238 return; | 250 return; |
| 239 | 251 |
| 240 this.createTextEditHandlerIfNeeded_(evt.target); | 252 this.createTextEditHandlerIfNeeded_(evt.target); |
| 241 | 253 |
| 242 // Since we queue output mostly for live regions support and there isn't a | 254 // Since we queue output mostly for live regions support and there isn't a |
| 243 // reliable way to know if this focus event resulted from a user's explicit | 255 // reliable way to know if this focus event resulted from a user's explicit |
| 244 // action, only flush when the focused node is not web content. | 256 // action, only flush when the focused node is not web content. |
| 245 if (node.root.role == RoleType.desktop) | 257 if (node.root.role == RoleType.desktop) |
| 246 Output.flushNextSpeechUtterance(); | 258 Output.flushNextSpeechUtterance(); |
| 247 | 259 |
| 248 this.onEventDefault( | 260 this.onEventDefault(new chrome.automation.AutomationEvent( |
| 249 new chrome.automation.AutomationEvent(EventType.focus, node)); | 261 EventType.focus, node, evt.eventFrom)); |
| 250 }, | 262 }, |
| 251 | 263 |
| 252 /** | 264 /** |
| 253 * Provides all feedback once a load complete event fires. | 265 * Provides all feedback once a load complete event fires. |
| 254 * @param {!AutomationEvent} evt | 266 * @param {!AutomationEvent} evt |
| 255 */ | 267 */ |
| 256 onLoadComplete: function(evt) { | 268 onLoadComplete: function(evt) { |
| 257 // Don't process nodes inside of web content if ChromeVox Next is inactive. | 269 // Don't process nodes inside of web content if ChromeVox Next is inactive. |
| 258 if (evt.target.root.role != RoleType.desktop && | 270 if (evt.target.root.role != RoleType.desktop && |
| 259 ChromeVoxState.instance.mode === ChromeVoxMode.CLASSIC) | 271 ChromeVoxState.instance.mode === ChromeVoxMode.CLASSIC) |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 DesktopAutomationHandler.init_ = function() { | 467 DesktopAutomationHandler.init_ = function() { |
| 456 chrome.automation.getDesktop(function(desktop) { | 468 chrome.automation.getDesktop(function(desktop) { |
| 457 ChromeVoxState.desktopAutomationHandler = | 469 ChromeVoxState.desktopAutomationHandler = |
| 458 new DesktopAutomationHandler(desktop); | 470 new DesktopAutomationHandler(desktop); |
| 459 }); | 471 }); |
| 460 }; | 472 }; |
| 461 | 473 |
| 462 DesktopAutomationHandler.init_(); | 474 DesktopAutomationHandler.init_(); |
| 463 | 475 |
| 464 }); // goog.scope | 476 }); // goog.scope |
| OLD | NEW |