1
0
forked from x/volcanos

opt xterm

This commit is contained in:
shylinux@163.com 2022-09-17 22:42:28 +08:00
parent e232e95427
commit 341bf3c671
12 changed files with 151 additions and 70 deletions

View File

@ -283,6 +283,7 @@ Volcanos(chat.ONAPPEND, {help: "渲染引擎", _init: function(can, meta, list,
can.core.CallFunc([table, chat.ONIMPORT, chat._INIT], {can: table, msg: msg, cb: function(msg) {
action === false || table.onappend._action(table, msg.Option(ice.MSG_ACTION)||can.Conf(ice.MSG_ACTION), action)
action === false || table.onappend._status(table, msg.Option(ice.MSG_STATUS))
// action === false || table.onimport.tool(table, can.base.Obj(msg.Option(ice.MSG_TOOLKIT)))
can.base.isFunc(cb) && cb(msg)
}, target: output||can._output})
})
@ -373,8 +374,9 @@ Volcanos(chat.ONAPPEND, {help: "渲染引擎", _init: function(can, meta, list,
return {text: [value, html.TD], onclick: function(event) { var target = event.target
if (can.page.tagis(html.INPUT, target) && target.type == html.BUTTON) { return run([ctx.ACTION, target.name]) }
if (key == mdb.HASH && can.user.mod.isDiv) { return can.user.jumps("/chat/div/"+value) }
can.sup.onaction.change(event, can.sup, key, event.target.innerText)
if (can.sup.onaction.change(event, can.sup, key, event.target.innerText).length == 0) {
can.sup && can.sup._item_click && can.sup._item_click(value, key)
}
}, ondblclick: function(event) { if ([mdb.KEY].indexOf(key) > -1) { return }
var item = can.core.List(can.Conf("feature.insert"), function(item) { if (item.name == key) { return item } })[0]||{name: key, value: value}
item.run = function(event, cmds, cb) { can.run(can.request(event, line), cmds, cb, true) }
@ -394,6 +396,9 @@ Volcanos(chat.ONAPPEND, {help: "渲染引擎", _init: function(can, meta, list,
})
return (code.scrollBy && code.scrollBy(0, 10000)), code
},
tools: function(can, msg, cb, target) {
can.onimport.tool(can, can.base.Obj(msg.Option(ice.MSG_TOOLKIT)), cb, target)
},
_plugin: function(can, value, meta, cb, target, field) {
meta.feature = can.base.getValid(meta.feature, can.base.Obj(value.meta))||{}
@ -619,7 +624,7 @@ Volcanos(chat.ONMOTION, {help: "动态特效", _init: function(can, target) {
if (pos) { item.scrollTo && item.scrollTo(0, pos-1); return item }
}).length > 0
},
delay: function(can, cb, interval) { can.core.Timer(interval||100, cb) },
delay: function(can, cb, interval) { can.core.Timer(interval||300, cb) },
focus: function(can, target) { if (!target) { return }
target.setSelectionRange && target.setSelectionRange(0, -1), target.focus()
},

View File

@ -24,7 +24,16 @@ Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg
if (val == undefined) { return msg && msg[key] && msg[key][0] || "" }
return msg.append = can.base.AddUniq(msg.append, key), msg[key] = can.core.List(arguments).slice(1), val
},
Result: function() { return msg.result && msg.result.join("") || "" },
Result: function() {
if (msg.result && msg.result[0] == ice.ErrWarn) {
var res = msg.result[0]
for (var i = 1; i < msg.result.length; i+=2) {
res += msg.result[i]+(msg.result[i+1]||"")+" "
}
return res
}
return msg.result && msg.result.join("") || ""
},
Length: function() {
var max = "", len = 0; can.core.List(msg.append, function(key, index) {

View File

@ -62,7 +62,7 @@ fieldset.full>legend { float:left; margin:0; margin-right:5px; }
fieldset.float input[type=button][name=close]{ display:block; }
fieldset.plug>form.option input[type=button][name=close]{ display:block; }
fieldset.full input[type=button][name=close]{ display:block; }
fieldset input[type=button][name=close]{ display:none; }
fieldset.plugin>form.option input[type=button][name=close]{ display:none; }
fieldset.plugin div.status { border-top:1px solid darkcyan; }
fieldset.story div.status { border-top:1px solid darkcyan; }
fieldset.output>form.option { display:none; }
@ -70,6 +70,9 @@ fieldset.output>div.action { display:none; }
fieldset.output div.status { display:none; }
fieldset.output div.toggle { display:none; }
fieldset.story>legend { float:left; margin:0px; margin-right:5px; }
fieldset.story { margin-top:10px; }
fieldset.input.key { overflow:auto; }
fieldset.input.key div.action { display:none; }
fieldset.input.key.simple div.status { display:none; }

View File

@ -33,10 +33,16 @@ fieldset.inner>div.output td.content>div.path { display:none; }
fieldset.inner div.output fieldset.toolkit { position:absolute; bottom:0px; right:0px; }
fieldset.inner>div.output fieldset.toolkit>div.output>fieldset { display:none; }
fieldset.inner>div.output fieldset.toolkit>div.output>fieldset.select { background-color:#0e3369b3; color:white; display:block; z-index:10; }
fieldset.inner>div.status legend { float:right; height:30px; }
fieldset.inner>div.status legend.select { background-color:green; }
fieldset.inner>div.status legend:hover { background-color:green; }
fieldset.inner>div.status { height:31px; overflow:auto; }
fieldset>div.output>fieldset.plug { position:absolute; bottom:0px; right:0px; }
fieldset>div.output>fieldset.plug { display:none; }
fieldset>div.output>fieldset.plug.select { background-color:#0e3369b3; color:white; display:block; z-index:10; }
fieldset>div.status legend { float:right; height:30px; }
fieldset>div.status legend.select { background-color:green; }
fieldset>div.status legend:hover { background-color:green; }
fieldset>div.status { height:31px; overflow:auto; }
fieldset.Action>div.status { display:none; }
body.white fieldset.inner>div.output div.content { color:black; }
body.white fieldset.inner.float>div.output div.content { color:white; }

View File

@ -558,6 +558,12 @@ Volcanos(chat.ONACTION, {help: "控件交互", list: ["搜索", "打开"],
},
_selectLine: function(event, can) { },
searchLine: function(event, can, value) {
can.runAction(can.request(event, {text: value}, can.Option()), "navigate", [], function(msg) {
msg.Append(nfs.FILE)? can.onimport.tabview(can, msg.Append(nfs.PATH), msg.Append(nfs.FILE), msg.Append(nfs.LINE)):
can.user.toast(can, "not found")
})
return
if (can.ui.search) {
can.ui.search.Update(event, [ctx.ACTION, nfs.TAGS, value.trim()])
} else {

View File

@ -17,7 +17,7 @@ fieldset.vimer>div.output div.complete div.pre {
font-size:1.1rem; color:#f0f8ff00; margin-left:5px; float:left;
}
fieldset.vimer>div.output div.complete table {
background:lightblue; max-height:400px; max-width:800px; overflow:auto; display:block; float:left;
background:darkblue; max-height:400px; max-width:800px; overflow:auto; display:block; float:left;
}
fieldset.vimer>div.output div.complete table.content th {
display:none;

View File

@ -253,7 +253,7 @@ Volcanos(chat.ONACTION, {help: "控件交互", list: [],
// list: [nfs.SAVE, code.COMPILE, code.AUTOGEN, nfs.SCRIPT, chat.WEBSITE, web.DREAM],
_run: function(event, can, button, args, cb) {
can.runAction(event, button, args, cb||function(msg) {
can.onimport.tabview(can, can.Option(nfs.PATH), msg.Option(nfs.FILE)), can.ui.source.refresh()
can.onimport.tabview(can, msg.Option(nfs.PATH)||can.Option(nfs.PATH), msg.Option(nfs.FILE)), can.ui.source.refresh()
can.user.toastSuccess(can, button)
})
},
@ -284,7 +284,7 @@ Volcanos(chat.ONACTION, {help: "控件交互", list: [],
can.onaction._runs(can.request(event, {file: can.base.trimSuffix(can.Option(nfs.FILE), can.base.Ext(can.Option(nfs.FILE)))+nfs.JS}), can, button)
},
website: function(event, can, button) {
can.onaction._runs(can.request(event, {file: (can.base.trimSuffix(can.Option(nfs.FILE), can.base.Ext(can.Option(nfs.FILE)))+nfs.ZML).split("/").pop()}), can, button)
can.onaction._runs(can.request(event, {path: "src/", file: (can.base.trimSuffix(can.Option(nfs.FILE), can.base.Ext(can.Option(nfs.FILE)))+nfs.ZML).split("/").pop()}), can, button)
},
dream: function(event, can, button) {
can.onaction._runs(can.request(event, {name: can.base.trimSuffix(can.Option(nfs.FILE).split(ice.PS).pop(), ice.PT+can.base.Ext(can.Option(nfs.FILE)))}), can, button, function(msg) { can.ui.dream.refresh()
@ -329,16 +329,68 @@ Volcanos(chat.ONACTION, {help: "控件交互", list: [],
},
_complete: function(event, can, target) { target = target||can.ui.complete
if (event == undefined) { return }
const PRE = "pre"
var pre = can.ui.current.value.slice(0, can.ui.current.selectionStart)
var end = can.ui.current.value.slice(can.ui.current.selectionStart)
var type = can.core.Split(pre).pop()||""
var name = can.core.Split(type, "", ice.PT).pop()||""
type = can.base.trimSuffix(type, name)
type = can.base.trimSuffix(type, ice.PT)
const PRE = "pre"
function update(target) { can.request(event, {type: type, name: name, text: pre, file: can.Option(nfs.FILE)})
can.runAction(event, "complete", [], function(msg) { can.ui.complete._msg = msg
function update() { target._pre = pre, target._index = -1
can.current.line.appendChild(target), can.page.style(can, target, html.LEFT, can.ui.current.offsetLeft-1, html.MARGIN_TOP, can.ui.current.offsetHeight+4)
can.runAction(can.request(event, {text: pre}, can.Option()), "complete", [], function(msg) {
can.page.Appends(can, target, [{view: [PRE, html.DIV, pre]}])
can.onappend.table(can, msg, function(value, key, index) { return {text: [value, html.TD], onclick: function(event) {
var left = can.ui.current.value.slice(0, can.ui.current.selectionStart)+value
can.current.text(can.ui.current.value = left+can.ui.current.value.slice(can.ui.current.selectionEnd))
can.ui.current.focus(), can.ui.content.scrollLeft -= 10000, can.ui.current.setSelectionRange(left.length, left.length)
}} }, target)
})
}
function filter() {
return can.page.Select(can, target, [html.TBODY, html.TR], function(tr) {
if (!can.page.ClassList.set(can, tr, html.HIDE, can.page.Select(can, tr, html.TD, function(td) {
if (td.innerText.toLowerCase().indexOf(can.base.trimSuffix((name == ice.PT? type: name).toLowerCase(), "(")) == 0) { return td }
}).length == 0)) { return tr }
}).length > (name == ice.PT? 1: 0)
}
function select(index, total) { index = (index+(total+1))%(total+1)
if (index == total) { can.current.text(can.ui.current.value = target._pre) }
can.page.Select(can, target, [html.TBODY, "tr:not(.hide)"], function(tr, i) { if (can.page.ClassList.set(can, tr, html.SELECT, i == index)) {
can.current.text(can.ui.current.value = target._pre+can.page.Select(can, tr, html.TD)[0].innerText)
} }); return index
}
if (event.ctrlKey) { if (event.type == "keyup") {
var total = can.page.Select(can, target, [html.TBODY, "tr:not(.hide)"]).length
switch (event.key) {
case "n": target._index = select(target._index+1, total); break
case "p": target._index = select(target._index-1, total); break
default: return false
}
return can.onkeymap.prevent(event)
} return }
switch (pre.slice(-1)) {
case "\t":
case " ":
case ".":
case "(":
case "{":
update()
break
case "":
default:
filter()
}
return
function update0(target) {
can.request(event, {type: type, name: name, text: pre, file: can.Option(nfs.FILE)})
can.runAction(event, "complete", [], function(msg) { target._msg = msg
if (msg.Length() == 0 && can.base.Ext(can.Option(nfs.FILE)) == nfs.JS) {
msg.name = [], msg.type = [], msg.text = []
can.core.Item(can.core.Value(window, type), function(k, v) {
@ -360,35 +412,6 @@ Volcanos(chat.ONACTION, {help: "控件交互", list: [],
})
}
function filter() {
return can.page.Select(can, target, [html.TBODY, html.TR], function(tr) {
if (!can.page.ClassList.set(can, tr, html.HIDE, can.page.Select(can, tr, html.TD, function(td) {
if (td.innerText.toLowerCase().indexOf(can.base.trimSuffix((name == ice.PT? type: name).toLowerCase(), "(")) == 0) { return td }
}).length == 0)) { return tr }
}).length > (name == ice.PT? 1: 0)
}
function select(index, total) { index = (index+(total+1))%(total+1)
if (index == total) { can.current.text(can.ui.current.value = can.ui.complete._msg.Option(PRE)) }
can.page.Select(can, target, [html.TBODY, "tr:not(.hide)"], function(tr, i) { if (can.page.ClassList.set(can, tr, html.SELECT, i == index)) {
can.current.text(can.ui.current.value = can.ui.complete._msg.Option(PRE)+can.page.Select(can, tr, html.TD)[0].innerText)
} })
return index
}
if (event.ctrlKey) {
if (event.type == "keyup") {
var total = can.page.Select(can, target, [html.TBODY, "tr:not(.hide)"]).length
switch (event.key) {
case "n": can.ui.complete._index = select(can.ui.complete._index+1, total); break
case "p": can.ui.complete._index = select(can.ui.complete._index-1, total); break
default: return false
}
return can.onkeymap.prevent(event)
}
return
}
can.current.line.appendChild(can.ui.complete), can.page.style(can, can.ui.complete, html.LEFT, can.ui.current.offsetLeft-1, html.MARGIN_TOP, can.ui.current.offsetHeight+4)
can.page.Select(can, target, "div.pre", function(item) { item.innerText = can.ui.complete._msg.Option(PRE)||pre })
if (pre == "") { return update(target) }

View File

@ -1,8 +1,11 @@
Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg) { can.onmotion.clear(can)
can.requireModules(["xterm/css/xterm.css", "xterm", "xterm-addon-fit", "xterm-addon-web-links"], function() {
var item = {hash: can.Option(mdb.HASH)}; msg.Table(function(value) { can.core.Value(item, value.key, value.value) })
can.onimport.layout(can, item), can.onappend._status(can), can.onimport._connect(can, item)
can.isCmdMode() && can.misc.Search(can, "hash") && can.onaction.full({}, can)
item.init && can.onmotion.delay(can, function() { can.onimport._input(can, item.init+ice.NL) })
can.onimport.layout(can), can.onappend._status(can), can.onappend.tools(can, msg, function(sub) {
sub._item_click = function(value, key) { can.onimport._input(can, value+ice.NL) }
}), can.isCmdMode() && can.misc.Search(can, mdb.HASH) && can.sup.onaction.full({}, can)
can.onimport._connect(can, item)
})
},
_connect: function(can, item) { var term = new Terminal({tabStopWidth: 4, cursorBlink: true})
@ -11,35 +14,34 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg) { can.o
term.loadAddon(new WebLinksAddon.WebLinksAddon())
term.onTitleChange(function(title) { can.isCmdMode() && can.user.title(title) })
term.onResize(function(size) { can.onimport._resize(can, item, size) })
term.onData(function(val) { can.onimport._input(can, item, val) })
term.onResize(function(size) { can.onimport._resize(can, size) })
term.onData(function(data) { can.onimport._input(can, data) })
term.onCursorMove(function() { can.onexport.term(can) })
can._current = term, term._item = item
term.open(can._output), term.focus()
},
_resize: function(can, item, size) {
can.runAction(can.request({}, size, item), "resize", [], function() { can.onexport.term(can) })
_resize: function(can, size) {
can.runAction(can.request({}, size, can._current._item), "resize", [], function() { can.onexport.term(can) })
},
_input: function(can, item, val) {
can.runAction(can.request({}, item, {"log.disable": ice.TRUE}), "input", [btoa(val)], function() {})
_input: function(can, data) { if (!can._current) { return }
can.runAction(can.request({}, can._current._item), "input", [btoa(data)], function() {})
},
layout: function(can, item) {
if (can.isCmdMode()) { item && can.onimport._title(can, item.name)
layout: function(can) {
if (can.isCmdMode()) { can._current && can.onimport._title(can, can._current._item.name)
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight()+10, html.WIDTH, can.ConfWidth()+20, html.MAX_WIDTH, "")
} else {
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth(), html.MAX_WIDTH, "")
}
can.onmotion.delay(can, function() { can.page.style(can, can._output, html.HEIGHT, "", html.WIDTH, "") })
can._current && can._current._fit.fit()
},
grow: function(can, msg) {
can._current.write(msg.Option(mdb.TEXT))
},
grow: function(can, msg) { can._current.write(msg.Option(mdb.TEXT)) },
})
Volcanos(chat.ONEXPORT, {help: "导出数据", list: [mdb.TYPE, "rows", "cols", "cursorY", "cursorX"],
Volcanos(chat.ONEXPORT, {help: "导出数据", list: [mdb.TYPE, mdb.NAME, "rows", "cols", "cursorY", "cursorX"],
term: function(can) { var term = can._current, item = term._item
can.core.List(can.onexport.list, function(key) {
can.Status(key, can.base.getValid(item[key], can._current[key], can._current.buffer.active[key], ""))
}), can.Status(mdb.TYPE, item[mdb.TYPE]||"")
can.Status(key, can.base.getValid(item[key], term[key], term.buffer.active[key], ""))
}), can.Status(mdb.TYPE, item[mdb.TYPE]||""), can.Status(mdb.NAME, item[mdb.NAME]||"")
},
})

View File

@ -20,10 +20,12 @@ fieldset.word table.content { display:block; max-height:400px; }
fieldset.word fieldset.story { margin:10px; }
fieldset.word fieldset.story.full { margin:0px; }
body.white fieldset.word svg.story.auto defs marker { stroke:red; fill:red; }
body.white fieldset.word svg.story.auto rect { stroke:blue; fill:yellow; }
body.white fieldset.word svg.story.auto text { stroke:blue; fill:blue; }
body.white fieldset.word svg.story.auto line { stroke:red; stroke-width:1; }
body.white fieldset.word svg.story.auto path { stroke:red; stroke-width:1; }
fieldset.word svg.story.auto defs marker { stroke:red; fill:red; }
fieldset.word svg.story.auto rect { stroke:yellow; fill:black; }
fieldset.word svg.story.auto text { stroke:yellow; fill:yellow; }
fieldset.word svg.story.auto line { stroke:red; stroke-width:1; }

View File

@ -38,7 +38,7 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _process: function(can, msg) {
})(); return }
var opt = can.base.Obj(item[ice.OPT], [])
sub.ConfHeight(can.ConfHeight()), sub.ConfWidth(can.ConfWidth()-4*html.PLUGIN_MARGIN)
sub.ConfHeight(can.ConfHeight()/2), sub.ConfWidth(can.ConfWidth())
sub.run = function(event, cmds, cb) {
var res = can.request(event, can.Option(), opts, {pid: msg.Option("pid")})
for (var i = 0; i < opt.length; i += 2) { res.Option(opt[i], opt[i+1]) }
@ -191,6 +191,15 @@ Volcanos(chat.ONACTION, {help: "交互操作", list: [
})
},
full: function(event, can) {
if (can.isCmdMode()) {
can.onmotion.hidden(can, can._legend), can.onmotion.hidden(can, can._option), can.onmotion.hidden(can, can._action), can.onmotion.hidden(can, can._status)
can.ConfHeight(window.innerHeight), can.ConfWidth(window.innerWidth)
can.onimport.layout(can)
} else {
can.onaction["切换全屏"](event, can)
}
},
clear: function(event, can, name) { can.onmotion.clear(can, can._output) },
close: function(event, can) {
if (can.isFullMode()) {

View File

@ -131,16 +131,30 @@ Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg, cb, tar
can.base.isFunc(cb) && cb(sub)
}, target)
},
tool: function(can, list, cb, target) { target = target||can._output
can.core.List(list, function(meta) { typeof meta == "string" && (meta = {index: meta})
can.onimport.plug(can, meta, target, function(sub) {
sub.ConfHeight(can.ConfHeight()-4*html.ACTION_HEIGHT), sub.ConfWidth(can.ConfWidth())
sub.page.style(sub, sub._output, html.MAX_HEIGHT, sub.ConfHeight())
sub.page.style(sub, sub._output, html.MAX_WIDTH, sub.ConfWidth())
can._status.appendChild(sub._legend), sub._legend.onclick = function(event) {
if (can.page.Select(can, can._status, ice.PT+html.SELECT)[0] == event.target) {
can.page.ClassList.del(can, event.target, html.SELECT)
can.page.ClassList.del(can, sub._target, html.SELECT)
return
}
can.onmotion.select(can, target, html.FIELDSET, sub._target), sub.Focus()
can.onmotion.select(can, can._status, html.LEGEND, event.target)
if (meta.msg == true) { meta.msg = false, sub.Update() }
}, sub.select = function() { return sub._legend.click(), sub }
sub.onaction.close = function() { sub.select() }
sub._legend.onmouseenter = null
can.base.isFunc(cb) && cb(sub)
})
})
},
})
Volcanos(chat.ONACTION, {help: "操作数据",
_trans: {"full": "全屏"},
full: function(event, can) {
if (can.isCmdMode()) {
can.onmotion.hidden(can, can._legend), can.onmotion.hidden(can, can._option), can.onmotion.hidden(can, can._action), can.onmotion.hidden(can, can._status)
can.ConfHeight(window.innerHeight), can.ConfWidth(window.innerWidth)
can.onimport.layout(can)
} else {
can.sup.onaction["切换全屏"](event, can.sup)
}
},
})

View File

@ -24,6 +24,7 @@ var ice = {
RUN: "run", ERR: "err", OPT: "opt",
CAN: "can",
PWD: "./",
ErrWarn: "warn: ",
MSG_DETAIL: "detail",
MSG_OPTION: "option",
@ -43,6 +44,7 @@ var ice = {
MSG_DISPLAY: "_display",
MSG_PROCESS: "_process",
MSG_TOOLKIT: "_toolkit",
MSG_USERNAME: "user.name",
MSG_USERNICK: "user.nick",