Skip to content

Instantly share code, notes, and snippets.

@mallowlabs
Forked from edvakf/spacnav-highlight.js
Created December 6, 2008 12:13
Show Gist options
  • Save mallowlabs/32865 to your computer and use it in GitHub Desktop.
Save mallowlabs/32865 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Hit-a-Hint accelerator
// @description Add CSS for HaH & kill page shortcut when HaH is on
// @namespace http://d.hatena.ne.jp/edvakf/
// @include http://*
// ==/UserScript==
(function(){
var log = opera.postError;
var moveFocusFunc = {
'up': document.moveFocusUp,
'down': document.moveFocusDown,
'left': document.moveFocusLeft,
'right': document.moveFocusRight,
}
var keyHash = {
16 : 'shift',
37 : 'left',
38 : 'up',
39 : 'right',
40 : 'down'
}
function highlightNext(theElm){
var elmSet = {};
var origBGSet = {};
function addStyle(dir){
style = elmSet[dir].style;
if(style.backgroundColor)
origBGSet[dir]=style.backgroundColor;
style.backgroundColor = 'pink';
}
function removeStyle(dir){
if(!elmSet[dir])return;
//log(theElm.className+' removeStyle '+dir+' '+elmSet[dir].className);
style = elmSet[dir].style;
if(origBGSet[dir])
style.backgroundColor=origBGSet[dir];
else
style.backgroundColor = '';
}
function moveFocusToCurrent(){
var style = document.activeElement.style;
var origNavRight = style.navRight;
style.navRight = '#'+theElm.id;
document.moveFocusRight();
if(document.activeElement==document.body)document.body.blur();
style.navRight = origNavRight;
}
function highlight(dir){
if(!moveFocusFunc[dir].call(document)) return;
elmSet[dir] = document.activeElement;
//log(theElm.className+' highlight '+dir+' '+elmSet[dir].className);
moveFocusToCurrent();
addStyle(dir);
}
/* set an id to the current element if not set*/
var tempId = 'spac-nav-current';
if(theElm.id) var origId = theElm.id;
else theElm.id = tempId;
/* highlight surrounding elements */
['left','up','right','down'].forEach(highlight);
function keyPressHandler(e){
var dir = keyHash[e.keyCode];
if(!dir || dir=='shift' || !e.shiftKey)return;
if(origId)theElm.id = origId;
else theElm.removeAttribute('id');
//log('*****from '+document.activeElement.className+' to '+elmSet[dir].className+'*****');
if(!moveFocusFunc[dir].call(document))return;
['down','right','up','left'].forEach(removeStyle);
var target = document.activeElement;
if(!target)return;
highlightNext(target);
// highlightNext(document.activeElement);
delete elmSet;
delete origBGSet;
e.preventDefault();
document.removeEventListener('keypress',arguments.callee,false);
}
document.addEventListener('keypress',keyPressHandler,false);
document.addEventListener('keyup',function(e){
if( keyHash[e.keyCode] !='shift' ) return;
['down','right','up','left'].forEach(removeStyle);
if(origId)theElm.id = origId;
else theElm.removeAttribute('id');
document.removeEventListener('keypress',keyPressHandler,false);
document.removeEventListener('keyup',arguments.callee,false);
delete elmSet;
delete origBGSet;
},false);
}
var inputting = false;
document.addEventListener('keydown',function(e){
if(keyHash[e.keyCode]!='shift')return;
if(inputting)return;
highlightNext(document.activeElement);
},false);
/** simple version of $X
* $X(exp);
* $X(exp, context);
* @source http://gist.github.com/3242.txt
*/
var $X = function (exp, context) {
context || (context = document);
var expr = (context.ownerDocument || context).createExpression(exp, function (prefix) {
return document.createNSResolver(context.documentElement || context).lookupNamespaceURI(prefix) ||
context.namespaceURI || document.documentElement.namespaceURI || "";
});
var result = expr.evaluate(context, XPathResult.ANY_TYPE, null);
switch (result.resultType) {
case XPathResult.STRING_TYPE : return result.stringValue;
case XPathResult.NUMBER_TYPE : return result.numberValue;
case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
// not ensure the order.
var ret = [], i = null;
while (i = result.iterateNext()) ret.push(i);
return ret;
}
return null;
}
$X(".//input[not(@type) or @type=\"text\"]").concat($X(".//textarea")).forEach(
function(input) {
input.addEventListener("focus", function(e) {
inputting = true;
}, false);
input.addEventListener("blur", function(e) {
inputting = false;
}, false);
}
);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment