スクロール処理の拡張
overflow が 指定されているエレメント hjkl で 操作できなかったので、
作ってみた。
h,j,k,l,
";d"で 選択で、抜けるのは、
scrollHeight と offsetHeight あるいは scrollWidth と offsetWidth
一致しないものを対象としてます。
(上手く 動作 するかは 別問題ですが…)
とりあえず、textarea も 動作しました。
また、bufferを弄っているので、異常動作する部位があるかもしれません。
(function(){ if(!liberator.plugins.caisui) liberator.plugins.caisui={}; const attr_name="vimperator_scroll_node"; const COL_WIDTH = 20; const LINE_HEIGHT = 32; let caisui=liberator.plugins.caisui; function hookBefore(obj,attr,func1){ let func2 obj[attr] = (func2=obj[attr]) ? function() func1.apply(obj,arguments) || func2.apply(obj,arguments) : func1; } if(!liberator.plugins.caisui.overflow){ hints.addMode("d","overflow" ,function() caisui.overflow.mark.apply(this,arguments) ,function() caisui.overflow.tags.apply(this,arguments) ); for(let f in liberator.modules.util.Array.itervalues([ "scrollLines","scrollToPercentile","scrollPages","scrollStart","scrollStart","scrollEnd","scrollColumns" ])) let(f=f) hookBefore(buffer, f,function() caisui.overflow[f].apply(this,arguments)); hookBefore(events, "onEscape", function() caisui.overflow.onEscape.apply(this, arguments)); } liberator.plugins.caisui.overflow={ tags:function(){ caisui.overflow.addMark(content.window); return "//*[@"+attr_name+">'0']"; },addMark:function(aWindow){ Array.forEach(aWindow.document.body.getElementsByTagName("*"),function(e){ if((e.offsetHeight !== e.scrollHeight) || (e.offsetWidth !== e.scrollWidth)){ e.setAttribute(attr_name,"1"); } }); Array.forEach(aWindow.frames, arguments.callee); },removeMark:function(aWindow){ if(!aWindow) aWindow=content.window; var doc=aWindow.document; for(var x in buffer.evaluateXPath("//*[@"+attr_name+"]",doc)){ x.removeAttribute(attr_name); } Array.forEach(aWindow.frames,arguments.callee); },mark:function(e){ e.setAttribute(attr_name,"2"); liberator.echo("mark node!"); },getElementCore:function(aWindow){ var e=aWindow.document.evaluate("//*[@"+attr_name+"='2']",aWindow.document,null,9,null).singleNodeValue; if(!e) for(var f in liberator.modules.util.Array.itervalues(aWindow.frames)){ if(e = arguments.callee(f)) break; } return e; },getElement:function() caisui.overflow.getElementCore(content.window) ,scrollY:function(e,y){ var h=e.scrollTop; e.scrollTop += y; if(h===e.scrollTop) liberator.beep(); },scrollLines:function(aLines){ var e=caisui.overflow.getElement(); if(!e) return false; caisui.overflow.scrollY(e, aLines * LINE_HEIGHT); return true; },scrollPages:function(pages){ var e=caisui.overflow.getElement(); if(!e) return false; caisui.overflow.scrollY(e, pages*e.offsetHeight); return true; },scrollToPercentile:function(percentage){ var e=caisui.overflow.getElement(); if(!e) return false; e.scrollTop = e.scrollHeight*percentage/100; return true; },scrollStart:function(){ var e=caisui.overflow.getElement(); if(!e) return false; e.scrollLeft = 0; return true; },scrollEnd:function(){ var e=caisui.overflow.getElement(); if(!e) return false; e.scrollLeft = e.scrollWidth; return true; },scrollColumns:function(cols){ var e=caisui.overflow.getElement(); if(!e) return false; var w = e.scrollLeft; e.scrollLeft += COL_WIDTH * cols; if(e.scrollLeft === w) liberator.beep(); return true; },onEscape:function(){ caisui.overflow.removeMark(); } }; })();