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

Unified Diff: chrome/browser/resources/access_chromevox/scripts/booksReader_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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/access_chromevox/scripts/booksReader_api.js
===================================================================
--- chrome/browser/resources/access_chromevox/scripts/booksReader_api.js (revision 0)
+++ chrome/browser/resources/access_chromevox/scripts/booksReader_api.js (revision 0)
@@ -0,0 +1,344 @@
+// 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.BooksReaderApi');
+
+goog.require('cvox.ChromeVox');
+
+/**
+ * @fileoverview API for accessing content and getting events from the Google
+ * Books Reader. The API exposes an event driven API for accessibility.
+ * Having this API keeps the accessibility scripts from being dependent on
+ * the inner workings of the Google Books Reader.
+ */
+BooksReaderApi = { };
+
+/**
+ * Collection of classnames. Used to check on the status of threads and
+ * messages.
+ * @private
+ * @type {Object.<String, String>}
+ */
+BooksReaderApi.CLASSES_ = {
+ PAGE_CONTENT_WRAPPER: 'gb-content',
+ PAGE_CONTENT: 'gb-two-page gb-content-justify',
+ PAGE_NUMBER: 'gb-pagecontrol-input',
+ DIALOG_CLOSE: 'SPRITE_dialog_close_box',
+ INDEX_ITEM: 'gb-result',
+ INDEX_ITEM_SELECTED: 'gb-result-hover',
+ INDEX_ITEM_TEXT: 'gb-result-snippet',
+ INDEX_ITEM_PAGE_NUMBER: 'gb-result-page',
+ TABLE_OF_CONTENTS_BUTTON: 'SPRITE_icon_toc',
+ TABLE_OF_CONTENTS_BUTTON_SELECTED: 'SPRITE_icon_toc_over',
+ SEARCH_BUTTON: 'SPRITE_icon_search',
+ SEARCH_BUTTON_SELECTED: 'SPRITE_icon_search_over',
+ SEARCH_FIELD: 'gb-search-input'
+};
+
+/**
+ * Callback listener to invoke when an event happens.
+ * @private
+ * @type {Function}
+ */
+BooksReaderApi.listener_ = null;
+
+/**
+ * Initializes the Books API script
+ * @private
+ */
+BooksReaderApi.init_ = function() {
+ window.addEventListener('DOMSubtreeModified',
+ BooksReaderApi.domSubtreeModified, true);
+ window.addEventListener('keydown',
+ BooksReaderApi.keyDownHandler, true);
+};
+
+/**
+ * Sets the BooksListener object to be used for callbacks.
+ *
+ * public:
+ * @param {function} booksListener The BooksListener to be used.
+ */
+BooksReaderApi.setBooksEventListener = function(booksListener) {
+ BooksReaderApi.listener_ = booksListener;
+};
+
+/**
+ * Handles the DOM Subtree Modified event. This event is fired when the user
+ * does some action (such as turning the page).
+ *
+ * @param {Object} evt The DOMSubtreeModified event used to determine when
+ * there is a user action that we should respond to.
+ */
+BooksReaderApi.domSubtreeModified = function(evt) {
+ var target = evt.target;
+ if (target.className &&
+ (target.className == BooksReaderApi.CLASSES_.PAGE_CONTENT_WRAPPER)) {
+ var pageContentNode = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.PAGE_CONTENT)[0];
+ var pageNumber = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.PAGE_NUMBER)[0].value;
+ var currentPage = new Page(pageContentNode, pageNumber);
+ BooksReaderApi.listener_.onPageTurned(currentPage);
+ if (document.activeElement && (document.activeElement.tagName == 'INPUT')) {
+ document.activeElement.blur();
+ }
+ }
+ if (target.className && (target.className.indexOf(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED) != -1)) {
+ var itemIndexNumber = target.getElementsByClassName(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_PAGE_NUMBER)[0].textContent;
+ var text = target.getElementsByClassName(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_TEXT)[0].textContent;
+ var indexItem = new IndexItem(target, text, itemIndexNumber);
+ BooksReaderApi.listener_.onIndexItemSelected(indexItem);
+ }
+ var searchInputField = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.SEARCH_FIELD)[0];
+ if (searchInputField) {
+ searchInputField.focus();
+ }
+};
+
+
+
+/**
+ * Handles keydown events and adds a few more key commands to the reader for
+ * quickly navigating to the various parts of the app.
+ *
+ * @param {Object} evt The keydown event.
+ * @return {boolean} Whether or not the default action should be taken.
+ */
+BooksReaderApi.keyDownHandler = function(evt) {
+ var keyCode = evt.keyCode;
+ // Esc to dismiss any popups from table of contents/search
+ if (evt.keyCode == 27) {
+ var closeBox = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.DIALOG_CLOSE)[0];
+ cvox.DomUtil.clickElem(closeBox, false);
+ }
+ // Down arrow to move through the Contents/Search results lists
+ if (evt.keyCode == 40) {
+ var items = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.INDEX_ITEM);
+ var length = items.length;
+ if (length > 0) {
+ for (var i = 0; item = items[i]; i++) {
+ if (item.className.indexOf(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED) != -1) {
+ item.className = item.className.replace(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED, '');
+ if (i < length - 1) {
+ items[i + 1].className = items[i + 1].className + ' ' +
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED;
+ return false;
+ }
+ }
+ }
+ items[0].className = items[0].className + ' ' +
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED;
+ return false;
+ }
+ return true;
+ }
+ // Down arrow to move through the Contents/Search results lists
+ if (evt.keyCode == 38) {
+ var items = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.INDEX_ITEM);
+ var length = items.length;
+ if (length > 0) {
+ for (var i = length - 1; item = items[i]; i--) {
+ if (item.className.indexOf(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED) != -1) {
+ item.className = item.className.replace(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED, '');
+ if (i > 0) {
+ items[i - 1].className = items[i - 1].className + ' ' +
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED;
+ return false;
+ }
+ }
+ }
+ items[length - 1].className = items[length - 1].className + ' ' +
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED;
+ return false;
+ }
+ return true;
+ }
+ // Enter to click on a result
+ if (evt.keyCode == 13) {
+ var currentItem = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED)[0];
+ if (currentItem) {
+ cvox.DomUtil.clickElem(currentItem, false);
+ var closeBox = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.DIALOG_CLOSE)[0];
+ cvox.DomUtil.clickElem(closeBox, false);
+ evt.stopPropagation();
+ return false;
+ }
+ return true;
+ }
+ // All keystrokes after this point should not be acted on if the user is
+ // trying to type in a text field.
+ if (document.activeElement && (document.activeElement.tagName == 'INPUT')) {
+ return true;
+ }
+ // Numbers that are typed will go straight into the page number area
+ if ((evt.keyCode >= 48) && (evt.keyCode <= 57)) {
+ // Focus on the page input field.
+ var jumpToPageInputField = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.PAGE_NUMBER)[0];
+ jumpToPageInputField.focus();
+ jumpToPageInputField.select();
+ return false;
+ }
+ // c for Contents
+ if (evt.keyCode == 67) {
+ var contentsButton = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.TABLE_OF_CONTENTS_BUTTON)[0];
+ if (!contentsButton) {
+ contentsButton = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.TABLE_OF_CONTENTS_BUTTON_SELECTED)[0];
+ }
+ if (contentsButton) {
+ cvox.DomUtil.clickElem(contentsButton, false);
+ }
+ return false;
+ }
+ // Slash (/) for Search
+ if (evt.keyCode == 191) {
+ var searchButton = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.SEARCH_BUTTON)[0];
+ if (!searchButton) {
+ searchButton = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.SEARCH_BUTTON_SELECTED)[0];
+ }
+ if (searchButton) {
+ cvox.DomUtil.clickElem(searchButton, false);
+ }
+ var currentItem = document.getElementsByClassName(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED)[0];
+ if (currentItem) {
+ currentItem.className = currentItem.className.replace(
+ BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED, '');
+ }
+ return false;
+ }
+};
+
+/**
+ * Listener interface for receiving Books events.
+ *
+ * public:
+ * @constructor
+ */
+var BooksListener = function() {
+};
+
+/**
+ * Called when the user has turned the page.
+ *
+ * public:
+ * @param {Object} pageObject The Page object.
+ */
+BooksListener.prototype.onPageTurned = function(pageObject) {
+};
+
+/**
+ * Called when the user has moved to a new index item.
+ *
+ * public:
+ * @param {Object} indexItemObject The IndexItem object.
+ */
+BooksListener.prototype.onIndexItemSelected = function(indexItemObject) {
+};
+
+/**
+ * Page object that holds the DOM node of the page and additional
+ * information about that page (such as the page number).
+ *
+ * public:
+ * @constructor
+ * @param {Element} node The node that contains the Page contents.
+ * @param {String} number The page number as a string. The page number is a
+ * string rather than an integer since the page numbers can sometimes be
+ * Roman numberals (for example, the numbering in the table of contents).
+ */
+var Page = function(node, number) {
+ this.node_ = node;
+ this.number_ = number;
+};
+
+/**
+ * Returns the DOM node for the page.
+ *
+ * public:
+ * @return {Element} The page node.
+ */
+Page.prototype.getNode = function() {
+ return this.node_;
+};
+
+/**
+ * Returns the page number as a string.
+ *
+ * public:
+ * @return {String} The page number as a string.
+ */
+Page.prototype.getPageNumber = function() {
+ return this.number_;
+};
+
+/**
+ * An index item is an item such as the table of contents entry,
+ * search result, etc. which consists of some text along with a page number.
+ * IndexItem object that holds the DOM node of the index item, the text
+ * of that item, and the page that the index is pointing at.
+ *
+ * public:
+ * @constructor
+ * @param {Element} node The node that contains the IndexItem contents.
+ * @param {String} text The text.
+ * @param {String} number The page number as a string. The page number is a
+ * string rather than an integer since the page numbers can sometimes be
+ * Roman numberals (for example, the numbering in the table of contents).
+ */
+var IndexItem = function(node, text, number) {
+ this.node_ = node;
+ this.text_ = text;
+ this.number_ = number;
+};
+
+/**
+ * Returns the DOM node for the IndexItem.
+ *
+ * public:
+ * @return {Element} The IndexItem node.
+ */
+IndexItem.prototype.getNode = function() {
+ return this.node_;
+};
+
+/**
+ * Returns the text for the IndexItem.
+ *
+ * public:
+ * @return {String} The text for the IndexItem.
+ */
+IndexItem.prototype.getText = function() {
+ return this.text_;
+};
+
+/**
+ * Returns the page number as a string.
+ *
+ * public:
+ * @return {String} The page number as a string.
+ */
+IndexItem.prototype.getPageNumber = function() {
+ return this.number_;
+};
+
+window.setTimeout(BooksReaderApi.init_, 100);
Property changes on: chrome/browser/resources/access_chromevox/scripts/booksReader_api.js
___________________________________________________________________
Added: svn:executable
+ *
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698