補完リストの拡張

ある程度動くようになったので公開です。
補完リストをオーバーレイっぽく表示にしてみた。

windows 以外では 微妙もしくは動作しないようです


こんな感じになります。

折角オーバレイなので透過させてます。

処理

vbox>iframe#liberator-completions


panel(tooltip)>vbox>iframe#liberator-completions

に変更し、表示・非表示できるように関数を修正してます。

usePanel

0 で tooltip を利用
1 で panel を 利用

useDummyAction

panel の 問題強引改修
0 無効 1 有効

useResize

windowリサイズに自動幅調整
0 無効 1 有効

delayResize

補完リスト幅リサイズ遅延時間
あまり小さいと多分重いかなと…

useWinGlass

きっとvista以降aero有効環境でグラス効果が入る!!


デフォルトは、1,1,1,0,100 となってます。


liberator.globalVariables.completionsTipStyleと
liberator.globalVariables.iframeStyle で styleの変更が可能です。



liberator-completions-ext.js

// vim: set fdm=marker :
(function(){
	//{{{ debug
	const usePanel       = 1;
	const useDummyAction = 1;
	const useResize      = 1;
	const useWinGlass    = 0;
  const useOpacity     = 1;

	const delayResize = 100;
	//}}}

	//{{{ style config
	const tipStyle = liberator.globalVariables.completionsTipStyle
		|| <>
		{useWinGlass ? <>
			background: transparent;
			-moz-appearance: -moz-win-glass;
		</>:<>
			-moz-appearance:none;
			background: {useOpacity ? "rgba(0,0,0,0.2)":"gray"};
		</>}
		{usePanel ? "" : <>max-width:65535em;</>}
		-moz-border-radius: 8px;
		padding:0.5em;
		border:none;
	</>;
	const iframeStyle = liberator.globalVariables.completionsIframeStyle
		|| useOpacity ? "opacity:0.8" : "";
	//}}}

	const oid = "liberator-completions";
	const sid = "liberator-statusline";

	var iframe = document.getElementById(oid);
	var vbox = iframe.parentNode;
	var tooltip = document.createElement(usePanel ? "panel" : "tooltip");
	tooltip.setAttribute("style",tipStyle);
	if(usePanel){
		//tooltip.setAttribute("noautofocus", true);
		tooltip.setAttribute("noautohide", true);

		if(dummyAction){
			var dummy = document.createElement("popup");
			dummy.setAttribute("style",<>
				-moz-appearance:none;
			</>);
      dummy.collapsed = true;
			dummy.addEventListener("popupshown",function(){
				this.hidePopup();
			},false);
			document.documentElement.appendChild(dummy);
		}
	}

	vbox.parentNode.insertBefore(tooltip, vbox);
	vbox.removeChild(iframe);

	var url = iframe.getAttribute("src");

	iframe = document.createElementNS(XHTML,"iframe");
	iframe.setAttribute("id", oid);
	iframe.setAttribute("style", iframeStyle);
	iframe.setAttribute("flex",1);
	vbox.appendChild(iframe);

	tooltip.appendChild(vbox);

	function oneEventListenr(obj, event, usecapture, func){
		let args = [event, function(){
			this.removeEventListener.apply(this, args);
			func.apply(this, arguments);
		},usecapture];
		obj.addEventListener.apply(obj,args);	
	}
	function dummyAction(){
		if(usePanel&&useDummyAction){
			let textbox = document.getElementById("liberator-commandline-command").parentNode;
			dummy.openPopup(textbox,"overlap",0,0,false, false);
		}
	}

	oneEventListenr(iframe, "load", true, function(){
		try{
			if(!this.contentDocument){
				liberator.echoerr(new Error("init:iframe failed!!"));
				return;
			}
			let(hack=commandline._completionList = ItemList(oid)){
				function _show_ext(self, isResize){
					let tip = self._container.parentNode;

					if(isResize) tip.hidePopup();
					if(!usePanel && tip.state === "open") return;

					tip.sizeTo(window.innerWidth, -1);
					tip.openPopup(document.getElementById(sid), "before_start", 0, 0, false, false);

					dummyAction();
				}
				hack.hide = function hide_ext(){
					this._container.collapsed = true;
					this._container.parentNode.hidePopup();
				};
				hack.show = function show_ext(){
					if(this._container.collapsed){
						if(this._minHeight == 0){
							oneEventListenr(tooltip, "popupshown", false, function(){
								hack._autoSize();
							});
						}
						this._container.collapsed = false;

						_show_ext(this);
					}else if(!usePanel) _show_ext(this);
				};

				if(useResize){
					let tid=0;
					window.addEventListener("resize",function resize(event){
						if(!hack._container.collapsed){
							tid&&window.clearTimeout(tid);
							tid = window.setTimeout(function(){
								try{
									tid = 0;
									let tooltip = hack._container.parentNode;

									_show_ext(hack, true);
								}catch(ex){liberator.echoerr(ex);}
							},delayResize);
						}
					},false);
				}
			}
		}catch(ex){liberator.echoerr(ex);}
	});

	iframe.setAttribute("src", url);
})();

usePanel=1 useDummyAction=0

選択候補が出現するものの,で候補の切り替えができません。


後述しますが、どこでも良いので右クリックしてコンテキストメニュを表示→非表示とすると動きました…

usePanel=0

panelをtooltipに変更

の問題は解決するものの以下の問題が発生

  • マウスのhoverで消える
  • tooltipなので最前面表示される(=他のwindowに切り替えても補完リストが表示されている)

usePanel=1 useDummyAction=1

panel 表示中のkeypressが届かない点を改修

バクなような気がしますが、他の要素をopenPopup して 隠すと
eventが届くようになることが経験的にわかったので実装
現状一番理想的に動作する。


window XP sp3 では 上記結果が出たのですが、
他の環境ではどうなるかは謎です。

2010.04.24 11:54

末尾のXPでの動作結果のuseXXXのフラグ記載に誤りを訂正

2010.04.24 22:46

useOpacity を 追加(その2を参照)

2010/05/03 13:48

OSに ついて 注意を 追加