| Index: chrome/browser/resources/access_chromevox/scripts/gmail_api.js
|
| ===================================================================
|
| --- chrome/browser/resources/access_chromevox/scripts/gmail_api.js (revision 0)
|
| +++ chrome/browser/resources/access_chromevox/scripts/gmail_api.js (revision 0)
|
| @@ -0,0 +1,625 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +goog.provide('cvox.GmailApi');
|
| +
|
| +goog.require('cvox.ChromeVox');
|
| +
|
| +/**
|
| + * @fileoverview API for accessing GMail content and getting events from GMail.
|
| + * The API exposes an event driven API for accessibility. Having this API keeps
|
| + * the accessibility scripts from being dependent on the inner workings of
|
| + * GMail.
|
| + */
|
| +var GmailApi = { };
|
| +
|
| +/**
|
| + * Collection of classnames. Used to check on the status of threads and
|
| + * messages.
|
| + * @private
|
| + * @type {Object.<String, String>}
|
| + */
|
| +GmailApi.CLASSES_ = {
|
| + MESSAGE_STARRED: 'f g9',
|
| + MESSAGE_NOT_STARRED: 'f g8',
|
| + THREAD_STARRED: 'W5RYx',
|
| + THREAD_NOT_STARRED: 'EqK8f',
|
| + UNREAD_SELECTED: 'zA zE x7',
|
| + UNREAD_NOT_SELECTED: 'zA zE',
|
| + READ_SELECTED: 'zA yO x7',
|
| + READ_NOT_SELECTED: 'zA yO',
|
| + MESSAGE_EXPANDED: 'h7',
|
| + BUTTERBAR_NOTIFICATION: 'vh'
|
| +};
|
| +
|
| +/**
|
| + * @private
|
| + * @type {Element}
|
| + */
|
| +GmailApi.previousThreadNode_ = null;
|
| +
|
| +/**
|
| + * @private
|
| + * @type {Element}
|
| + */
|
| +GmailApi.previousMessageNode_ = null;
|
| +
|
| +/**
|
| + * @private
|
| + * @type {Element}
|
| + */
|
| +GmailApi.previousSearchCompletionNode_ = null;
|
| +
|
| +/**
|
| + * Callback listener to invoke when an event happens.
|
| + * @private
|
| + * @type {Function}
|
| + */
|
| +GmailApi.listener_ = null;
|
| +
|
| +/**
|
| + * Initializes the Gmail script.
|
| + * @private
|
| + */
|
| +GmailApi.init_ = function() {
|
| + window.addEventListener('keyup', GmailApi.keyupHandler_, true);
|
| + window.addEventListener('DOMSubtreeModified',
|
| + GmailApi.domSubtreeModified_, true);
|
| +};
|
| +
|
| +/**
|
| + * Sets the GmailListener object to be used for callbacks.
|
| + *
|
| + * public:
|
| + * @param {function} gmailListener The GmailListener to be used.
|
| + */
|
| +GmailApi.setGmailEventListener = function(gmailListener) {
|
| + GmailApi.listener_ = gmailListener;
|
| +};
|
| +
|
| +/**
|
| + * Gets the current GmailThread if it has changed since the last time
|
| + * this function was called.
|
| + *
|
| + * @private
|
| + * @return {Object} The current GmailThread if it has changed. Returns
|
| + * null otherwise.
|
| + */
|
| +GmailApi.getCurrentThreadIfChanged_ = function() {
|
| + var currentThread = GmailApi.getCurrentThread();
|
| + if ((currentThread != null) &&
|
| + (currentThread.getNode() != GmailApi.previousThreadNode_)) {
|
| + GmailApi.previousThreadNode_ = currentThread.getNode();
|
| + return currentThread;
|
| + }
|
| + return null;
|
| +};
|
| +
|
| +/**
|
| + * Returns the current GmailThread with the chevron arrow pointed at it.
|
| + *
|
| + * public:
|
| + * @return {Object} The current GmailThread object.
|
| + */
|
| +GmailApi.getCurrentThread = function() {
|
| + var chevronNodes = document.getElementsByClassName('oZ-jd');
|
| + if (!chevronNodes) {
|
| + return null;
|
| + }
|
| + // Start from the end of the list and work backwards since GMail keeps
|
| + // the previous chevron nodes and the style for those are still 'visible'.
|
| + for (var node, i = chevronNodes.length - 1; node = chevronNodes[i]; i--) {
|
| + if (node.style.visibility == 'visible') {
|
| + var currentThread = node.parentNode.parentNode;
|
| + var starred = false;
|
| + var selected = false;
|
| + var read = false;
|
| + // TODO: These checks could come from a GMail function to return the
|
| + // status info.
|
| + // Check if the current thread is selected
|
| + if ((currentThread.className == GmailApi.CLASSES_.READ_SELECTED) ||
|
| + (currentThread.className == GmailApi.CLASSES_.UNREAD_SELECTED)) {
|
| + selected = true;
|
| + }
|
| + // Check if the current thread is starred.
|
| + // Note that Gmail has an inconsistency in its alt text. If a thread is
|
| + // starred when Gmail is loaded, it will have alt text "starred". But
|
| + // if it is starred/unstarred later, the alt text is not dynamically
|
| + // changed.
|
| + if (currentThread.getElementsByClassName(
|
| + GmailApi.CLASSES_.STARRED).length > 0) {
|
| + starred = true;
|
| + currentThread.getElementsByClassName(
|
| + GmailApi.CLASSES_.STARRED)[0].alt = '';
|
| + } else if (currentThread.getElementsByClassName(
|
| + GmailApi.CLASSES_.NOT_STARRED).length > 0) {
|
| + currentThread.getElementsByClassName(
|
| + GmailApi.CLASSES_.NOT_STARRED)[0].alt = '';
|
| + }
|
| + // Check if the current thread is read
|
| + if ((currentThread.className == GmailApi.CLASSES_.READ_SELECTED) ||
|
| + (currentThread.className == GmailApi.CLASSES_.READ_NOT_SELECTED)) {
|
| + read = true;
|
| + }
|
| + return new GmailThread(currentThread, starred, selected, read);
|
| + }
|
| + }
|
| + return null;
|
| +};
|
| +
|
| +/**
|
| + * Gets the current message if it has changed since the last time
|
| + * this function was called.
|
| + *
|
| + * @private
|
| + * @return {GmailMessage?} The current message if it has changed. Returns
|
| + * null otherwise.
|
| + */
|
| +GmailApi.getCurrentMessageIfChanged_ = function() {
|
| + var currentMessage = GmailApi.getCurrentMessage();
|
| + if ((currentMessage != null) &&
|
| + (currentMessage.getNode() != GmailApi.previousMessageNode_)) {
|
| + GmailApi.previousMessageNode_ = currentMessage.getNode();
|
| + return currentMessage;
|
| + }
|
| + return null;
|
| +};
|
| +
|
| +/**
|
| + * Returns the current message node with the chevron arrow pointed at it.
|
| + *
|
| + * public:
|
| + * @return {GmailMessage?} The current message node.
|
| + */
|
| +GmailApi.getCurrentMessage = function() {
|
| + var chevronNodes = document.getElementsByClassName('hF');
|
| + var actualMessageNode = null;
|
| + if (chevronNodes) {
|
| + for (var node, i = 0; node = chevronNodes[i]; i++) {
|
| + if (node.className == 'hF') {
|
| + if (actualMessageNode) {
|
| + if (node.parentNode.textContent.length >
|
| + actualMessageNode.textContent.length) {
|
| + actualMessageNode = node.parentNode;
|
| + }
|
| + } else {
|
| + actualMessageNode = node.parentNode;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + var gmailMessage;
|
| + if (actualMessageNode != null) {
|
| + // TODO: Get the actual starred/not starred status.
|
| + // This hack of always setting the starred status to
|
| + // false happens to work here since we are reading the
|
| + // entire message node and the alt text for the star status
|
| + // is changed correctly on messages.
|
| + gmailMessage = new GmailMessage(actualMessageNode, false);
|
| + }
|
| + return gmailMessage;
|
| +};
|
| +
|
| +/**
|
| + * Gets the current search completion if it has changed since the last time
|
| + * this function was called.
|
| + *
|
| + * @private
|
| + * @return {GmailSearchCompletion?} The current search completion if it has
|
| + * changed. Returns null otherwise.
|
| + */
|
| +GmailApi.getCurrentSearchCompletionIfChanged_ = function() {
|
| + var currentSearchCompletion = GmailApi.getCurrentSearchCompletion();
|
| + if ((currentSearchCompletion != null) &&
|
| + (currentSearchCompletion.getNode() !=
|
| + GmailApi.previousSearchCompletionNode_)) {
|
| + GmailApi.previousSearchCompletionNode_ = currentSearchCompletion.getNode();
|
| + return currentSearchCompletion;
|
| + }
|
| + return null;
|
| +};
|
| +
|
| +/**
|
| + * Returns the current search completion node that is highlighted.
|
| + *
|
| + * public:
|
| + * @return {Element?} The current search completion node.
|
| + */
|
| +GmailApi.getCurrentSearchCompletion = function() {
|
| + var currentSearchCompletionNode = null;
|
| + var highlightedCompletionNodes =
|
| + document.getElementsByClassName('aq Jd-Je Je');
|
| + if (highlightedCompletionNodes && (highlightedCompletionNodes.length > 0)) {
|
| + currentSearchCompletionNode = highlightedCompletionNodes[0];
|
| + }
|
| + var gmailSearchCompletion;
|
| + if (currentSearchCompletionNode != null) {
|
| + gmailSearchCompletion = new GmailSearchCompletion(
|
| + currentSearchCompletionNode);
|
| + }
|
| + return gmailSearchCompletion;
|
| +};
|
| +
|
| +/**
|
| + * Catches DOM mutation events which indicate if a thread/message has been
|
| + * starred, selected, etc. and dispatches these status change events to
|
| + * the GmailListener.
|
| + *
|
| + * @private
|
| + * @param {Event} evt The DOMSubtreeModified event used to determine when
|
| + * an interesting status change has occurred.
|
| + */
|
| +GmailApi.domSubtreeModified_ = function(evt) {
|
| + var target = evt.target;
|
| + if (target.className) {
|
| + // TODO: These checks could come from a GMail function to return the status
|
| + // info.
|
| + switch (target.className) {
|
| + case GmailApi.CLASSES_.MESSAGE_STARRED:
|
| + GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.Starred,
|
| + '');
|
| + break;
|
| + case GmailApi.CLASSES_.MESSAGE_NOT_STARRED:
|
| + GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.NotStarred,
|
| + '');
|
| + break;
|
| + case GmailApi.CLASSES_.THREAD_STARRED:
|
| + GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.Starred,
|
| + '');
|
| + break;
|
| + case GmailApi.CLASSES_.THREAD_NOT_STARRED:
|
| + GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.NotStarred,
|
| + '');
|
| + break;
|
| + case GmailApi.CLASSES_.READ_SELECTED:
|
| + GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.Selected,
|
| + '');
|
| + break;
|
| + case GmailApi.CLASSES_.READ_NOT_SELECTED:
|
| + GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.NotSelected,
|
| + '');
|
| + break;
|
| + case GmailApi.CLASSES_.UNREAD_SELECTED:
|
| + GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.Selected,
|
| + '');
|
| + break;
|
| + case GmailApi.CLASSES_.UNREAD_NOT_SELECTED:
|
| + GmailApi.listener_.onStatusChangeEvent(GmailListener.STATUS.NotSelected,
|
| + '');
|
| + break;
|
| + case GmailApi.CLASSES_.MESSAGE_EXPANDED:
|
| + var messageObj = null;
|
| + if (messageObj = GmailApi.getCurrentMessageIfChanged_()) {
|
| + GmailApi.listener_.onNavigatedToNewMessage(messageObj);
|
| + }
|
| + break;
|
| + case GmailApi.CLASSES_.BUTTERBAR_NOTIFICATION:
|
| + // Use a timeout here to
|
| + window.setTimeout(function() {
|
| + GmailApi.listener_.onStatusChangeEvent(
|
| + GmailListener.STATUS.Notification,
|
| + evt.target.firstChild.textContent);
|
| + }, 100);
|
| + break;
|
| + }
|
| + }
|
| +};
|
| +
|
| +/**
|
| + * Checks to see if the user has pressed a key that has caused
|
| + * navigation to happen, and if so, dispatches the navigation event
|
| + * to the GmailListener.
|
| + *
|
| + * @private
|
| + * @param {Event} evt The keyup event. This is not actually used.
|
| + */
|
| +GmailApi.keyupHandler_ = function(evt) {
|
| + // Ignore key events if they somehow involve the ctrl and/or alt keys.
|
| + if (evt.ctrlKey || evt.altKey || (evt.keyCode == 17) || (evt.keyCode == 18)) {
|
| + return;
|
| + }
|
| + var threadObj = null;
|
| + if (threadObj = GmailApi.getCurrentThreadIfChanged_()) {
|
| + GmailApi.listener_.onNavigatedToNewThread(threadObj);
|
| + }
|
| + var messageObj = null;
|
| + if (messageObj = GmailApi.getCurrentMessageIfChanged_()) {
|
| + GmailApi.listener_.onNavigatedToNewMessage(messageObj);
|
| + }
|
| + var searchCompletionObj = null;
|
| + if (searchCompletionObj = GmailApi.getCurrentSearchCompletionIfChanged_()) {
|
| + GmailApi.listener_.onNavigatedToNewSearchCompletion(searchCompletionObj);
|
| + }
|
| +};
|
| +
|
| +
|
| +/**
|
| + * Listener interface for receiving GMail events.
|
| + *
|
| + * public:
|
| + * @constructor
|
| + */
|
| +var GmailListener = function() {
|
| +};
|
| +
|
| +/**
|
| + * Collection of status codes.
|
| + *
|
| + * public:
|
| + * @type {Object}
|
| + */
|
| +GmailListener.STATUS = {
|
| + Starred: 0,
|
| + NotStarred: 1,
|
| + Selected: 2,
|
| + NotSelected: 3,
|
| + Read: 4,
|
| + Unread: 5,
|
| + Notification: 6
|
| +};
|
| +
|
| +/**
|
| + * Called when the user has navigated to a new thread.
|
| + *
|
| + * public:
|
| + * @param {Object} threadObject The GmailThread object.
|
| + */
|
| +GmailListener.prototype.onNavigatedToNewThread = function(threadObject) {
|
| +};
|
| +
|
| +/**
|
| + * Called when the user has navigated to a new message.
|
| + *
|
| + * public:
|
| + * @param {Object} messageObject The GmailThread object.
|
| + */
|
| +GmailListener.prototype.onNavigatedToNewMessage = function(messageObject) {
|
| +};
|
| +
|
| +/**
|
| + * Called when the user has navigated to a new search completion.
|
| + *
|
| + * public:
|
| + * @param {Object} searchCompletionObject The GmailSearchCompletion object.
|
| + */
|
| +GmailListener.prototype.onNavigatedToNewSearchCompletion =
|
| + function(searchCompletionObject) {
|
| +};
|
| +
|
| +
|
| +/**
|
| + * Called when there is a status change.
|
| + *
|
| + * public:
|
| + * @param {number} status The current status code.
|
| + * @param {String?} message Optional string if there is more information.
|
| + */
|
| +GmailListener.prototype.onStatusChangeEvent = function(status, message) {
|
| +};
|
| +
|
| +/**
|
| + * GMail thread object that holds the DOM node of the thread + status
|
| + * information for that thread.
|
| + *
|
| + * public:
|
| + * @constructor
|
| + * @param {Element} node The node that contains the GmailThread.
|
| + * @param {boolean} starred Whether or not the GmailThread is starred.
|
| + * @param {boolean} selected Whether or not the GmailThread is selected.
|
| + * @param {boolean} read Whether or not the GmailThread is read.
|
| + */
|
| +var GmailThread = function(node, starred, selected, read) {
|
| + this.node_ = node;
|
| + this.starred_ = starred;
|
| + this.selected_ = selected;
|
| + this.read_ = read;
|
| +};
|
| +
|
| +/**
|
| + * Returns the DOM node for the thread.
|
| + *
|
| + * public:
|
| + * @return {Object} The current thread node.
|
| + */
|
| +GmailThread.prototype.getNode = function() {
|
| + return this.node_;
|
| +};
|
| +
|
| +/**
|
| + * Returns whether or not the thread is starred.
|
| + *
|
| + * public:
|
| + * @return {boolean} Whether or not the thread is starred.
|
| + */
|
| +GmailThread.prototype.isStarred = function() {
|
| + return this.starred_;
|
| +};
|
| +
|
| +/**
|
| + * Returns whether or not the thread is selected.
|
| + *
|
| + * public:
|
| + * @return {boolean} Whether or not the thread is selected.
|
| + */
|
| +GmailThread.prototype.isSelected = function() {
|
| + return this.selected_;
|
| +};
|
| +
|
| +/**
|
| + * Returns whether or not the thread is read.
|
| + *
|
| + * public:
|
| + * @return {boolean} Whether or not the thread is read.
|
| + */
|
| +GmailThread.prototype.isRead = function() {
|
| + return this.read_;
|
| +};
|
| +
|
| +/**
|
| + * Returns an array of labels for the thread.
|
| + *
|
| + * public:
|
| + * @return {Object} Array of labels for the thread.
|
| + */
|
| +GmailThread.prototype.getLabels = function() {
|
| + return new Array();
|
| +};
|
| +
|
| +/**
|
| + * Returns an array of authors for the thread.
|
| + *
|
| + * public:
|
| + * @return {Object} Array of authors for the thread.
|
| + */
|
| +GmailThread.prototype.getAuthors = function() {
|
| + return new Array();
|
| +};
|
| +
|
| +/**
|
| + * Returns the subject of the thread.
|
| + *
|
| + * public:
|
| + * @return {string} The thread subject.
|
| + */
|
| +GmailThread.prototype.getSubject = function() {
|
| + return '';
|
| +};
|
| +
|
| +/**
|
| + * Returns the snippet for the thread.
|
| + *
|
| + * public:
|
| + * @return {string} The snippet for the thread.
|
| + */
|
| +GmailThread.prototype.getSnippet = function() {
|
| + return '';
|
| +};
|
| +
|
| +/**
|
| + * Returns the date/time string for the thread.
|
| + *
|
| + * public:
|
| + * @return {string} The date/time for the thread.
|
| + */
|
| +GmailThread.prototype.getDateTime = function() {
|
| + return '';
|
| +};
|
| +
|
| +/**
|
| + * GMail message object that holds the DOM node of the message + status
|
| + * information for that message.
|
| + *
|
| + * public:
|
| + * @constructor
|
| + * @param {Element} node The node that contains the GmailMessage.
|
| + * @param {boolean} starred Whether or not the GmailMessage is starred.
|
| + */
|
| +var GmailMessage = function(node, starred) {
|
| + this.node_ = node;
|
| + this.starred_ = starred;
|
| +};
|
| +
|
| +/**
|
| + * Returns the DOM node for the message.
|
| + *
|
| + * public:
|
| + * @return {Object} The current message node.
|
| + */
|
| +GmailMessage.prototype.getNode = function() {
|
| + return this.node_;
|
| +};
|
| +
|
| +/**
|
| + * Returns whether or not the message is starred.
|
| + *
|
| + * public:
|
| + * @return {boolean} Whether or not the message is starred.
|
| + */
|
| +GmailMessage.prototype.isStarred = function() {
|
| + return this.starred_;
|
| +};
|
| +
|
| +/**
|
| + * Returns whether or not the message is read.
|
| + *
|
| + * public:
|
| + * @return {boolean} Whether or not the message is read.
|
| + */
|
| +GmailMessage.prototype.isRead = function() {
|
| + return this.read_;
|
| +};
|
| +
|
| +/**
|
| + * Returns the author for the message.
|
| + *
|
| + * public:
|
| + * @return {string} The author of the message.
|
| + */
|
| +GmailMessage.prototype.getAuthor = function() {
|
| + return '';
|
| +};
|
| +
|
| +/**
|
| + * Returns the subject of the message.
|
| + *
|
| + * public:
|
| + * @return {string} The message subject.
|
| + */
|
| +GmailMessage.prototype.getSubject = function() {
|
| + return '';
|
| +};
|
| +
|
| +/**
|
| + * Returns the content for the message.
|
| + *
|
| + * public:
|
| + * @return {string} The content for the message.
|
| + */
|
| +GmailMessage.prototype.getContent = function() {
|
| + return '';
|
| +};
|
| +
|
| +/**
|
| + * Returns the date/time string for the message.
|
| + *
|
| + * public:
|
| + * @return {string} The date/time for the message.
|
| + */
|
| +GmailMessage.prototype.getDateTime = function() {
|
| + return '';
|
| +};
|
| +
|
| +/**
|
| + * Returns the message's GmailThread object.
|
| + *
|
| + * public:
|
| + * @return {GmailThread?} The GmailThread object.
|
| + */
|
| +GmailMessage.prototype.getThread = function() {
|
| + return null;
|
| +};
|
| +
|
| +/**
|
| + * GMail search completion object that holds the DOM node of the
|
| + * search completion.
|
| + *
|
| + * public:
|
| + * @constructor
|
| + * @param {Element} node The node that contains the GmailSearchCompletion.
|
| + */
|
| +var GmailSearchCompletion = function(node) {
|
| + this.node_ = node;
|
| +};
|
| +
|
| +/**
|
| + * Returns the DOM node for the search completion.
|
| + *
|
| + * public:
|
| + * @return {Object} The current search completion node.
|
| + */
|
| +GmailSearchCompletion.prototype.getNode = function() {
|
| + return this.node_;
|
| +};
|
| +
|
| +window.setTimeout(GmailApi.init_, 100);
|
|
|
| Property changes on: chrome/browser/resources/access_chromevox/scripts/gmail_api.js
|
| ___________________________________________________________________
|
| Added: svn:executable
|
| + *
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|