diff --git a/frame.js b/frame.js index 439994a5..79d27a4c 100644 --- a/frame.js +++ b/frame.js @@ -149,17 +149,23 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }); return sub }, _option: function(can, meta, option, skip) { var index = -1, args = can.base.Obj(meta.args||meta.arg, []), opts = can.base.Obj(meta.opts, {}) - can.core.List([""].concat(meta.inputs), function(item) { + can.core.List([""].concat(meta.inputs), function(item) { if (item != "" && item.type != html.BUTTON) { return } var icon = { run: {name: web.PLAY, cb: function(event) { can.Update(event) }}, list: {name: web.REFRESH, cb: function(event) { can.Update(event) }}, - refresh: {name: web.REFRESH, cb: function(event) { can.Update(event) }}, back: {name: "goback", cb: function(event) { can.onimport._back(can) }}, - create: {name: mdb.CREATE, cb: function(event) { can.Update(event, [ctx.ACTION, mdb.CREATE]) }}, - insert: {name: mdb.CREATE, cb: function(event) { can.Update(event, [ctx.ACTION, mdb.INSERT]) }}, - play: {name: web.PLAY, cb: function(event) { can.Update(event, [ctx.ACTION, web.PLAY]) }}, + refresh: {name: web.REFRESH, cb: function(event) { can.Update(event) }}, + next: {name: mdb.NEXT}, + prev: {name: mdb.PREV}, + // create: {name: mdb.CREATE}, + // insert: {name: mdb.CREATE}, + play: {name: web.PLAY}, "": {name: mdb.DELETE, cb: function(event) { can.onaction.close(event, can) }}, - }[item.name||""]; icon && can.page.Append(can, option, [{view: [[html.ITEM, html.ICON, icon.name, item.name], html.DIV, can.page.unicode[icon.name]], title: item.name, onclick: icon.cb}]) + }[item.name||""]; if (!icon) { return } item.style = "icons" + can.page.Append(can, option, [{view: [[html.ITEM, html.ICON, icon.name, item.name], html.DIV, can.page.unicode[icon.name]], title: item.name, onclick: icon.cb||function(event) { + var msg = can.request(event), cmds = [ctx.ACTION, item.name] + msg.RunAction(event, can.core.Value(can, chat._OUTPUTS_CURRENT), cmds) || msg.RunAction(event, can, cmds) || can.Update(event, cmds) + }}]) }) function add(item, next) { item = can.base.isString(item)? {type: html.TEXT, name: item}: item, item.type != html.BUTTON && index++ return Volcanos(item.name, {_root: can._root, _follow: can.core.Keys(can._follow, item.name), @@ -194,7 +200,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { }), item), "", action) }), meta }, - _output0: function(can, meta, event, cmds, cb, silent) { var msg = can.request(event); if (msg.RunAction(event, can, cmds) || msg.RunAction(event, can.core.Value(can, chat._OUTPUTS_CURRENT), cmds)) { return } + _output0: function(can, meta, event, cmds, cb, silent) { var msg = can.request(event); if (msg.RunAction(event, can, cmds)) { return } 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]}) var action = meta.feature[cmds[1]]; if (can.base.isFunc(action)) { cb = cb||function() { can.Update() } return action.list && action.list.length > 0? can.user.input(event, can, action.list, function(data) { @@ -225,6 +231,8 @@ 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.isCmdMode() && can.onappend.style(can, can.misc.Search(can, ctx.STYLE), can._target) + if (can.isCmdMode()) { can.onimport.size(can, can.page.height(), can.page.width(), true) } can.core.List([chat.FLOAT, chat.FULL, chat.CMD], function(mode) { can.page.ClassList.has(can, can._target, mode) && sub.onlayout[mode](sub) }) can.onmotion.story.auto(can, can._output), can.onexport.output(can, msg), can.base.isFunc(cb) && cb(msg) }, target: output}) @@ -333,6 +341,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { icon.push({icon: mdb.DELETE, onclick: function(event) { _input.value = "", item.name == html.FILTER && can.page.Select(can, can._output, html.TR, function(tr) { can.page.ClassList.del(can, tr, html.HIDE) }) }}) } if (item.range) { input._init = function(target) { can.onappend.figure(can, item, target, function(sub, value, old) { target.value = value, can.core.CallFunc([can.onaction, item.name], [event, can, item.name]) }) } } var _input = can.page.Append(can, target, [{view: [[html.ITEM].concat(style, [item.type, item.name])], list: [input].concat(icon), _init: function(target, _input) { + item.style && can.onappend.style(can, item.style, target) if (item.type == html.SELECT) { _input.select.value = value||_item.value||_item.values[0], can.onappend.select(can, _input.select, _item) } }}])[item.name]; return _input }, @@ -533,8 +542,8 @@ Volcanos(chat.ONMOTION, {_init: function(can, target) { }) }, }, - scrollHold: function(can, cb, target) { target = target || can._output - var top = target.scrollTop, left = target.scrollLeft; cb(), target.scrollTop = top, target.scrollLeft = left + scrollHold: function(can, cb, target, scroll) { target = target || can._output + var top = target.scrollTop, left = target.scrollLeft; cb(), scroll || (target.scrollTop = top), target.scrollLeft = left }, clearFloat: function(can) { var list = ["fieldset.input.float", "div.input.float", "div.carte.float"]; for (var i = 0; i < list.length; i++) { @@ -584,7 +593,7 @@ Volcanos(chat.ONMOTION, {_init: function(can, target) { }).length == 0) }) }, tableFilter: function(can, target, value) { can.page.Select(can, target, html.TR, function(tr, index) { - index > 0 && can.page.ClassList.set(can, tr, html.HIDDEN, can.page.Select(can, tr, html.TD, function(td) { if (td.innerText.indexOf(value) > -1) { return td } }) == 0) + index > 0 && can.page.ClassList.set(can, tr, html.HIDDEN, can.page.Select(can, tr, html.TD, function(td) { if (td.innerText.toLowerCase().indexOf(value.toLowerCase()) > -1) { return td } }) == 0) }) }, delayResize: function(can, target, key) { can.onmotion.delay(can, function() { can.page.Select(can, target, key, function(_target) { can.page.style(can, target, html.WIDTH, _target.offsetWidth+10, html.LEFT, (window.innerWidth-_target.offsetWidth)/2) diff --git a/index.css b/index.css index 7ce9f166..a7b798c1 100644 --- a/index.css +++ b/index.css @@ -17,6 +17,7 @@ input:hover[type=button][name=create] { background-color:blue; color:white; } input:hover[type=button][name=insert] { background-color:blue; color:white; } input:hover[type=button][name=restart] { background-color:blue; color:white; } input:hover[type=button][name=start] { background-color:blue; color:white; } +input:hover[type=button][name=run] { background-color:blue; color:white; } input:hover[type=button][name=open] { background-color:blue; color:white; } input:hover[type=button][name=stop] { background-color:red; color:white; } input:hover[type=button][name=trash] { background-color:red; color:white; } @@ -92,7 +93,7 @@ body div.float { background-color:#061c3ceb; padding:5px; overflow:auto; } body>div.toast div.title { color:blue; float:left; } body>div.toast div.duration { color:gray; float:right; } body>div.toast div.content { color:blue; text-align:center; } -body>div.toast div.progress { border:green solid 1px; margin-left:0px; height:20px; clear:both; } +body>div.toast div.progress { border:blue solid 1px; margin-left:0px; height:20px; clear:both; } body>div.toast div.progress div.current { background-color:red; height:18px; } body>div.toast div.action { width:100%; display:block; } body>div.toast div.action>div.item { float:right; } @@ -155,26 +156,21 @@ form.option>div.icon { line-height:30px; font-size:26px; padding:0 5px; height:3 form.option>div.icon.refresh { line-height:28px; } form.option>div.icon.goback { line-height:28px; } form.option>div.icon.play { line-height:28px; } +form.option>div.icon.next { font-size:18px; } +form.option>div.icon.prev { font-size:18px; } form.option>div.icon.lt { font-size:20px; line-height:30px; } form.option>div.icon:hover { background-color:white; } fieldset:not(.float)>form.option>div.text>span.value { display:none; } fieldset.float div.item.text:hover>span.icon.delete { visibility:hidden; } fieldset.float>form.option>div.text>input { display:none; } -fieldset.float>form.option>div.text>span.value { padding:7px; display:block; } +fieldset.float>form.option>div.text>span.value { padding:7px; height:32px; display:block; } fieldset.float>form.option>div.item.button { display:none; } fieldset.float>form.option>div.icon { display:block; } fieldset.full>form.option>div.icon.delete { display:block; } fieldset.cmd>form.option>div.icon { display:block; } -fieldset.cmd>form.option>div.item.button.run { display:none; } -fieldset.cmd>form.option>div.item.button.list { display:none; } -fieldset.cmd>form.option>div.item.button.back { display:none; } -fieldset.cmd>form.option>div.item.button.create { display:none; } +fieldset.cmd>form.option>div.item.button.icons { display:none; } fieldset.story>form.option>div.icon { display:block; } -fieldset.story>form.option>div.item.button.run { display:none; } -fieldset.story>form.option>div.item.button.list { display:none; } -fieldset.story>form.option>div.item.button.back { display:none; } -fieldset.story>form.option>div.item.button.create { display:none; } -fieldset.story>form.option>div.item.button.insert { display:none; } +fieldset.story>form.option>div.item.button.icons { display:none; } fieldset.plug>form.option>div.icon { margin-left:5px; } div.carte.select.float { border-radius:0; } div.carte.select.float>div.item { text-align:center; } @@ -192,10 +188,6 @@ select, input[type=text], textarea { box-shadow:4px 4px 20px 4px #626bd0; } body.black input[type=text], body.black textarea { background-color:#243783bd; color:white; outline:none; } legend, select, input[type=button], div.tabs, div.item, span.item, th, td, h1, h2, h3 { cursor:pointer; } div.title, div.story[data-type=spark] { cursor:copy; } -table.content tr:not(:hover) input[type=button][name=stop] { visibility:hidden; } -table.content tr:not(:hover) input[type=button][name=trash] { visibility:hidden; } -table.content tr:not(:hover) input[type=button][name=delete] { visibility:hidden; } -table.content tr:not(:hover) input[type=button][name=remove] { visibility:hidden; } /* theme */ body.black a { color:yellow; } body.black div.project div.zone>div.list>div.zone>div.item { background-color:#09466fc2; } diff --git a/lib/misc.js b/lib/misc.js index 4ca1b208..9f7c49a7 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -118,7 +118,7 @@ Volcanos("misc", { obj.pod = can.core.Keys(can.misc.Search(can, ice.POD), obj.pod); return can.misc.MergeURL(can, obj, true) }, MergeURL: function(can, obj, clear) { var path = location.pathname; obj._path && (path = obj._path), delete(obj._path) - var hash = obj._hash||""; delete(obj._hash) + can.misc.Search(can, log.DEBUG) && (obj.debug = ice.TRUE); var hash = obj._hash||""; delete(obj._hash) var args = [web.CHAT]; can.core.List([ice.POD, ice.CMD, web.WEBSITE], function(key) { obj[key] && args.push(key, obj[key]), delete(obj[key]) }) var _location = location; if (can.user.isExtension) { var _location = new URL(Volcanos.meta.iceberg) } return can.base.MergeURL(_location.origin+(args.length == 1? path: ice.PS+args.join(ice.PS))+(clear? "": _location.search), obj)+(hash? "#"+hash: "") @@ -129,6 +129,10 @@ Volcanos("misc", { for (var i = 1; i < ls.length; i += 2) { if (can.base.isIn(ls[i], [ice.POD, ice.CMD, web.WEBSITE])) { args[ls[i]] = ls[i+1] } } return args }, + SplitPath: function(can, path) { var ls = path.split(ice.PS); if (ls.length == 1) { return [nfs.PWD, ls[0]] } + if (ls[0] == ice.USR) { return [ls.slice(0, 2).join(ice.PS)+ice.PS, ls.slice(2).join(ice.PS)] } + return [ls.slice(0, 1).join(ice.PS)+ice.PS, ls.slice(1).join(ice.PS)] + }, Search: function(can, key, value) { var args = this.ParseURL(can, location.href) if (can.base.isUndefined(key)) { return args } else if (can.base.isObject(key)) { can.core.Item(key, function(k, v) { v === ""? delete(args[k]): (args[k] = v) }) diff --git a/panel/action.js b/panel/action.js index 0dcfb1ed..62496ef3 100644 --- a/panel/action.js +++ b/panel/action.js @@ -37,16 +37,6 @@ Volcanos(chat.ONACTION, {_init: function(can, target) { var target = can.page.Append(can, can._target, [{view: [[html.TOGGLE, chat.PROJECT], "", can.page.isDisplay(river)? lt: gt], onclick: function(event) { can.page.Modify(can, target, (can._river_show = can.onmotion.toggle(can, river))? lt: gt) can.onaction.layout(can) - return - var total = 230, length = 20 - var margin = can._river_show? -total: 0 - can.ConfWidth(can.page.width()-(can._river_show? 0: total)) - step = can._river_show? total/length: -total/length - can.core.Timer({interval: 10, length: length}, function() { - can.page.style(can, river, {"margin-left": margin += step, "display": "block"}) - can.ConfWidth(can.ConfWidth()-step) - can.onaction.layout(can, "", true) - }) }}])._target; can._toggle = target }); if (!can.Conf(chat.TOOL) && !can.user.mod.isCmd) { return } can._names = location.pathname can.Conf(chat.TOOL)? can.onappend.layout(can, can._output, FLOW, can.core.List(can.Conf(chat.TOOL), function(item, index, list) { item.type = chat.PLUGIN @@ -67,7 +57,7 @@ Volcanos(chat.ONACTION, {_init: function(can, target) { _onaction_cmd: function(can) { can.onengine.signal(can, chat.ONACTION_CMD), can.onlayout._init(can) }, onaction_cmd: function(can, msg) { can.page.ClassList.add(can, can._target, can.Mode(chat.CMD)), can.Conf(html.MARGIN_Y, 0), can.Conf(html.MARGIN_X, 0) }, onsearch: function(can, msg, arg) { var fields = msg.Option(ice.MSG_FIELDS).split(ice.FS) - if (arg[0] == mdb.FOREACH || arg[0] == mdb.PLUGIN) { can.onexport.plugin(can, msg, arg, fields) } + if (arg[0] == mdb.PLUGIN) { can.onexport.plugin(can, msg, arg, fields) } if (arg[0] == ctx.COMMAND) { can.onexport.command(can, msg, arg, fields) } }, onkeydown: function(can, msg, model) { if (can.isCmdMode() && !msg._event.metaKey) { return } diff --git a/panel/footer.css b/panel/footer.css index e02be23d..50ff656c 100644 --- a/panel/footer.css +++ b/panel/footer.css @@ -1,6 +1,6 @@ fieldset.Footer>div.output { height:32px; } fieldset.Footer>div.output div.item { padding:7px; cursor:pointer; float:left; } -fieldset.Footer>div.output div.title:first-child { text-align:center; margin-right:10px; width:230px; } +fieldset.Footer>div.output div.title:first-child { font-style:italic; text-align:center; margin-right:10px; width:230px; } fieldset.Footer>div.output div.state { float:right; } fieldset.Footer>div.output div.state label { font-size:12px; } fieldset.Footer>div.output div.toast { float:right; } diff --git a/panel/footer.js b/panel/footer.js index 51dab2de..e1c982e3 100644 --- a/panel/footer.js +++ b/panel/footer.js @@ -59,7 +59,7 @@ Volcanos(chat.ONPLUGIN, { "w3schools": shy("教程", function(can) { can.user.open("https://www.w3schools.com/colors/colors_names.asp") }), "mozilla": shy("文档", function(can) { can.user.open("https://developer.mozilla.org/en-US/") }), "w3": shy("标准", function(can) { can.user.open("https://www.w3.org/TR/?tag=css") }), - }, ["type:select=log,info,warn,error,debug,onremote,wss", web.FILTER, ice.LIST, "prune", "w3schools", "mozilla", "w3"], function(can, msg, arg, cb) { var _can = can, can = msg._can + }, ["type:select=error,log,info,warn,error,debug,onremote,wss", web.FILTER, ice.LIST, "prune", "w3schools", "mozilla", "w3"], function(can, msg, arg, cb) { var _can = can, can = msg._can var stat = {}; var ui = can.page.Appends(can, can._output, [{view: [html.CONTENT, html.TABLE], list: [{type: html.TR, list: [ {text: [mdb.TEXT, html.TH]}, ]}].concat(can.core.List(can.misc._list, function(list) { stat[list[2]] = ((stat[list[2]]||0)+1); return (!arg || !arg[0] || arg[0] == "log" || arg[0] == list[2]) && {type: html.TR, list: [ diff --git a/panel/header.css b/panel/header.css index 2caae0cf..44cee949 100644 --- a/panel/header.css +++ b/panel/header.css @@ -1,5 +1,5 @@ fieldset.Header>div.output { font-size:1.1rem; line-height:21px; height:48px; overflow:hidden; } -fieldset.Header>div.output div.item { font-family:unset; padding:13px; float:left; } +fieldset.Header>div.output div.item { font-family:unset; padding:13.5px; float:left; } fieldset.Header>div.output div.title:first-child { font-style:italic; font-weight:bold; text-align:center; margin-right:5px; width:230px; cursor:pointer; } fieldset.Header>div.output div.state { float:right; } fieldset.Header>div.output div.state.time { margin-left:10px; } diff --git a/panel/search.css b/panel/search.css index 18f408a2..d42bcd25 100644 --- a/panel/search.css +++ b/panel/search.css @@ -1,3 +1,3 @@ -fieldset.Search { background-color:#061c3ceb; padding:10px; position:fixed; left:230px; top:32px; } +fieldset.Search { background-color:#061c3ceb; padding:10px; position:fixed; left:230px; top:48px; } fieldset.Search>div.action>div.item.filter>input { margin-right:0; width:320px; } fieldset.Search>div.output table.content { width:100%; } diff --git a/panel/search.js b/panel/search.js index 706fe0e6..cb1bbc9f 100644 --- a/panel/search.js +++ b/panel/search.js @@ -46,9 +46,12 @@ Volcanos(chat.ONACTION, {_init: function(can) { can.onmotion.hidden(can) }, list }, plugin: function(event, can, data) { if (can.base.isFunc(data.text)) { return can.onmotion.hidden(can), data.text(event) } var cmd = data.cmd == ctx.COMMAND? can.core.Keys(data.type, data.name.split(ice.SP)[0]): can.core.Keys(data.ctx, data.cmd) - can.onappend.plugin(can, {index: cmd||msg.Option(mdb.INDEX), args: cmd == web.WIKI_WORD? [data.name]: []}, function(sub) { can._plugins = (can._plugins||[]).concat(sub) - sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), true), sub.Focus() - }, can.ui.profile) + var meta = {index: cmd||msg.Option(mdb.INDEX), args: cmd == web.WIKI_WORD? [data.name]: []} + if (data.type == cli.OPENS) { return can.runAction(event, cli.OPENS, [data.text], null, true) } + if (data.type == ssh.SHELL) { meta = {index: web.CODE_XTERM, args: [data.text]} } + if (data.type == ctx.INDEX) { meta = {index: data.text.split(",")[0], args: data.text.split(",").slice(1) } } + if (data.type == nfs.FILE) { meta = {index: web.CODE_VIMER, args: can.misc.SplitPath(can, data.text)} } + can.onappend.plugin(can, meta, function(sub) { can._plugins = (can._plugins||[]).concat(sub), sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), true), sub.Focus() }, can.ui.profile) }, }) Volcanos(chat.ONEXPORT, {statusHeight: function(can) { return can.db.type == mdb.FOREACH? 0: html.ACTION_HEIGHT }, diff --git a/plugin/input/key.js b/plugin/input/key.js index dd34a114..da01a9b6 100644 --- a/plugin/input/key.js +++ b/plugin/input/key.js @@ -12,7 +12,7 @@ Volcanos(chat.ONFIGURE, {key: { msg.Option(ice.MSG_PROCESS) == ice.PROCESS_AGAIN && can.onmotion.delay(can, function() { can._load(event, can, cb, target, name, value) }) }} }), can.onappend._status(can, [mdb.TOTAL, mdb.INDEX]), can.Status(mdb.TOTAL, msg.Length()) - can.page.style(can, can._output, html.MAX_HEIGHT, can.page.height()/2, html.MIN_WIDTH, target.offsetWidth, html.MAX_WIDTH, can.page.width()/2) + can.page.style(can, can._output, html.MAX_HEIGHT, can.page.height()/2, html.MIN_WIDTH, target.offsetWidth, html.MAX_WIDTH, can.Conf("style.width")||can.page.width()/2) msg.append.length == 1 && can.page.ClassList.add(can, can._target, chat.SIMPLE), can.onlayout.figure({target: target}, can, can._target) }, onclick: function(event, can, meta, target, cbs) { can.onmotion.focus(can, target) }, diff --git a/plugin/input/keyboard.css b/plugin/input/keyboard.css index a0442960..dbe6904e 100644 --- a/plugin/input/keyboard.css +++ b/plugin/input/keyboard.css @@ -23,5 +23,5 @@ fieldset.keyboard>div.output>div.key.Backspace { width:90px; } fieldset.keyboard>div.output>div.key>span { margin-top:2px; display:block; } fieldset.keyboard>div.output>div.key.special>span { margin-top:10px; } -table.content td input { width:50px; } -body.mobile table.content td input { width:80px; } +// table.content td input { width:50px; } +// body.mobile table.content td input { width:80px; } diff --git a/plugin/local/code/inner.css b/plugin/local/code/inner.css index 2fa61f61..086366de 100644 --- a/plugin/local/code/inner.css +++ b/plugin/local/code/inner.css @@ -39,12 +39,16 @@ fieldset.inner.cmd>div.output>div.layout.flow>div.tabs>div { padding:10px; heigh fieldset.inner.cmd>div.output>div.layout.flow>div.tabs>div>span { font-style:italic; } fieldset.inner.cmd>div.output>div.layout.flow>div.tabs>div>span.icon { padding:0 5px; } fieldset.inner.cmd>div.output>div.layout.flow>div.tabs div.website.icon { font-size:18px; line-height:32px; padding:2px 5px; position:sticky; top:0; } +fieldset.inner.cmd>div.output>div.layout.flow>div.tabs div.usernick { float:right; position:sticky; top:0; } fieldset.inner.cmd>div.output>div.layout.flow>div.tabs div.avatar { padding:0; height:38px; float:right; position:sticky; top:0; } fieldset.inner.cmd>div.output>div.layout.flow>div.tabs div.avatar>img { height:38px; } fieldset.inner.cmd>div.output>div.layout.flow>div.tabs div.time { float:right; position:sticky; top:0; } fieldset.inner.cmd>div.output>div.layout.flow>div.path { font-style:italic; padding:5px; display:block; } fieldset.inner.cmd>div.output>div.layout.flow>div.path.hide { display:none; } -fieldset.inner.cmd>div.output>div.layout.flow>div.path span.func { margin-left:20px; } +fieldset.inner.cmd>div.output>div.layout.flow>div.path span.func { padding:5px 10px; margin-left:20px; } +fieldset.inner.cmd>div.output>div.layout.flow>div.path span.mode { padding:5px 10px; margin-left:20px; cursor:pointer; } +fieldset.inner.cmd>div.output>div.layout.flow>div.path span.mode.normal { background-color:blue; color:white; } +fieldset.inner.cmd>div.output>div.layout.flow>div.path span.mode.insert { background-color:red; color:white; } fieldset.inner.cmd>div.output>div.layout.flow>div.path span.view { font-size:22px; line-height:12px; padding:0 4px; float:right; cursor:pointer; } fieldset.inner.cmd>div.output>div.layout.flow>div.plug { height:32px; clear:both; position:fixed; bottom:0; right:0; } fieldset.inner.cmd>div.output>div.layout.flow>div.plug>legend { font-size:1rem; padding:0 10px; float:right; } diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index bc77366b..912d1efb 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -1,7 +1,7 @@ (function() { - const PROJECT_HIDE = "web.code.inner:project" - const CURRENT_FILE = "web.code.inner:currentFile", SELECT_LINE = "web.code.inner:selectLine" - const VIEW_CREATE = "tabview.view.create", VIEW_REMOVE = "tabview.view.remove", LINE_SELECT = "tabview.line.select" +const PROJECT_HIDE = "web.code.inner:project", TABFUNC_HIDE = "web.code.inner:tabview" +const CURRENT_FILE = "web.code.inner:currentFile", SELECT_LINE = "web.code.inner:selectLine" +const VIEW_CREATE = "tabview.view.create", VIEW_REMOVE = "tabview.view.remove", LINE_SELECT = "tabview.line.select" Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.clear(can), can.onappend.style(can, code.INNER) if (msg.Option(nfs.FILE)) { can.Option(nfs.FILE, msg.Option(nfs.FILE)) msg.Option(nfs.PATH) && can.Option(nfs.PATH, msg.Option(nfs.PATH)) @@ -20,8 +20,9 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl case chat.SIMPLE: // no break case chat.FLOAT: can.onmotion.hidden(can, can.ui.project); break case chat.CMD: can.onimport._keydown(can), can.onmotion.hidden(can, can._status) - can.misc.sessionStorage(can, "web.code.inner:project") == html.HIDE && can.onmotion.hidden(can, can.ui.project) - // var plug = can.base.Obj(msg.Option(html.PLUG), []).concat(can.misc.Search(can, log.DEBUG) == ice.TRUE? ["can.debug", "log.debug"]: []) + can.misc.sessionStorage(can, PROJECT_HIDE) == html.HIDE && can.onmotion.hidden(can, can.ui.project) + if (can.misc.sessionStorage(can, TABFUNC_HIDE) == html.HIDE) { can.onmotion.hidden(can, can.ui.project), can.onmotion.hidden(can, can.ui.tabs) } + var plug = can.base.Obj(msg.Option(html.PLUG), []).concat(can.misc.Search(can, log.DEBUG) == ice.TRUE? ["can.debug", "log.debug"]: []) // plug.length > 0 && can.run({}, [ctx.ACTION, ctx.COMMAND].concat(plug.reverse()), function(msg) { msg.Table(function(value) { can.onimport.toolkit(can, value) }) }) case chat.FULL: // no break default: can.onimport.project(can, paths), can.onimport._tabs(can) @@ -63,6 +64,20 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl can.core.Timer({interval: 100}, function() { can.page.Modify(can, target, can.user.time(can, null, "%H:%M:%S %w")) }) can.onappend.figure(can, {action: "date", _hold: true}, target, function(sub, value) {}) }}]), can.user.info.avatar && can.page.Append(can, can.ui.tabs, [{view: aaa.AVATAR, list: [{img: can.user.info.avatar}]}]) + can.page.Append(can, can.ui.tabs, [{view: ["usernick", "", can.user.info.usernick], onclick: function(event) { + can._root.Header.onaction.usernick(event, can._root.Header) + }}]) + }, + __tabPath: function(can, skip) { can.onmotion.clear(can, can.ui.path) + can.onimport._tabPath(can, ice.PS, nfs.PATH, can.base.Path(can.Option(nfs.PATH), can.Option(nfs.FILE)), function(ls) { + if (ls[0] == ice.USR && ls.length > 2) { + can.onimport.tabview(can, ls.slice(0, 2).join(ice.PS)+ice.PS, ls.slice(2).join(ice.PS)) + } else if (ls.length > 1) { + can.onimport.tabview(can, ls.slice(0, 1).join(ice.PS)+ice.PS, ls.slice(1).join(ice.PS)) + } else { + can.onimport.tabview(can, nfs.PWD, ls[0]) + } + }, can.ui.path), can.onimport._tabFunc(can, can.ui.path, skip), can.onimport._tabMode(can), can.onimport._tabIcon(can) }, _tabPath: function(can, ps, key, value, cb, target) { can.core.List(can.core.Split(value, ps), function(value, index, array) { can.page.Append(can, target, [{text: [value+(index 0) { can.db.tabFunc = can.db.tabFunc||{} + var last = can.db.tabFunc[can.Option(nfs.PATH)+can.Option(nfs.FILE)]||{}; can.db.tabFunc[can.Option(nfs.PATH)+can.Option(nfs.FILE)] = last + var carte, list = [web.FILTER]; can.core.Item(last, function(key) { list.push(key) }), list = list.concat(func.list) + } + can.page.Append(can, target, [{view: [[html.ITEM, "func"], html.SPAN, (func.current||"func")+"/"+can.db.max+func.percent+ice.SP+can.base.Size(can._msg.result[0].length)], onclick: function(event) { + carte = can.user.carte(event, can, {_style: nfs.PATH}, list, function(ev, button) { last[button] = true, carte.close() + can.onimport.tabview(can, can.Option(nfs.PATH), can.Option(nfs.FILE), can.core.Split(button, ice.DF)[1]) + }) + }}]) + }, + _tabMode: function(can) { + var mode = can.db.mode||"", target = can.ui.current; if (target && mode != mdb.PLUGIN) { mode += ice.SP+target.selectionStart+ice.PS+target.value.length } + can.page.Append(can, can.ui.path, [{text: [mode, "", ["mode", can.db.mode||""]], onclick: function(event) { + var list = {}; can.core.Item(can.onkeymap._mode[can.db.mode], function(k, cb) { list[cb.help+ice.TB+k] = function(event, can, button) { can.core.CallFunc(cb, {event: event, can: can}) } }) + can.core.Item(can.onkeymap._mode[can.db.mode+"_ctrl"], function(k, cb) { list[cb.help+ice.TB+"C-"+k] = function(event, can, button) { can.core.CallFunc(cb, {event: event, can: can}) } }) + can.user.carte(event, can, list, []) + }}]) + }, + _tabIcon: function(can) { can.user.isWindows || can.page.Append(can, can.ui.path, can.core.Item({ "\u25E8 ": function(event) { if (can.page.isDisplay(can.ui.profile)) { return can.onmotion.hidden(can, can.ui.profile), can.onimport.layout(can) } can.onaction.show(event, can) @@ -86,50 +125,35 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl "\u25E8": shy({"font-size": "23px", rotate: "90deg", translate: "1px 1px"}, function(event) { if (can.page.isDisplay(can.ui.display)) { return can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) } can.onaction.exec(event, can) }), - "\u25E7": function(event) { can.onmotion.toggle(can, can.ui.project), can.onimport.layout(can) }, - "\u2756": !can.user.isMobile && shy({"font-size": "20px", translate: "0 2px"}, function(event) { can.onaction.plug(event, can) }), - "\u271A": !can.user.isMobile && shy({"font-size": "20px", translate: "0 2px"}, function(event) { can.onaction.open(event, can) }), + "\u25E7": function(event) { + var show = can.onmotion.toggle(can, can.ui.project); can.onimport.layout(can) + can.isCmdMode() && can.misc.sessionStorage(can, PROJECT_HIDE, show? "": html.HIDE) + }, + "\u2756": shy({"font-size": "20px", translate: "0 2px"}, function(event) { can.onaction.plug(event, can) }), + "\u271A": shy({"font-size": "20px", translate: "0 2px"}, function(event) { can.onaction.open(event, can) }), }, function(text, cb) { return cb && {text: [text, html.SPAN, html.VIEW], style: cb.meta, onclick: cb} })) - var func = can.onexport.func(can); if (func.list.length == 0) { return } can.db.tabFunc = can.db.tabFunc||{} - var last = can.db.tabFunc[can.Option(nfs.PATH)+can.Option(nfs.FILE)]||{}; can.db.tabFunc[can.Option(nfs.PATH)+can.Option(nfs.FILE)] = last - var carte, list = ["filter"]; can.core.Item(last, function(key) { list.push(key) }), list = list.concat(func.list) - can.page.Append(can, target, [{view: [[html.ITEM, "func"], html.SPAN, (func.current||"func")+" / "+can.db.max+func.percent+ice.SP+can.base.Size(can._msg.result[0].length)], onclick: function(event) { - carte = can.user.carte(event, can, {_style: nfs.PATH}, list, function(ev, button) { last[button] = true, carte.close() - can.onimport.tabview(can, can.Option(nfs.PATH), can.Option(nfs.FILE), can.core.Split(button, ice.DF)[1]) - }) - }}]), can.ui.path.ondblclick = function(event) { var show = can.onmotion.toggle(can, can.ui.tabs); can.onmotion.toggle(can, can.ui.project, show), can.onimport.layout(can) } }, _tabview: function(can, path, file, line, cb) { var key = can.onexport.keys(can, path, file) if (!can.user.isWebview) { return can.onimport.tabview(can, path, file, line, cb) } if (!can.db.tabview[key]) { return can.onimport.tabview(can, path, file, line, cb), can.db.tabview[key] = true } }, - tabview: function(can, path, file, line, cb) { path = path||can.Option(nfs.PATH); var key = can.onexport.keys(can, path, file) - function isIndex() { return line == ctx.INDEX } function isDream() { return line == web.DREAM } + tabview: function(can, path, file, line, cb) { path = path||can.Option(nfs.PATH); var key = can.onexport.keys(can, path, file); can.db._keylist = [] + function isIndex() { return line == ctx.INDEX } function isSpace() { return line == web.SPACE } function show(skip) { can._msg && can._msg.Option(nfs.LINE, can.Option(nfs.LINE)), can._msg = can.db.tabview[key] can.Option(can.onimport.history(can, {path: path, file: file, line: line||can.misc.sessionStorage(can, SELECT_LINE+ice.DF+path+file)||can._msg.Option(nfs.LINE)||1})) can.onsyntax._init(can, can._msg, function(content) { var msg = can._msg; can.onexport.hash(can) can.isCmdMode() && can.onexport.title(can, path+file), can.onmotion.select(can, can.ui.tabs, html.DIV_TABS, msg._tab), can.isCmdMode() && msg._tab.scrollIntoView() if (isIndex()) { can.ui.path.innerHTML = can.Option(nfs.FILE) - } else if (isDream()) { + } else if (isSpace()) { can.ui.path.innerHTML = can.page.Format(html.A, can.misc.MergePodCmd(can, {pod: can.Option(nfs.FILE)})) - } else { can.ui.path.innerHTML = "" - can.onimport._tabPath(can, ice.PS, nfs.PATH, can.base.Path(can.Option(nfs.PATH), can.Option(nfs.FILE)), function(ls) { - if (ls[0] == ice.USR && ls.length > 2) { - can.onimport.tabview(can, ls.slice(0, 2).join(ice.PS)+ice.PS, ls.slice(2).join(ice.PS)) - } else if (ls.length > 1) { - can.onimport.tabview(can, ls.slice(0, 1).join(ice.PS)+ice.PS, ls.slice(1).join(ice.PS)) - } else { - can.onimport.tabview(can, nfs.PWD, ls[0]) - } - }, can.ui.path), can.onimport._tabFunc(can, can.ui.path) - } + } else { can.onimport.__tabPath(can) } can.page.SelectChild(can, can.ui._content.parentNode, can.page.Keys(html.DIV_CONTENT, html.FIELDSET_STORY, [[[html.IFRAME, html.CONTENT]]]), function(target) { if (can.onmotion.toggle(can, target, target == msg._content)) { can.ui.content = msg._content } }), can.ui.content._plugin = msg._plugin, can.ui.profile._plugin = msg._profile can.page.SelectChild(can, can.ui._content.parentNode, can.page.Keys(html.DIV_PROFILE, [[[html.IFRAME, html.PROFILE]]]), function(target) { if (can.onmotion.toggle(can, target, target == msg._profile)) { can.ui.profile = msg._profile } - }), can.onimport.layout(can), can.ui.current && can.onmotion.toggle(can, can.ui.current, !isIndex() && !isDream()) + }), can.onimport.layout(can), can.ui.current && can.onmotion.toggle(can, can.ui.current, !isIndex() && !isSpace()) skip || can.onaction.selectLine(can, can.Option(nfs.LINE), true), can.base.isFunc(cb) && cb(), cb = null var ls = can.db.file.split(ice.PS); if (ls.length > 4) { ls = [ls.slice(0, 2).join(ice.PS)+"/.../"+ls.slice(-2).join(ice.PS)] } can.Status(kit.Dict(nfs.FILE, ls.join(ice.PS), mdb.TYPE, can.db.parse)) @@ -149,7 +173,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl }, can.ui.tabs) } if (can.db.tabview[key]) { return !can._msg._tab && !can.isSimpleMode()? load(can.db.tabview[key]): show() } - isIndex()||isDream()? load(can.request({}, {index: file, line: line})): can.run({}, [path, file], load, true) + isIndex()||isSpace()? load(can.request({}, {index: file, line: line})): can.run({}, [path, file], load, true) }, history: function(can, record) { can.base.Eq(record, can.db.history[can.db.history.length-1], mdb.TEXT) || can.db.history.push(record) @@ -170,9 +194,8 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl var per = 0.5; if (msg.Append(ctx.INDEX) == web.WIKI_WORD) { per = 0.6 } var width = can.onexport.size(can, can.db.profile_size[can.onexport.keys(can)]||per, can.ConfWidth()-can.ui.project.offsetWidth) can.onimport.process(can, msg, can.ui.profile, height, width, function(sub) { can.ui.profile._plugin = can._msg._profile = sub - var _width = can.base.Max(sub._target.offsetWidth, width-2); if (_width == sub.ConfWidth()) { return } - can.page.style(can, sub._output, html.MAX_WIDTH, "") - can.db.profile_size[can.onexport.keys(can)] = _width, can.onimport.layout(can), sub.onimport.size(sub, height, _width, true) + can.page.style(can, sub._output, html.MAX_WIDTH, ""); var _width = can.base.Max(sub._target.offsetWidth, width) + can.db.profile_size[can.onexport.keys(can)] = _width, can.onimport.layout(can), sub.onimport.size(sub, height, _width == width? _width-1: _width, true) }) can.page.Select(can, can.ui.profile, html.TABLE, function(target) { can.onmotion.delay(can, function() { if (target.offsetWidth < can.ui._profile.offsetWidth) { can.db.profile_size[can.onexport.keys(can)] = target.offsetWidth, can.onimport.layout(can) } @@ -183,10 +206,10 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl var height = can.onexport.size(can, can.db.display_size[can.onexport.keys(can)]||0.5, can.ui.content.offsetHeight||can.ConfHeight()) can.page.style(can, can.ui.display, html.MAX_HEIGHT, can.ConfHeight()/2) can.onimport.process(can, msg, can.ui.display, height, width, function(sub) { - var _height = can.base.Max(sub._target.offsetHeight, height) - // ; if (_height == sub.ConfHeight()) { return } if (sub.ConfHeight() < can.ui.content.offsetHeight-100) { can.page.style(can, sub._output, html.MAX_HEIGHT, "") } - can.db.display_size[can.onexport.keys(can)] = _height, can.onimport.layout(can), sub.onimport.size(sub, _height, width, true) + can.onmotion.delay(can, function() { var _height = can.base.Max(sub._target.offsetHeight, height) // ; if (_height == sub.ConfHeight()) { return } + can.db.display_size[can.onexport.keys(can)] = _height, can.onimport.layout(can), sub.onimport.size(sub, _height == height? _height-1: _height, width, true) + }) }) }, process: function(can, msg, target, height, width, cb) { can.onmotion.clear(can, target) @@ -239,7 +262,6 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.cl }, layout: function(can) { if (can.isSimpleMode()) { return can.page.style(can, can.ui.content, html.WIDTH, can.ConfWidth()) } if (can.isCmdMode()) { can.ConfHeight(can.page.height()), can.ConfWidth(can.page.width()) } - can.isCmdMode() && can.misc.sessionStorage(can, "web.code.inner:project", can.page.isDisplay(can.ui.project)? "": html.HIDE) // can.ui.size = {profile: can.db.profile_size[can.onexport.keys(can)]||0.5, display: can.db.display_size[can.onexport.keys(can)]||3*html.ACTION_HEIGHT} can.ui.size = {profile: can.db.profile_size[can.onexport.keys(can)]||0.5, display: can.db.display_size[can.onexport.keys(can)]} can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(content_height, content_width) { @@ -307,14 +329,14 @@ Volcanos(chat.ONSYNTAX, {_init: function(can, msg, cb) { }) }, _index: function(can, msg, cb) { if (msg._content) { return can.base.isFunc(cb) && cb(msg._content) } - if (can.Option(nfs.LINE) == web.DREAM) { can.ui.zone.dream && can.onmotion.delay(can, function() { can.ui.zone.dream.refresh() }, 5000) + if (can.Option(nfs.LINE) == web.SPACE) { can.ui.zone.space && can.onmotion.delay(can, function() { can.ui.zone.space.refresh() }, 5000) return can.base.isFunc(cb) && cb(msg._content = can.page.insertBefore(can, [{view: [html.CONTENT, html.IFRAME], src: can.misc.MergePodCmd(can, {pod: can.Option(nfs.FILE)}), height: can.ui.content.offsetHeight, width: can.ui.content.offsetWidth}], can.ui._content)) } var index = msg.Option(ctx.INDEX).split(ice.FS), meta = {type: chat.STORY, index: index[0], args: index.slice(1)} if (meta.index == "web.code.xterm" && meta.args.length > 0) { meta.style = "output" } return can.onimport.plug(can, meta, function(sub) { sub.onimport.size(sub, can.ui.content.offsetHeight, can.ui.content.offsetWidth, true) sub.onimport._open = function(sub, msg, arg) { var url = can.base.ParseURL(arg), ls = url.origin.split("/chat/pod/") - arg.indexOf(location.origin) == 0 && ls.length > 1? can.onimport.tabview(can, can.Option(nfs.PATH), ls[1].split(ice.PS)[0], web.DREAM): can.user.open(arg), sub.Update() + arg.indexOf(location.origin) == 0 && ls.length > 1? can.onimport.tabview(can, can.Option(nfs.PATH), ls[1].split(ice.PS)[0], web.SPACE): can.user.open(arg), sub.Update() } sub.onaction["打开链接"] = function() { can.onimport.tabview(can, can.Option(nfs.PATH), [meta.index].concat(sub.Input([], false)).join(ice.FS), ctx.INDEX) } sub.onaction.close = function() { can.onaction.back(can), msg._tab._close() } @@ -352,12 +374,16 @@ Volcanos(chat.ONACTION, {list: ["调试", "首页", "官网", "源码", "百度" appendLine: function(can, value) { var ui = can.page.Append(can, can.ui._content, [{view: [nfs.LINE, html.TR], list: [ {view: [nfs.LINE, html.TD, ++can.db.max], onclick: function(event) { can.onaction.selectLine(can, ui.tr) + can.onkeymap._insert(event, can, 0, (event.offsetX)/12-1) }, ondblclick: function(event) { can.onaction.find(event, can) }}, {view: [mdb.TEXT, html.TD, can.onsyntax._parse(can, value)], onclick: function(event) { - can.onaction.selectLine(can, ui.tr) - if (event.metaKey) { if (ui.text.innerText.indexOf(ice.HTTP) > -1) { var ls = (/(http[^ ]+)/).exec(ui.text.innerText); if (ls && ls[1]) { can.user.open(ls[1]) } } } + can.onmotion.scrollHold(can, function() { + can.onaction.selectLine(can, ui.tr) + can.onkeymap._insert(event, can, 0, (event.offsetX)/10-1) + if (event.metaKey) { if (ui.text.innerText.indexOf(ice.HTTP) > -1) { var ls = (/(http[^ ]+)/).exec(ui.text.innerText); if (ls && ls[1]) { can.user.open(ls[1]) } } } + }, can.ui.content) }, ondblclick: function(event) { can.onaction.searchLine(event, can, can.onexport.selection(can, ui.text.innerText)) }} @@ -377,11 +403,10 @@ Volcanos(chat.ONACTION, {list: ["调试", "首页", "官网", "源码", "百度" can.onexport.hash(can), scroll && can.onaction.scrollIntoView(can), can.onengine.signal(can, LINE_SELECT, can._msg) }) if (can.isCmdMode()) { - if (can.user.isWebview) { - can.misc.localStorage(can, CURRENT_FILE, [can.Option(nfs.PATH), can.Option(nfs.FILE), can.onaction._getLineno(can, can.current.line)].join(ice.DF)) - } can.misc.sessionStorage(can, SELECT_LINE+ice.DF+can.Option(nfs.PATH)+can.Option(nfs.FILE), can.onaction._getLineno(can, can.current.line)) + can.user.isWebview && can.misc.localStorage(can, CURRENT_FILE, [can.Option(nfs.PATH), can.Option(nfs.FILE), can.onaction._getLineno(can, can.current.line)].join(ice.DF)) } + can.onimport.__tabPath(can) return can.onexport.line(can, line) }, scrollIntoView: function(can, offset) { var current = can.onaction._getLineno(can, can.current.line), window = can.current.window(); offset = offset||parseInt(window/4)+2 @@ -460,11 +485,12 @@ Volcanos(chat.ONACTION, {list: ["调试", "首页", "官网", "源码", "百度" } else { cb(msg) } }, true) }}], function(list, input) { input.cancel(); var ls = can.core.Split(list[0], ice.DF, ice.DF); switch (ls[0]) { - case "_open": return can.runAction(event, ls[0], ls[1]) - case ctx.INDEX: - case web.DREAM: return can.onimport.tabview(can, can.Option(nfs.PATH), ls[1], ls[0]) case nfs.LINE: return can.onaction.selectLine(can, parseInt(ls[1]), true) - default: can.core.List(can.db.paths, function(path) { if (list[0].indexOf(path) == 0) { can.onimport.tabview(can, path, list[0].slice(path.length)) } }) + case web.SPACE: return can.onimport.tabview(can, "", ls[1].indexOf(ice.HTTP) == 0? list[0].slice(6): ls[1], web.SPACE) + case ctx.INDEX: return can.onimport.tabview(can, "", ls[1], ls[0]) + case ssh.SHELL: return can.onimport.tabview(can, "", web.CODE_XTERM+","+(list[0].slice(6)), ctx.INDEX) + case cli.OPENS: return can.runAction(event, ls[0], ls[1], null, true) + default: var ls = can.onexport.split(can, list[0]); can.onimport.tabview(can, ls[0], ls[1]) } }); can.page.Modify(can, input._target, {"className": "input vimer open float"}) can.page.style(can, input._target, html.LEFT, can.ui.project.offsetWidth+can.ui.content.offsetWidth/4-34, html.TOP, can.ui.content.offsetHeight/4, html.RIGHT, "") }, @@ -528,7 +554,7 @@ Volcanos(chat.ONEXPORT, {list: [mdb.COUNT, mdb.TYPE, nfs.FILE, nfs.LINE, ice.BAC case ice.SP: indent++; break default: return indent } } } - var package = "", block = "", current = "", percent = "" + var package = "", block = "", current = can.Option(nfs.LINE), percent = " = "+parseInt(can.Option(nfs.LINE)*100/(can.db.max||1))+"%" can.page.Select(can, can.ui.content, "tr.line>td.text", function(item, index) { var text = item.innerText, _indent = indent(text) function push(item) { list.push(item); if (index < can.Option(nfs.LINE)) { current = list[list.length-1], percent = " = "+parseInt((index+1)*100/(can.db.max||1))+"%" } } if (can.db.parse == nfs.JS) { var ls = can.core.Split(text, "\t (,", ice.DF) diff --git a/plugin/local/code/vimer.css b/plugin/local/code/vimer.css index 5024b8e6..04cae38a 100644 --- a/plugin/local/code/vimer.css +++ b/plugin/local/code/vimer.css @@ -1,5 +1,5 @@ fieldset.vimer>div.output div.project div.zone.recent>div.list { max-height:200px; } -fieldset.vimer>div.output div.project div.zone.dream div.item.stop { color:gray; } +fieldset.vimer>div.output div.project div.zone.space div.item.stop { color:gray; } fieldset.vimer>div.output input.current { background-color:transparent; color:transparent; padding-left:10px; height:20px; position:absolute; } fieldset.vimer>div.output input.current.insert { caret-color:black; } fieldset.vimer>div.output input.current.normal { caret-color:lightgray; } diff --git a/plugin/local/code/vimer.js b/plugin/local/code/vimer.js index 6face954..e4d3f03e 100644 --- a/plugin/local/code/vimer.js +++ b/plugin/local/code/vimer.js @@ -4,15 +4,20 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.require(["i }, target) }) }, _input: function(can) { var ui = can.page.Append(can, can.ui.content.parentNode, [ {view: [code.CURRENT, html.INPUT], spellcheck: false, onkeydown: function(event) { can.onimport._value(can); if (event.metaKey) { return } - can.db._keylist = can.onkeymap._parse(event, can, can.db.mode+(event.ctrlKey? "_ctrl": ""), can.db._keylist, can.ui.current) - if (can.db.mode == mdb.NORMAL) { can.onkeymap.prevent(event), can.Status(mdb.KEYS, can.db._keylist.join("")) } - if (can.db.mode == mdb.INSERT) { can.db._keylist = [] } + can.onmotion.scrollHold(can, function() { + can.db._keylist = can.onkeymap._parse(event, can, can.db.mode+(event.ctrlKey? "_ctrl": ""), can.db._keylist, can.ui.current) + if (can.db.mode == mdb.NORMAL) { can.onkeymap.prevent(event), can.Status(mdb.KEYS, can.db._keylist.join("")) } + if (can.db.mode == mdb.INSERT) { can.db._keylist = [] } + }, can.ui.content, event.ctrlKey) }, onkeyup: function(event) { can.onimport._value(can); if (event.metaKey) { return } can.onaction._complete(event, can) }, onfocus: function(event) { can.current.line.appendChild(can.ui.complete) }, onclick: function(event) { can.onkeymap._insert(event, can) }}, {view: [[code.COMPLETE]]}, ]); can.ui.current = ui.current, can.ui.complete = ui.complete, can.onkeymap._build(can), can.onkeymap._plugin(can) }, - _value: function(can) { can.db.mode == mdb.INSERT && can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) }) }, + _value: function(can) { + can.db.mode == mdb.INSERT && can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) }) + can.onimport.__tabPath(can, true) + }, }, [""]) Volcanos(chat.ONFIGURE, { source: function(can, target, zone, path) { var args = can.base.getValid(can.misc.SearchHash(can), [can.Option(nfs.PATH), can.Option(nfs.FILE)]) @@ -45,19 +50,19 @@ Volcanos(chat.ONFIGURE, { }) }, favor: function(can, target, zone) { can.onimport._zone(can, zone, web.CHAT_FAVOR, function(sub, msg) { sub.onexport.record = function(sub, value, key, item, event) { switch (item.type) { - case mdb.LINK: event.shiftKey? can.user.open(item.text): can.onimport.tabview(can, "", item.text, web.DREAM); break + case mdb.LINK: event.shiftKey? can.user.open(item.text): can.onimport.tabview(can, "", item.text, web.SPACE); break case nfs.FILE: var ls = can.onexport.split(can, item.text); can.onimport.tabview(can, ls[0], ls[1]); break case ctx.INDEX: can.onimport.tabview(can, "", item.text, ctx.INDEX); break case ssh.SHELL: can.onimport.tabview(can, "", [web.CODE_XTERM, item.text].join(","), ctx.INDEX); break - case "_open": can.runAction(event, "_open", [item.text]); break + case cli.OPENS: can.runAction(event, cli.OPENS, [item.text]); break } } }) }, - dream: function(can, target, zone) { can.onimport._zone(can, zone, web.DREAM, function(sub, msg) { + space: function(can, target, zone) { can.onimport._zone(can, zone, web.DREAM, function(sub, msg) { can.page.Select(can, sub._output, html.DIV_ITEM, function(target, index) { can.onappend.style(can, msg.status[index], target) }) sub.onimport._open = function(sub, msg, arg) { var url = can.misc.ParseURL(can, arg) - url.pod? can.onimport.tabview(can, can.Option(nfs.PATH), url.pod+(url.cmd? "/cmd/"+url.cmd:""), web.DREAM): can.user.open(arg) + url.pod? can.onimport.tabview(can, can.Option(nfs.PATH), url.pod+(url.cmd? "/cmd/"+url.cmd:""), web.SPACE): can.user.open(arg) } - sub.onexport.record = function(sub, value, key) { can.onimport.tabview(can, can.Option(nfs.PATH), value, web.DREAM) } + sub.onexport.record = function(sub, value, key) { can.onimport.tabview(can, can.Option(nfs.PATH), value, web.SPACE) } }) }, }) Volcanos(chat.ONACTION, {list: ["编译", "调试", "首页", "提交", "收藏", "计划"], @@ -113,8 +118,8 @@ Volcanos(chat.ONACTION, {list: ["编译", "调试", "首页", "提交", "收藏" }) }, "编译": function(event, can) { can.onaction.compile(event, can, code.COMPILE) }, - "调试": function(event, can) { can.onimport.tabview(can, "", can.base.MergeURL(location.href, log.DEBUG, ice.TRUE), web.DREAM) }, - "首页": function(event, can) { can.onimport.tabview(can, "", location.origin+(can.misc.Search(can, log.DEBUG) == ice.TRUE? "?debug=true": ""), web.DREAM) }, + "调试": function(event, can) { can.onimport.tabview(can, "", can.base.MergeURL(location.href, log.DEBUG, ice.TRUE), web.SPACE) }, + "首页": function(event, can) { can.onimport.tabview(can, "", location.origin+ice.PS+(can.misc.Search(can, log.DEBUG) == ice.TRUE? "?debug=true": ""), web.SPACE) }, "提交": function(event, can) { can.onimport.tabview(can, "", web.CODE_GIT_STATUS, ctx.INDEX) }, "收藏": function(event, can) { can.onimport.tabview(can, "", web.CHAT_FAVOR, ctx.INDEX) }, "计划": function(event, can) { can.onimport.tabview(can, "", web.TEAM_PLAN, ctx.INDEX) }, @@ -170,6 +175,8 @@ Volcanos(chat.ONACTION, {list: ["编译", "调试", "首页", "提交", "收藏" }, _selectLine: function(can) { 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.db.mode == mdb.NORMAL && can.onkeymap._normal(can) + return if (event && event.target && event.target.tagName && can.page.tagis(event.target, html.TD, html.SPAN)) { can.onkeymap._insert(event, can, 0, (event.offsetX)/12-1), can.onmotion.clear(can, can.ui.complete) } else { @@ -186,7 +193,10 @@ Volcanos(chat.ONACTION, {list: ["编译", "调试", "首页", "提交", "收藏" }) Volcanos(chat.ONEXPORT, {list: [mdb.COUNT, mdb.TYPE, nfs.FILE, nfs.LINE, ice.BACK, ice.MODE, mdb.KEYS]}) Volcanos(chat.ONKEYMAP, { - _model: function(can, value) { can.Status(ice.MODE, can.db.mode = value), can.page.styleClass(can, can.ui.current, [code.CURRENT, can.db.mode]), can.page.styleClass(can, can.ui.complete, [code.COMPLETE, can.db.mode, chat.FLOAT]) }, + _model: function(can, value) { + can.Status(ice.MODE, can.db.mode = value), can.page.styleClass(can, can.ui.current, [code.CURRENT, can.db.mode]), can.page.styleClass(can, can.ui.complete, [code.COMPLETE, can.db.mode, chat.FLOAT]) + can.onimport.__tabPath(can, true) + }, _plugin: function(can) { can.onkeymap._model(can, mdb.PLUGIN), can.ui.current.blur() }, _normal: function(can) { can.onkeymap._model(can, mdb.NORMAL), can.onaction.scrollHold(can), can.onkeymap.prevent(event) }, _insert: function(event, can, count, begin) { can.onkeymap._model(can, mdb.INSERT), can.onaction.scrollHold(can, count, begin), can.onkeymap.prevent(event) }, diff --git a/plugin/local/code/xterm.js b/plugin/local/code/xterm.js index 68b2e236..781b6db8 100644 --- a/plugin/local/code/xterm.js +++ b/plugin/local/code/xterm.js @@ -11,6 +11,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { can.onmotion.clear(can) can.sup._listen || can.onengine.listen(can, chat.ONTHEMECHANGE, function() { can = can.core.Value(can.sup, chat._OUTPUTS_CURRENT) can._current.selectAll(), can.sup._save = can.base.trimSuffix(can._current.getSelection(), ice.NL), can.Update() }), can.sup._listen = true + can.sup.onexport.link = function() { return can.misc.MergePodCmd(can, {cmd: web.CODE_XTERM, hash: item.hash, style: html.OUTPUT}) } }) }, _connect: function(can, item) { var term = new Terminal({tabStopWidth: 4, cursorBlink: true, theme: can.onimport._theme(can, item)}); term.loadAddon(new WebLinksAddon.WebLinksAddon()) diff --git a/plugin/local/team/plan.js b/plugin/local/team/plan.js index 9170e5fb..52f5b27b 100644 --- a/plugin/local/team/plan.js +++ b/plugin/local/team/plan.js @@ -120,7 +120,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear( }) } }, [""]) -Volcanos(chat.ONACTION, {list: [mdb.PREV, mdb.NEXT, mdb.INSERT, mdb.EXPORT, mdb.IMPORT, +Volcanos(chat.ONACTION, {list: [ ["status", "all", "prepare", "process", "cancel", "finish"], ["level", "all", "l1", "l2", "l3", "l4", "l5"], ["score", "all", "s1", "s2", "s3", "s4", "s5"], diff --git a/plugin/local/wiki/word.js b/plugin/local/wiki/word.js index 5e362b6a..0bfb320c 100644 --- a/plugin/local/wiki/word.js +++ b/plugin/local/wiki/word.js @@ -83,12 +83,10 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear( can.onappend._init(can, item, [chat.PLUGIN_STATE_JS], function(sub) { sub.run = function(event, cmds, cb, silent) { var msg = sub.request(event) if (msg.Option(nfs.PATH) == can.Option(nfs.PATH)) { msg.Option(nfs.PATH, "") } - can.runAction(event, chat.STORY, [meta.type, meta.name, meta.text].concat(cmds), function(msg) { - cb(msg), can.sup.onexport.output && can.sup.onexport.output(can.sup, msg) - }, true) + can.runAction(event, chat.STORY, [meta.type, meta.name, meta.text].concat(cmds), cb, true) }, can._plugins = (can._plugins||[]).concat([sub]) - sub.ConfHeight(can.base.Min(300, can.ConfHeight()-300)), sub.ConfWidth(item.width = (width||can.ConfWidth())-(can.user.isWindows? 40: 20)) + sub.ConfHeight(can.base.Min(300, can.ConfHeight()-300)), sub.ConfWidth(item.width = (width||can.ConfWidth())-(can.user.isWindows? 42: 22)) can.page.style(can, sub._output, html.MAX_WIDTH, sub.ConfWidth()) can.core.Value(item, "auto.cmd") && can.onmotion.delay(function() { diff --git a/plugin/state.js b/plugin/state.js index 7082ac5e..5fe9cfe4 100644 --- a/plugin/state.js +++ b/plugin/state.js @@ -51,7 +51,7 @@ Volcanos(chat.ONIMPORT, { size: function(can, height, width, auto, mode) { height -= can.onexport.actionHeight(can)+can.onexport.statusHeight(can) auto? can.page.style(can, can._output, html.HEIGHT, "", html.WIDTH, "", html.MAX_HEIGHT, height? can.ConfHeight(height): "", html.MAX_WIDTH, can.ConfWidth(width)): can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(height), html.WIDTH, can.ConfWidth(width), html.MAX_HEIGHT, "", html.MAX_WIDTH, "") - var sub = can.core.Value(can, chat._OUTPUTS_CURRENT); if (!sub) { return auto } sub.ConfHeight(can.ConfHeight()), sub.ConfWidth(can.ConfWidth()) + var sub = can.core.Value(can, chat._OUTPUTS_CURRENT); if (!sub) { return can.Mode(mode), auto } sub.ConfHeight(can.ConfHeight()), sub.ConfWidth(can.ConfWidth()) if (mode) { sub.Mode(can.Mode(mode)), sub.onlayout[mode](sub) } else { sub.onlayout._init(sub) } return auto }, change: function(event, can, name, value, cb) { return can.page.SelectArgs(can, can._option, "", function(input) { if (input.name != name || value == input.value) { return } @@ -77,6 +77,7 @@ Volcanos(chat.ONACTION, {list: [ can.ConfHeight(back.height), can.ConfWidth(back.width), can.Mode(back.mode), can.onmotion.toggle(can, can._action, back.action), can.onmotion.toggle(can, can._status, back.status) can.page.style(can, can._output, back.output), can.page.style(can, can._target, back.style), can.base.isFunc(load) && load(back) + if (!sub) { return } sub.ConfHeight(can.ConfHeight()), sub.ConfWidth(can.ConfWidth()), sub.Mode(can.Mode()), sub.onlayout._init(sub) } }, @@ -86,7 +87,7 @@ Volcanos(chat.ONACTION, {list: [ can.getActionSize(function(left) { can.onmotion.move(can, can._target, {left: (left||0)+(can.user.isMobile? 0: html.PLUGIN_MARGIN), top: can.page.height()/2-html.PLUGIN_MARGIN-html.ACTION_HEIGHT}) }) can.ConfHeight(can.page.height()/2-can.onexport.actionHeight(can)-can.onexport.statusHeight(can)), can.ConfWidth(can.page.width()/(can.user.isMobile? 1: 2)) }) }, - "切换全屏": function(event, can) { var sub = can._outputs[0]; can.onaction._switch(can, sub, chat.FULL, function() { can.page.style(can, can._target, html.LEFT, "", html.TOP, "", html.BOTTOM, "") + "切换全屏": function(event, can, button, sub) { can.onaction._switch(can, sub, chat.FULL, function() { can.page.style(can, can._target, html.LEFT, "", html.TOP, "", html.BOTTOM, "") can.ConfHeight(can.page.height()-can.onexport.actionHeight(can)-can.onexport.statusHeight(can)), can.ConfWidth(can.page.width()) }) }, "远程控制": function(event, can) { can.onaction.keyboard(event, can) }, @@ -124,7 +125,9 @@ Volcanos(chat.ONACTION, {list: [ refresh: function(event, can) { var sub = can.core.Value(can, chat._OUTPUTS_CURRENT); if (sub) { sub.ConfHeight(can.ConfHeight()), sub.ConfWidth(can.ConfWidth()), sub.onimport.layout(sub) } }, close: function(event, can) { - if (can.isFullMode()) { + if (can.isCmdMode()) { + can.user.close() + } else if (can.isFullMode()) { can.onaction["切换全屏"](event, can, "切换全屏", can.core.Value(can, chat._OUTPUTS_CURRENT)) } else if (can.isFloatMode()) { can.onaction["切换浮动"](event, can, "切换浮动", can.core.Value(can, chat._OUTPUTS_CURRENT)) diff --git a/proto.js b/proto.js index 2b15e76a..4eb0e136 100644 --- a/proto.js +++ b/proto.js @@ -80,7 +80,7 @@ var web = {CHAT: "chat", Accept: "Accept", ContentType: "Content-Type", ContentJSON: "application/json", ContentFORM: "application/x-www-form-urlencoded", VIDEO_WEBM: "video/webm", - CODE_XTERM: "web.code.git.status", + CODE_GIT_STATUS: "web.code.git.status", CODE_XTERM: "web.code.xterm", CODE_VIMER: "web.code.vimer", CODE_INNER: "web.code.inner", @@ -119,6 +119,7 @@ var nfs = { ZML: "zml", IML: "iml", TXT: "txt", PNG: "png", WEBM: "webm", _CSS: ".css", _JS: ".js", SRC: "src/", + OPENS: "opens", } var cli = { PWD: "pwd", SYSTEM: "system", DAEMON: "daemon", ORDER: "order", BUILD: "build", @@ -127,6 +128,7 @@ var cli = { MAGENTA: "magenta", SILVER: "silver", ALICEBLUE: "aliceblue", TRANSPARENT: "transparent", MAKE: "make", MAIN: "main", EXEC: "exec", DONE: "done", COST: "cost", FROM: "from", CLEAR: "clear", PLAY: "play", + OPENS: "opens", } var log = { INFO: "info", WARN: "warn", ERROR: "error", DEBUG: "debug", TRACE: "trace",