summaryrefslogtreecommitdiff
path: root/src/hints.js.h
blob: 102d9c6bd4bb352d221040179b6cb3341100fe61 (plain)
1
#define HINTS_JS "Object.freeze((function(){'use strict';var hints=[],docs=[],validHints=[],activeHint,filterText=\"\",filterNum=0,cId=\"_hintContainer\",lClass=\"_hintLabel\",hClass=\"_hintElem\",fClass=\"_hintFocus\",config;function Hint(){this.hide=function(){this.label.style.display=\"none\";this.e.classList.remove(fClass);this.e.classList.remove(hClass);};this.show=function(){this.label.style.display=\"\";this.e.classList.add(hClass);var text=[];if(this.e instanceof HTMLInputElement){var type=this.e.type;if(type===\"checkbox\"){text.push(this.e.checked?\"☑\":\"☐\");}else if(type===\"radio\"){text.push(this.e.checked?\"⊙\":\"○\");}}if(this.showText&&this.text){text.push(this.text.substr(0,20));}this.label.innerText=this.num+(text.length?\": \"+text.join(\" \"):\"\");};}function clear(){var i,j,doc,e;for(i=0;i<docs.length;i++){doc=docs[i];var res=xpath(doc.doc,\"//*[contains(@vimbhint,'hint')]\");for(j=0;j<res.snapshotLength;j++){e=res.snapshotItem(j);e.removeAttribute(\"vimbhint\");e.classList.remove(fClass);e.classList.remove(hClass);}doc.div.parentNode.removeChild(doc.div);}docs=[];hints=[];validHints=[];filterText=\"\";filterNum=0;}function create(){var count=0;function helper(win,offsets){if(typeof win.document==\"undefined\"){return;}offsets=offsets||{left:0,right:0,top:0,bottom:0};offsets.right=win.innerWidth-offsets.right;offsets.bottom=win.innerHeight-offsets.bottom;function isVisible(e){if(typeof e==\"undefined\"){return false;}var rect=e.getBoundingClientRect();if(!rect||rect.top>offsets.bottom||rect.bottom<offsets.top||rect.left>offsets.right||rect.right<offsets.left){return false;}if((!rect.width||!rect.height)&&(e.textContent||!e.name)){var arr=Array.prototype.slice.call(e.childNodes);var check=function(e){return e instanceof Element&&e.style.float!=\"none\"&&isVisible(e);};if(!arr.some(check)){return false;}}var s=win.getComputedStyle(e,null);return s.display!==\"none\"&&s.visibility==\"visible\";}var doc=win.document,res=xpath(doc,config.xpath),labelTmpl=doc.createElement(\"span\"),e,i;labelTmpl.className=lClass;labelTmpl.setAttribute(\"vimbhint\",\"label\");var containerOffsets=getOffsets(doc),offsetX=containerOffsets[0],offsetY=containerOffsets[1],fragment=doc.createDocumentFragment(),rect,label,text,showText,start=hints.length;for(i=0;i<res.snapshotLength;i++){e=res.snapshotItem(i);if(!isVisible(e)){continue;}count++;rect=e.getBoundingClientRect();label=labelTmpl.cloneNode(false);label.setAttribute(\"style\",[\"display:none;\",\"left:\",Math.max((rect.left+offsetX),offsetX),\"px;\",\"top:\",Math.max((rect.top+offsetY),offsetY),\"px;\"].join(\"\"));text=\"\";showText=false;if(e instanceof HTMLImageElement){text=e.title||e.alt;showText=true;}else if(e.firstElementChild instanceof HTMLImageElement&&/^\\s*$/.test(e.textContent)){text=e.firstElementChild.title||e.firstElementChild.alt;showText=true;}else if(e instanceof HTMLInputElement){var type=e.type;if(type===\"image\"){text=e.alt||\"\";}else if(e.value&&type!==\"password\"){text=e.value;showText=(type===\"radio\"||type===\"checkbox\");}}else if(e instanceof HTMLSelectElement){if(e.selectedIndex>=0){text=e.item(e.selectedIndex).text;}}else{text=e.textContent;}fragment.appendChild(label);e.setAttribute(\"vimbhint\",\"hint\");hints.push({e:e,label:label,text:text,showText:showText,__proto__:new Hint});if(count>=config.maxHints){break;}}var hDiv=doc.createElement(\"div\");hDiv.id=cId;hDiv.setAttribute(\"vimbhint\",\"container\");hDiv.appendChild(fragment);if(doc.body){doc.body.appendChild(hDiv);}createStyle(doc);docs.push({doc:doc,start:start,end:hints.length-1,div:hDiv});for(i=0;i<win.frames.length;i++){var rect,f=win.frames[i],e=f.frameElement;if(isVisible(e)){rect=e.getBoundingClientRect();helper(f,{left:Math.max(offsets.left-rect.left,0),right:Math.max(rect.right-offsets.right,0),top:Math.max(offsets.top-rect.top,0),bottom:Math.max(rect.bottom-offsets.bottom,0)});}}}helper(window);}function show(fireLast){var i,hint,newIdx,n=1,matcher=getMatcher(filterText),str=getHintString(filterNum);if(config.hintNumSameLength){var hintCount=0;for(i=0;i<hints.length;i++){if(matcher(hints[i].text)){hintCount++;}}var len=config.hintKeys.length;while(n *(len-1)<hintCount){n *=len;}}validHints=[];for(i=0;i<hints.length;i++){hint=hints[i];if(!matcher(hint.text)){hint.hide();}else{hint.num=getHintString(n++);if(!filterNum||0===hint.num.indexOf(str)){hint.show();validHints.push(hint);}else{hint.hide();}}}if(fireLast&&config.followLast&&validHints.length<=1){focusHint(0);return fire();}if(!activeHint||validHints.indexOf(activeHint)<0){return focusHint(0);}}function getMatcher(text){var tokens=text.toLowerCase().split(/\\s+/);return function(itemText){itemText=itemText.toLowerCase();return tokens.every(function(token){return 0<=itemText.indexOf(token);});};}function getHintString(n){var res=[],len=config.hintKeys.length;do{res.push(config.hintKeys[n % len]);n=Math.floor(n / len);}while(n>0);return res.reverse().join(\"\");}function getOffsets(doc){var body=doc.body||doc.documentElement,style=body.style,rect;if(style&&/^(absolute|fixed|relative)$/.test(style.position)){rect=body.getClientRects()[0];return [-rect.left,-rect.top];}return [doc.defaultView.scrollX,doc.defaultView.scrollY];}function createStyle(doc){if(doc.hasStyle){return;}var e=doc.createElement(\"style\");e.innerHTML=\"" HINT_CSS "\";doc.head.appendChild(e);doc.hasStyle=true;}function focus(back){var idx=validHints.indexOf(activeHint);if(idx<0){idx=0;}if(back){if(--idx<0){idx=validHints.length-1;}}else{if(++idx>=validHints.length){idx=0;}}return focusHint(idx);}function fire(){if(!activeHint){return\"ERROR:\";}var e=activeHint.e,res;if(config.handleForm){res=handleForm(e);}if(config.keepOpen){filterNum=0;show(false);}else{clear();}return res||config.action(e);}function handleForm(e){var tag=e.nodeName.toLowerCase(),type=e.type||\"\";if(tag===\"input\"||tag===\"textarea\"||tag===\"select\"){if(type===\"radio\"||type===\"checkbox\"){e.focus();click(e);return\"DONE:\";}if(type===\"submit\"||type===\"reset\"||type===\"button\"||type===\"image\"){click(e);return\"DONE:\";}e.focus();return\"INSERT:\";}if(tag===\"iframe\"||tag===\"frame\"){e.focus();return\"DONE:\";}}function open(e,newWin){var oldTarget=e.target;if(newWin){e.target=\"_blank\";}else if(e.target===\"_blank\"){e.removeAttribute(\"target\");}click(e,newWin);e.target=oldTarget;}function focusHint(newIdx){if(activeHint){activeHint.e.classList.remove(fClass);activeHint.label.classList.remove(fClass);mouseEvent(activeHint.e,\"mouseout\");}if((activeHint=validHints[newIdx])){activeHint.e.classList.add(fClass);activeHint.label.classList.add(fClass);mouseEvent(activeHint.e,\"mouseover\");return\"OVER:\"+getSrc(activeHint.e);;}}function click(e,ctrl){mouseEvent(e,\"mouseover\",ctrl);mouseEvent(e,\"mousedown\",ctrl);mouseEvent(e,\"mouseup\",ctrl);mouseEvent(e,\"click\",ctrl);}function mouseEvent(e,name,ctrl){var evObj=e.ownerDocument.createEvent(\"MouseEvents\");evObj.initMouseEvent(name,true,true,e.ownerDocument.defaultView,0,0,0,0,0,(typeof ctrl!=\"undefined\")?ctrl:false,false,false,false,0,null);e.dispatchEvent(evObj);}function getSrc(e){return e.href||e.src||\"\";}function xpath(doc,expr){return doc.evaluate(expr,doc,function(p){return\"http://www.w3.org/1999/xhtml\";},XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);}function followLink(rel,patterns,count){function followFrame(frame){var i,p,reg,res=[],doc=frame.document,elems=[],all=doc.getElementsByTagName(\"a\");for(i=all.length-1;i>=0;i--){var s=doc.defaultView.getComputedStyle(all[i],null);if(s.display!==\"none\"&&s.visibility===\"visible\"){if(all[i].rel.toLowerCase()===rel){res.push(all[i]);}else{elems.push(all[i]);}}}for(p=0;p<patterns.length;p++){reg=patterns[p];for(i=elems.length-1;i>=0;i--){if(elems[i].innerText.match(reg)){res.push(elems[i]);}}}return res;}var i,j,elems,frames=allFrames(window);for(i=0;i<frames.length;i++){elems=followFrame(frames[i]);for(j=0;j<elems.length;j++){if(--count==0){open(elems[j],false);return\"DONE:\";}}}return\"ERROR:\";}function incrementUri(count){var oldnum,newnum,matches=location.href.match(/(.*?)(\\d+)(\\D*)$/);if(matches){oldnum=matches[2];newnum=String(Math.max(parseInt(oldnum)+count,0));if(/^0/.test(oldnum)){while(newnum.length<oldnum.length){newnum=\"0\"+newnum;}}matches[2]=newnum;location.href=matches.slice(1).join(\"\");return\"DONE:\";}return\"ERROR:\";}function allFrames(win){var i,f,frames=[win];for(i=0;i<win.frames.length;i++){frames.push(win.frames[i].frameElement);}return frames;}return{init:function init(mode,keepOpen,maxHints,hintKeys,followLast,hintNumSameLength){var prop,xpathmap={otY:\"//*[@href]|//*[@onclick or @tabindex or @class='lk'or @role='link'or @role='button']|//input[not(@type='hidden'or @disabled or @readonly)]|//textarea[not(@disabled or @readonly)]|//button|//select\",e:\"//input[not(@type)or @type='text']|//textarea\",iI:\"//img[@src]\",OpPsTxy:\"//*[@href]|//img[@src and not(ancestor::a)]|//iframe[@src]\"},actionmap={o:function(e){open(e,false);return\"DONE:\";},t:function(e){open(e,true);return\"DONE:\";},eiIOpPsTxy:function(e){return\"DATA:\"+getSrc(e);},Y:function(e){return\"DATA:\"+(e.textContent||\"\");}};config={maxHints:maxHints,keepOpen:keepOpen,handleForm:(\"eot\".indexOf(mode)>=0),hintKeys:hintKeys,followLast:followLast,hintNumSameLength:hintNumSameLength,};for(prop in xpathmap){if(prop.indexOf(mode)>=0){config[\"xpath\"]=xpathmap[prop];break;}}for(prop in actionmap){if(prop.indexOf(mode)>=0){config[\"action\"]=actionmap[prop];break;}}create();return show(true);},filter:function filter(text){filterNum=0;filterText=text||\"\";return show(true);},update:function update(n){var pos,keys=config.hintKeys;if(null===n&&filterNum){filterNum=Math.floor(filterNum / keys.length);return show(false);}if((pos=keys.indexOf(n))>=0){filterNum=filterNum * keys.length+pos;return show(true);}return\"ERROR:\";},clear:clear,fire:fire,focus:focus,followLink:followLink,incrementUri:incrementUri,};})());"