| 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
|
|
|
|
|