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

Side by Side Diff: chrome/browser/resources/chromeos/select_to_speak/select_to_speak.js

Issue 2814213002: Refactor Select-to-speak so that mouse events are forwarded to the extension. (Closed)
Patch Set: Tests updated, ready for review Created 3 years, 7 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 var AutomationEvent = chrome.automation.AutomationEvent; 5 var AutomationEvent = chrome.automation.AutomationEvent;
6 var AutomationNode = chrome.automation.AutomationNode; 6 var AutomationNode = chrome.automation.AutomationNode;
7 var EventType = chrome.automation.EventType; 7 var EventType = chrome.automation.EventType;
8 var RoleType = chrome.automation.RoleType; 8 var RoleType = chrome.automation.RoleType;
9 9
10 /** 10 /**
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 var SelectToSpeak = function() { 51 var SelectToSpeak = function() {
52 /** @private { AutomationNode } */ 52 /** @private { AutomationNode } */
53 this.node_ = null; 53 this.node_ = null;
54 54
55 /** @private { boolean } */ 55 /** @private { boolean } */
56 this.down_ = false; 56 this.down_ = false;
57 57
58 /** @private {{x: number, y: number}} */ 58 /** @private {{x: number, y: number}} */
59 this.mouseStart_ = {x: 0, y: 0}; 59 this.mouseStart_ = {x: 0, y: 0};
60 60
61 /** @private {{x: number, y: number}} */
62 this.mouseEnd_ = {x: 0, y: 0};
63
64 /** @private {AutomationRootNode} */
61 chrome.automation.getDesktop(function(desktop) { 65 chrome.automation.getDesktop(function(desktop) {
66 this.desktop_ = desktop;
67
68 // After the user selects a region of the screen, we do a hit test at
69 // the center of that box using the automation API. The result of the
70 // hit test is a MOUSE_RELEASED accessibility event.
62 desktop.addEventListener( 71 desktop.addEventListener(
63 EventType.MOUSE_PRESSED, this.onMousePressed_.bind(this), true); 72 EventType.MOUSE_RELEASED, this.onMouseReleasedHitTest_.bind(this),
73 true);
74
75 // A MOUSE_CANCELED accessibility event is fired if the user releases
David Tseng 2017/05/07 06:10:27 Would be great to also handle key events in this e
dmazzoni 2017/05/10 19:43:18 OK, done. The event handler now forwards all keybo
76 // the Search key while the mouse is still down.
64 desktop.addEventListener( 77 desktop.addEventListener(
65 EventType.MOUSE_DRAGGED, this.onMouseDragged_.bind(this), true); 78 EventType.MOUSE_CANCELED, this.onMouseCanceled_.bind(this),
66 desktop.addEventListener( 79 true);
67 EventType.MOUSE_RELEASED, this.onMouseReleased_.bind(this), true);
68 desktop.addEventListener(
69 EventType.MOUSE_CANCELED, this.onMouseCanceled_.bind(this), true);
70 }.bind(this)); 80 }.bind(this));
71 81
72 /** @private { ?string } */ 82 /** @private { ?string } */
73 this.voiceNameFromPrefs_ = null; 83 this.voiceNameFromPrefs_ = null;
74 84
75 /** @private { ?string } */ 85 /** @private { ?string } */
76 this.voiceNameFromLocale_ = null; 86 this.voiceNameFromLocale_ = null;
77 87
78 /** @private { Set<string> } */ 88 /** @private { Set<string> } */
79 this.validVoiceNames_ = new Set(); 89 this.validVoiceNames_ = new Set();
80 90
81 /** @private { number } */ 91 /** @private { number } */
82 this.speechRate_ = 1.0; 92 this.speechRate_ = 1.0;
83 93
84 /** @const { string } */ 94 /** @const { string } */
85 this.color_ = "#f73a98"; 95 this.color_ = "#f73a98";
86 96
87 this.initPreferences_(); 97 this.initPreferences_();
98
99 this.captureMouseEvents_();
88 }; 100 };
89 101
90 SelectToSpeak.prototype = { 102 SelectToSpeak.prototype = {
91 /** 103 /**
92 * Called when the mouse is pressed and the user is in a mode where 104 * Called when the mouse is pressed and the user is in a mode where
93 * select-to-speak is capturing mouse events (for example holding down 105 * select-to-speak is capturing mouse events (for example holding down
94 * Search). 106 * Search).
95 * 107 *
96 * @param {!AutomationEvent} evt 108 * @param {!Event} evt The DOM event
David Tseng 2017/05/07 06:10:27 Dom event listeners have a return value (i.e. add
dmazzoni 2017/05/10 19:43:18 Done.
97 */ 109 */
98 onMousePressed_: function(evt) { 110 onMouseDown_: function(evt) {
99 this.down_ = true; 111 this.down_ = true;
David Tseng 2017/05/07 06:59:40 Now that you have the mouse event, I don't think y
dmazzoni 2017/05/10 19:43:18 Changed to this.trackingMouse_ - it's not whether
100 this.mouseStart_ = {x: evt.mouseX, y: evt.mouseY}; 112 this.mouseStart_ = {x: evt.screenX, y: evt.screenY};
101 this.startNode_ = evt.target;
102 chrome.tts.stop(); 113 chrome.tts.stop();
103 this.onMouseDragged_(evt); 114
115 // Fire a hit test event on click to warm up the cache.
116 this.desktop_.hitTest(ctrX, ctrY, EventType.NONE);
117
118 this.onMouseMove_(evt);
104 }, 119 },
105 120
106 /** 121 /**
107 * Called when the mouse is moved or dragged and the user is in a 122 * Called when the mouse is moved or dragged and the user is in a
108 * mode where select-to-speak is capturing mouse events (for example 123 * mode where select-to-speak is capturing mouse events (for example
109 * holding down Search). 124 * holding down Search).
110 * 125 *
111 * @param {!AutomationEvent} evt 126 * @param {!Event} evt The DOM event
David Tseng 2017/05/07 06:10:27 Ditto, @return
dmazzoni 2017/05/10 19:43:18 Done.
112 */ 127 */
113 onMouseDragged_: function(evt) { 128 onMouseMove_: function(evt) {
114 if (!this.down_) 129 if (!this.down_)
115 return; 130 return;
116 131
117 var rect = rectFromPoints( 132 var rect = rectFromPoints(
118 this.mouseStart_.x, this.mouseStart_.y, 133 this.mouseStart_.x, this.mouseStart_.y,
119 evt.mouseX, evt.mouseY); 134 evt.screenX, evt.screenY);
120 chrome.accessibilityPrivate.setFocusRing([rect], this.color_); 135 chrome.accessibilityPrivate.setFocusRing([rect], this.color_);
121 }, 136 },
122 137
123 /** 138 /**
124 * Called when the mouse is released and the user is in a 139 * Called when the mouse is released and the user is in a
125 * mode where select-to-speak is capturing mouse events (for example 140 * mode where select-to-speak is capturing mouse events (for example
126 * holding down Search). 141 * holding down Search).
127 * 142 *
128 * @param {!AutomationEvent} evt 143 * @param {!AutomationEvent} evt
David Tseng 2017/05/07 06:10:27 This is a DOM event listener, not an automation ev
dmazzoni 2017/05/10 19:43:18 Done.
129 */ 144 */
David Tseng 2017/05/07 06:10:27 @return
dmazzoni 2017/05/10 19:43:18 Done.
130 onMouseReleased_: function(evt) { 145 onMouseUp_: function(evt) {
131 this.onMouseDragged_(evt); 146 this.onMouseMove_(evt);
132 this.down_ = false; 147 this.down_ = false;
133 148
134 chrome.accessibilityPrivate.setFocusRing([]); 149 chrome.accessibilityPrivate.setFocusRing([]);
135 150
151 this.mouseEnd_ = {x: evt.screenX, y: evt.screenY};
152 var ctrX = Math.floor((this.mouseStart_.x + this.mouseEnd_.x) / 2);
153 var ctrY = Math.floor((this.mouseStart_.y + this.mouseEnd_.y) / 2);
154
155 // Do a hit test at the center of the area the user dragged over.
156 // This will give us some context when searching the accessibility tree.
157 // The hit test will result in a EventType.MOUSE_RELEASED event being
158 // fired on the result of that hit test, which will trigger
159 // onMouseReleasedHitTest_.
David Tseng 2017/05/07 06:10:27 Just wondering, but it seems confusing to have a m
dmazzoni 2017/05/10 19:43:18 I agree, this is confusing. I think we should get
160 this.desktop_.hitTest(ctrX, ctrY, EventType.MOUSE_RELEASED);
161 },
162
163 /**
164 * Called in response to our hit test afterthe mouse is released,
David Tseng 2017/05/07 06:10:27 nit: after the
dmazzoni 2017/05/10 19:43:18 Done.
165 * when the user is in a mode where select-to-speak is capturing
166 * mouse events (for example holding down Search).
167 *
168 * @param {!AutomationEvent} evt The automation event.
169 */
170 onMouseReleasedHitTest_: function(evt) {
David Tseng 2017/05/07 06:10:27 nit: Maybe rename the listeners like onAutomationF
dmazzoni 2017/05/10 19:43:18 Done.
136 // Walk up to the nearest window, web area, or dialog that the 171 // Walk up to the nearest window, web area, or dialog that the
David Tseng 2017/05/07 06:10:28 Might as well include toolbar as well.
dmazzoni 2017/05/10 19:43:18 Done.
137 // hit node is contained inside. Only speak objects within that 172 // hit node is contained inside. Only speak objects within that
138 // container. In the future we might include other container-like 173 // container. In the future we might include other container-like
139 // roles here. 174 // roles here.
140 var root = this.startNode_; 175 var root = evt.target;
141 while (root.parent && 176 while (root.parent &&
142 root.role != RoleType.WINDOW && 177 root.role != RoleType.WINDOW &&
143 root.role != RoleType.ROOT_WEB_AREA && 178 root.role != RoleType.ROOT_WEB_AREA &&
144 root.role != RoleType.DESKTOP && 179 root.role != RoleType.DESKTOP &&
145 root.role != RoleType.DIALOG) { 180 root.role != RoleType.DIALOG) {
146 root = root.parent; 181 root = root.parent;
147 } 182 }
148 183
149 var rect = rectFromPoints( 184 var rect = rectFromPoints(
150 this.mouseStart_.x, this.mouseStart_.y, 185 this.mouseStart_.x, this.mouseStart_.y,
151 evt.mouseX, evt.mouseY); 186 this.mouseEnd_.x, this.mouseEnd_.y);
152 var nodes = []; 187 var nodes = [];
153 this.findAllMatching_(root, rect, nodes); 188 this.findAllMatching_(root, rect, nodes);
154 this.startSpeechQueue_(nodes); 189 this.startSpeechQueue_(nodes);
155 }, 190 },
156 191
157 /** 192 /**
193 * Set up event listeners for all mouse events.
194 */
195 captureMouseEvents_: function() {
196 document.addEventListener('mousedown', this.onMouseDown_.bind(this));
David Tseng 2017/05/07 06:10:27 Do these listeners need to be removed at some poin
dmazzoni 2017/05/10 19:43:19 We're tracking keys in the extension now, as sugge
197 document.addEventListener('mouseup', this.onMouseUp_.bind(this));
198 document.addEventListener('mousemove', this.onMouseMove_.bind(this));
David Tseng 2017/05/07 06:10:27 nit: sort
dmazzoni 2017/05/10 19:43:19 Done.
199 },
200
201 /**
158 * Called when the user cancels select-to-speak's capturing of mouse 202 * Called when the user cancels select-to-speak's capturing of mouse
159 * events (for example by releasing Search while the mouse is still down). 203 * events (for example by releasing Search while the mouse is still down).
160 * 204 *
161 * @param {!AutomationEvent} evt 205 * @param {!AutomationEvent} evt
162 */ 206 */
163 onMouseCanceled_: function(evt) { 207 onMouseCanceled_: function(evt) {
164 this.down_ = false; 208 this.down_ = false;
165 chrome.accessibilityPrivate.setFocusRing([]); 209 chrome.accessibilityPrivate.setFocusRing([]);
166 chrome.tts.stop(); 210 chrome.tts.stop();
167 }, 211 },
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 this.voiceNameFromLocale_ = voices[0].voiceName; 358 this.voiceNameFromLocale_ = voices[0].voiceName;
315 359
316 chrome.storage.sync.get(['voice'], (function(prefs) { 360 chrome.storage.sync.get(['voice'], (function(prefs) {
317 if (!prefs['voice']) { 361 if (!prefs['voice']) {
318 chrome.storage.sync.set({'voice': voices[0].voiceName}); 362 chrome.storage.sync.set({'voice': voices[0].voiceName});
319 } 363 }
320 }).bind(this)); 364 }).bind(this));
321 }).bind(this)); 365 }).bind(this));
322 } 366 }
323 }; 367 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698