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