diff --git a/frame.js b/frame.js index f0b22c91..10a45843 100644 --- a/frame.js +++ b/frame.js @@ -159,10 +159,10 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { CloneField: can.Clone, CloneInput: function() { can.onmotion.focus(can, add(item)._target) }, Input: can.Input, Option: can.Option, Action: can.Action, Status: can.Status, }, [item.display, chat.PLUGIN_INPUT_JS], function(sub) { sub.Conf(item) if (item.type == html.TEXT) { can.page.Append(can, sub._target.parentNode, [{text: [sub._target.value, html.SPAN, mdb.VALUE]}]) } - if (item.type == html.BUTTON && can.base.isIn(item.name, mdb.CREATE, mdb.INSERT)) { can.onappend.style(can, "icons", sub._target.parentNode) + if (item.type == html.BUTTON && can.base.isIn(item.name, mdb.CREATE, mdb.INSERT, mdb.PRUNES, mdb.PRUNE)) { can.onappend.style(can, "icons", sub._target.parentNode) can.page.Append(can, sub._target.parentNode, [{icon: item.name, onclick: function(event) { can.Update(event, [ctx.ACTION, item.name]) }}]) } - sub.run = function(event, cmds, cb, silent) { var msg = can.request(event, kit.Dict(chat._TOAST, ice.PROCESS))._caller() + sub.run = function(event, cmds, cb, silent) { var msg = can.requestAction(event, item.name)._caller() msg.RunAction(event, sub, cmds) || msg.RunAction(event, can.sub, cmds) || can.Update(event, can.Input(cmds, !silent), cb, silent) }, can._inputs = can._inputs||{}, can._inputs[item.name] = sub, sub.sup = can can.core.ItemCB(sub.onaction, function(key, cb) { sub._target[key] = function(event) { can.misc.Event(event, can, function(msg) { cb(event, sub, sub._target) })} }) @@ -174,7 +174,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }; var auto; can.core.Next(can.core.Value(can, [chat.ONIMPORT, mdb.LIST])||meta.inputs, add, function() { skip || can.Conf(ice.AUTO) == "delay" || auto && auto.click() }) }, _action: function(can, list, action, meta) { meta = meta||can.onaction||{}, action = action||can._action, can.onmotion.clear(can, action) - function run(event, button) { can.misc.Event(event, can, function(msg) { var _can = can._fields? can.sup: can + function run(event, button) { can.misc.Event(event, can, function(msg) { var _can = can._fields? can.sup: can; can.requestAction(event, button) var cb = meta[button]||meta[chat._ENGINE]; cb? can.core.CallFunc(cb, {event: event, can: can, button: button}): can.run(event, button == mdb.LIST? []: [ctx.ACTION, button].concat(_can.Input())) }) } return can.core.List(can.page.inputs(can, can.base.getValid(can.base.Obj(list), can.core.Value(can, [chat.ONACTION, mdb.LIST]), meta != can.onaction? can.core.Item(meta): [])||[]), function(item) { @@ -226,10 +226,9 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { can.core.CallFunc([sub, chat.ONIMPORT, chat._INIT], {can: sub, msg: msg, cb: function(msg) { action === false || can.onmotion.clear(can, can._action), sub.onappend._action(sub, can.Conf(ice.MSG_ACTION)||msg.Option(ice.MSG_ACTION), action||can._action) action === false || sub.onappend._status(sub, sub.onexport&&sub.onexport.list||msg.Option(ice.MSG_STATUS)), can.user.isMobile || sub.onappend.tools(sub, msg) - can.onimport.size(can, can.ConfHeight(), can.ConfWidth(), can.Conf("_auto"), can.Mode()) can.onappend.style(sub, sub.Conf(ctx.STYLE)), can.onmotion.story.auto(can, can._output) - if (can.onimport.size) { if (can.isFullMode() || can.isCmdMode()) { can.onimport.size(can, can.page.height(), can.page.width(), true) } - can.onexport.output(sub, msg) + if (can.onimport.size) { if (can.isFullMode() || can.isCmdMode()) { can.ConfHeight(can.page.height()), can.ConfWidth(can.page.width()) } + can.onimport.size(can, can.ConfHeight(), can.ConfWidth(), can.Conf("_auto"), can.Mode()), can.onexport.output(sub, msg) } can.base.isFunc(cb) && cb(msg) }, target: output}) }) @@ -277,7 +276,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { if (msg.append.length == 2 && msg.append[0] == mdb.KEY && msg.append[1] == mdb.VALUE) { if (key == mdb.VALUE) { key = data.key } data = {}, can.core.List(list, function(item) { data[item.key] = item.value }) } function run(event, cmd, arg) { can.misc.Event(event, can, function(msg) { can.run(can.request(event, data, can.Option()), [ctx.ACTION, cmd].concat(arg)) }) } return {text: [value, html.TD], onclick: function(event) { var target = event.target - if (can.page.tagis(target, html.INPUT) && target.type == html.BUTTON) { can.request(event, {action: target.name}) + if (can.page.tagis(target, html.INPUT) && target.type == html.BUTTON) { can.requestAction(event, target.name) meta && meta[target.name]? can.user.input(event, can, meta[target.name], function(args) { run(event, target.name, args) }): run(event, target.name) } else { can.sup.onimport.change(event, can.sup, key, event.target.innerText) || can.sup.onexport.record(can.sup, value, key, data, event) } }, ondblclick: function(event) { if (can.base.isIn(key, mdb.KEY, mdb.HASH, mdb.ID)) { return } @@ -311,22 +310,37 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { if (can.base.endWith(style, ".css")) { return can.require([style]) } can.base.isObject(style) && !can.base.isArray(style)? can.page.style(can, target, style): can.page.ClassList.add(can, target, style) }, - scroll: function(can, target, offset, length) { if (target.scrollHeight/target.offsetHeight == 1) { return } + scroll: function(can, target, offset, length) { if (offset) { var ui = can.page.Append(can, target, [{view: "scrollbar", style: {height: length*target.offsetHeight*2}}]) target.addEventListener("scroll", function(event) { can.page.style(can, ui.scrollbar, html.TOP, target.scrollTop+offset*target.offsetHeight, html.RIGHT, -target.scrollLeft) }) return ui.scrollbar } - var begin, _target = can.page.Append(can, target, [{view: "scrollbar", - onmousedown: function(event) { begin = {top: target.scrollTop, y: event.y}, window._mousemove = event.target }, - onmousemove: function(event) { if (!begin) { return } target.scrollTop = begin.top+(event.y-begin.y)/target.offsetHeight*target.scrollHeight, can.onkeymap.prevent(event) }, - onmouseup: function(event) { begin = null, delete(window._mousemove) }, + var vbegin, vbar = can.page.Append(can, target, [{view: [["scrollbar", html.VERTICAL]], + onmousedown: function(event) { vbegin = {top: target.scrollTop, y: event.y}, window._mousemove = event.target }, + onmousemove: function(event) { if (!vbegin) { return } target.scrollTop = vbegin.top+(event.y-vbegin.y)/target.offsetHeight*target.scrollHeight, can.onkeymap.prevent(event) }, + onmouseup: function(event) { vbegin = null, delete(window._mousemove) }, }])._target - target.addEventListener("scroll", function(event) { var height = can.base.Min(target.offsetHeight*target.offsetHeight/target.scrollHeight, target.offsetHeight/4) - can.page.style(can, _target, html.HEIGHT, height, html.RIGHT, -target.scrollLeft, "visibility", "visible", + var hbegin, hbar = can.page.Append(can, target, [{view: [["scrollbar", html.HORIZON]], + onmousedown: function(event) { hbegin = {left: target.scrollLeft, x: event.x}, window._mousemove = event.target }, + onmousemove: function(event) { if (!hbegin) { return } target.scrollLeft = hbegin.left+(event.x-hbegin.x)/target.offsetWidth*target.scrollWidth, can.onkeymap.prevent(event) }, + onmouseup: function(event) { hbegin = null, delete(window._mousemove) }, + }])._target + target.addEventListener("scroll", function(event) { + var height = can.base.Min(target.offsetHeight*target.offsetHeight/target.scrollHeight, target.offsetHeight/4) + target.scrollHeight > target.offsetHeight && can.page.style(can, vbar, html.HEIGHT, height, html.RIGHT, -target.scrollLeft, html.VISIBILITY, html.VISIBLE, html.TOP, target.scrollTop+target.scrollTop/(target.scrollHeight-target.offsetHeight)*(target.offsetHeight-height), - ), can.onmotion.delayOnce(can, function() { can.page.style(can, _target, "visibility", "hidden") }, 3000, target._delay_scroll = target._delay_scroll||[]) + ) + vbar.innerHTML = `${target.scrollTop}+${target.offsetHeight}/${target.scrollHeight}` + var width = can.base.Min(target.offsetWidth*target.offsetWidth/target.scrollWidth, target.offsetWidth/4) + target.scrollWidth > target.offsetWidth && can.page.style(can, hbar, html.WIDTH, width, html.BOTTOM, -target.scrollTop, html.VISIBILITY, html.VISIBLE, + html.LEFT, target.scrollLeft+target.scrollLeft/(target.scrollWidth-target.offsetWidth)*(target.offsetWidth-width), + ) + hbar.innerHTML = `${target.scrollLeft}+${target.offsetWidth}/${target.scrollWidth}` + can.onmotion.delayOnce(can, function() { + can.page.style(can, vbar, html.VISIBILITY, html.HIDDEN), can.page.style(can, hbar, html.VISIBILITY, html.HIDDEN) + }, 1000, target._delay_scroll = target._delay_scroll||[]) }) - return _target + return vbar }, toggle: function(can, target) { var toggle = can.page.Append(can, target, [ diff --git a/index.css b/index.css index 630b8fe1..60c02d7e 100644 --- a/index.css +++ b/index.css @@ -35,6 +35,7 @@ table.content.action th:last-child { position:sticky; right:2px; box-shadow: var table.content.action td:last-child { position:sticky; right:2px; box-shadow: var(--box-shadow); } table.content col.time { width:180px; } table.content col.action { width:180px; } +table.content:hover col.option { background-color:var(--hover-bg-color); } fieldset.panel.Action.tabs table.content { width:100%; } h1 { text-align:center; margin:20px 0; } h2 { margin:20px 0; } h3 { margin:20px 0; } hr, td.hr { border-bottom:var(--plugin-border-color) dashed 1px; margin:5px; } @@ -134,8 +135,8 @@ legend>i:first-child { margin-right:10px; } div.item>i:first-child { margin-righ form.option div.icon, form.option span.icon { font-size:20px; line-height:32px; padding:0 5px; margin:0; height:32px; } div.action div.icon, div.action span.icon { font-size:20px; line-height:32px; padding:0 5px; margin:0; height:32px; } form.option div.icon:first-child { margin-left:-5px; } -form.option div.icon.refresh { font-size:26px; line-height:28px; } -form.option div.icon.goback { font-size:26px; line-height:28px; } +form.option div.icon.refresh { font-size:28px; line-height:28px; translate:0 -1px; } +form.option div.icon.goback { font-size:28px; line-height:28px; translate:0 -1px; } form.option div.icon.next { font-size:18px; } form.option div.icon.prev { font-size:18px; } div.item.select>span.icon { margin-left:-25px; margin-right:3px; visibility:hidden; } @@ -144,7 +145,7 @@ div.item.text { position:relative; } div.item.text>span.icon { margin-left:-25px; margin-right:3px; cursor:pointer; } div.item.text>span.icon.delete { position:absolute; font-size:20px; visibility:hidden; } div.item.text:hover>span.icon.delete { visibility:visible; } -div.item.button>span.icon.create { font-size:26px; line-height:28px; } +div.item.button>span.icon.create { font-size:32px; line-height:32px; translate:0px -2px; display:block; } div.tabs span.icon { margin-left:5px; visibility:hidden; } div.tabs>div.select span.icon { visibility:visible; } div.tabs>div:hover span.icon { visibility:visible; } @@ -163,9 +164,10 @@ fieldset.float>div.action>div.button.icons>input { display:none; } fieldset.full>div.action>div.button.icons>input { display:none; } fieldset.cmd>div.action>div.button.icons>input { display:none; } fieldset:not(.float)>form.option>div.text>span.value { display:none; } -fieldset.float>form.option>div.text>input { display:none; } -fieldset.float>form.option>div.text>span { display:none; } -fieldset.float>form.option>div.text>span.value { white-space:pre; padding:7px; height:32px; max-width:200px; display:block; overflow:auto; } +fieldset.float.plug>form.option>div.text>span.value { display:none; } +fieldset.float:not(.plug)>form.option>div.text>input { display:none; } +fieldset.float:not(.plug)>form.option>div.text>span { display:none; } +fieldset.float:not(.plug)>form.option>div.text>span.value { white-space:pre; padding:7px; height:32px; max-width:200px; display:block; overflow:auto; } fieldset.float div.text:hover>span.icon.delete { visibility:hidden; } body.mobile:not(.landscape) fieldset.float>form.option>div.text>span.value { display:none; } body.windows form.option>div.icon { font-size:21px; } @@ -242,10 +244,14 @@ input:hover[type=button][name=create] { background-color:var(--create-bg-color); input:hover[type=button][name=insert] { background-color:var(--create-bg-color); color:var(--create-fg-color); } input:hover[type=button][name=restart] { background-color:var(--create-bg-color); color:var(--create-fg-color); } input:hover[type=button][name=start] { background-color:var(--create-bg-color); color:var(--create-fg-color); } +input:hover[type=button][name=build] { background-color:var(--create-bg-color); color:var(--create-fg-color); } input:hover[type=button][name=run] { background-color:var(--create-bg-color); color:var(--create-fg-color); } input:hover[type=button][name=open] { background-color:var(--create-bg-color); color:var(--create-fg-color); } input:hover[type=button][name=stop] { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } +input:hover[type=button][name=drop] { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } input:hover[type=button][name=trash] { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } +input:hover[type=button][name=prune] { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } +input:hover[type=button][name=prunes] { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } input:hover[type=button][name=delete] { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } input:hover[type=button][name=remove] { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } /* theme */ @@ -296,6 +302,7 @@ div.tabs div { background-color:var(--plugin-bg-color); } div.tabs div:hover { background-color:var(--hover-bg-color); color:var(--hover-fg-color); } div.tabs div.select { background-color:var(--hover-bg-color); color:var(--hover-fg-color); } div.plug legend { background-color:var(--output-bg-color); } +div.plug legend:hover { background-color:var(--hover-bg-color); } div.plug legend.select { background-color:var(--plugin-bg-color); } div.complete>table { background-color:var(--plugin-bg-color); } body.light fieldset.panel:not(.main)>div.output div.state:hover { background-color:var(--panel-hover-bg-color); color:var(--panel-hover-fg-color); } @@ -361,14 +368,18 @@ fieldset.can.data { font-size:14px; } img, iframe { margin-bottom:-3px; } iframe { height:420px; width:100%; } /* scrollbar */ -div.scrollbar { background-color:#0000ff66; width:10px; position:absolute; right:0; top:0; transition:width .3s 1s; visibility:hidden; } -div.scrollbar:hover { width:30px; transition:width .1s;} +div.scrollbar { background-color:#0000ff66; border-radius:10px; position:absolute; visibility:hidden; font-size:8px !important; } +div.scrollbar.vertical { writing-mode:tb; width:10px; right:0; top:0; transition:width .3s 1s; } +div.scrollbar.vertical:hover { width:30px; transition:width .1s; font-size:24px !important; } +div.scrollbar.horizon:hover { height:30px; transition:height .1s; font-size:24px !important; } +div.scrollbar.horizon { height:10px; left:0; bottom:0; transition:height .3s 1s; } fieldset.panel.River>div.output::-webkit-scrollbar { width:0 !important; height:0 !important; } fieldset.panel.Action>div.output::-webkit-scrollbar { width:0 !important; height:0 !important; } form.option>div.text>span.value::-webkit-scrollbar { width:0 !important; height:0 !important; } div.status::-webkit-scrollbar { width:0 !important; height:0 !important; } div.project::-webkit-scrollbar { width:0 !important; height:0 !important; } div.content::-webkit-scrollbar { width:0 !important; height:0 !important; } +fieldset.word>div.output::-webkit-scrollbar { width:0 !important; height:0 !important; } div.toggle::-webkit-scrollbar { width:0 !important; height:0 !important; } div.story[data-type=spark]::-webkit-scrollbar { width:0 !important; height:0 !important; } div.carte::-webkit-scrollbar { width:0 !important; height:0 !important; } diff --git a/lib/page.js b/lib/page.js index cf3b2f50..141acce9 100644 --- a/lib/page.js +++ b/lib/page.js @@ -171,7 +171,8 @@ Volcanos("page", { AppendTable: function(can, msg, target, list, cb) { if (!msg.append||msg.append.length == 0) { return } var ui = can.page.Append(can, target, [{type: html.TABLE, list: [ {type: "colgroup", list: can.core.List(list, function(key) { if (key[0] != "_") { - if (can.Option(key) == undefined) { return {view: [key, "col"]} } return {view: [[key, "option"], "col"]} + try { var value = can.Option(key) } catch {} + if (value == undefined) { return {view: [key, "col"]} } return {view: [[key, "option"], "col"]} } }) }, {type: html.THEAD}, {type: html.TBODY}]}]) can.page.Append(can, ui.thead, [{data: {dataset: {index: -1}}, th: can.core.List(list, function(key) { if (key[0] != "_") { return key } }) }]) @@ -264,10 +265,11 @@ Volcanos("page", { width: function() { return window.innerWidth }, ismodkey: function(event) { return [code.META, code.ALT, code.CONTROL, code.SHIFT].indexOf(event.key) > -1 }, unicode: { - menu: "☰", prev: "❮", next: "❯", play: "▸", - push: "⇈", pull: "⇊", refresh: "↻", goback: "↺", create: "+", remove: "✕", insert: "+", delete: "✕", - open: "▾", close: "▸", + refresh: "↻", goback: "↺", prunes: "♻︎", prune: "♻︎", + menu: "☰", play: "▸", prev: "❮", next: "❯", + push: "⇈", pull: "⇊", open: "▾", close: "▸", + select: "▿", inner: "..", back: "◀", reback: "▶", lt: "❮", gt: "❯", diff --git a/lib/user.js b/lib/user.js index 673b0142..6ff1e3e4 100644 --- a/lib/user.js +++ b/lib/user.js @@ -90,9 +90,9 @@ Volcanos("user", { var carte = can.user.toast(can, {content: content, title: title, action: action||[cli.CLOSE], duration: -1}) can.page.style(can, carte._target, html.TOP, 200, html.BOTTOM, ""); return carte }, - toastProcess: function(can, content, title) { return can.user.toast(can, {content: content||ice.PROCESS, title: title, duration: -1, caller: 2}) }, - toastSuccess: function(can, content, title) { return can.user.toast(can, {content: "\u2705 "+(content||ice.SUCCESS), title: title, caller: 2}) }, - toastFailure: function(can, content, title) { return can.user.toast(can, {content: "\u274C "+(content||ice.FAILURE), title: title, duration: 10000, caller: 2}) }, + toastProcess: function(can, content, title) { return can.user.toast(can, {content: "🕑 "+(content||ice.PROCESS), title: title, duration: -1, caller: 2}) }, + toastSuccess: function(can, content, title) { return can.user.toast(can, {content: "✅ "+(content||ice.SUCCESS), title: title, caller: 2}) }, + toastFailure: function(can, content, title) { return can.user.toast(can, {content: "❌ "+(content||ice.FAILURE), title: title, duration: 10000, caller: 2}) }, toast: function(can, content, title, duration, progress, caller) { var meta = can.base.isObject(content)? content: {content: content, duration: duration, progress: progress, caller: caller} meta.title = meta.title||can.core.Keys(can.Conf(web.SPACE), can.Conf(ctx.INDEX))||can._name.split(nfs.PS).slice(-2).join(nfs.PS) diff --git a/panel/footer.js b/panel/footer.js index c660bd15..1d7aba64 100644 --- a/panel/footer.js +++ b/panel/footer.js @@ -31,15 +31,12 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.Conf(NKEY, can. }) Volcanos(chat.ONACTION, {_init: function(can) { can.ui = {}, can.db = {} }, onsize: function(can) { can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth) }, - onlogin: function(can, msg) { - var msg = can.request(); msg._method = web.GET - can.run(msg._event, [], function(msg) { can.onmotion.clear(can), can.onimport._init(can, msg, can._output) }) }, + onlogin: function(can, msg) { var msg = can.request(); msg._method = web.GET, can.run(msg._event, [], function(msg) { can.onmotion.clear(can), can.onimport._init(can, msg, can._output) }) }, ontoast: function(can, msg) { can.core.CallFunc(can.onimport.ntip, {can: can, msg: msg}) }, onremote: function(can, msg) { can.core.CallFunc(can.onimport.ncmd, {can: can, msg: msg}) }, onlayout: function(can, layout) { can.onmotion.toggle(can, can._target, !layout || layout == html.TABS) }, onaction_cmd: function(can) { can.onappend.style(can, html.HIDE) }, oncommand_focus: function(can) { can.page.Select(can, can._output, ["div.cmd", html.INPUT], function(target) { can.onmotion.focus(can, target) }) }, - ondebugs: function(can, msg) { can.runAction({}, msg.Option(ctx.ACTION), [msg.Option(ctx.INDEX)], function(_msg) { _msg.Table(function(item) { item.mode = chat.FLOAT can.onappend.plugin(can, item, function(sub) { diff --git a/panel/header.js b/panel/header.js index 24f8a81b..18e6eaa5 100644 --- a/panel/header.js +++ b/panel/header.js @@ -147,10 +147,11 @@ Volcanos(chat.ONPLUGIN, { sessionStorage: shy("会话存储", { create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.sessionStorage(can, name, value) }), remove: shy(function(can, name) { name && can.misc.sessionStorage(can, name, "") }), + prunes: shy(function(can, name) { can.core.Item(can.misc.sessionStorage(can), function(key, value) { can.misc.sessionStorage(can, key, "") }) }), modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.sessionStorage(can, msg.Option(mdb.NAME), arg[1]) } else { can.misc.sessionStorage(can, arg[1], msg.Option(mdb.VALUE)), can.misc.sessionStorage(can, msg.Option(mdb.NAME), "") } }), - }, [web.FILTER, ice.LIST, mdb.CREATE], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() }) + }, [web.FILTER, ice.LIST, mdb.CREATE, mdb.PRUNES], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() }) can.core.Item(can.misc.sessionStorage(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) }) }), location: shy("请求地址", {copy: function(can) { can.user.copy(msg._event, can, location.href) }}, [mdb.LINK, ice.LIST, ice.COPY], function(can, msg, cb) { diff --git a/plugin/local/code/inner.css b/plugin/local/code/inner.css index 475cb1a8..18c28dd0 100644 --- a/plugin/local/code/inner.css +++ b/plugin/local/code/inner.css @@ -58,6 +58,8 @@ fieldset.inner.cmd>div.output>div.layout>div.path { font-style:italic; padding:5 fieldset.inner.cmd>div.output>div.layout>div.path.hide { display:none; } fieldset.inner.cmd>div.output>div.layout>div.path span.func { padding:5px 10px; margin-left:20px; } fieldset.inner.cmd>div.output>div.layout>div.path span.mode { padding:5px 10px; margin-left:20px; } +fieldset.inner.cmd>div.output>div.layout>div.path span.mode.insert { color:red; } +fieldset.inner.cmd>div.output>div.layout>div.path span.mode.normal { color:blue; } fieldset.inner.cmd>div.output>div.layout>div.path span.view { font-size:22px; line-height:12px; padding:0 4px; float:right; } fieldset.inner.cmd>div.output>div.layout>fieldset.plug { bottom:32px; } fieldset.inner.cmd>div.output>div.layout>div.plug { height:32px; clear:both; position:fixed; bottom:0; right:0; } diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index ad52fef1..bb505fdd 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -9,7 +9,12 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp if (can.Mode() == ice.MSG_RESULT) { msg.result = msg.result||[can._output.innerHTML], can.Mode(chat.SIMPLE) } can.core.List(paths.concat(can.core.Split(msg.Option(nfs.REPOS))), function(p) { if (can.base.beginWith(p, nfs.USR_LOCAL_WORK) || can.base.endWith(p, "-dict/")) { return } if (p && paths.indexOf(p) == -1 && p[0] != nfs.PS) { paths.push(p) } - }), can.onmotion.clear(can), can.onappend.style(can, code.INNER), can.sup.onimport._process = function() {} + }), can.onmotion.clear(can), can.onappend.style(can, code.INNER), can.sup.onimport._process = function(_can, msg) { + if (msg.OptionProcess() == ice.PROCESS_REWRITE) { + var args = {}, arg = msg._arg; for (var i = 0; i < arg.length; i += 2) { args[arg[i]] = arg[i+1] } + can.onimport.tabview(can, args.path, args.file, args.line) + } + } can.db = {paths: paths, tabview: {}, history: [], _history: [], toolkit: {}}, can.db.tabview[can.onexport.keys(can)] = msg can.ui = can.onappend.layout(can, [html.PROJECT, [html.TABS, nfs.PATH, [html.CONTENT, html.PROFILE], html.DISPLAY, html.PLUG]]) can.ui._content = can.ui.content, can.ui._profile = can.ui.profile, can.ui._display = can.ui.display, can.onmotion.hidden(can, can.ui.plug) @@ -27,7 +32,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp } var args = can.misc.SearchHash(can), tabs = can.onexport.session(can, RECOVER_TABS), tool = can.onexport.session(can, RECOVER_TOOL) can.onimport.tabview(can, can.Option(nfs.PATH), can.Option(nfs.FILE), can.Option(nfs.LINE), function() { if (!can.isCmdMode()) { return } if (tabs) { - can.core.Next(tabs, function(item, next) { can.onimport.tabview(can, item[0], item[1], item[2], next) }, function() { + can.core.Next(tabs, function(item, next) { can.onimport.tabview(can, item[0], item[1], item[2], function() { + can.onmotion.delay(can, next) + }) }, function() { args.length > 0 && can.onimport.tabview(can, args[args.length-3], args[args.length-2]||can.Option(nfs.FILE), args[args.length-1]) }) } else { @@ -144,11 +151,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp } else { name = file.split(mdb.FS)[0].split(isIndex()? nfs.PT: nfs.PS).pop() } - var tabs = can.onimport.tabs(can, [{name: name, text: file, _menu: shy([ - nfs.SAVE, nfs.TRASH, web.REFRESH, - ], function(event, button, meta) { - can.onaction[button](event, can, button) - })}], function(event, tabs) { + var tabs = can.onimport.tabs(can, [{name: name, text: file, _menu: shy([nfs.SAVE, nfs.TRASH, web.REFRESH], function(event, button, meta) { + can.request(event, msg) + can.onaction[button](event, can, button) })}], function(event, tabs) { can._tab = msg._tab = tabs._target, show(skip), skip = true }, function(tabs) { can.onengine.signal(can, VIEW_REMOVE, msg), can.ui.zone.source.refresh() msg.__content || can.page.Remove(can, msg._content), msg._profile != can.ui._profile && can.page.Remove(can, msg._profile) @@ -174,8 +179,16 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp can.onmotion.toggle(can, can.ui.profile, true), can.onmotion.delay(can, function() { can.onimport.layout(can)}) } else { can.page.style(can, can.ui.profile, html.HEIGHT, height, html.WIDTH, width), can.ui.profile = _msg._profile = can.ui._profile + if (can.ui.profile._plugin && can.base.isIn(msg.Append(ctx.INDEX), web.CODE_XTERM)) { + if (can.onexport.session(can, PROFILE_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE))) { + return can.onmotion.toggle(can, can.ui.profile, true), can.onimport.layout(can) + } + } can.onimport.process(can, msg, can.ui.profile, height, width-border, function(sub) { can.page.style(can, sub._output, html.MAX_WIDTH, ""), can.ui.profile._plugin = _msg._profile = sub sub.Conf(ctx.ARGS) && can.onexport.session(can, PROFILE_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE), JSON.stringify(sub.Conf(ctx.ARGS))) + sub.onaction.close = function() { can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) + can.onexport.session(can, PROFILE_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE), "") + } if (sub._index == web.WIKI_WORD) { can.page.style(can, can.ui.profile, html.WIDTH, width+border, html.MAX_WIDTH, width+border), can.onimport.layout(can); return } can.page.style(can, can.ui.profile, html.WIDTH, width+border, html.MAX_WIDTH, width+border), can.onimport.layout(can) }) @@ -184,8 +197,16 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp display: function(can, msg) { var _msg = can.db.tabview[can.onexport.keys(can)]; _msg.Option(html.HEIGHT, msg.Option(html.HEIGHT)), border = 1 var height = can.onexport.size(can, _msg.Option(html.HEIGHT)||0.5, can.ui.project.offsetHeight||can.ConfHeight())+border, width = can.ConfWidth()-can.ui.project.offsetWidth can.page.style(can, can.ui.display, html.MAX_HEIGHT, height, html.MAX_WIDTH, width), can.ui.display = _msg._display = can.ui._display + if (can.ui.display._plugin && can.base.isIn(msg.Append(ctx.INDEX), web.CODE_XTERM)) { + if (can.onexport.session(can, DISPLAY_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE))) { + return can.onmotion.toggle(can, can.ui.display, true), can.onimport.layout(can) + } + } can.onimport.process(can, msg, can.ui.display, height-border, width, function(sub) { can.page.style(can, sub._output, html.MAX_HEIGHT, ""), can.ui.display._plugin = _msg._display = sub sub.Conf(ctx.ARGS) && can.onexport.session(can, DISPLAY_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE), JSON.stringify(sub.Conf(ctx.ARGS))) + sub.onaction.close = function() { can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) + can.onexport.session(can, DISPLAY_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE), "") + } if (sub._index == web.WIKI_WORD) { can.page.style(can, can.ui.display, html.HEIGHT, height+border, html.MAX_HEIGHT, height+border), can.onimport.layout(can); return } var _height = can.base.Max(sub._target.offsetHeight+border, height); _msg.Option(html.HEIGHT, _height), sub.onimport.size(sub, _height-border, width, true), can.onimport.layout(can) }) @@ -196,7 +217,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp if (can.base.isIn(item.index, web.WIKI_WORD)) { item.style = html.OUTPUT } can.onimport.plug(can, item, function(sub) { sub.onaction.close = function() { can.onmotion.hidden(can, target), can.onimport.layout(can) } - sub.onexport.output = function(_sub, _msg) { can.onmotion.delay(can, function() { can.base.isFunc(cb) && cb(_sub.sup, _msg) }) } + sub.onexport.output = function(_sub, _msg) { can.base.isFunc(cb) && cb(_sub.sup, _msg) } }, target) }) } else if (msg.Option(ice.MSG_DISPLAY) != "") { @@ -220,16 +241,16 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { var paths = can.core.Sp } return can.onmotion.toggle(can, target, true), can.onmotion.delay(can, function() { can.onimport.layout(can), can.user.toastSuccess(can) }) }, toolkit: function(can, meta, cb) { - can.onimport.tool(can, [meta], function(sub) { sub._legend._list = {index: meta.index, args: meta.args}, sub.onexport.record = function(sub, value, key, item) { if (!item.file) { return } - can.user.isWebview && can.onexport.recover(can) + can.onimport.tool(can, [meta], function(sub) { meta.index != ice.CAN_PLUGIN && (sub._legend._list = {index: meta.index, args: meta.args}), sub.onexport.record = function(sub, value, key, item) { if (!item.file) { return } if (item.file.indexOf("require/src") == 0) { item.path = nfs.SRC, item.file = line.file.slice(12) } can.onimport.tabview(can, item.path, can.base.trimPrefix(item.file, nfs.PWD), parseInt(item.line)); return true - }, can.base.isFunc(cb) && cb(sub) }, can.ui.plug.parentNode, can.ui.plug), can.page.isDisplay(can.ui.plug) || can.onmotion.toggle(can, can.ui.plug, true) && can.onimport.layout(can) + }, can.base.isFunc(cb) && cb(sub), can.user.isWebview && can.onexport.recover(can) }, can.ui.plug.parentNode, can.ui.plug) + can.page.isDisplay(can.ui.plug) || can.onmotion.toggle(can, can.ui.plug, true) && can.onimport.layout(can) }, layout: function(can) { if (can.isSimpleMode() || can.Conf(ctx.STYLE) == html.OUTPUT) { return can.page.style(can, can.ui.content, html.WIDTH, can.ConfWidth()) } if (can.isCmdMode()) { can.ConfHeight(can.page.height()) } var content = can.ui.content; if (content._root) { can.ui.content = content._root } can.ui.size = {profile: can._msg.Option(html.WIDTH), display: can._msg.Option(html.HEIGHT)} can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(height, width) { can.ui.content = content, can.onlayout.layout(can, height, width) - var sub = can.ui.profile._plugin; sub && can.page.isDisplay(can.ui.profile) && sub.onimport && sub.onimport.size(sub, can.ui.profile.offsetHeight, can.ui.profileWidth, true) + var sub = can.ui.profile._plugin; sub && can.page.isDisplay(can.ui.profile) && sub.onimport && sub.onimport.size(sub, can.ui.profile.offsetHeight, can.ui.profile.offsetWidth-1, true) var sub = can.ui.content._plugin; if (!sub) { return } if (height == sub.ConfHeight()+sub.onexport.actionHeight(sub)+sub.onexport.statusHeight(sub) && width == sub.ConfWidth()) { return } content._root || sub.onimport.size(sub, height, width, true), can.onlayout.layout(can, height, width) }) @@ -307,7 +328,10 @@ Volcanos(chat.ONSYNTAX, {_init: function(can, msg, cb) { var key = can.onexport. if (can.onexport.parse(can) == nfs.SVG) { msg.Option(ctx.INDEX, web.WIKI_DRAW+mdb.FS+path+file) } if (msg.Option(ctx.INDEX)) { return can.onsyntax._index(can, msg, function(target) { can.ui.content = target, cb(msg._content = content._root? (target._root = content._root): target) }, content._root? content: can.ui._profile.parentNode) } function show(p) { - p && p.include && can.core.List(p.include, function(from) { can.core.Item(can.onsyntax[from].keyword, function(key, value) { p.keyword[key] = p.keyword[key] || value }) }) + p && p.include && can.core.List(p.include, function(from) { + p.keyword = p.keyword||{}, can.core.Item(can.onsyntax[from].keyword, function(key, value) { p.keyword[key] = p.keyword[key] || value }) + can.core.Item(can.onsyntax[from], function(key, value) { p[key] = p[key] || value }) + }) if (!content._root && can.db.history.length > 1) { content = can.ui.content = can.page.insertBefore(can, [{view: html.CONTENT, style: {width: can.ui.content.offsetWidth}}], can.ui._profile), content._cache_key = key } content._max = 0, content._msg = msg, msg.__content = content, can.page.Appends(can, content, [{view: ["tips", "", msg.Option(nfs.FILE)]}]) if (msg.Length() > 0) { can.onsyntax._change(can, msg), can.onaction.rerankLine(can, "tr.line:not(.delete)>td.line") @@ -456,12 +480,10 @@ Volcanos(chat.ONACTION, { show: function(event, can) { can.runAction(can.request(event, {_toast: "渲染中...", args: can.onexport.session(can, PROFILE_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE))}), mdb.RENDER, [can.onexport.parse(can), can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { can.onimport.profile(can, msg) }) }, exec: function(event, can) { can.runAction(can.request(event, {_toast: "执行中...", args: can.onexport.session(can, DISPLAY_ARGS+can.Option(nfs.PATH)+can.Option(nfs.FILE))}), mdb.ENGINE, [can.onexport.parse(can), can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) { can.onimport.display(can, msg) }) }, plug: function(event, can) { - function show(index, args) { input.cancel(); - var sub = can.db.toolkit[index]; if (sub) { sub.select(); return } can.onimport.toolkit(can, {index: index, args: can.core.Split(args||"")}, function(sub) { can.db.toolkit[index] = sub.select() }) } + function show(index, args) { input.cancel(); var sub = can.db.toolkit[index]; if (sub) { sub.select(); return } can.onimport.toolkit(can, {index: index, args: can.core.Split(args||"")}, function(sub) { can.db.toolkit[index] = sub.select() }) } var input = can.user.input(event, can, [{type: html.TEXT, name: ctx.INDEX, run: function(event, cmds, cb) { can.run(event, cmds, function(msg) { if (cmds[0] == ctx.ACTION && cmds[1] == mdb.INPUTS && cmds[2] == ctx.INDEX) { var _msg = can.request({}) can.core.Item(can.db.toolkit, function(index) { _msg.Push(ctx.INDEX, index) }), _msg.Push(ctx.INDEX, "") - // can.core.List(msg.index, function() { msg.Push("cb", show) }) _msg.Copy(msg), cb(_msg) } else { cb(msg) } }, true) }}, ctx.ARGS], function(list) { show(list[0], list[1]) }) @@ -527,7 +549,6 @@ Volcanos(chat.ONACTION, { if (can.page.isDisplay(can.ui.profile)) { return can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) } }, onkeydown: function(event, can) { - // if (can.page.tagis(event.target, html.TD)) { return } if (can.onkeymap.selectCtrlN(event, can, can.ui.tabs, html.DIV_TABS)) { return } can.db._key_list = can.onkeymap._parse(event, can, mdb.PLUGIN, can.db._key_list, can.ui.content) }, diff --git a/plugin/local/code/inner/search.js b/plugin/local/code/inner/search.js index 37e4832a..1500db06 100644 --- a/plugin/local/code/inner/search.js +++ b/plugin/local/code/inner/search.js @@ -1,4 +1,4 @@ Volcanos(chat.ONIMPORT, {list: ["value", "filter", "run:button"], _init: function(can, msg) { - can.onmotion.clear(can), can.onappend.table(can, msg), can.onmotion.highlight(can, can.Option(mdb.VALUE, msg.Option(mdb.VALUE))) + can.onmotion.clear(can), can.onappend.table(can, msg), can.onappend.board(can, msg), can.onmotion.highlight(can, can.Option(mdb.VALUE, msg.Option(mdb.VALUE))) can.page.Select(can, can._option, "input[name=filter]", function(target) { target.onkeyup = function(event) { can.onmotion.highlight(can, target.value) } }) }}) diff --git a/plugin/local/code/vimer.css b/plugin/local/code/vimer.css index 0ff1a565..f9c41f7f 100644 --- a/plugin/local/code/vimer.css +++ b/plugin/local/code/vimer.css @@ -2,16 +2,19 @@ fieldset.vimer>div.output>div.project>div.zone.space div.item.stop { color:gray; fieldset.inner>div.output>div.layout>div.layout>div.content div.tips { display:none; } fieldset.vimer>div.output>div.layout>div.layout div.content div.tips { color:gray; font-style:italic; position:absolute; top:0; right:0; } fieldset.vimer>div.output>div.layout>div.layout div.content input.current { background-color:transparent; color:transparent; padding-left:10px; height:20px; position:absolute; } -fieldset.vimer>div.output>div.layout>div.layout div.content div.complete { background-color:unset; padding-top:0; display:none; overflow:auto; position:absolute; } +fieldset.vimer>div.output>div.layout>div.layout div.content div.complete { background-color:unset; padding-top:0; display:none; position:absolute; height:1px; overflow:visible; } fieldset.vimer>div.output>div.layout>div.layout div.content div.complete div.prefix { color:transparent; white-space:pre; float:left; } fieldset.vimer>div.output>div.layout>div.layout div.content div.complete table.content thead { display:none; } fieldset.vimer>div.output>div.layout>div.layout div.content div.complete table.content { padding-left:5px; width:unset; max-width:600px; display:block; } fieldset.vimer>div.output>div.layout>div.layout>div.layout div.content { border-left:var(--box-border); border-top:var(--box-border); } +fieldset.vimer>div.output>div.layout>div.layout div.content tr.line:hover { background-color:var(--hover-bg-color); } fieldset.vimer>div.output>div.layout>div.layout div.content.normal tr.line.select>td.line { background-color:blue; color:white; } fieldset.vimer>div.output>div.layout>div.layout div.content.insert tr.line.select>td.line { background-color:red; color:white; } fieldset.vimer>div.output>div.layout>div.layout div.content.insert div.complete:not(.hide) { display:block; top:unset; } -fieldset.vimer>div.output>div.layout>div.layout div.content.normal input:not([type=button]) { border:blue solid 1px; } -fieldset.vimer>div.output>div.layout>div.layout div.content.insert input:not([type=button]) { border:red solid 1px; } +fieldset.vimer>div.output>div.layout>div.layout div.content.normal input:not([type=button]) { border:var(--notice-fg-color) solid 1px; } +fieldset.vimer>div.output>div.layout>div.layout div.content.insert input:not([type=button]) { border:var(--danger-bg-color) solid 1px; } +fieldset.vimer>div.output>div.layout>div.path span.mode.insert { color:var(--danger-bg-color); } +fieldset.vimer>div.output>div.layout>div.path span.mode.normal { color:var(--notice-fg-color); } fieldset.vimer>div.output>div.layout>div.layout div.content.normal input.current { caret-color:lightgray; } fieldset.vimer>div.output>div.layout>div.layout div.content.insert input.current { caret-color:black; } body.dark fieldset.vimer>div.output>div.layout>div.layout div.content.normal input.current { caret-color:gray; } diff --git a/plugin/local/code/vimer.js b/plugin/local/code/vimer.js index 6e0bdc67..0429014e 100644 --- a/plugin/local/code/vimer.js +++ b/plugin/local/code/vimer.js @@ -16,6 +16,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { for (end; end < target.value.length; end++) { if (!reg.test(target.value.slice(end, end+1))) { break } } can.onaction.searchLine(event, can, target.value.slice(begin, end)) } + can.onmotion.delay(can, function() { can.page.SelectChild(can, can.ui.complete, html.DIV, function(target) { + target.innerText = can.ui.current.value.slice(0, can.ui.current.selectionStart) + }) }) }}, {view: [[code.COMPLETE]]}, ]); can.ui.current = ui.current, can.ui.complete = ui.complete, can.onkeymap._plugin(can) }, _value: function(can) { can.onimport.__tabPath(can, true), can.db.mode == mdb.INSERT && can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) }) }, @@ -64,13 +67,8 @@ Volcanos(chat.ONFIGURE, { }) Volcanos(chat.ONACTION, {list: ["编译", "构建", "路由", "终端", "源码", "文档", "计划", "流程", "桌面", "后台", "官网"], _trans: {show: "预览", exec: "展示"}, - _run: function(event, can, button, args, cb) { can.runAction(event, button, args, cb||function(msg) { - can.onimport.tabview(can, msg.Option(nfs.PATH), msg.Option(nfs.FILE)), can.user.toastSuccess(can, button) - can.ui.zone.source.refresh() - }) }, - _runs: function(event, can, button, cb) { var meta = can.Conf(); can.request(event, {action: button}) - can.user.input(event, can, meta.feature[button], function(args) { can.onaction._run(event, can, button, args, cb) }) - }, + _run: function(event, can, button, args, cb) { can.runAction(event, button, args, cb||function(msg) { can.onimport.tabview(can, msg.Option(nfs.PATH), msg.Option(nfs.FILE)), can.user.toastSuccess(can, button), can.ui.zone.source.refresh() }) }, + _runs: function(event, can, button, cb) { var meta = can.Conf(); can.request(event, {action: button}), can.user.input(event, can, meta.feature[button], function(args) { can.onaction._run(event, can, button, args, cb) }) }, save: function(event, can, button) { can.request(event, {file: can.Option(nfs.FILE), content: can.onexport.content(can)}) function imports(str) { var block = "", count = 0; can.core.List(str.split(lex.NL), function(item) { if (can.base.beginWith(item, "import (")) { block = can.core.Split(item)[0]; return } @@ -89,22 +87,17 @@ Volcanos(chat.ONACTION, {list: ["编译", "构建", "路由", "终端", "源码" script: function(event, can, button) { can.onaction._runs(event, can, button) }, module: function(event, can, button) { can.onaction._runs(event, can, button) }, compile: function(event, can, button) { can.runAction(can.request(event, {_toast: "编译中..."}), button, [], function(msg) { can.ui.search && can.ui.search.hidden() - if (msg.Length() > 0 || msg.Result()) { return can.onimport.exts(can, "inner/search.js", function(sub) { can.onappend._output(sub, msg, sub.Conf(ctx.DISPLAY)), sub.select() }) } - var toast = can.user.toastProcess(can, "重启中..."); can.onmotion.delay(can, function() { toast.close(), can.user.toastSuccess(can) }, 3000) - }) }, - "命令": function(event, can) { can.user.input(event, can, [{name: ctx.INDEX, need: "must"}, ctx.ARGS], function(list) { - can.onimport.tabview(can, "", list[0]+(list[1]? mdb.FS+list[1]: ""), ctx.INDEX) + if (msg.Length() > 0 || msg.Result()) { return can.onimport.exts(can, "inner/search.js", function(sub) { can.ui.search = sub, sub.select() + can.onmotion.delay(can, function() { can.onappend._output(sub, msg, sub.Conf(ctx.DISPLAY)) }) + }) } var toast = can.user.toastProcess(can, "重启中..."); can.onmotion.delay(can, function() { toast.close(), can.user.toastSuccess(can) }, 3000) }) }, + "命令": function(event, can) { can.user.input(event, can, [{name: ctx.INDEX, need: "must"}, ctx.ARGS], function(list) { can.onimport.tabview(can, "", list[0]+(list[1]? mdb.FS+list[1]: ""), ctx.INDEX) }) }, "插件": function(event, can) { can.user.input(event, can, [{name: ctx.INDEX, need: "must"}, ctx.ARGS], function(list) { var sub = can.db.toolkit[list.join(",")]; if (sub) { sub.select(); return } can.onimport.toolkit(can, {index: list[0], args: can.core.Split(list[1]||"")}, function(sub) { can.db.toolkit[list.join(",")] = sub.select() }) }) }, - "扩展": function(event, can) { can.user.input(can.request(event, {action: "extension"}), can, ["url"], function(list) { - var sub = can.db.toolkit[list[0]]; sub? sub.select(): can.onimport.exts(can, list[0]) - }) }, + "扩展": function(event, can) { can.user.input(can.request(event, {action: "extension"}), can, ["url"], function(list) { var sub = can.db.toolkit[list[0]]; sub? sub.select(): can.onimport.exts(can, list[0]) }) }, "编译": function(event, can) { can.onaction.compile(event, can, code.COMPILE) }, - "终端": function(event, can) { can.user.input(can.request(event, {action: "xterm"}), can, [mdb.TYPE], function(args) { - can.onimport.tabview(can, "", [web.CODE_XTERM, args[1]||"ish"].join(mdb.FS), ctx.INDEX) - }) }, + "终端": function(event, can) { can.user.input(can.request(event, {action: "xterm"}), can, [mdb.TYPE], function(args) { can.onimport.tabview(can, "", [web.CODE_XTERM, args[1]||"ish"].join(mdb.FS), ctx.INDEX) }) }, "路由": function(event, can) { can.onimport.tabview(can, "", web.ROUTE, ctx.INDEX) }, "构建": function(event, can) { can.onimport.tabview(can, "", web.CODE_COMPILE, ctx.INDEX) }, "源码": function(event, can) { can.onimport.tabview(can, "", web.CODE_GIT_STATUS, ctx.INDEX) }, @@ -117,10 +110,12 @@ Volcanos(chat.ONACTION, {list: ["编译", "构建", "路由", "终端", "源码" insertLine: function(can, value, before) { var line = can.onaction.appendLine(can, value); before && can.ui.content.insertBefore(line, can.onaction._getLine(can, before)); return can.onaction.rerankLine(can), can.onexport.line(can, line) }, deleteLine: function(can, line) { line = can.onaction._getLine(can, line); var next = line.nextSibling||line.previousSibling; return can.page.Remove(can, line), can.onaction.rerankLine(can), next }, _selectLine: function(can) { can.current && can.page.Select(can, can.current.line, "td.text", function(td) { var target = can.ui.current; target.value = td.innerText - can.current.line.appendChild(target), can.page.style(can, target, html.LEFT, td.offsetLeft-1, html.TOP, td.offsetTop, - html.WIDTH, can.base.Min(td.offsetWidth, can.ui.content.offsetWidth-can.page.Select(can, can.current.line, "td.line")[0].offsetWidth)) + can.current.line.appendChild(target), can.page.style(can, target, html.LEFT, td.offsetLeft-1, html.TOP, td.offsetTop, html.WIDTH, can.base.Min(td.offsetWidth, can.ui.content.offsetWidth-can.page.Select(can, can.current.line, "td.line")[0].offsetWidth)) can.db.mode == mdb.NORMAL && can.onkeymap._normal(can) - if (can.ui.content._root) { can.onmotion.select(can, can.ui.content.parentNode, "*", can.ui.content) } + if (can.ui.content._root) { can.onmotion.select(can, can.ui.content.parentNode, "", can.ui.content) } + can.onmotion.delay(can, function() { can.page.SelectChild(can, can.ui.complete, html.DIV, function(target) { + target.innerText = can.ui.current.value.slice(0, can.ui.current.selectionStart) + }) }) }) }, }) Volcanos(chat.ONKEYMAP, { @@ -138,8 +133,8 @@ Volcanos(chat.ONKEYMAP, { can.runAction(can.request(event, {text: pre}, can.Option()), code.COMPLETE, [], function(msg) { can.page.Appends(can, target, [{view: [lex.PREFIX, html.DIV, pre]}]) var parse = can.onsyntax[can.onexport.parse(can)]; can.core.CallFunc(can.core.Value(parse, code.COMPLETE), [event, can, msg, target, pre, key]) can.core.Item(can.core.Value(parse, code.KEYWORD), function(key, value) { msg.Push(mdb.NAME, key) }) - can.onappend.table(can, msg, function(value, key, index) { return {text: [value, html.TD], onclick: function(event) { change(value) }} }, target) - can.page.style(can, target, html.MAX_HEIGHT, can.ui.content.offsetHeight-(can.current.line.offsetTop-can.ui.content.scrollTop)-can.current.line.offsetHeight) + var table = can.onappend.table(can, msg, function(value, key, index) { return {text: [value, html.TD], onclick: function(event) { change(value) }} }, target) + can.page.style(can, table, html.MAX_HEIGHT, can.ui.content.offsetHeight-(can.current.line.offsetTop-can.ui.content.scrollTop)-can.current.line.offsetHeight) can.onmotion.toggle(can, target, true) }) } diff --git a/plugin/local/code/xterm.js b/plugin/local/code/xterm.js index 17fc6995..87d906c4 100644 --- a/plugin/local/code/xterm.js +++ b/plugin/local/code/xterm.js @@ -1,5 +1,4 @@ -(function() { -const RECOVER_STORE = "recover:" +(function() { const RECOVER_STORE = "recover:" Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { can.page.requireModules(can, ["xterm/css/xterm.css", "xterm", "xterm-addon-fit", "xterm-addon-web-links"], function() { var item = msg.TableDetail(); item.hash = item.hash||can.Option(mdb.HASH), can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg), can.onappend._status(can), can.onkeymap._build(can) if (item.type == html.LAYOUT) { can.onimport._layout(can, item) } else { can.onimport._connect(can, item, can._output) } can.onimport.layout(can) @@ -58,7 +57,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { can.page.requireModules }, _recover: function(can, item, term, text) { var recover = can.onexport.session(can, RECOVER_STORE+item.hash) if (recover) { can.onexport.session(can, RECOVER_STORE+item.hash, ""), can.onmotion.delay(can, function() { term.write(recover.replaceAll(lex.NL, "\r\n")) }) } - can.onengine.listen(can, chat.ONUNLOAD, function(msg) { term.selectAll(), can.onexport.session(can, RECOVER_STORE+item.hash, JSON.stringify(can.base.trimSuffix(term.getSelection(), lex.NL)+lex.NL)) }) + can.onengine.listen(can, chat.ONUNLOAD, function(msg) { term.selectAll(), can.onexport.session(can, RECOVER_STORE+item.hash, can.base.trimSuffix(term.getSelection(), lex.NL)+lex.NL) }) text && can.onmotion.delay(can, function() { term.write(text.replaceAll(lex.NL, "\r\n")) }) }, _resize: function(can, term, size) { can.runAction(can.request({}, size, term._item), web.RESIZE, [], function(msg) { @@ -77,7 +76,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { can.page.requireModules }) } }, - grow: function(can, msg) { var arg = msg.detail.slice(1), term = can.db[arg[0]]; arg[1] == "~~~end~~~"? can.onaction.delete(can, term._output): term.write(arg[1]); msg.Option(ice.LOG_DISABLE, ice.TRUE) }, + grow: function(can, msg) { + var arg = msg.detail.slice(1), term = can.db[arg[0]]; arg[1] == "~~~end~~~"? can.onaction.delete(can, term._output): term.write(arg[1]); msg.Option(ice.LOG_DISABLE, ice.TRUE) + }, layout: function(can) { function show(target, height, width) { var list = can.page.SelectChild(can, target, can.page.Keys(html.DIV_OUTPUT, html.DIV_LAYOUT)) var h = height/list.length, w = width; if (can.page.ClassList.has(can, target, html.FLEX)) { h = height, w = width/list.length } if (target == can._fields) { h = height, w = width } can.core.List(list, function(target) { can.page.style(can, target, html.HEIGHT, h, html.WIDTH, w), can.page.ClassList.has(can, target, html.LAYOUT)? show(target, h, w): target._term && target._term._fit.fit() }) @@ -130,7 +131,15 @@ Volcanos(chat.ONACTION, { can._output._root = root, can._output = can.page.insertBefore(can, [html.OUTPUT], can._output.nextSibling, layout) can._output._root = root, can._output._tabs = tabs, can.onimport._init(can, msg), can.onmotion.delay(can, function() { can._output.click() }) }) }) }, - delete: function(can, output) { if (can.page.Select(can, can._fields, html.DIV_OUTPUT).length == 1) { can.onmotion.delay(can, function() { can.sup.onimport._back(can.sup) }) } + delete: function(can, output) { + if (can.page.Select(can, can._fields, html.DIV_OUTPUT).length == 1) { can.onmotion.delay(can, function() { + var args = can.Conf(ctx.ARGS) + if (args && args.length > 0) { + can.sup.onaction.close({}, can.sup) + } else { + can.sup.onimport._back(can.sup) + } + }) } if (output == can.sup._output) { can.onmotion.clear(can, output) } else { while (output && output.parentNode.children.length == 1) { output = output.parentNode } var next = output.parentNode; can.page.Remove(can, output), can.onmotion.delay(can, function() { can.page.Select(can, next, html.DIV_OUTPUT, function(target) { target.click() }) }) } can.onimport.layout(can) @@ -172,8 +181,10 @@ Volcanos(chat.ONEXPORT, {list: [mdb.TIME, mdb.HASH, mdb.TYPE, mdb.NAME, "rows", } else { var item = target._term._item; return {type: item.type, name: name, text: item.text, hash: item.hash} } } return show(target._output) }) }, title: function(can, term, title) { can.page.Modify(can, can.page.SelectOne(can, term._output._tabs, html.SPAN_NAME), title), can.Status(mdb.NAME, title), can.sup.onexport.title(can.sup, title) }, - recover: function(can, key, value) { - + recover: function(can) { + can.core.Item(can.db, function(hash, term) { + term.selectAll(), can.onexport.session(can, RECOVER_STORE+hash, can.base.trimSuffix(term.getSelection(), lex.NL)+lex.NL) + }) }, }) })() diff --git a/plugin/local/wiki/word.css b/plugin/local/wiki/word.css index c389b5a6..5e35457d 100644 --- a/plugin/local/wiki/word.css +++ b/plugin/local/wiki/word.css @@ -17,6 +17,7 @@ fieldset.word>div.output svg.story[data-index] text { cursor:pointer; } fieldset.word>div.output input.story[type=button] { font-family:system-ui; font-weight:bold; padding:20px 40px; margin:10px; height:64px; box-shadow:var(--box-shadow); } fieldset.word>div.output fieldset.web.code.inner.output div.output td.line { border-right:var(--box-border); } fieldset.word>div.output fieldset.story { margin:20px 0; } +fieldset.word>div.output ul { margin:20px 40px; } fieldset.word>div.output fieldset.story:not(.float)>form.option>div.icon.delete { display:none; } fieldset.word>div.navmenu { background-color:inherit; overflow:auto; min-width:120px; clear:both; float:left; } diff --git a/plugin/local/wiki/word.js b/plugin/local/wiki/word.js index 33c6ae9c..e19e58cc 100644 --- a/plugin/local/wiki/word.js +++ b/plugin/local/wiki/word.js @@ -1,5 +1,6 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.Conf(html.PADDING, 10) can.onmotion.clear(can), can.page.Modify(can, target, msg.Result()), can.onimport._display(can, target) + can.onmotion.delay(can, function() { can.onappend.scroll(can, can._output) }) }, _display: function(can, target, cb) { can.onappend.style(can, web.WIKI_WORD) can.page.Select(can, target, wiki.STORY_ITEM, function(target) { var meta = target.dataset||{}; cb && cb(target, meta) diff --git a/plugin/state.js b/plugin/state.js index ed7ca4d5..3098f9cb 100644 --- a/plugin/state.js +++ b/plugin/state.js @@ -13,6 +13,7 @@ Volcanos(chat.ONIMPORT, { _inner: function(can, msg) { can.onappend.table(can, msg), can.onappend.board(can, msg), can.onmotion.story.auto(can) }, _field: function(can, msg, cb) { var height = can.ConfHeight(), width = can.ConfWidth(); can.page.SelectChild(can, can._output, can.page.Keys(html.TABLE, html.DIV_CODE), function(target) { height -= target.offsetHeight }) height = can.base.Min(msg.Option(html.HEIGHT)||height, can.isCmdMode()? can.ConfHeight()/2: 320), width = msg.Option(html.WIDTH)||can.ConfWidth() + height -= 2*html.ACTION_HEIGHT msg.Table(function(item) { can.onappend._plugin(can, item, {index: item.index, args: can.base.Obj(item.args||item.arg, []), height: height, width: width}, function(sub) { sub.run = function(event, cmds, cb) { var index = msg.Option(ice.MSG_INDEX) can.run(event, (!index || index == can._index || index.indexOf("can.") == 0? msg[ice.MSG_PREFIX]||[]: [ice.RUN, index]).concat(cmds), cb, true) @@ -129,7 +130,7 @@ Volcanos(chat.ONACTION, {list: [ } else if (can.isFloatMode()) { can.onaction["切换浮动"](event, can, "切换浮动", can.sub) } else { - can.onaction._close(event, can) + can.onaction._close(event, can), can.onexport.close(can) } }, _close: function(event, can) { can.page.Remove(can, can._target) }, clear: function(event, can) { can.onmotion.clear(can, can._output) }, @@ -189,5 +190,6 @@ Volcanos(chat.ONEXPORT, { link: function(can) { var meta = can.Conf(), args = can.Option() args.pod = meta._space||meta.space||meta.pod, args.cmd = meta.index||can.core.Keys(meta.ctx, meta.cmd) return can.misc.MergePodCmd(can, args, true) - }, args: function(can) { return can.Option() } + }, args: function(can) { return can.Option() }, + close: function(can, msg) {}, }) diff --git a/plugin/table.js b/plugin/table.js index 217738a2..06a409d6 100644 --- a/plugin/table.js +++ b/plugin/table.js @@ -169,6 +169,8 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear( }) Volcanos(chat.ONLAYOUT, { _init: function(can, height, width) { can.core.CallFunc([can.onimport, html.LAYOUT], {can: can, height: height, width: width}) }, + zone: function(can, height, width) { can.onlayout._init(can, height, width) }, + result: function(can, height, width) { can.onlayout._init(can, height, width) }, simple: function(can, height, width) { can.onlayout._init(can, height, width) }, output: function(can, height, width) { can.onlayout._init(can, height, width) }, float: function(can, height, width) { can.onlayout._init(can, height, width) }, @@ -184,5 +186,5 @@ Volcanos(chat.ONEXPORT, { var res = [msg.append && msg.append.join(mdb.FS)]; msg.Table(function(line, index, array) { res.push(can.core.Item(line, function(key, value) { return value }).join(ice.FS)) }); return res.join(lex.NL) }, board: function(can) { var msg = can._msg; return msg.Result() }, - session: function(can, key, value) { return can.misc[can.user.isWebview? "localStorage": "sessionStorage"](can, [can.Conf(ctx.INDEX), key, location.pathname].join(":"), JSON.stringify(value)) }, + session: function(can, key, value) { return can.misc[can.user.isWebview? "localStorage": "sessionStorage"](can, [can.Conf(ctx.INDEX), key, location.pathname].join(":"), value == ""? "": JSON.stringify(value)) }, }) diff --git a/proto.js b/proto.js index e807dd58..f9ee14b8 100644 --- a/proto.js +++ b/proto.js @@ -38,6 +38,7 @@ var ice = { MSG_PROCESS: "_process", PROCESS_AGAIN: "_again", PROCESS_FIELD: "_field", + PROCESS_REWRITE: "_rewrite", MSG_PREFIX: "_prefix", MSG_USERNICK: "user.nick", MSG_USERNAME: "user.name", MSG_USERROLE: "user.role", MSG_LANGUAGE: "user.lang", @@ -67,6 +68,7 @@ var mdb = { INPUTS: "inputs", PRUNES: "prunes", EXPORT: "export", IMPORT: "import", REVERT: "revert", NORMAL: "normal", SEARCH: "search", ENGINE: "engine", RENDER: "render", PLUGIN: "plugin", DETAIL: "detail", + PRUNE: "prune", KEYS: "keys", MAIN: "main", PAGE: "page", NEXT: "next", PREV: "prev", LIMIT: "limit", OFFEND: "offend", @@ -251,6 +253,9 @@ var html = {PLUGIN_MARGIN: 10, ACTION_HEIGHT: 32, ACTION_MARGIN: 200, DISPLAY: "display", BLOCK: "block", NONE: "none", OVERFLOW: "overflow", HIDDEN: "hidden", SCROLL: "scroll", FLOAT: "float", CLEAR: "clear", BOTH: "both", LEFT: "left", TOP: "top", RIGHT: "right", BOTTOM: "bottom", FLEX: "flex", FLOW: "flow", + SCROLLBAR: "scrollbar", + VISIBILITY: "visibility", + VERTICAL: "vertical", HORIZON: "horizon", SIZE: "size", OPACITY: "opacity", VISIBLE: "visible", CLASS: "class", LIGHT: "light", DARK: "dark", @@ -321,9 +326,10 @@ var Volcanos = shy({iceberg: "/chat/", volcano: "/frame.js", cache: {}, pack: {} can.base.isFunc(item.Option)? can.core.List(item.Option(), function(key) { key.indexOf("_") == 0 || key.indexOf("user.") == 0 || set(key, item.Option(key)) }): can.core.Item(can.base.isFunc(item)? item(): item, set) - }); set(ice.MSG_HEIGHT, can.ConfHeight()||32), set(ice.MSG_WIDTH, can.ConfWidth()||320), set(ice.MSG_MODE, can.Mode()) + }); set(ice.MSG_HEIGHT, can.ConfHeight()||"32"), set(ice.MSG_WIDTH, can.ConfWidth()||"320"), set(ice.MSG_MODE, can.Mode()) return msg }, + requestAction: function(event, button) { return can.request(event, {action: button, _toast: ice.PROCESS+" "+button}) }, runActionInputs: function(event, cmds, cb) { var msg = can.request(event), meta = can.Conf() if (msg.Option(ice.MSG_HANDLE) != ice.TRUE && cmds && cmds[0] == ctx.ACTION && meta.feature[cmds[1]]) { var msg = can.request(event, {action: cmds[1]}) if (can.base.isFunc(meta.feature[cmds[1]])) { return meta.feature[cmds[1]](can, msg, cmds.slice(2)) }