| OLD | NEW |
| (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.ChromeVoxInstantSearch'); |
| 6 |
| 7 goog.require('cvox.ChromeVox'); |
| 8 |
| 9 /** |
| 10 * @fileoverview Script for enhancing Google Instant Search. |
| 11 */ |
| 12 cvox.ChromeVoxInstantSearch = { }; |
| 13 |
| 14 /** |
| 15 * @type {boolean} |
| 16 */ |
| 17 cvox.ChromeVoxInstantSearch.speakFirstResult = false; |
| 18 |
| 19 /** |
| 20 * @type {number} |
| 21 */ |
| 22 cvox.ChromeVoxInstantSearch.updateDelay = 2000; |
| 23 |
| 24 /** |
| 25 * @type {number} |
| 26 */ |
| 27 cvox.ChromeVoxInstantSearch.updateTime = new Date().getTime() + |
| 28 cvox.ChromeVoxInstantSearch.updateDelay; |
| 29 |
| 30 /** |
| 31 * @type {Object} |
| 32 */ |
| 33 cvox.ChromeVoxInstantSearch.previousSnippetNode = null; |
| 34 |
| 35 /** |
| 36 * Initializes the Psychic Search script. |
| 37 */ |
| 38 cvox.ChromeVoxInstantSearch.init = function() { |
| 39 var headID = document.getElementsByTagName('head')[0]; |
| 40 var cssNode = document.createElement('style'); |
| 41 cssNode.type = 'text/css'; |
| 42 cssNode.innerHTML = '#knavm-container {font-size: 150%}'; |
| 43 headID.appendChild(cssNode); |
| 44 |
| 45 window.addEventListener('DOMSubtreeModified', |
| 46 cvox.ChromeVoxInstantSearch.domSubtreeModified, true); |
| 47 window.setTimeout(cvox.ChromeVoxInstantSearch.processUpdateQueue, 200); |
| 48 }; |
| 49 |
| 50 /** |
| 51 * Goes to the current result with the chevron arrow pointed at it and |
| 52 * speaks it if it wasn't just spoken. Returns true if it was able to |
| 53 * find such a result and speak it. |
| 54 * |
| 55 * @return {boolean} whether or not it was able to find and speak the |
| 56 * current result on the page. |
| 57 */ |
| 58 cvox.ChromeVoxInstantSearch.gotoCurrentResult = function() { |
| 59 var currentChevronNode = document.getElementById('knavm'); |
| 60 if (currentChevronNode) { |
| 61 currentResultNode = currentChevronNode.parentNode; |
| 62 if (currentResultNode != cvox.ChromeVoxInstantSearch.previousSnippetNode) { |
| 63 var containerNode = document.getElementById('knavm-container'); |
| 64 if (containerNode != null) { |
| 65 containerNode.id = ''; |
| 66 } |
| 67 currentResultNode.id = 'knavm-container'; |
| 68 cvox.ChromeVoxInstantSearch.previousSnippetNode = currentResultNode; |
| 69 var resultText = cvox.DomUtil.getText(currentResultNode); |
| 70 // Use a setTimeout here so we don't get clobbered by the focus event. |
| 71 window.setTimeout(function() { |
| 72 cvox.ChromeVox.tts.speak(resultText, 0, null); |
| 73 }, 0); |
| 74 if (currentResultNode.previousSibling) { |
| 75 cvox.ChromeVox.navigationManager.syncToNode( |
| 76 currentResultNode.previousSibling); |
| 77 } else { |
| 78 // Sync to the top of the results section. |
| 79 cvox.ChromeVox.navigationManager.syncToNode( |
| 80 document.getElementById('subform_ctrl')); |
| 81 } |
| 82 return true; |
| 83 } |
| 84 } |
| 85 return false; |
| 86 }; |
| 87 |
| 88 /** |
| 89 * Speaks when the user is moving through the results with the highlight |
| 90 * and when the user is moving through suggestions. |
| 91 * |
| 92 * @param {Object} evt The DOMSubtreeModified event used to determine when |
| 93 * there is a user action that we should respond to. |
| 94 */ |
| 95 cvox.ChromeVoxInstantSearch.domSubtreeModified = function(evt) { |
| 96 if (cvox.ChromeVoxInstantSearch.gotoCurrentResult()) { |
| 97 return; |
| 98 } |
| 99 var target = evt.target; |
| 100 if (target.className && |
| 101 (target.className == 'gac_b')) { |
| 102 var completion = target.getElementsByClassName('gac_c')[0]; |
| 103 cvox.ChromeVox.tts.speak(completion.textContent, 0, null); |
| 104 cvox.ChromeVoxInstantSearch.speakFirstResult = true; |
| 105 cvox.ChromeVoxInstantSearch.updateTime = new Date().getTime() + |
| 106 cvox.ChromeVoxInstantSearch.updateDelay; |
| 107 } |
| 108 }; |
| 109 |
| 110 /** |
| 111 * Speaks the first result when the results area is updated. |
| 112 */ |
| 113 cvox.ChromeVoxInstantSearch.processUpdateQueue = function() { |
| 114 var resultsNode = document.getElementById('ires'); |
| 115 var results = resultsNode.getElementsByTagName('li'); |
| 116 if (results.length > 0) { |
| 117 if ((cvox.ChromeVoxInstantSearch.speakFirstResult) && |
| 118 (new Date().getTime() > cvox.ChromeVoxInstantSearch.updateTime)) { |
| 119 var resultText = cvox.DomUtil.getText(results[0]); |
| 120 cvox.ChromeVox.tts.speak(resultText, 0, null); |
| 121 cvox.ChromeVoxInstantSearch.speakFirstResult = false; |
| 122 } |
| 123 } |
| 124 window.setTimeout(cvox.ChromeVoxInstantSearch.processUpdateQueue, 200); |
| 125 }; |
| 126 |
| 127 window.setTimeout(cvox.ChromeVoxInstantSearch.init, 500); |
| OLD | NEW |