command_store.js revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2014 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
6/**
7 * @fileoverview This class acts as the persistent store for all static data
8 * about commands.
9 *
10 * This store can safely be used within either a content or background script
11 * context.
12 *
13 * If you are looking to add a user command, follow the below steps for best
14 * integration with existing components:
15 * 1. Add a command below in cvox.CommandStore.CMD_WHITELIST. Pick a
16 * programmatic name and fill in each of the relevant JSON keys.
17 * Be sure to add a msg id and define it in chromevox/messages/messages.js which
18 * describes the command. Please also add a category msg id so that the command
19 * will show up in the options page.
20 * 2. Add the command's logic to cvox.UserCommands inside of our switch-based
21 * dispatch method (doCommand_).
22 * 3. Add a key binding in chromevox/background/keymaps/classic_keymap.json and
23 * chromevox/background/keymaps/flat_keymap.json.
24 *
25 * Class description:
26 * This class is entirely static and holds a JSON structure that stores
27 * commands and their associated metadata.
28 *
29 * From this metadata, we compute relevant subsets of data such as all present
30 * categories.
31 */
32
33
34goog.provide('cvox.CommandStore');
35
36goog.require('cvox.PlatformFilter');
37
38
39/**
40 * Returns all of the categories in the store as an array.
41 * @return {Array.<string>} The collection of categories.
42 */
43cvox.CommandStore.categories = function() {
44  var categorySet = {};
45  for (var cmd in cvox.CommandStore.CMD_WHITELIST) {
46    var struct = cvox.CommandStore.CMD_WHITELIST[cmd];
47    if (struct.category) {
48      categorySet[struct.category] = true;
49    }
50  }
51  var ret = [];
52  for (var category in categorySet) {
53    ret.push(category);
54  }
55  return ret;
56};
57
58
59/**
60 * Gets a message given a command.
61 * @param {string} command The command to query.
62 * @return {string|undefined} The message id, if any.
63 */
64cvox.CommandStore.messageForCommand = function(command) {
65  return (cvox.CommandStore.CMD_WHITELIST[command] || {}).msgId;
66};
67
68
69/**
70 * Gets a category given a command.
71 * @param {string} command The command to query.
72 * @return {string|undefined} The command, if any.
73 */
74cvox.CommandStore.categoryForCommand = function(command) {
75  return (cvox.CommandStore.CMD_WHITELIST[command] || {}).category;
76};
77
78
79/**
80 * Gets all commands for a category.
81 * @param {string} category The category to query.
82 * @return {Array.<string>} The commands, if any.
83 */
84cvox.CommandStore.commandsForCategory = function(category) {
85  var ret = [];
86  for (var cmd in cvox.CommandStore.CMD_WHITELIST) {
87    var struct = cvox.CommandStore.CMD_WHITELIST[cmd];
88    if (category == struct.category) {
89      ret.push(cmd);
90    }
91  }
92  return ret;
93};
94
95
96/**
97 * List of commands and their properties
98 * @type {Object.<string, {forward: (undefined|boolean),
99 *                         backward: (undefined|boolean),
100 *                         announce: boolean,
101 *                         category: (undefined|string),
102 *                         findNext: (undefined|string),
103 *                         doDefault: (undefined|boolean),
104 *                         msgId: (undefined|string),
105 *                         nodeList: (undefined|string),
106 *                         platformFilter: (undefined|cvox.PlatformFilter),
107 *                         skipInput: (undefined|boolean),
108 *                         allowEvents: (undefined|boolean),
109 *                         disallowContinuation: (undefined|boolean)
110 *                         }>}
111 *  forward: Whether this command points forward.
112 *  backward: Whether this command points backward. If neither forward or
113 *            backward are specified, it stays facing in the current direction.
114 *  announce: Whether to call finishNavCommand and announce the current
115 *            position after the command is done.
116 *  findNext: The id from the map above if this command is used for
117 *            finding next/previous of something.
118 *  category: The message resource describing the command's category.
119 *  doDefault: Whether to do the default action. This means that keys will be
120 *             passed through to the usual DOM capture/bubble phases.
121 *  msgId: The message resource describing the command.
122 *  nodeList: The id from the map above if this command is used for
123 *            showing a list of nodes.
124 *  platformFilter: Specifies to which platforms this command applies. If left
125 *                  undefined, the command applies to all platforms.
126 *  skipInput: Explicitly skips this command when text input has focus.
127 *             Defaults to false.
128 *  disallowOOBE: Explicitly disallows this command when on chrome://oobe/*.
129 *             Defaults to false.
130 *  allowEvents: Allows EventWatcher to continue processing events which can
131 * trump TTS.
132 *  disallowContinuation: Disallows continuous read to proceed. Defaults to
133 * false.
134 */
135cvox.CommandStore.CMD_WHITELIST = {
136  'toggleStickyMode': {announce: false,
137                       msgId: 'toggle_sticky_mode',
138                       'disallowOOBE': true,
139                       category: 'modifier_keys'},
140  'toggleKeyPrefix': {announce: false,
141                      skipInput: true,
142                      msgId: 'prefix_key',
143                         'disallowOOBE': true,
144                      category: 'modifier_keys'},
145  'passThroughMode': {announce: false,
146                      msgId: 'pass_through_key_description',
147                      category: 'modifier_keys'},
148
149  'stopSpeech': {announce: false,
150                 disallowContinuation: true,
151                 doDefault: true,
152                 msgId: 'stop_speech_key',
153                 category: 'controlling_speech'},
154  'toggleChromeVox': {announce: false,
155                      platformFilter: cvox.PlatformFilter.WML,
156                      msgId: 'toggle_chromevox_active',
157                      category: 'controlling_speech'},
158  'decreaseTtsRate': {announce: false,
159                      msgId: 'decrease_tts_rate',
160                      category: 'controlling_speech'},
161  'increaseTtsRate': {announce: false,
162                      msgId: 'increase_tts_rate',
163                      category: 'controlling_speech'},
164  'decreaseTtsPitch': {announce: false,
165                      msgId: 'decrease_tts_pitch',
166                      category: 'controlling_speech'},
167  'increaseTtsPitch': {announce: false,
168                      msgId: 'increase_tts_pitch',
169                      category: 'controlling_speech'},
170  'decreaseTtsVolume': {announce: false,
171                      msgId: 'decrease_tts_volume',
172                      category: 'controlling_speech'},
173  'increaseTtsVolume': {announce: false,
174                      msgId: 'increase_tts_volume',
175                      category: 'controlling_speech'},
176  'cyclePunctuationEcho': {announce: false,
177                           msgId: 'cycle_punctuation_echo',
178                           category: 'controlling_speech'},
179  'cycleTypingEcho': {announce: false,
180                      msgId: 'cycle_typing_echo',
181                      category: 'controlling_speech'},
182
183
184  'toggleEarcons': {announce: true,
185                    msgId: 'toggle_earcons',
186                    category: 'controlling_speech'},
187
188  'handleTab': {
189    allowEvents: true,
190    msgId: 'handle_tab_next',
191    disallowContinuation: true,
192    category: 'navigation'},
193  'handleTabPrev': {
194    allowEvents: true,
195    msgId: 'handle_tab_prev',
196    disallowContinuation: true,
197    category: 'navigation'},
198  'forward': {forward: true,
199              announce: true,
200              msgId: 'forward',
201              category: 'navigation'},
202  'backward': {backward: true,
203               announce: true,
204               msgId: 'backward',
205               category: 'navigation'},
206  'right': {forward: true,
207            announce: true,
208            msgId: 'right',
209            category: 'navigation'},
210  'left': {backward: true,
211           announce: true,
212           msgId: 'left',
213           category: 'navigation'},
214  'previousGranularity': {announce: true,
215                          msgId: 'previous_granularity',
216                          category: 'navigation'},
217  'nextGranularity': {announce: true,
218                          msgId: 'next_granularity',
219                          category: 'navigation'},
220
221  'previousCharacter': {backward: true,
222                        announce: true,
223                        msgId: 'previous_character',
224                        skipInput: true,
225                        category: 'navigation'},
226  'nextCharacter': {forward: true,
227                    announce: true,
228                    msgId: 'next_character',
229                    skipInput: true,
230                    category: 'navigation'},
231  'previousWord': {backward: true,
232                        announce: true,
233                        msgId: 'previous_word',
234                        skipInput: true,
235                        category: 'navigation'},
236  'nextWord': {forward: true,
237                    announce: true,
238                    msgId: 'next_word',
239                    skipInput: true,
240                    category: 'navigation'},
241  'previousLine': {backward: true,
242                        announce: true,
243                        msgId: 'previous_line',
244                        category: 'navigation'},
245  'nextLine': {forward: true,
246                    announce: true,
247                    msgId: 'next_line',
248                    category: 'navigation'},
249  'previousSentence': {backward: true,
250                        announce: true,
251                        msgId: 'previous_sentence',
252                        skipInput: true,
253                        category: 'navigation'},
254  'nextSentence': {forward: true,
255                    announce: true,
256                    msgId: 'next_sentence',
257                    skipInput: true,
258                    category: 'navigation'},
259  'previousObject': {backward: true,
260                        announce: true,
261                        msgId: 'previous_object',
262                        skipInput: true,
263                        category: 'navigation'},
264  'nextObject': {forward: true,
265                    announce: true,
266                    msgId: 'next_object',
267                    skipInput: true,
268                    category: 'navigation'},
269  'previousGroup': {backward: true,
270                        announce: true,
271                        msgId: 'previous_group',
272                        skipInput: true,
273                        category: 'navigation'},
274  'nextGroup': {forward: true,
275                    announce: true,
276                    msgId: 'next_group',
277                    skipInput: true,
278                    category: 'navigation'},
279
280  'jumpToTop': {forward: true,
281                announce: true,
282                msgId: 'jump_to_top',
283                category: 'navigation'
284},
285  'jumpToBottom': {backward: true,
286                   announce: true,
287                   msgId: 'jump_to_bottom',
288                   category: 'navigation'},
289  // Intentionally uncategorized.
290  'moveToStartOfLine': {forward: true, announce: true},
291  'moveToEndOfLine': {backward: true, announce: true},
292
293  'readFromHere': {forward: true,
294                   announce: false,
295                   msgId: 'read_from_here',
296                   category: 'navigation'},
297
298  'performDefaultAction': {disallowContinuation: true,
299                           msgId: 'perform_default_action',
300                           doDefault: true,
301                           skipInput: true,
302                           category: 'navigation'},
303  'forceClickOnCurrentItem': {announce: true,
304                              disallowContinuation: true,
305                              allowEvents: true,
306                              msgId: 'force_click_on_current_item',
307                              category: 'navigation'},
308  'forceDoubleClickOnCurrentItem': {announce: true,
309                                    allowEvents: true,
310                                    disallowContinuation: true},
311
312  'readLinkURL': {announce: false,
313                  msgId: 'read_link_url',
314                  category: 'information'},
315  'readCurrentTitle': {announce: false,
316                       msgId: 'read_current_title',
317                       category: 'information'},
318  'readCurrentURL': {announce: false,
319                     msgId: 'read_current_url',
320                     category: 'information'},
321
322  'fullyDescribe': {announce: false,
323                    msgId: 'fully_describe',
324                    category: 'information'},
325  'speakTimeAndDate': {announce: false,
326                       msgId: 'speak_time_and_date',
327                       category: 'information'},
328  'toggleSelection': {announce: true,
329                      msgId: 'toggle_selection',
330                      category: 'information'},
331
332  'toggleSearchWidget': {announce: false,
333                         disallowContinuation: true,
334                         msgId: 'toggle_search_widget',
335                         category: 'information'},
336
337  'toggleKeyboardHelp': {announce: false,
338                         disallowContinuation: true,
339                         msgId: 'show_power_key',
340                         category: 'help_commands'},
341  'help': {announce: false,
342           msgId: 'help',
343           'disallowOOBE': true,
344           disallowContinuation: true,
345           category: 'help_commands'},
346  'contextMenu': {announce: false,
347                  disallowContinuation: true},
348
349  'showOptionsPage': {announce: false,
350                      disallowContinuation: true,
351                      msgId: 'show_options_page',
352                      'disallowOOBE': true,
353                      category: 'help_commands'},
354  'showKbExplorerPage': {announce: false,
355                         disallowContinuation: true,
356                         msgId: 'show_kb_explorer_page',
357                         'disallowOOBE': true,
358                         category: 'help_commands'},
359
360
361  'showFormsList': {announce: false,
362                    disallowContinuation: true,
363                    nodeList: 'formField',
364                    msgId: 'show_forms_list',
365                    category: 'overview'},
366  'showHeadingsList': {announce: false, nodeList: 'heading',
367                       disallowContinuation: true,
368                       msgId: 'show_headings_list',
369                       category: 'overview'},
370  'showLandmarksList': {announce: false, nodeList: 'landmark',
371                        disallowContinuation: true,
372                        msgId: 'show_landmarks_list',
373                        category: 'overview'},
374  'showLinksList': {announce: false, nodeList: 'link',
375                    disallowContinuation: true,
376                    msgId: 'show_links_list',
377                    category: 'overview'},
378  'showTablesList': {announce: false, nodeList: 'table',
379                     disallowContinuation: true,
380                     msgId: 'show_tables_list',
381                     category: 'overview'},
382
383  'nextArticle': {forward: true,
384                  findNext: 'article'},
385
386  'nextButton': {forward: true,
387                 findNext: 'button',
388                 msgId: 'next_button',
389                 category: 'jump_commands'},
390  'nextCheckbox': {forward: true,
391                   findNext: 'checkbox',
392                   msgId: 'next_checkbox',
393                   category: 'jump_commands'},
394  'nextComboBox': {forward: true,
395                   findNext: 'combobox',
396                   msgId: 'next_combo_box',
397                   category: 'jump_commands'},
398  'nextControl': {forward: true, findNext: 'control'},
399  'nextEditText': {forward: true,
400                   findNext: 'editText',
401                   msgId: 'next_edit_text',
402                   category: 'jump_commands'},
403  'nextFormField': {forward: true,
404                    findNext: 'formField',
405                    msgId: 'next_form_field',
406                    category: 'jump_commands'},
407  'nextGraphic': {forward: true,
408                  findNext: 'graphic',
409                  msgId: 'next_graphic',
410                  category: 'jump_commands'},
411  'nextHeading': {forward: true,
412                  findNext: 'heading',
413                  msgId: 'next_heading',
414                  category: 'jump_commands'},
415  'nextHeading1': {forward: true,
416                   findNext: 'heading1',
417                   msgId: 'next_heading1',
418                   category: 'jump_commands'},
419  'nextHeading2': {forward: true,
420                   findNext: 'heading2',
421                   msgId: 'next_heading2',
422                   category: 'jump_commands'},
423  'nextHeading3': {forward: true,
424                   findNext: 'heading3',
425                   msgId: 'next_heading3',
426                   category: 'jump_commands'},
427  'nextHeading4': {forward: true,
428                   findNext: 'heading4',
429                   msgId: 'next_heading4',
430                   category: 'jump_commands'},
431  'nextHeading5': {forward: true,
432                   findNext: 'heading5',
433                   msgId: 'next_heading5',
434                   category: 'jump_commands'},
435  'nextHeading6': {forward: true,
436                   findNext: 'heading6',
437                   msgId: 'next_heading6',
438                   category: 'jump_commands'},
439
440  'nextLandmark': {forward: true,
441                   findNext: 'landmark',
442                   msgId: 'next_landmark',
443                   category: 'jump_commands'},
444  'nextLink': {forward: true,
445               findNext: 'link',
446               msgId: 'next_link',
447               category: 'jump_commands'},
448  'nextList': {forward: true,
449               findNext: 'list',
450               msgId: 'next_list',
451               category: 'jump_commands'},
452  'nextListItem': {forward: true,
453                   findNext: 'listItem',
454                   msgId: 'next_list_item',
455                   category: 'jump_commands'},
456  'nextMath': {forward: true,
457               findNext: 'math',
458               msgId: 'next_math',
459               category: 'jump_commands'},
460  'nextMedia': {forward: true,
461                findNext: 'media',
462                msgId: 'next_media',
463                category: 'jump_commands'},
464  'nextRadio': {forward: true,
465                findNext: 'radio',
466                msgId: 'next_radio',
467                category: 'jump_commands'},
468  'nextSection': {forward: true, findNext: 'section'},
469  'nextSlider': {forward: true, findNext: 'slider'},
470  'nextTable': {forward: true,
471                findNext: 'table',
472                msgId: 'next_table',
473                category: 'jump_commands'},
474  'nextVisitedLink': {forward: true,
475                findNext: 'visitedLink',
476                msgId: 'next_visited_link',
477                category: 'jump_commands'},
478
479
480  'previousArticle': {backward: true,
481                  findNext: 'article'},
482
483  'previousButton': {backward: true,
484                 findNext: 'button',
485                 msgId: 'previous_button',
486                 category: 'jump_commands'},
487  'previousCheckbox': {backward: true,
488                   findNext: 'checkbox',
489                   msgId: 'previous_checkbox',
490                   category: 'jump_commands'},
491  'previousComboBox': {backward: true,
492                   findNext: 'combobox',
493                   msgId: 'previous_combo_box',
494                   category: 'jump_commands'},
495  'previousControl': {backward: true, findNext: 'control'},
496  'previousEditText': {backward: true,
497                   findNext: 'editText',
498                   msgId: 'previous_edit_text',
499                   category: 'jump_commands'},
500  'previousFormField': {backward: true,
501                    findNext: 'formField',
502                    msgId: 'previous_form_field',
503                    category: 'jump_commands'},
504  'previousGraphic': {backward: true,
505                  findNext: 'graphic',
506                  msgId: 'previous_graphic',
507                  category: 'jump_commands'},
508  'previousHeading': {backward: true,
509                  findNext: 'heading',
510                  msgId: 'previous_heading',
511                  category: 'jump_commands'},
512  'previousHeading1': {backward: true,
513                   findNext: 'heading1',
514                   msgId: 'previous_heading1',
515                   category: 'jump_commands'},
516  'previousHeading2': {backward: true,
517                   findNext: 'heading2',
518                   msgId: 'previous_heading2',
519                   category: 'jump_commands'},
520  'previousHeading3': {backward: true,
521                   findNext: 'heading3',
522                   msgId: 'previous_heading3',
523                   category: 'jump_commands'},
524  'previousHeading4': {backward: true,
525                   findNext: 'heading4',
526                   msgId: 'previous_heading4',
527                   category: 'jump_commands'},
528  'previousHeading5': {backward: true,
529                   findNext: 'heading5',
530                   msgId: 'previous_heading5',
531                   category: 'jump_commands'},
532  'previousHeading6': {backward: true,
533                   findNext: 'heading6',
534                   msgId: 'previous_heading6',
535                   category: 'jump_commands'},
536
537  'previousLandmark': {backward: true,
538                   findNext: 'landmark',
539                   msgId: 'previous_landmark',
540                   category: 'jump_commands'},
541  'previousLink': {backward: true,
542                   findNext: 'link',
543                   msgId: 'previous_link',
544                   category: 'jump_commands'},
545  'previousList': {backward: true,
546               findNext: 'list',
547               msgId: 'previous_list',
548               category: 'jump_commands'},
549  'previousListItem': {backward: true,
550                   findNext: 'listItem',
551                   msgId: 'previous_list_item',
552                   category: 'jump_commands'},
553  'previousMath': {backward: true,
554                   findNext: 'math',
555                   msgId: 'previous_math',
556                   category: 'jump_commands'},
557  'previousMedia': {backward: true,
558                    findNext: 'media',
559                    msgId: 'previous_media',
560                    category: 'jump_commands'},
561  'previousRadio': {backward: true,
562                findNext: 'radio',
563                msgId: 'previous_radio',
564                category: 'jump_commands'},
565  'previousSection': {backward: true, findNext: 'section'},
566  'previousSlider': {backward: true, findNext: 'slider'},
567  'previousTable': {backward: true,
568                findNext: 'table',
569                msgId: 'previous_table',
570                category: 'jump_commands'},
571  'previousVisitedLink': {backward: true,
572                          findNext: 'visitedLink',
573                          msgId: 'previous_visited_link',
574                          category: 'jump_commands'},
575
576
577  // Table Actions.
578  'announceHeaders': {announce: false,
579                      msgId: 'announce_headers',
580                      category: 'tables'},
581  'speakTableLocation': {announce: false,
582                         msgId: 'speak_table_location',
583                         category: 'tables'},
584  'goToFirstCell': {announce: true,
585                    msgId: 'skip_to_beginning',
586                    category: 'tables'},
587  'goToLastCell': {announce: true,
588                   msgId: 'skip_to_end',
589                   category: 'tables'},
590  'goToRowFirstCell': {announce: true,
591                       msgId: 'skip_to_row_beginning',
592                       category: 'tables'},
593  'goToRowLastCell': {announce: true,
594                      msgId: 'skip_to_row_end',
595                      category: 'tables'},
596  'goToColFirstCell': {announce: true,
597                       msgId: 'skip_to_col_beginning',
598                       category: 'tables'},
599  'goToColLastCell': {announce: true,
600                      msgId: 'skip_to_col_end',
601                      category: 'tables'},
602  // These commands are left out of the options page because they involve
603  // multiple, non-user configurable modifiers.
604  'previousRow': {backward: true, announce: true, skipInput: true},
605  'previousCol': {backward: true, announce: true, skipInput: true},
606  'nextRow': {forward: true, announce: true, skipInput: true},
607  'nextCol': {forward: true, announce: true, skipInput: true},
608
609  // Generic Actions.
610  'enterShifter': {announce: true,
611                   msgId: 'enter_content',
612                   category: 'navigation'},
613  'exitShifter': {announce: true,
614                  msgId: 'exit_content',
615                  category: 'navigation'},
616  'exitShifterContent': {announce: true},
617
618  'openLongDesc': {announce: false,
619                   msgId: 'open_long_desc',
620                   category: 'information'},
621
622  'pauseAllMedia': {announce: false,
623                    msgId: 'pause_all_media',
624                    category: 'information'},
625
626  // Math specific commands.
627  'toggleSemantics': {announce: false,
628                      msgId: 'toggle_semantics',
629                      category: 'information'},
630
631  // Braille specific commands.
632  'routing': {announce: false,
633              allowEvents: true,
634              msgId: 'braille_routing',
635              category: 'braille'},
636  'pan_left': {backward: true,
637               announce: true,
638               msgId: 'braille_pan_left',
639               category: 'braille'},
640  'pan_right': {forward: true,
641                announce: true,
642                msgId: 'braille_pan_right',
643                category: 'braille'},
644  'line_up': {backward: true,
645              announce: true,
646              msgId: 'braille_line_up',
647              category: 'braille'},
648  'line_down': {forward: true,
649                announce: true,
650                msgId: 'braille_line_down',
651                category: 'braille'},
652  'top': {forward: true,
653                announce: true,
654                msgId: 'braille_top',
655                category: 'braille'},
656  'bottom': {backward: true,
657                announce: true,
658                msgId: 'braille_bottom',
659                category: 'braille'},
660
661  // Developer commands.
662  'enableConsoleTts': {announce: false,
663                      msgId: 'enable_tts_log',
664                      category: 'developer'},
665  'toggleBrailleCaptions': {announce: false,
666                            msgId: 'braille_captions',
667                            category: 'developer'},
668
669  'startHistoryRecording': {announce: false},
670  'stopHistoryRecording': {announce: false},
671  'autorunner': {announce: false},
672
673  'debug': {announce: false},
674
675  'nop': {announce: false}
676};
677
678
679/**
680 * List of find next commands and their associated data.
681 * @type {Object.<string, {predicate: string,
682 *                         forwardError: string,
683 *                         backwardError: string}>}
684 *  predicate: The name of the predicate. This must be defined in DomPredicates.
685 *  forwardError: The message id of the error string when moving forward.
686 *  backwardError: The message id of the error string when moving backward.
687 */
688cvox.CommandStore.NODE_INFO_MAP = {
689  'checkbox': {predicate: 'checkboxPredicate',
690               forwardError: 'no_next_checkbox',
691               backwardError: 'no_previous_checkbox',
692               typeMsg: 'aria_role_checkbox'},
693  'radio': {predicate: 'radioPredicate',
694            forwardError: 'no_next_radio_button',
695            backwardError: 'no_previous_radio_button',
696            typeMsg: 'aria_role_radio'},
697  'slider': {predicate: 'sliderPredicate',
698             forwardError: 'no_next_slider',
699             backwardError: 'no_previous_slider',
700             typeMsg: 'aria_role_slider'},
701  'graphic': {predicate: 'graphicPredicate',
702              forwardError: 'no_next_graphic',
703              backwardError: 'no_previous_graphic',
704              typeMsg: 'UNUSED'},
705  'article': {predicate: 'articlePredicate',
706             forwardError: 'no_next_ARTICLE',
707             backwardError: 'no_previous_ARTICLE',
708             typeMsg: 'TAG_ARTICLE'},
709  'button': {predicate: 'buttonPredicate',
710             forwardError: 'no_next_button',
711             backwardError: 'no_previous_button',
712             typeMsg: 'aria_role_button'},
713  'combobox': {predicate: 'comboBoxPredicate',
714               forwardError: 'no_next_combo_box',
715               backwardError: 'no_previous_combo_box',
716               typeMsg: 'aria_role_combobox'},
717  'editText': {predicate: 'editTextPredicate',
718               forwardError: 'no_next_edit_text',
719               backwardError: 'no_previous_edit_text',
720               typeMsg: 'input_type_text'},
721  'heading': {predicate: 'headingPredicate',
722              forwardError: 'no_next_heading',
723              backwardError: 'no_previous_heading',
724              typeMsg: 'aria_role_heading'},
725  'heading1': {predicate: 'heading1Predicate',
726               forwardError: 'no_next_heading_1',
727               backwardError: 'no_previous_heading_1'},
728  'heading2': {predicate: 'heading2Predicate',
729               forwardError: 'no_next_heading_2',
730               backwardError: 'no_previous_heading_2'},
731  'heading3': {predicate: 'heading3Predicate',
732               forwardError: 'no_next_heading_3',
733               backwardError: 'no_previous_heading_3'},
734  'heading4': {predicate: 'heading4Predicate',
735               forwardError: 'no_next_heading_4',
736               backwardError: 'no_previous_heading_4'},
737  'heading5': {predicate: 'heading5Predicate',
738               forwardError: 'no_next_heading_5',
739               backwardError: 'no_previous_heading_5'},
740  'heading6': {predicate: 'heading6Predicate',
741               forwardError: 'no_next_heading_6',
742               backwardError: 'no_previous_heading_6'},
743
744  'link': {predicate: 'linkPredicate',
745           forwardError: 'no_next_link',
746           backwardError: 'no_previous_link',
747           typeMsg: 'aria_role_link'},
748  'table': {predicate: 'tablePredicate',
749            forwardError: 'no_next_table',
750            backwardError: 'no_previous_table',
751            typeMsg: 'table_strategy'},
752  'visitedLink': {predicate: 'visitedLinkPredicate',
753            forwardError: 'no_next_visited_link',
754            backwardError: 'no_previous_visited_link',
755            typeMsg: 'tag_link'},
756  'list': {predicate: 'listPredicate',
757           forwardError: 'no_next_list',
758           backwardError: 'no_previous_list',
759           typeMsg: 'aria_role_list'},
760  'listItem': {predicate: 'listItemPredicate',
761               forwardError: 'no_next_list_item',
762               backwardError: 'no_previous_list_item',
763               typeMsg: 'aria_role_listitem'},
764  'formField': {predicate: 'formFieldPredicate',
765                forwardError: 'no_next_form_field',
766                backwardError: 'no_previous_form_field',
767                typeMsg: 'aria_role_form'},
768  'landmark': {predicate: 'landmarkPredicate',
769               forwardError: 'no_next_landmark',
770               backwardError: 'no_previous_landmark',
771               typeMsg: 'role_landmark'},
772  'math': {predicate: 'mathPredicate',
773           forwardError: 'no_next_math',
774           backwardError: 'no_previous_math',
775           typeMsg: 'math_expr'},
776  'media': {predicate: 'mediaPredicate',
777            forwardError: 'no_next_media_widget',
778            backwardError: 'no_previous_media_widget'},
779  'section': {predicate: 'sectionPredicate',
780           forwardError: 'no_next_section',
781           backwardError: 'no_previous_section'},
782  'control': {predicate: 'controlPredicate',
783           forwardError: 'no_next_control',
784           backwardError: 'no_previous_control'}
785};
786