search_tools.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 Uses ChromeVox API to access the search tools menu.
8 */
9
10goog.provide('cvox.SearchTool');
11
12goog.require('cvox.ChromeVox');
13goog.require('cvox.DomUtil');
14goog.require('cvox.Search');
15goog.require('cvox.SearchConstants');
16goog.require('cvox.SearchUtil');
17
18/**
19 * @constructor
20 */
21cvox.SearchTool = function() {
22};
23
24/**
25 * Index of the current menu in focus.
26 * @type {number}
27 */
28cvox.SearchTool.menuIndex;
29
30/**
31 * Array of menus.
32 * @type {Array.<Node>}
33 */
34cvox.SearchTool.menus = [];
35
36/**
37 * Index of the current menu item in focus.
38 * @type {number}
39 */
40cvox.SearchTool.menuItemIndex;
41
42/**
43 * Array of menu items for the current menu.
44 * @type {Array.<Node>}
45 */
46cvox.SearchTool.menuItems = [];
47
48/**
49 * Id of the clear button.
50 * @type {string}
51 */
52cvox.SearchTool.CLEAR_ID = 'hdtb_rst';
53
54/**
55 * Toggles a menu open / close by simulating a click.
56 */
57cvox.SearchTool.toggleMenu = function() {
58  var menu = cvox.SearchTool.menus[cvox.SearchTool.menuIndex];
59  var menuDiv = menu.previousSibling;
60  cvox.DomUtil.clickElem(menuDiv, false, false, false);
61};
62
63/**
64 * Syncs the first item in the current menu to ChromeVox.
65 */
66cvox.SearchTool.syncToMenu = function() {
67  cvox.SearchTool.menuItemIndex = 0;
68  cvox.SearchTool.toggleMenu();
69  cvox.SearchTool.populateMenuItems();
70  cvox.SearchTool.syncToMenuItem();
71};
72
73/**
74 * Syncs the current menu item to ChromeVox.
75 */
76cvox.SearchTool.syncToMenuItem = function() {
77  var menuItem = cvox.SearchTool.menuItems[cvox.SearchTool.menuItemIndex];
78  cvox.ChromeVox.syncToNode(menuItem, true);
79};
80
81/**
82 * Fills in menuItems with the current menu's items.
83 */
84cvox.SearchTool.populateMenuItems = function() {
85  var menu = cvox.SearchTool.menus[cvox.SearchTool.menuIndex];
86  cvox.SearchTool.menuItems = [];
87  /* For now, we just special case on the clear button. */
88  if (menu.id !== cvox.SearchTool.CLEAR_ID) {
89    var MENU_ITEM_SELECTOR = '.hdtbItm';
90    var menuItemNodeList = menu.querySelectorAll(MENU_ITEM_SELECTOR);
91    for (var i = 0; i < menuItemNodeList.length; i++) {
92      cvox.SearchTool.menuItems.push(menuItemNodeList.item(i));
93    }
94  } else {
95    cvox.SearchTool.menuItems = [];
96    cvox.SearchTool.menuItems.push(menu);
97  }
98};
99
100/**
101 * Fills in menus with the menus of the page.
102 */
103cvox.SearchTool.populateMenus = function() {
104  var MENU_SELECTOR = '.hdtbU';
105  var menuDivs = document.querySelectorAll(MENU_SELECTOR);
106  for (var i = 0; i < menuDivs.length; i++) {
107    cvox.SearchTool.menus.push(menuDivs.item(i));
108  }
109
110  var clearDiv = document.getElementById(cvox.SearchTool.CLEAR_ID);
111  if (clearDiv) {
112    cvox.SearchTool.menus.push(clearDiv);
113  }
114};
115
116/**
117 * Switches focus to the tools interface, giving keyboard access.
118 */
119cvox.SearchTool.activateTools = function() {
120  var MENU_BAR_SELECTOR = '#hdtbMenus';
121  var menuBar = document.querySelector(MENU_BAR_SELECTOR);
122  var MENUS_OPEN_CLASS = 'hdtb-td-o';
123  menuBar.className = MENUS_OPEN_CLASS;
124
125  cvox.SearchTool.populateMenus();
126  cvox.SearchTool.menuIndex = 0;
127  cvox.SearchTool.syncToMenu();
128};
129
130/**
131 * Goes to the link of the current menu item action.
132 */
133cvox.SearchTool.gotoMenuItem = function() {
134  var menuItem = cvox.SearchTool.menuItems[cvox.SearchTool.menuItemIndex];
135  var LOCATION_INPUT_ID = '#lc-input';
136  var input = menuItem.querySelector(LOCATION_INPUT_ID);
137  /* Special case for setting location. */
138  if (input) {
139    input.focus();
140    return;
141  }
142
143  /* Custom Date Range. */
144  var CDR_ID = 'cdr_opt';
145  switch (menuItem.id) {
146  case cvox.SearchTool.CLEAR_ID:
147    window.location = menuItem.dataset.url;
148    break;
149  case CDR_ID:
150    var CDR_LINK_SELECTOR = '#cdrlnk';
151    var cdrLink = menuItem.querySelector(CDR_LINK_SELECTOR);
152    cvox.DomUtil.clickElem(cdrLink, false, false, false);
153    cvox.SearchTool.toggleMenu();
154    break;
155  default:
156    window.location = cvox.SearchUtil.extractURL(menuItem);
157    break;
158  }
159};
160
161/**
162 * Handles key events for the tools interface.
163 * @param {Event} evt Keydown event.
164 * @return {boolean} True if key was handled, false otherwise.
165 */
166cvox.SearchTool.keyhandler = function(evt) {
167  if (cvox.SearchUtil.isSearchWidgetActive()) {
168    return false;
169  }
170
171  switch (evt.keyCode) {
172  case cvox.SearchConstants.KeyCode.UP:
173    cvox.SearchTool.menuItemIndex = cvox.SearchUtil.subOneWrap(
174      cvox.SearchTool.menuItemIndex, cvox.SearchTool.menuItems.length);
175    cvox.SearchTool.syncToMenuItem();
176    break;
177
178  case cvox.SearchConstants.KeyCode.DOWN:
179    cvox.SearchTool.menuItemIndex = cvox.SearchUtil.addOneWrap(
180      cvox.SearchTool.menuItemIndex, cvox.SearchTool.menuItems.length);
181    cvox.SearchTool.syncToMenuItem();
182    break;
183
184  case cvox.SearchConstants.KeyCode.LEFT:
185    cvox.SearchTool.toggleMenu();
186    cvox.SearchTool.menuIndex = cvox.SearchUtil.subOneWrap(
187      cvox.SearchTool.menuIndex, cvox.SearchTool.menus.length);
188    cvox.SearchTool.syncToMenu();
189    break;
190
191  case cvox.SearchConstants.KeyCode.RIGHT:
192    cvox.SearchTool.toggleMenu();
193    cvox.SearchTool.menuIndex = cvox.SearchUtil.addOneWrap(
194      cvox.SearchTool.menuIndex, cvox.SearchTool.menus.length);
195    cvox.SearchTool.syncToMenu();
196    break;
197
198  case cvox.SearchConstants.KeyCode.ENTER:
199    cvox.SearchTool.gotoMenuItem();
200    break;
201
202  default:
203    return false;
204  }
205  evt.preventDefault();
206  evt.stopPropagation();
207  return true;
208};
209