PageRenderTime 27ms CodeModel.GetById 16ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/CVox/res/raw/basic.user.js

http://eyes-free.googlecode.com/
JavaScript | 226 lines | 192 code | 18 blank | 16 comment | 69 complexity | 8dbea4d9b53a7ddd8e230f7070b7b3a6 MD5 | raw file
  1// ==UserScript==
  2// @name          CVOX
  3// @description   Generic CVOX Script
  4// @author        Charles L. Chen
  5// @include       http://*
  6// ==/UserScript==
  7
  8var currentElem = null;
  9var prevElem = null;
 10var inputFocused = false;
 11
 12function getNextLeafNode(){
 13  prevElem = currentElem;
 14  if (currentElem == null){
 15    currentElem = document.body;
 16  } else {
 17    while (!currentElem.nextSibling){
 18    currentElem = currentElem.parentNode;
 19    if (currentElem == document.body){
 20      currentElem = null;
 21      return currentElem;
 22    }
 23  }
 24  currentElem = currentElem.nextSibling;
 25  }
 26  while (currentElem.firstChild){
 27    currentElem = currentElem.firstChild;
 28  }
 29  return currentElem;  
 30}
 31
 32function getPrevLeafNode(){
 33  prevElem = currentElem;
 34  if (currentElem == null){
 35    currentElem = document.body;
 36  } else {
 37    while (!currentElem.previousSibling){
 38    currentElem = currentElem.parentNode;
 39    if (currentElem == document.body){
 40      currentElem = null;
 41      return currentElem;
 42    }
 43  }
 44  currentElem = currentElem.previousSibling;
 45  }
 46  while (currentElem.lastChild){
 47    currentElem = currentElem.lastChild;
 48  }
 49  return currentElem;  
 50}
 51
 52function containsText(textStr){
 53  if (textStr === null){
 54    return false;
 55  }
 56  if (textStr.length < 1){
 57    return false;
 58  }
 59  var myregexp = new RegExp("[a-zA-Z0-9]");
 60  return myregexp.test(textStr);
 61}
 62
 63function getLineage(targetNode){
 64  var lineage = new Array();
 65  while (targetNode){
 66    lineage.push(targetNode);      
 67    targetNode = targetNode.parentNode;
 68  }
 69  lineage.reverse();
 70  while(lineage.length && !lineage[0].tagName && !lineage[0].nodeValue){
 71    lineage.shift();
 72  }
 73  return lineage;
 74}
 75
 76//Compares Lineage A with Lineage B and returns
 77//the index value in B at which B diverges from A.
 78//If there is no divergence, the result will be -1.
 79//Note that if B is the same as A except B has more nodes
 80//even after A has ended, that is considered a divergence.
 81//The first node that B has which A does not have will
 82//be treated as the divergence point.
 83//
 84function compareLineages(lina, linb){
 85  var i = 0;
 86  while( lina[i] && linb[i] && (lina[i] == linb[i]) ){
 87    i++;
 88  }
 89  if ( !lina[i] && !linb[i] ){
 90    i = -1;
 91  }
 92  return i;
 93}
 94
 95
 96
 97function getInfoOnCurrentElem(){
 98  var currentLineage = getLineage(currentElem);
 99  var divergence = compareLineages(getLineage(prevElem), currentLineage);
100  var infoStr = "";
101  for (var i=divergence, elem; elem = currentLineage[i]; i++){
102    if (elem.tagName){
103    if (elem.tagName == 'H1'){
104      infoStr = infoStr + 'H 1. ';
105    } else if (elem.tagName == 'H2'){
106      infoStr = infoStr + 'H 2. ';
107    } else if (elem.tagName == 'H3'){
108      infoStr = infoStr + 'H 3. ';
109    } else if (elem.tagName == 'H4'){
110      infoStr = infoStr + 'H 4. ';
111    } else if (elem.tagName == 'H5'){
112      infoStr = infoStr + 'H 5. ';
113    } else if (elem.tagName == 'H6'){
114      infoStr = infoStr + 'H 6. ';
115    } else if (elem.tagName == 'A'){
116      infoStr = infoStr + 'Link. ';
117    }
118  }
119  }
120  return infoStr;
121}
122
123function readNext(){
124  getNextLeafNode();
125  while (!containsText(currentElem.textContent)){
126    getNextLeafNode();
127    if (currentElem === null){
128      speak("End of document", 0, null);
129      return;
130    }
131  }
132  speak(getInfoOnCurrentElem() + ' ' + currentElem.textContent, 0, null);
133  scrollToElem(currentElem);
134}
135
136function readPrev(){
137  getPrevLeafNode();
138  while (!containsText(currentElem.textContent)){
139    getPrevLeafNode();
140    if (currentElem === null){
141      speak("Beginning of document", 0, null);
142      return;
143    }
144  }
145  speak(getInfoOnCurrentElem() + ' ' + currentElem.textContent, 0, null);
146  scrollToElem(currentElem);
147}
148
149function scrollToElem(targetNode){
150  while (!targetNode.offsetParent){
151    targetNode = targetNode.parentNode;
152  }
153  var left = 0;
154  var top = 0;
155  while (targetNode.offsetParent) { 
156    left += targetNode.offsetLeft;
157    top += targetNode.offsetTop; 
158    targetNode = targetNode.offsetParent;
159  }
160  left += targetNode.offsetLeft;
161  top += targetNode.offsetTop;
162  window.scrollTo(left, top);
163}
164
165function speak(textStr, queueMode, paramsArray){
166  window.ttsHelper.speak(textStr, queueMode);
167  //alert(textStr);
168}
169
170//TODO: Come up with a working escape sequence!
171function keyPressHandler(evt){
172  var keyCode = evt.keyCode;
173  if (inputFocused){
174    return true;
175  }
176  if (keyCode == 106) { // j
177    readNext();
178    return false;
179  }
180  if (keyCode == 107) { // k
181    readPrev();
182    return false;
183  }  
184  return true;
185}
186
187function keyDownHandler(evt){
188  window.ttsHelper.stop();
189  var keyCode = evt.keyCode;
190  if (inputFocused){
191    return true;
192  }
193  if ((keyCode == 32) || (keyCode == 13)) { // space or Enter (G1 enter key does not work)
194    var targetElem = currentElem;
195    while (targetElem){
196	  if (targetElem.tagName == 'A'){
197	    document.location = targetElem.href;
198      return false;
199	  }
200	  targetElem = targetElem.parentNode;
201	}
202    return true;
203  }
204  return true;
205}
206
207function focusHandler(evt){
208  if (evt.target.tagName && 
209      evt.target.tagName == 'INPUT'){
210      inputFocused = true;
211      }
212  return true;
213}
214
215function blurHandler(evt){
216  inputFocused = false;
217  return true;
218}
219
220if (document.location.toString().indexOf('http://www.google.com/search?') != 0){
221  document.addEventListener('keypress', keyPressHandler, true);
222  document.addEventListener('keydown', keyDownHandler, true);
223  document.addEventListener('focus', focusHandler, true);
224  document.addEventListener('blur', blurHandler, true);
225  speak(document.title, 0, null);
226}