2017年3月17日金曜日

インクリメンタルサーチ式ミニライブラリ

プログラミングの際に利用する定型文とそれを識別するためのキーワードをセットにして保存・検索するためのプログラムを作成しました。
サンプルプログラムもセットで保存することができ、動作確認が容易にできます。


起動画面


最上段から順に以下の配置になっています。
・キーワード入力用inputbox
・入力中キーワードを含むタイトル一覧エリア
・タイトルに対応する内容のテキストエリア
・サンプル一覧エリア

キーワード入力用inputboxに文字列を入れるとonkeyupイベントが発生する度に入力内容を含むタイトル一覧が表示されます。



登録済みタイトルと同一のキーワードを入力するか、タイトル一覧に選択されているものをクリックすると、それに対応する内容がテキストエリアに表示されます。
サンプルも登録済みなら表示されます。



以下ソース
<html>
<head>
<title>miniライブラリ</title>
<style type="text/css">
.max{width:100%;height:100%}
.w-max{width:100%}
.nowrap{white-space:nowrap}
.ta-c{text-align:center}
.bc{border-collapse:collapse}
.of-auto{overflow:auto}
.of-hidden{overflow:hidden}
.border1{border:solid 1px #000}
</style>
</head>
<body class=of-hidden>
<table class="bc max">
<tr height=1><td><input id=inp class=w-max></td></tr>
<tr height=1><td><div id=div候補 class="of-auto border1" style="height:100px"></div></td></tr>
<tr><td><textarea id=ta class=max wrap=off></textarea></td></tr>
<tr height=200><td><div id=divSample class="of-auto border1 max"></div></td></tr>
<tr height=1><td><button id=btn保存>保存</button><button id=btnサンプル追加>サンプル追加</button></td></tr>
</table>
</body>
<script>
resizeTo(300,600)
window.attachEvent('onload',function(){
基準フォルダ = decodeURI(location.href.replace(/^file:|[\\\/][^\\\/]+$/g,'').replace(/^\/+([A-Z]:)/i,'$1'))
loadMethods()
})
objMethod = {}
objSample = {}
loadMethods=function(){
pathObj = 基準フォルダ+'/method.obj'
if(!fso.AXO.FileExists(pathObj)){ return }
eval(fso.Read(pathObj))
}
saveMethods=function(){
var m=arguments.callee
if(!m.func){
var obj変換={
'\\\\' : '\\\\',
'"' : '\\"',
'\\r' : '\\r',
'\\n' : '\\n'
}
forIn(obj変換, function(name,v){obj変換[name] = {R:new RegExp(name,'g'), v:v}})
var エスケープ=function(str){
forIn(obj変換,function(n,o){ str = str.replace(o.R, o.v) })
return str
}
m.func = function(){
var arr=[], i=0, arrSample=[]
forIn(objMethod, function(name,str){ arr[i++] = '"' + エスケープ(name) + '" : "' + エスケープ(str) + '"' })
forIn(objSample, function(name,obj){
var arr=[], i=0
forIn(obj, function(サンプル名,str){
arr[i++] = '\t\t"' + エスケープ(サンプル名) + '" : "' + エスケープ(str) + '"'
})
arrSample.push('\t"'+エスケープ(name)+'":{\r\n' + arr.join(',\r\n') + '\r\n\t}')
})
fso.Write(pathObj, 'objMethod = {\r\n\t'+arr.join(',\r\n\t')+'\r\n}\r\n\r\nobjSample = {\r\n'+arrSample.join(',\r\n')+'\r\n}')
edit.setFlag(false)
}
}
m.func()
}
edit={
flag:false,
setFlag:function(sw){ document.title = 'miniライブラリ' + ((this.flag = sw) ? ' - 編集中' : '') }
}
btn保存.onclick=function(){
var name=inp.value
if(!name){
inp.focus()
return alert('名前を入力してください')
}
objMethod[name] = ta.value
saveMethods()
}
btnサンプル追加.onclick=function(){
var name=inp.value
if(!name){
inp.focus()
return alert('名前を入力してください')
}
var サンプル名=prompt('追加するサンプル名を入力してください','sample.wsf')
if(!サンプル名){return}
if(!objSample[name]){ objSample[name] = {} }
objSample[name][サンプル名] = ''
サンプル表示(サンプル名)
}
ta.onchange = function(){ edit.setFlag(true) }
ta.onkeyup = function(){
if(edit.flag){return}
var name=inp.value, str=this.value
if((!name && str) || !objMethod[name] || objMethod[name]!=str){edit.setFlag(true)}
}
inp.onkeyup=function(){
var str=inp.value
div候補[iH] = '<div style="padding:2px;width:100%"><input class=w-max></div>'
var div=div候補[FI].removeNode(true), newDIV
var name付きfunc=function(name, func){func.name = name; return func}
var arr=[]
forIn(objMethod, function(name){ name.indexOf(str)!=-1 && arr.push(name) })
for0L(arr.sort(),function(i,name){
div候補[iB](newDIV=div.cloneNode(true))
var inp候補=newDIV[FI]
setTimeout(function(){inp候補.value = name},0)
inp候補.onchange = name付きfunc(name, function(){ method名前変更(arguments.callee.name, this) })
inp候補.onclick = name付きfunc(name, function(){ method表示(arguments.callee.name) })
})
ta.value = objMethod[str] || ''
サンプル表示()
}
method名前変更=function(before, inp候補){
var after=inp候補.value
var 中断=function(msg){
inp候補.value = before
msg && alert(msg)
}
if(!after){
if(!confirm('['+before+']を削除しますか?')){return 中断()}
return method削除(before, inp候補)
}
if(objMethod[after]){return 中断('['+after+']は定義済みです')}
objMethod[after] = objMethod[before]
delete objMethod[before]
if(inp.value==before){inp.value = after}
saveMethods()
}
method表示=function(name){
if(edit.flag && !confirm('['+inp.value+']への編集をキャンセルして['+name+']を表示しますか?')){return}
inp.value = name
setTimeout(function(){ta.value = objMethod[name]},0)
edit.setFlag(false)
サンプル表示()
}
サンプル表示=function(selectサンプル名){
var name=inp.value
divSample[iH] = (''+function(){/*
<div style="padding:10px;width:100%">
<table class="bc w-max" border=1>
<tr>
<td>
<table class="w-max bc"><td><input class=w-max></td><td width=1><button>run</button></td></table>
</td>
</tr>
<tr><td><textarea class=w-max wrap=off style="height:100px"></textarea></td></tr>
</table>
</div>
*/}).split('/*')[1].split('*/')[0].replace(/\t/g,'')
var tbl=divSample[FI].removeNode(true), newTBL
var getsETN=function(elem,name){return elem.getElementsByTagName(name)}
forIn(objSample[name], function(サンプル名, v){
divSample[iB](newTBL=tbl.cloneNode(true))
var inpサンプル名=getsETN(newTBL,'input')[0], btn=getsETN(newTBL,'button')[0], ta=getsETN(newTBL,'textarea')[0]
inpサンプル名.onchange=function(){
var str=this.value, name=inp.value
if(!str){
if(!confirm('サンプル['+サンプル名+']を削除しますか?')){return this.value = サンプル名}
delete objSample[name][サンプル名]
return newTBL.removeNode(true)
}
if(objSample[name][str]){
alert('['+str+']というサンプルは定義済みです')
return this.value = サンプル名
}
objSample[name][str] = objSample[name][サンプル名]
delete objSample[name][サンプル名]
}
btn.onclick=function(){
var path=fso.gsf2+'\\'+サンプル名
fso.Write(path, ta.value)
fso.Write(path+'.wsf', ['<'+'job>','<'+'script>','('+function(path){
AXO=function(name){return new ActiveXObject(name)}
AXO('WScript.Shell').run(path, 1, true)
fs=AXO('Scripting.FileSystemObject')
d=function(p){fs.DeleteFile(p)}
d(path)
d(WScript.ScriptFullName)
}+')("'+path.replace(/\\/g,'\\\\')+'")','<'+'/script>','<'+'/job>'].join('\r\n'))
shell.run(path+'.wsf')
}
ta.onchange=function(){
objSample[name][サンプル名] = this.value
edit.setFlag(true)
}
setTimeout(function(){
inpサンプル名.value = サンプル名
ta.value = v
},0)
selectサンプル名 == サンプル名 && setTimeout(function(){ ta.focus() },0)
})
}
method削除=function(name, inp候補){
delete objMethod[name]
delete objSample[name]
name==inp.value && サンプル表示()
inp候補[PA].removeNode(true)
saveMethods()
}
iT='innerText', iH='innerHTML', FI='firstChild', CN='childNodes', PA='parentNode', iB='insertBefore', LEN='length'
for0L = function(arr,fun){for(var i=0,L=arr[LEN],res;i<L;i++){if(res=fun(i,arr[i])){return res}}}
forIn = function(obj,fun){var name,res; for(name in obj){if(res=fun(name, obj[name])){return res}}}
AXO=function(name){return new ActiveXObject(name)}
shell=AXO('WScript.Shell')
fso=function(){
var fs=AXO('Scripting.FileSystemObject')
return {
AXO:fs,
gsf2:fs.GetSpecialFolder(2), // Z:\TEMP
Read:function(path, swCreate, swUnicode){
if(!fs.FileExists(path)){return}
with(fs.OpenTextFile(path, 1, swCreate, swUnicode)){ var str=AtEndOfStream ? '' : ReadAll(); Close() }
return str
},
Write:function(path,str,swUnicode,sw上書きしない){ with(fs.CreateTextFile(path, !sw上書きしない, swUnicode)){ Write(str); Close() } },
Lock:function(path){
var pathL=path+'.lock', ws, wsn=AXO('WScript.Network')
try{
ws=fs.CreateTextFile(pathL)
ws.Write(wsn.computerName+'\r\n'+wsn.userName)
return {Close:function(){ ws.Close(); fs.DeleteFile(pathL) }}
}
catch(e){
return this.Read(pathL)
}
}
}
}()
</script>
</html>

0 件のコメント:

コメントを投稿