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

Side by Side 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 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.BooksReaderApi');
6
7 goog.require('cvox.ChromeVox');
8
9 /**
10 * @fileoverview API for accessing content and getting events from the Google
11 * Books Reader. The API exposes an event driven API for accessibility.
12 * Having this API keeps the accessibility scripts from being dependent on
13 * the inner workings of the Google Books Reader.
14 */
15 BooksReaderApi = { };
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 BooksReaderApi.CLASSES_ = {
24 PAGE_CONTENT_WRAPPER: 'gb-content',
25 PAGE_CONTENT: 'gb-two-page gb-content-justify',
26 PAGE_NUMBER: 'gb-pagecontrol-input',
27 DIALOG_CLOSE: 'SPRITE_dialog_close_box',
28 INDEX_ITEM: 'gb-result',
29 INDEX_ITEM_SELECTED: 'gb-result-hover',
30 INDEX_ITEM_TEXT: 'gb-result-snippet',
31 INDEX_ITEM_PAGE_NUMBER: 'gb-result-page',
32 TABLE_OF_CONTENTS_BUTTON: 'SPRITE_icon_toc',
33 TABLE_OF_CONTENTS_BUTTON_SELECTED: 'SPRITE_icon_toc_over',
34 SEARCH_BUTTON: 'SPRITE_icon_search',
35 SEARCH_BUTTON_SELECTED: 'SPRITE_icon_search_over',
36 SEARCH_FIELD: 'gb-search-input'
37 };
38
39 /**
40 * Callback listener to invoke when an event happens.
41 * @private
42 * @type {Function}
43 */
44 BooksReaderApi.listener_ = null;
45
46 /**
47 * Initializes the Books API script
48 * @private
49 */
50 BooksReaderApi.init_ = function() {
51 window.addEventListener('DOMSubtreeModified',
52 BooksReaderApi.domSubtreeModified, true);
53 window.addEventListener('keydown',
54 BooksReaderApi.keyDownHandler, true);
55 };
56
57 /**
58 * Sets the BooksListener object to be used for callbacks.
59 *
60 * public:
61 * @param {function} booksListener The BooksListener to be used.
62 */
63 BooksReaderApi.setBooksEventListener = function(booksListener) {
64 BooksReaderApi.listener_ = booksListener;
65 };
66
67 /**
68 * Handles the DOM Subtree Modified event. This event is fired when the user
69 * does some action (such as turning the page).
70 *
71 * @param {Object} evt The DOMSubtreeModified event used to determine when
72 * there is a user action that we should respond to.
73 */
74 BooksReaderApi.domSubtreeModified = function(evt) {
75 var target = evt.target;
76 if (target.className &&
77 (target.className == BooksReaderApi.CLASSES_.PAGE_CONTENT_WRAPPER)) {
78 var pageContentNode = document.getElementsByClassName(
79 BooksReaderApi.CLASSES_.PAGE_CONTENT)[0];
80 var pageNumber = document.getElementsByClassName(
81 BooksReaderApi.CLASSES_.PAGE_NUMBER)[0].value;
82 var currentPage = new Page(pageContentNode, pageNumber);
83 BooksReaderApi.listener_.onPageTurned(currentPage);
84 if (document.activeElement && (document.activeElement.tagName == 'INPUT')) {
85 document.activeElement.blur();
86 }
87 }
88 if (target.className && (target.className.indexOf(
89 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED) != -1)) {
90 var itemIndexNumber = target.getElementsByClassName(
91 BooksReaderApi.CLASSES_.INDEX_ITEM_PAGE_NUMBER)[0].textContent;
92 var text = target.getElementsByClassName(
93 BooksReaderApi.CLASSES_.INDEX_ITEM_TEXT)[0].textContent;
94 var indexItem = new IndexItem(target, text, itemIndexNumber);
95 BooksReaderApi.listener_.onIndexItemSelected(indexItem);
96 }
97 var searchInputField = document.getElementsByClassName(
98 BooksReaderApi.CLASSES_.SEARCH_FIELD)[0];
99 if (searchInputField) {
100 searchInputField.focus();
101 }
102 };
103
104
105
106 /**
107 * Handles keydown events and adds a few more key commands to the reader for
108 * quickly navigating to the various parts of the app.
109 *
110 * @param {Object} evt The keydown event.
111 * @return {boolean} Whether or not the default action should be taken.
112 */
113 BooksReaderApi.keyDownHandler = function(evt) {
114 var keyCode = evt.keyCode;
115 // Esc to dismiss any popups from table of contents/search
116 if (evt.keyCode == 27) {
117 var closeBox = document.getElementsByClassName(
118 BooksReaderApi.CLASSES_.DIALOG_CLOSE)[0];
119 cvox.DomUtil.clickElem(closeBox, false);
120 }
121 // Down arrow to move through the Contents/Search results lists
122 if (evt.keyCode == 40) {
123 var items = document.getElementsByClassName(
124 BooksReaderApi.CLASSES_.INDEX_ITEM);
125 var length = items.length;
126 if (length > 0) {
127 for (var i = 0; item = items[i]; i++) {
128 if (item.className.indexOf(
129 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED) != -1) {
130 item.className = item.className.replace(
131 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED, '');
132 if (i < length - 1) {
133 items[i + 1].className = items[i + 1].className + ' ' +
134 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED;
135 return false;
136 }
137 }
138 }
139 items[0].className = items[0].className + ' ' +
140 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED;
141 return false;
142 }
143 return true;
144 }
145 // Down arrow to move through the Contents/Search results lists
146 if (evt.keyCode == 38) {
147 var items = document.getElementsByClassName(
148 BooksReaderApi.CLASSES_.INDEX_ITEM);
149 var length = items.length;
150 if (length > 0) {
151 for (var i = length - 1; item = items[i]; i--) {
152 if (item.className.indexOf(
153 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED) != -1) {
154 item.className = item.className.replace(
155 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED, '');
156 if (i > 0) {
157 items[i - 1].className = items[i - 1].className + ' ' +
158 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED;
159 return false;
160 }
161 }
162 }
163 items[length - 1].className = items[length - 1].className + ' ' +
164 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED;
165 return false;
166 }
167 return true;
168 }
169 // Enter to click on a result
170 if (evt.keyCode == 13) {
171 var currentItem = document.getElementsByClassName(
172 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED)[0];
173 if (currentItem) {
174 cvox.DomUtil.clickElem(currentItem, false);
175 var closeBox = document.getElementsByClassName(
176 BooksReaderApi.CLASSES_.DIALOG_CLOSE)[0];
177 cvox.DomUtil.clickElem(closeBox, false);
178 evt.stopPropagation();
179 return false;
180 }
181 return true;
182 }
183 // All keystrokes after this point should not be acted on if the user is
184 // trying to type in a text field.
185 if (document.activeElement && (document.activeElement.tagName == 'INPUT')) {
186 return true;
187 }
188 // Numbers that are typed will go straight into the page number area
189 if ((evt.keyCode >= 48) && (evt.keyCode <= 57)) {
190 // Focus on the page input field.
191 var jumpToPageInputField = document.getElementsByClassName(
192 BooksReaderApi.CLASSES_.PAGE_NUMBER)[0];
193 jumpToPageInputField.focus();
194 jumpToPageInputField.select();
195 return false;
196 }
197 // c for Contents
198 if (evt.keyCode == 67) {
199 var contentsButton = document.getElementsByClassName(
200 BooksReaderApi.CLASSES_.TABLE_OF_CONTENTS_BUTTON)[0];
201 if (!contentsButton) {
202 contentsButton = document.getElementsByClassName(
203 BooksReaderApi.CLASSES_.TABLE_OF_CONTENTS_BUTTON_SELECTED)[0];
204 }
205 if (contentsButton) {
206 cvox.DomUtil.clickElem(contentsButton, false);
207 }
208 return false;
209 }
210 // Slash (/) for Search
211 if (evt.keyCode == 191) {
212 var searchButton = document.getElementsByClassName(
213 BooksReaderApi.CLASSES_.SEARCH_BUTTON)[0];
214 if (!searchButton) {
215 searchButton = document.getElementsByClassName(
216 BooksReaderApi.CLASSES_.SEARCH_BUTTON_SELECTED)[0];
217 }
218 if (searchButton) {
219 cvox.DomUtil.clickElem(searchButton, false);
220 }
221 var currentItem = document.getElementsByClassName(
222 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED)[0];
223 if (currentItem) {
224 currentItem.className = currentItem.className.replace(
225 BooksReaderApi.CLASSES_.INDEX_ITEM_SELECTED, '');
226 }
227 return false;
228 }
229 };
230
231 /**
232 * Listener interface for receiving Books events.
233 *
234 * public:
235 * @constructor
236 */
237 var BooksListener = function() {
238 };
239
240 /**
241 * Called when the user has turned the page.
242 *
243 * public:
244 * @param {Object} pageObject The Page object.
245 */
246 BooksListener.prototype.onPageTurned = function(pageObject) {
247 };
248
249 /**
250 * Called when the user has moved to a new index item.
251 *
252 * public:
253 * @param {Object} indexItemObject The IndexItem object.
254 */
255 BooksListener.prototype.onIndexItemSelected = function(indexItemObject) {
256 };
257
258 /**
259 * Page object that holds the DOM node of the page and additional
260 * information about that page (such as the page number).
261 *
262 * public:
263 * @constructor
264 * @param {Element} node The node that contains the Page contents.
265 * @param {String} number The page number as a string. The page number is a
266 * string rather than an integer since the page numbers can sometimes be
267 * Roman numberals (for example, the numbering in the table of contents).
268 */
269 var Page = function(node, number) {
270 this.node_ = node;
271 this.number_ = number;
272 };
273
274 /**
275 * Returns the DOM node for the page.
276 *
277 * public:
278 * @return {Element} The page node.
279 */
280 Page.prototype.getNode = function() {
281 return this.node_;
282 };
283
284 /**
285 * Returns the page number as a string.
286 *
287 * public:
288 * @return {String} The page number as a string.
289 */
290 Page.prototype.getPageNumber = function() {
291 return this.number_;
292 };
293
294 /**
295 * An index item is an item such as the table of contents entry,
296 * search result, etc. which consists of some text along with a page number.
297 * IndexItem object that holds the DOM node of the index item, the text
298 * of that item, and the page that the index is pointing at.
299 *
300 * public:
301 * @constructor
302 * @param {Element} node The node that contains the IndexItem contents.
303 * @param {String} text The text.
304 * @param {String} number The page number as a string. The page number is a
305 * string rather than an integer since the page numbers can sometimes be
306 * Roman numberals (for example, the numbering in the table of contents).
307 */
308 var IndexItem = function(node, text, number) {
309 this.node_ = node;
310 this.text_ = text;
311 this.number_ = number;
312 };
313
314 /**
315 * Returns the DOM node for the IndexItem.
316 *
317 * public:
318 * @return {Element} The IndexItem node.
319 */
320 IndexItem.prototype.getNode = function() {
321 return this.node_;
322 };
323
324 /**
325 * Returns the text for the IndexItem.
326 *
327 * public:
328 * @return {String} The text for the IndexItem.
329 */
330 IndexItem.prototype.getText = function() {
331 return this.text_;
332 };
333
334 /**
335 * Returns the page number as a string.
336 *
337 * public:
338 * @return {String} The page number as a string.
339 */
340 IndexItem.prototype.getPageNumber = function() {
341 return this.number_;
342 };
343
344 window.setTimeout(BooksReaderApi.init_, 100);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698