Improvement to Hit-a-Hint bookmarklet for Opera
Sunday, 27. July 2008, 17:52:46
Vimperator for Opera - Blazeix's Blog - by Blazeix
I made a change to the original script so that I can have any letters I want for hints.
Here it is.
javascript:(function(){var hintkeys='asdfghjkl';var maxdigit=4;function createText(m){var ret='';var l=hintkeys.length;var d=maxdigit*l;while(m>=0){while(m-l*d<0){d--;}ret=hintkeys.charAt(m-l*d)+ret;m=d-1;}return ret;}function retrieveNumber(w){var ret=0;var wlen=w.length;for(var i=0;i<wlen;i++){var fix=(i==0)?0:1;var t=w.charAt(wlen-i-1);ret+=(hintkeys.indexOf(t)+fix)*Math.pow(hintkeys.length,i);}return ret;}var bgcolor = '#FF0';var bghighlight = '#0F0';var color = '#000';var hintlist = new Array();var hintedlinks = new Array();var map = new Array();var choices = new Array();var mapindex = 0;var choice = '';var keycodemapping = {'13':'Enter','27':'Esc','8':'Bkspc','44':','};for(var i=0;i<hintkeys.length;i++){var ithkey=hintkeys[i];keycodemapping[ithkey.charCodeAt(0)]=ithkey;}var originalTitle = document.title;function drawHints(){document.addEventListener('keypress',interpretKeyStroke,true);document.title+=' - ';var allLinks = document.getElementsByTagName('a');var viewportStart = window.pageYOffset - 5;var viewportEnd = viewportStart + window.innerHeight + 10;for (var i = 0;i<allLinks.length;i++){linkYcoord = getAbsoluteY(allLinks[i]);if(linkYcoord > viewportStart && linkYcoord < viewportEnd && allLinks[i].href != '') {hintedlinks.push(allLinks[i]);}}for (var i = 0;i<allLinks.length;i++){var hint = document.createElement('span');hintlist.push(hint);hint.style.backgroundColor=bgcolor;hint.style.color=color;hint.style.position='absolute';hint.innerHTML = createText(mapindex);map[createText(mapindex)]=hintedlinks[i].href;mapindex++;hintedlinks[i].appendChild(hint,hintedlinks[i]);}}function getAbsoluteY(element){var y = 0;while (element) {y += element.offsetTop;element = element.offsetParent;}return y;}function removeHints(){for (var i=0;i<hintedlinks.length;i++){hintedlinks[i].removeChild(hintlist[i],hintedlinks[i]);}choice='';document.title=originalTitle;document.removeEventListener('keypress',interpretKeyStroke,true);delete map;delete hintlist;delete hintedlinks;delete choices;}function interpretKeyStroke(e){e.preventDefault();var key=keycodemapping[(typeof event!='undefined')?window.event.keyCode:e.keyCode];if(key=='Enter'){choices.push(choice);for (var i=0;i<choices.length;i++) {if(map[choices[i]]!=undefined){window.open(map[choices[i]]);}}removeHints();}else if(key==','){if(choice!=''){choices.push(choice);hintlist[retrieveNumber(choice)].style.backgroundColor=bghighlight;choice = '';document.title+=',';}}else if(key=='Esc'){removeHints();}else if(key=='Bkspc'){if(choices.length){if(choice!=''){choice='';}else{hintlist[retrieveNumber(choices.pop())].style.backgroundColor=bgcolor;document.title=originalTitle+' - '+choices.join(',');}}}else if(key == undefined){removeHints();}else{choice+=key;var choicestring = (choices.length) ? choices.join(',')+','+choice : choice;document.title=originalTitle+' - '+choicestring;}}drawHints();})();
It's only for the extended hints mode (see Blazeix's post).
It doesn't work on firefox (Hints disappear when you start typing them in).
You can set any hint letters by changing
var hintkeys='asdfghjkl';
The following
var maxdigit=4;is the maximum number of hints it can deal with. If you have too few letters for hints, you'd better change this. By default it's capable of showing (9 letters)^(4 digits)=6561 hints.
The main change is the next two functions.
function createText(m){var ret='';var l=hintkeys.length;var d=maxdigit*l;while(m>=0){while(m-l*d<0){d--;}ret=hintkeys.charAt(m-l*d)+ret;m=d-1;}return ret;}
function retrieveNumber(w){var ret=0;var wlen=w.length;for(var i=0;i<wlen;i++){var fix=(i==0)?0:1;var t=w.charAt(wlen-i-1);ret+=(hintkeys.indexOf(t)+fix)*Math.pow(hintkeys.length,i);}return ret;}
The first one is to convert the a number (1,2,3,...) to a hint (a,s,d,...aa,as,ad,...), and the second one does exactly the opposite. I inserted them in the code.
Then I changed keycode mapping as the following so that your added letters will be reflected.
var keycodemapping = {'13':'Enter','27':'Esc','8':'Bkspc','44':','};for(var i=0;i<hintkeys.length;i++){var ithkey=hintkeys[i];keycodemapping[ithkey.charCodeAt(0)]=ithkey;}
That's it. Enjoy!

