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

Side by Side Diff: chrome/browser/resources/access_chromevox/scripts/gmail_api.js

Issue 6254007: Adding ChromeVox as a component extensions (enabled only for ChromeOS, for no... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 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 | Annotate | Revision Log
Property Changes:
Added: svn:executable
+ *
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 goog.provide('cvox.GmailApi');
6
7 goog.require('cvox.ChromeVox');
8
9 /**
10 * @fileoverview API for accessing GMail content and getting events from GMail.
11 * The API exposes an event driven API for accessibility. Having this API keeps
12 * the accessibility scripts from being dependent on the inner workings of
13 * GMail.
14 */
15 var GmailApi = { };
16
17 /**
18 * Collection of classnames. Used to check on the status of threads and
19 * messages.
20 * @private
21 * @type {Object.<String, String>}
22 */
23 GmailApi.CLASSES_ = {
24 MESSAGE_STARRED: 'f g9',
25 MESSAGE_NOT_STARRED: 'f g8',
26 THREAD_STARRED: 'W5RYx',
27 THREAD_NOT_STARRED: 'EqK8f',
28 UNREAD_SELECTED: 'zA zE x7',
29 UNREAD_NOT_SELECTED: 'zA zE',
30 READ_SELECTED: 'zA yO x7',
31 READ_NOT_SELECTED: 'zA yO',
32 MESSAGE_EXPANDED: 'h7',
33 BUTTERBAR_NOTIFICATION: 'vh'
34 };
35
36 /**
37 * @private
38 * @type {Element}
39 */
40 GmailApi.previousThreadNode_ = null;
41
42 /**
43 * @private
44 * @type {Element}
45 */
46 GmailApi.previousMessageNode_ = null;
47
48 /**
49 * @private
50 * @type {Element}
51 */
52 GmailApi.previousSearchCompletionNode_ = null;
53
54 /**
55 * Callback listener to invoke when an event happens.
56 * @private
57 * @type {Function}
58 */
59 GmailApi.listener_ = null;
60
61 /**
62 * Initializes the Gmail script.
63 * @private
64 */
65 GmailApi.init_ = function() {
66 window.addEventListener('keyup', GmailApi.keyupHandler_, true);
67 window.addEventListener('DOMSubtreeModified',
68 GmailApi.domSubtreeModified_, true);
69 };
70
71 /**
72 * Sets the GmailListener object to be used for callbacks.
73 *
74 * public:
75 * @param {function} gmailListener The GmailListener to be used.
76 */
77 GmailApi.setGmailEventListener = function(gmailListener) {
78 GmailApi.listener_ = gmailListener;
79 };
80
81 /**
82 * Gets the current GmailThread if it has changed since the last time
83 * this function was called.
84 *
85 * @private
86 * @return {Object} The current GmailThread if it has changed. Returns
87 * null otherwise.
88 */
89 GmailApi.getCurrentThreadIfChanged_ = function() {
90 var currentThread = GmailApi.getCurrentThread();
91 if ((currentThread != null) &&
92 (currentThread.getNode() != GmailApi.previousThreadNode_)) {
93 GmailApi.previousThreadNode_ = currentThread.getNode();
94 return currentThread;
95 }
96 return null;
97 };
98
99 /**
100 * Returns the current GmailThread with the chevron arrow pointed at it.
101 *
102 * public:
103 * @return {Object} The current GmailThread object.
104 */
105 GmailApi.getCurrentThread = function() {
106 var chevronNodes = document.getElementsByClassName('oZ-jd');
107 if (!chevronNodes) {
108 return null;
109 }
110 // Start from the end of the list and work backwards since GMail keeps
111 // the previous chevron nodes and the style for those are still 'visible'.
112 for (var node, i = chevronNodes.length - 1; node = chevronNodes[i]; i--) {
113 if (node.style.visibility == 'visible') {
114 var currentThread = node.parentNode.parentNode;
115 var starred = false;
116 var selected = false;
117 var read = false;
118 // TODO: These checks could come from a GMail function to return the
119 // status info.
120 // Check if the current thread is selected
121 if ((currentThread.className == GmailApi.CLASSES_.READ_SELECTED) ||
122 (currentThread.className == GmailApi.CLASSES_.UNREAD_SELECTED)) {
123 selected = true;
124 }
125 // Check if the current thread is starred.
126 // Note that Gmail has an inconsistency in its alt text. If a thread is
127 // starred when Gmail is loaded, it will have alt text "starred". But
128 // if it is starred/unstarred later, the alt text is not dynamically
129 // changed.
130 if (currentThread.getElementsByClassName(
131 GmailApi.CLASSES_.STARRED).length > 0) {
132 starred = true;
133 currentThread.getElementsByClassName(
134 GmailApi.CLASSES_.STARRED)[0].alt = '';
135 } else if (currentThread.getElementsByClassName(
136 GmailApi.CLASSES_.NOT_STARRED).length > 0) {
137 currentThread.getElementsByClassName(
138 GmailApi.CLASSES_.NOT_STARRED)[0].alt = '';
139 }
140 // Check if the current thread is read
141 if ((currentThread.className == GmailApi.CLASSES_.READ_SELECTED) ||
142 (currentThread.className == GmailApi.CLASSES_.READ_NOT_SELECTED)) {
143 read = true;
144 }
145 return new GmailThread(currentThread, starred, selected, read);
146 }
147 }
148 return null;
149 };
150
151 /**
152 * Gets the current message if it has changed since the last time
153 * this function was called.
154 *
155 * @private
156 * @return {GmailMessage?} The current message if it has changed. Returns
157 * null otherwise.
158 */
159 GmailApi.getCurrentMessageIfChanged_ = function() {
160 var currentMessage = GmailApi.getCurrentMessage();
161 if ((currentMessage != null) &&
162 (currentMessage.getNode() != GmailApi.previousMessageNode_)) {
163 GmailApi.previousMessageNode_ = currentMessage.getNode();
164 return currentMessage;
165 }
166 return null;
167 };
168
169 /**
170 * Returns the current message node with the chevron arrow pointed at it.
171 *
172 * public:
173 * @return {GmailMessage?} The current message node.
174 */
175 GmailApi.getCurrentMessage = function() {
176 var chevronNodes = document.getElementsByClassName('hF');
177 var actualMessageNode = null;
178 if (chevronNodes) {
179 for (var node, i = 0; node = chevronNodes[i]; i++) {
180 if (node.className == 'hF') {
181 if (actualMessageNode) {
182 if (node.parentNode.textContent.length >
183 actualMessageNode.textContent.length) {
184 actualMessageNode = node.parentNode;
185 }
186 } else {
187 actualMessageNode = node.parentNode;
188 }
189 }
190 }
191 }
192 var gmailMessage;
193 if (actualMessageNode != null) {
194 // TODO: Get the actual starred/not starred status.
195 // This hack of always setting the starred status to
196 // false happens to work here since we are reading the
197 // entire message node and the alt text for the star status
198 // is changed correctly on messages.
199 gmailMessage = new GmailMessage(actualMessageNode, false);
200 }
201 return gmailMessage;
202 };
203
204 /**
205 * Gets the current search completion if it has changed since the last time
206 * this function was called.
207 *
208 * @private
209 * @return {GmailSearchCompletion?} The current search completion if it has
210 * changed. Returns null otherwise.
211 */
212 GmailApi.getCurrentSearchCompletionIfChanged_ = function() {
213 var currentSearchCompletion = GmailApi.getCurrentSearchCompletion();
214 if ((currentSearchCompletion != null) &&
215 (currentSearchCompletion.getNode() !=
216 GmailApi.previousSearchCompletionNode_)) {
217 GmailApi.previousSearchCompletionNode_ = currentSearchCompletion.getNode();
218 return currentSearchCompletion;
219 }
220 return null;
221 };
222
223 /**
224 * Returns the current search completion node that is highlighted.
225 *
226 * public:
227 * @return {Element?} The current search completion node.
228 */
229 GmailApi.getCurrentSearchCompletion = function() {
230 var currentSearchCompletionNode = null;
231 var highlightedCompletionNodes =
232 document.getElementsByClassName('aq Jd-Je Je');
233 if (highlightedCompletionNodes && (highlightedCompletionNodes.length > 0)) {
234 currentSearchCompletionNode = highlightedCompletionNodes[0];
235 }
236 var gmailSearchCompletion;
237 if (currentSearchCompletionNode != null) {
238 gmailSearchCompletion = new GmailSearchCompletion(
239 currentSearchCompletionNode);
240 }
241 return gmailSearchCompletion;
242 };
243
244 /**
245 * Catches DOM mutation events which indicate if a thread/message has been
246 * starred, selected, etc. and dispatches these status change events to
247 * the GmailListener.
248 *
249 * @private
250 * @param {Event} evt The DOMSubtreeModified event used to determine when
251 * an interesting status change has occurred.
252 */
253 GmailApi.domSubtreeModified_ = function(evt) {
254 var target = evt.target;
255 if (target.className) {
256 // TODO: These checks could come from a GMail function to return the status
257 // info.
258 switch (target.className) {
259 case GmailApi.CLASSES_.MESSAGE_STARRED:
260 GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.Starred,
261 '');
262 break;
263 case GmailApi.CLASSES_.MESSAGE_NOT_STARRED:
264 GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.NotStarred,
265 '');
266 break;
267 case GmailApi.CLASSES_.THREAD_STARRED:
268 GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.Starred,
269 '');
270 break;
271 case GmailApi.CLASSES_.THREAD_NOT_STARRED:
272 GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.NotStarred,
273 '');
274 break;
275 case GmailApi.CLASSES_.READ_SELECTED:
276 GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.Selected,
277 '');
278 break;
279 case GmailApi.CLASSES_.READ_NOT_SELECTED:
280 GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.NotSelected,
281 '');
282 break;
283 case GmailApi.CLASSES_.UNREAD_SELECTED:
284 GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.Selected,
285 '');
286 break;
287 case GmailApi.CLASSES_.UNREAD_NOT_SELECTED:
288 GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.NotSelected,
289 '');
290 break;
291 case GmailApi.CLASSES_.MESSAGE_EXPANDED:
292 var messageObj = null;
293 if (messageObj = GmailApi.getCurrentMessageIfChanged_()) {
294 GmailApi.listener_.onNavigatedToNewMessage(messageObj);
295 }
296 break;
297 case GmailApi.CLASSES_.BUTTERBAR_NOTIFICATION:
298 // Use a timeout here to
299 window.setTimeout(function() {
300 GmailApi.listener_.onStatusChangeEvent(
301 GmailListener.STATUS.Notification,
302 evt.target.firstChild.textContent);
303 }, 100);
304 break;
305 }
306 }
307 };
308
309 /**
310 * Checks to see if the user has pressed a key that has caused
311 * navigation to happen, and if so, dispatches the navigation event
312 * to the GmailListener.
313 *
314 * @private
315 * @param {Event} evt The keyup event. This is not actually used.
316 */
317 GmailApi.keyupHandler_ = function(evt) {
318 // Ignore key events if they somehow involve the ctrl and/or alt keys.
319 if (evt.ctrlKey || evt.altKey || (evt.keyCode == 17) || (evt.keyCode == 18)) {
320 return;
321 }
322 var threadObj = null;
323 if (threadObj = GmailApi.getCurrentThreadIfChanged_()) {
324 GmailApi.listener_.onNavigatedToNewThread(threadObj);
325 }
326 var messageObj = null;
327 if (messageObj = GmailApi.getCurrentMessageIfChanged_()) {
328 GmailApi.listener_.onNavigatedToNewMessage(messageObj);
329 }
330 var searchCompletionObj = null;
331 if (searchCompletionObj = GmailApi.getCurrentSearchCompletionIfChanged_()) {
332 GmailApi.listener_.onNavigatedToNewSearchCompletion(searchCompletionObj);
333 }
334 };
335
336
337 /**
338 * Listener interface for receiving GMail events.
339 *
340 * public:
341 * @constructor
342 */
343 var GmailListener = function() {
344 };
345
346 /**
347 * Collection of status codes.
348 *
349 * public:
350 * @type {Object}
351 */
352 GmailListener.STATUS = {
353 Starred: 0,
354 NotStarred: 1,
355 Selected: 2,
356 NotSelected: 3,
357 Read: 4,
358 Unread: 5,
359 Notification: 6
360 };
361
362 /**
363 * Called when the user has navigated to a new thread.
364 *
365 * public:
366 * @param {Object} threadObject The GmailThread object.
367 */
368 GmailListener.prototype.onNavigatedToNewThread = function(threadObject) {
369 };
370
371 /**
372 * Called when the user has navigated to a new message.
373 *
374 * public:
375 * @param {Object} messageObject The GmailThread object.
376 */
377 GmailListener.prototype.onNavigatedToNewMessage = function(messageObject) {
378 };
379
380 /**
381 * Called when the user has navigated to a new search completion.
382 *
383 * public:
384 * @param {Object} searchCompletionObject The GmailSearchCompletion object.
385 */
386 GmailListener.prototype.onNavigatedToNewSearchCompletion =
387 function(searchCompletionObject) {
388 };
389
390
391 /**
392 * Called when there is a status change.
393 *
394 * public:
395 * @param {number} status The current status code.
396 * @param {String?} message Optional string if there is more information.
397 */
398 GmailListener.prototype.onStatusChangeEvent = function(status, message) {
399 };
400
401 /**
402 * GMail thread object that holds the DOM node of the thread + status
403 * information for that thread.
404 *
405 * public:
406 * @constructor
407 * @param {Element} node The node that contains the GmailThread.
408 * @param {boolean} starred Whether or not the GmailThread is starred.
409 * @param {boolean} selected Whether or not the GmailThread is selected.
410 * @param {boolean} read Whether or not the GmailThread is read.
411 */
412 var GmailThread = function(node, starred, selected, read) {
413 this.node_ = node;
414 this.starred_ = starred;
415 this.selected_ = selected;
416 this.read_ = read;
417 };
418
419 /**
420 * Returns the DOM node for the thread.
421 *
422 * public:
423 * @return {Object} The current thread node.
424 */
425 GmailThread.prototype.getNode = function() {
426 return this.node_;
427 };
428
429 /**
430 * Returns whether or not the thread is starred.
431 *
432 * public:
433 * @return {boolean} Whether or not the thread is starred.
434 */
435 GmailThread.prototype.isStarred = function() {
436 return this.starred_;
437 };
438
439 /**
440 * Returns whether or not the thread is selected.
441 *
442 * public:
443 * @return {boolean} Whether or not the thread is selected.
444 */
445 GmailThread.prototype.isSelected = function() {
446 return this.selected_;
447 };
448
449 /**
450 * Returns whether or not the thread is read.
451 *
452 * public:
453 * @return {boolean} Whether or not the thread is read.
454 */
455 GmailThread.prototype.isRead = function() {
456 return this.read_;
457 };
458
459 /**
460 * Returns an array of labels for the thread.
461 *
462 * public:
463 * @return {Object} Array of labels for the thread.
464 */
465 GmailThread.prototype.getLabels = function() {
466 return new Array();
467 };
468
469 /**
470 * Returns an array of authors for the thread.
471 *
472 * public:
473 * @return {Object} Array of authors for the thread.
474 */
475 GmailThread.prototype.getAuthors = function() {
476 return new Array();
477 };
478
479 /**
480 * Returns the subject of the thread.
481 *
482 * public:
483 * @return {string} The thread subject.
484 */
485 GmailThread.prototype.getSubject = function() {
486 return '';
487 };
488
489 /**
490 * Returns the snippet for the thread.
491 *
492 * public:
493 * @return {string} The snippet for the thread.
494 */
495 GmailThread.prototype.getSnippet = function() {
496 return '';
497 };
498
499 /**
500 * Returns the date/time string for the thread.
501 *
502 * public:
503 * @return {string} The date/time for the thread.
504 */
505 GmailThread.prototype.getDateTime = function() {
506 return '';
507 };
508
509 /**
510 * GMail message object that holds the DOM node of the message + status
511 * information for that message.
512 *
513 * public:
514 * @constructor
515 * @param {Element} node The node that contains the GmailMessage.
516 * @param {boolean} starred Whether or not the GmailMessage is starred.
517 */
518 var GmailMessage = function(node, starred) {
519 this.node_ = node;
520 this.starred_ = starred;
521 };
522
523 /**
524 * Returns the DOM node for the message.
525 *
526 * public:
527 * @return {Object} The current message node.
528 */
529 GmailMessage.prototype.getNode = function() {
530 return this.node_;
531 };
532
533 /**
534 * Returns whether or not the message is starred.
535 *
536 * public:
537 * @return {boolean} Whether or not the message is starred.
538 */
539 GmailMessage.prototype.isStarred = function() {
540 return this.starred_;
541 };
542
543 /**
544 * Returns whether or not the message is read.
545 *
546 * public:
547 * @return {boolean} Whether or not the message is read.
548 */
549 GmailMessage.prototype.isRead = function() {
550 return this.read_;
551 };
552
553 /**
554 * Returns the author for the message.
555 *
556 * public:
557 * @return {string} The author of the message.
558 */
559 GmailMessage.prototype.getAuthor = function() {
560 return '';
561 };
562
563 /**
564 * Returns the subject of the message.
565 *
566 * public:
567 * @return {string} The message subject.
568 */
569 GmailMessage.prototype.getSubject = function() {
570 return '';
571 };
572
573 /**
574 * Returns the content for the message.
575 *
576 * public:
577 * @return {string} The content for the message.
578 */
579 GmailMessage.prototype.getContent = function() {
580 return '';
581 };
582
583 /**
584 * Returns the date/time string for the message.
585 *
586 * public:
587 * @return {string} The date/time for the message.
588 */
589 GmailMessage.prototype.getDateTime = function() {
590 return '';
591 };
592
593 /**
594 * Returns the message's GmailThread object.
595 *
596 * public:
597 * @return {GmailThread?} The GmailThread object.
598 */
599 GmailMessage.prototype.getThread = function() {
600 return null;
601 };
602
603 /**
604 * GMail search completion object that holds the DOM node of the
605 * search completion.
606 *
607 * public:
608 * @constructor
609 * @param {Element} node The node that contains the GmailSearchCompletion.
610 */
611 var GmailSearchCompletion = function(node) {
612 this.node_ = node;
613 };
614
615 /**
616 * Returns the DOM node for the search completion.
617 *
618 * public:
619 * @return {Object} The current search completion node.
620 */
621 GmailSearchCompletion.prototype.getNode = function() {
622 return this.node_;
623 };
624
625 window.setTimeout(GmailApi.init_, 100);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698