diff --git a/frame.js b/frame.js index fe3a045a..def027b5 100644 --- a/frame.js +++ b/frame.js @@ -348,6 +348,9 @@ Volcanos("onappend", { _init: function(can, meta, list, cb, target, field) { met meta.detail = meta.feature["detail"] || {} sub.onimport._init(sub, sub.Conf(meta), list, function() {}, field) sub.onappend._status(sub, status) + // sub.Conf("height", meta.height || sub.Conf("height")) + // sub.Conf("width", meta.width || sub.Conf("width")) + // 添加控件 var index = -1 @@ -372,10 +375,6 @@ Volcanos("onappend", { _init: function(can, meta, list, cb, target, field) { met var p = sub.user.Cookie(can, item.name) item.type != "button" && p != undefined && (input._target.value = p) } - if (can.user.Search(can, "active") == meta.name || can.user.Search(can, "title") == meta.name) { - var p = sub.user.Search(can, item.name) - p != undefined && (input._target.value = p) - } input.run = function(event, cmds, cb, silent) { var msg = sub.request(event) sub.core.Item(sub.Conf("option"), msg.Option) @@ -435,8 +434,8 @@ Volcanos("onappend", { _init: function(can, meta, list, cb, target, field) { met var table = Volcanos(display, { _help: display, _follow: can._follow+"."+meta.name+"."+display, _target: output, Option: sub.Option, Action: sub.Action, Status: sub.Status, _option: option, _action: action, _output: output, + _fields: field, }, Volcanos.meta.libs.concat(["/frame.js", display]), function(table) { table.Conf(sub.Conf()), table._msg = msg - table.onimport && table.onimport._init && table.onimport._init(table, msg, msg.result||[], function() {}, output) table.run = function(event, cmds, cb, silent) { cmds = cmds? cmds: sub.page.Select(sub, option, "textarea.args,input.args,select.args", function(item) { return item.name && item.value || "" @@ -448,11 +447,13 @@ Volcanos("onappend", { _init: function(can, meta, list, cb, target, field) { met return run(event, cmds, cb, silent) } - // 交互控件 - can.onappend._action(table, action) - can.onappend._detail(table, msg, msg["_detail"] || sub.Conf("detail"), output) - can.onappend._status(table, status) - sub.Status("ncmd", sub._history.length+"/"+count) + table.onimport && table.onimport._init && table.onimport._init(table, msg, msg.result||[], function() { + // 交互控件 + can.onappend._action(table, action, meta._action) + can.onappend._detail(table, msg, msg["_detail"] || sub.Conf("detail"), output) + can.onappend._status(table, status) + sub.Status("ncmd", sub._history.length+"/"+count) + }, output) }); sub._outputs.push(table) }, silent) } }); cb(sub) diff --git a/index.css b/index.css index 4f5ebe39..fff8aba3 100644 --- a/index.css +++ b/index.css @@ -119,15 +119,6 @@ fieldset>div.output>div.project div.item:hover { fieldset>div.output>div.project div.list { margin-left:10px; } -fieldset>div.output>pre.profile { - float:right; -} -fieldset>div.output>div.profile>div.item { - clear:both; -} -fieldset>div.output>div.profile>div.item:hover { - border:solid 1px red; -} fieldset>div.output>pre.display { position:sticky; bottom:0; /* max-height:120px; */ diff --git a/lib/page.js b/lib/page.js index b1f02edb..91dfecdb 100644 --- a/lib/page.js +++ b/lib/page.js @@ -632,5 +632,25 @@ var page = Volcanos("page", {help: "网页模块", } return {Top: offsetTop, Left: offsetLeft} }, + + EnableDrop: function(can, parent, search, target) { + return can.page.Modify(can, target, { draggable: true, + ondragstart: function(event) { var target = event.target; can.drop = function(event, tab) { + parent.insertBefore(target, tab) + can.page.Select(can, parent, search, function(item) { + can.page.ClassList.del(can, item, "over") + }) + } }, + ondragover: function(event) { event.preventDefault() + can.page.Select(can, parent, search, function(item) { + can.page.ClassList.del(can, item, "over") + }), can.page.ClassList.add(can, event.target, "over") + }, + ondrop: function(event) { event.preventDefault() + can.drop(event, event.target) + }, + + }) + }, }) diff --git a/pane/Action.js b/pane/Action.js index 772b05e7..e430683b 100644 --- a/pane/Action.js +++ b/pane/Action.js @@ -6,6 +6,13 @@ Volcanos("onaction", {help: "交互操作", list: [], _init: function(can, msg, }, add_plugin: function(can, river, storm, value) { + if (can.user.Search(can, "river") == river && can.user.Search(can, "storm") == storm && can.user.Search(can, "active") == value.name) { + value.args = can.core.List(value.inputs, function(item) { + if (item._input == "text" || item._input == "select") { + return can.user.Search(can, item.name) || item.value + } + }) + } value.name && can.onappend._init(can, value, Volcanos.meta.libs.concat(["/plugin/state.js"]), function(sub) { sub.run = function(event, cmds, cb, silent) { var msg = can.request(event) can.Conf("active", sub.Option()) @@ -13,8 +20,8 @@ Volcanos("onaction", {help: "交互操作", list: [], _init: function(can, msg, can.Conf("current", sub) // 插件回调 return can.run(event, can.onengine[cmds[0]]? cmds: [river, storm, value.action].concat(cmds), function(msg) { - can.run(msg._event, ["search", "Footer.onaction.ncmd"]); - can.user.toast(can, "执行成功", value.name, 1000); + can.run(msg._event, ["search", "Footer.onaction.ncmd"]) + can.user.toast(can, "执行成功", value.name, 1000) typeof cb == "function" && cb(msg) }, silent) } @@ -24,8 +31,7 @@ Volcanos("onaction", {help: "交互操作", list: [], _init: function(can, msg, meta[item] && meta[item](event, can, value, sub) }) } - }, can._output); - + }, can._output) }, }) Volcanos("ondetail", {help: "交互菜单", list: ["共享", "更名", "删除"], @@ -38,13 +44,13 @@ Volcanos("ondetail", {help: "交互菜单", list: ["共享", "更名", "删除"] can.user.share(can, msg, list) }, }) -Volcanos("onexport", {help: "导出数据", list: [], _init: function(can, msg, list, cb, target) { var key = "action"; - can.Cache(can.Conf("river")+"."+can.Conf("storm"), can._output, can._output.scrollTop+1); +Volcanos("onexport", {help: "导出数据", list: [], _init: function(can, msg, list, cb, target) { var key = "action" + can.Cache(can.Conf("river")+"."+can.Conf("storm"), can._output, can._output.scrollTop+1) var river = can.Conf("river", msg.Option("river")), storm = can.Conf("storm", msg.Option("storm")||"main") - var position = can.Conf(key, msg.Option(key, can.Cache(river+"."+storm, can._output)||"")); + var position = can.Conf(key, msg.Option(key, can.Cache(river+"."+storm, can._output)||"")) if (position) { can._output.scrollTo(0, position-1); return } - msg.Clear("option"), can.run(msg._event, [river, storm], function(sup) { can._output.innerHTML = ""; + msg.Clear("option"), can.run(msg._event, [river, storm], function(sup) { can._output.innerHTML = "" can.core.Next(sup.Table(), function(value, next) { // value.inputs = can.base.Obj(value.inputs||"[]", []) // value.args = typeof value.args == "string"? value.args.split(","): value.args diff --git a/plugin/input.js b/plugin/input.js index 4265b279..29762de5 100644 --- a/plugin/input.js +++ b/plugin/input.js @@ -25,6 +25,13 @@ Volcanos("onaction", {help: "控件交互", list: [], return } + var sub = can.sup && can.sup._outputs && can.sup._outputs[0] + var cb = sub && sub.onaction[can.Conf("name")] + if (typeof cb == "function") { + cb(event, sub, can.Conf("name")) + return + } + switch (can.Conf("type")) { case "button": var toast = can.user.toast(can, "执行中...", can.sup._help, 100000) diff --git a/plugin/input/key.js b/plugin/input/key.js index 524bbac4..7c990bf6 100644 --- a/plugin/input/key.js +++ b/plugin/input/key.js @@ -4,7 +4,7 @@ Volcanos("onfigure", {help: "控件详情", list: [], _merge: function(can, sub) key: {onclick: function(event, can, item, target) { function run() { var msg = can.request(event); msg.Option(item) - can.run(event, ["action", "input", item.name, target.value], function(msg) { + can.run(event, ["action", "inputs", item.name, target.value], function(msg) { if (!msg.append) { return } var figure = can.onappend.field(can, document.body, "input key", {}) diff --git a/plugin/local/code/inner.css b/plugin/local/code/inner.css index 0731ee81..7cb8eb7d 100644 --- a/plugin/local/code/inner.css +++ b/plugin/local/code/inner.css @@ -1,13 +1,10 @@ -fieldset.editor>div.action { - clear:none; -} fieldset.editor>div.action>div.file { border:solid 2px red; padding:2px; float:left; margin:2px 0; cursor:pointer; } -fieldset.editor>div.action>div.file:hover { - background-color:green; +fieldset.editor>div.action>div.file.over { + background-color:blue; } fieldset.editor>div.action>div.file.select { background-color:green; @@ -17,29 +14,25 @@ fieldset.editor>form.option div.item input.args[name=line] { } fieldset.editor>div.output { - max-height:560px; overflow:auto; background-color:black; + min-width:800px; } -fieldset.editor>div.output>div.project { +fieldset.editor>div.output div.project { text-align:left; max-height:400px; overflow:auto; max-width:160px; color:white; } -fieldset.editor>div.output>div.project div.item { +fieldset.editor>div.output div.project div.item { cursor:pointer; } -fieldset.editor>div.output>div.project div.item:hover { +fieldset.editor>div.output div.project div.item:hover { border:solid 2px red; } -fieldset.editor>div.output>div.profile { - position:absolute; right:0; - width:80px; overflow:auto; -} -fieldset.editor>div.output>div.profile:hover { - width:480px; -} +fieldset.editor>div.output div.profile { + max-height:400px; overflow:auto; +} fieldset.editor>div.output div.preview { font-family:monospace; float:left; @@ -60,7 +53,7 @@ fieldset.editor>div.output div.content { font-size:16px; font-family:monospace; border-left:solid 2px red; min-height:200px; - min-width:600px; + min-width:200px; overflow:auto; float:left; } @@ -74,7 +67,6 @@ fieldset.editor>div.output div.content>pre.item { color:white; } fieldset.editor>div.output div.content>pre.item.select { - /* background-color:red; */ border:solid 1px red; } fieldset.editor>div.output div.content>pre.item span.comment { @@ -105,6 +97,7 @@ fieldset.editor>div.output pre.display:hover { max-height:640px; z-index:10; } + fieldset.editor>div.output div.search { text-align:left; padding:6px; border:solid 1px red; @@ -116,35 +109,4 @@ fieldset.editor>div.output div.search td>div { max-height:100px; overflow:hidden; } -fieldset.editor>div.output div.holdon { - max-height:400px; overflow:auto; -} - -fieldset.editor>div.output textarea.editor { - position:absolute; padding:0; margin:0; - font-size:16px; font-family:monospace; - padding-left:12px; - - background-color:#00000000; color:#00000000; - caret-color:yellow; - display:none; - min-width:480px; -} -fieldset.editor>div.output textarea.editor.normal { - caret-color:#00000000; -} -fieldset.editor>div.output textarea.command { - clear:both; - padding:0; margin:0; - font-size:16px; font-family:monospace; - padding-left:12px; - - background-color:black; color:white; - caret-color:red; - - border:solid 1px red; - border-left:solid 3px green; - z-index:200; - min-width:480px; -} diff --git a/plugin/local/code/inner.js b/plugin/local/code/inner.js index 9e9fe6ac..85700a08 100644 --- a/plugin/local/code/inner.js +++ b/plugin/local/code/inner.js @@ -1,108 +1,49 @@ -Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb, target) { target.innerHTML = "" - var feature = can.Conf("feature") - can.onaction.list = feature.action || can.onaction.list - can.Conf("height", feature.height || can.Conf("height")) - can.Conf("width", feature.width || can.Conf("width")) - - if (can.Conf("height") < 600) { can.Conf("height", 600) } - can.onimport._share(can); var width = can.Conf("width"), height = can.Conf("height") - // can.page.Modify(can, target, {style: {"max-height": height-160+"px"}}) - - can.onappend.table(can, target, "table", msg), can.ui = can.page.Append(can, target, [ +Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb, target) { + can.ui = can.page.Appends(can, target, [ {view: "project", style: {display: "none"}}, - {view: "profile"}, - - {view: "holdon", list: [ - {view: "preview"}, - {view: "content", style: {"max-width": can.Conf("width")-(feature.width?0:120)+"px"}}, + {view: "profile", list: [ + {view: "preview"}, {view: "content"} ]}, - - {view: ["editor", "textarea"], onkeydown: function(event) { - can.onkeymap.parse(event, can, "insert"), can.Timer(10, function() { - can.onaction.modifyLine(can, can.current, can.editor.value) - }) - }, onblur: function(event) { - can.onaction.modifyLine(can, can.current, can.editor.value) - }, onclick: function(event) { - - }, ondblclick: function(event) { - can.onkeymap._mode(can, "insert") - }}, - {view: ["command", "textarea"], onkeydown: function(event) { - can.onkeymap.parse(event, can, "command") - }}, - {type: "code", list: [{view: ["display", "pre"]}]}, + {view: ["display", "pre"]}, {view: "search", style: {display: "none"}}, ]) - can.history = [{ - path: msg.Option("path"), - file: msg.Option("file"), - line: msg.Option("line"), - }] - msg.Option("path", can.Option("path")) - msg.Option("file", can.Option("file")) - msg.Option("line", can.Option("line")) - can.tabview = {}, can.Timer(10, function() { - can.onimport.project(can, can.Option("path")) - can.onsyntax._init(can, msg) - can.onkeymap._init(can) - }) + can.tabview = {}, can.history = [] + can.tabview[can.Option("path")+can.Option("file")] = msg + msg.Option({path: can.Option("path"), file: can.Option("file"), line: can.Option("line")||1}) + can.onimport.tabview(can, can.Option("path"), can.Option("file"), can.Option("line")) return typeof cb == "function" && cb(msg) }, - _share: function(can) { - if (can.user.Search(can, "share") && can.user.Search(can, "river") && can.user.Search(can, "storm")) { - can.page.Select(can, can._option, "input[type=button]", function(item) { - can.page.Remove(can, item) - }) - can.onaction.list = ["项目", "运行", "列表"] - can.Conf("height", can.Conf("height") + 64) - } - }, + tabview: function(can, path, file, line) { var push = {path: path, file: file, line: line} !can.core.Eq(can.history[can.history.length-1], push) && can.history.push(push) function show() { - if (can._msg) { - can._msg.Option("line", can.Option("line")) - } - + can._msg && can._msg.Option("line", can.Option("line")) can._msg = can.tabview[path+file] - can.file = file, can.parse = can.base.Ext(file), can.max = 0 + can.Option({path: path, file: file, line: line||parseInt(can._msg.Option("line"))}) + can.file = file, can.parse = can.base.Ext(file), can.max = 0 can.onsyntax._init(can, can._msg) + + var width = can._target.offsetWidth - can.ui.project.offsetWidth - can.ui.preview.offsetWidth - 20 + can.Status("当前行", can.onexport.position(can, parseInt(can.Option("line")))-1) + can.page.Modify(can, can.ui.content, {style: {"max-width": width+"px"}}) } if (can.tabview[path+file]) { return show() } can.run({}, ["action", "render", can.base.Ext(file), file, path], function(msg) { - can.tabview[path+file] = msg msg.Option({path: path, file: file, line: line||1}) - can.page.Append(can, can._action, [{view: ["file", "div", file], onclick: function(event) { - can.onimport.tabview(can, path, file) - }, ondblclick: function(event) { - can.onkeymap._remote(event, can, "运行", ["action", "engine", can.parse, can.Option("file"), can.Option("path")]) - }, oncontextmenu: function(event) { - can.user.carte(can, null, ["保存", "运行"]) - }, draggable: true, - ondragstart: function(event) { var target = event.target; can.drop = function(event, tab) { td.append(target) - can.onaction.modifyTask(event, can, task, "begin_time", time, task.begin_time) - } }, - ondragover: function(event) { event.preventDefault() - can.page.Select(can, can.ui.content, "td", function(item) { - can.page.ClassList.del(can, item, "over") - }), can.page.ClassList.add(can, event.target, "over") - }, - ondrop: function(event) { event.preventDefault() - can.drop(event, event.target) - }, + can.tabview[path+file] = msg - }]).first.click() + can.page.EnableDrop(can, can._action, "div.file", can.page.Append(can, can._action, [{view: ["file", "div", file], onclick: function(event) { + can.onimport.tabview(can, path, file) + }}]).first).click() }, true) }, project: function(can, path) { can.Option({path: path}) - var msg = can.request({}) - msg.Option("dir_deep", "true") + var msg = can.request({}); msg.Option("dir_deep", "true") can.run(msg._event, ["action", "render", "dir", "", path+"/"], function(msg) { can.ui.project.innerHTML = "" can.onappend.tree(can, msg, can.ui.project, function(event, value) { can.onimport.tabview(can, can.Option("path"), value.path) @@ -111,7 +52,6 @@ Volcanos("onimport", {help: "导入数据", _init: function(can, msg, list, cb, }, }, ["/plugin/local/code/inner.css"]) Volcanos("onsyntax", {help: "语法高亮", list: ["keyword", "prefix", "line"], _init: function(can, msg) { can._msg = msg - // action can.page.Select(can, can._action, "div.file", function(item) { item.innerText == msg.Option("file")? can.page.ClassList.add(can, item, "select"): can.page.ClassList.del(can, item, "select") @@ -119,37 +59,35 @@ Volcanos("onsyntax", {help: "语法高亮", list: ["keyword", "prefix", "line"], // caches save can.core.List(["preview", "content", "display"], function(item) { - can.Cache(can.file+item, can.ui[item], can.ui.holdon.scrollTop) - }); + can.Cache(can.file+item, can.ui[item], can.ui.profile.scrollTop) + }) // caches load can.file = can.base.Path(msg.Option("path"), msg.Option("file")) var cache = false; can.core.List(["preview", "content", "display"], function(item) { - var p = can.Cache(can.file+item, can.ui[item]); if (!cache && p != undefined) { can.ui.holdon.scrollTo(0, p); cache = true } + var p = can.Cache(can.file+item, can.ui[item]); if (!cache && p != undefined) { can.ui.profile.scrollTo(0, p); cache = true } }); if (cache) { return } - // remote - can.parse = can.base.Ext(can.file), can.max = 0 - // status - can.Status("文件名", can.file), can.Status("解析器", can.parse) - can.Status("当前行", can.onexport.position(can, 0)) - - // plugin - function init(p) { p.display && can.onkeymap._remote({}, can, "运行") - typeof p.display == "object" && ( p.display.height && can.page.Modify(can, can.ui.display, {style: { - // "max-height": p.display.height, - }})) + function init(p) { can.core.List(can.ls = msg.Result().split("\n"), function(item) { can.onaction.appendLine(can, item) }) can.onaction.selectLine(can, can.Option("line")||1) - }; var p = can.onsyntax[can.parse]; !p? can.run({}, ["action", "plugin", can.parse, can.Option("file"), can.Option("path")], function(msg) { - p = can.onsyntax[can.parse] = can.base.Obj(msg.Result()), can.onsyntax._init(can, can._msg) + + can.Status("文件名", can.file), can.Status("解析器", can.parse) + can.Status("当前行", can.onexport.position(can, 0)) + } + + // plugin + can.parse = can.base.Ext(can.file), can.max = 0 + var p = can.onsyntax[can.parse]; !p? can.run({}, ["action", "plugin", can.parse, can.Option("file"), can.Option("path")], function(msg) { + init(p = can.onsyntax[can.parse] = can.base.Obj(msg.Result())) }, true): init(p) }, - parse: function(can, line) { var p = can.onsyntax[can.parse]; if (!p) { return } + _parse: function(can, line) { line = line.replace("<", "<").replace(">", ">") + var p = can.onsyntax[can.parse]; if (!p) { return } p = can.onsyntax[p.link] || p - line = line.replace("<", "<").replace(">", ">") + function wrap(type, str) { return type? ''+str+'': str } p.keyword && (line = can.core.List(can.core.Split(line, p.split && p.split.space || " ", p.split && p.split.operator || "{[(|)]}"), function(item, index, array) { item = typeof item == "object"? item: {text: item}, p.word && (item = p.word(item, index, array)) @@ -170,6 +108,7 @@ Volcanos("onsyntax", {help: "语法高亮", list: ["keyword", "prefix", "line"], }) return p.line? p.line(can, line): line }, + makefile: { prefix: {"#": "comment"}, suffix: {":": "comment"}, @@ -190,7 +129,7 @@ Volcanos("onsyntax", {help: "语法高亮", list: ["keyword", "prefix", "line"], }, json: {link: "js"}, css: { - suffix: {"{": "comment"}, + suffix: {"": "comment"}, }, html: { split: { @@ -210,7 +149,6 @@ Volcanos("onsyntax", {help: "语法高亮", list: ["keyword", "prefix", "line"], height: "600px", width: can.Conf("width")-80+"px", }}]) }]} - // return {type: "iframe", data: {src: line}, style: {height: "200px", width: can.Conf("width")-80+"px"}} } }, svg: { @@ -253,253 +191,31 @@ Volcanos("onsyntax", {help: "语法高亮", list: ["keyword", "prefix", "line"], } }, }, - // url: { - // line: function(can, line) { var auto = true, loop = true, total = 0 - // function cb(event) { console.log(event) } - // return {className: "preview", type: "video", style: {height: can.Conf("height")-160+"px", width: can.Conf("width")-160+"px"}, - // data: {src: line, controls: "controls", autoplay: auto, loop: loop}, - // oncontextmenu: cb, onplay: cb, onpause: cb, onended: cb, - // onloadedmetadata: function(event) { total = event.timeStamp - // event.target.currentTime = can._msg.currentTime || 0 - // }, onloadeddata: cb, ontimeupdate: function(event) { - // can.Status("当前行", can.onexport.position(can, (can._msg.currentTime=event.target.currentTime)-1, event.target.duration)) - // }, - // } - // }, - // }, }) -Volcanos("onkeymap", {help: "键盘交互", list: ["command", "normal", "insert"], _init: function(can, mode) { - can.page.Modify(can, can.ui.command, {style: {display: "none", width: can._target.offsetWidth-20+"px"}}) - - can.history = [], can.editor = can.ui.editor - can.core.List(can.onkeymap.list, function(item) { var engine = {} - can.core.Item(can.onkeymap[item], function(key, cb) { var map = engine - for (var i = key.length-1; i > -1; i--) { - map = map[key[i]] = i == 0? cb: (map[key[i]]||{}) - } - }), can.onkeymap[item]._engine = engine - }), can.onkeymap._mode(can, mode||"normal") +Volcanos("onaction", {help: "控件交互", list: ["运行", "项目", "搜索"], + "返回": function(event, can) { + var last = can.history.pop(); last = can.history.pop() + last && can.onimport.tabview(can, last.path, last.file, last.line) }, - _merge: function(can, value) { return true }, - _mode: function(can, value) { can.Action("mode", can.mode = value) - can.page.Modify(can, can.ui.editor, {className: "editor "+can.mode, style: {display: "none"}}) - can.page.Modify(can, can.ui.command, {className: "command "+can.mode, style: {display: "none"}}) - return value - }, - _command: function(can) { can.onkeymap._mode(can, "command") - can.page.Modify(can, can.ui.command, {value: "", style: {display: "block"}}) - can.ui.command.focus() - }, - _normal: function(can) { can.onkeymap._mode(can, "normal") }, - _insert: function(can) { can.onkeymap._mode(can, "insert") }, - - _remote: function(event, can, key, arg, cb) { can.ui.display.innerHTML = "", can.ui.profile.innerHTML = "" - var p = can.onsyntax[can.parse]; can.display = p && p.profile && can.ui.profile || can.ui.display - if (p && p.show) { p.show(can); return } - - can.page.Modify(can, can.display, {innerHTML: "", style: {display: "none"}}) - var msg = can.request(event); msg.Option("content", can.onexport.content(can)) - can.run(event, arg||["action", key, can.Option("path"), can.Option("file")], cb||function(msg) { - (msg.Result() || msg.append && msg.append.length > 0) && can.page.Modify(can, can.display, {innerHTML: "", style: {display: "block"}}) - can.onappend.table(can, can.display, "table", msg) - can.onappend.board(can, can.display, "board", msg) + "运行": function(event, can) { + can.page.Modify(can, can.ui.display, {innerHTML: "", style: {display: "none"}}) + can.run(event, ["action", "engine", can.parse, can.Option("file"), can.Option("path")], function(msg) { + (msg.Result() || msg.append && msg.append.length > 0) && can.page.Modify(can, can.ui.display, {innerHTML: "", style: {display: "block"}}) + can.onappend.table(can, can.ui.display, "table", msg) + can.onappend.board(can, can.ui.display, "board", msg) }, true) }, - _engine: { - w: function(event, can) { can.onkeymap._remote(event, can, "保存") }, - e: function(event, can, line, ls) { - can.onimport.tabview(can, can.Option("path"), ls[1]) - }, - r: function(event, can) { can.onkeymap._remote(event, can, "运行") }, - - commit: function(event, can) { can.onkeymap._remote(event, can, "提交") }, - history: function(event, can) { can.onkeymap._remote(event, can, "历史") }, + "项目": function(event, can) { var hide = can.ui.project.style.display == "none" + can.page.Modify(can, can.ui.project, {style: {display: hide? "": "none"}}) + var width = can._target.offsetWidth - can.ui.project.offsetWidth - can.ui.preview.offsetWidth - 120 + can.page.Modify(can, can.ui.content, {style: {"max-width": hide? width+"px": ""}}) + hide && can.onimport.project(can, can.Option("path")) + }, + "搜索": function(event, can) { var hide = can.ui.search.style.display == "none" + can.page.Modify(can, can.ui.search, {style: {display: hide? "": "none"}}) + hide && can.onaction.searchLine(event, can, "") }, - parse: function(event, can, mode) { - event.key.length == 1 && can.history.push(event.key); if (can.mode != mode) { - event.stopPropagation(), event.preventDefault() - }; can.mode != "command" && can.Status("输入值", can.history.join()) - - for (var pre = 0; pre < can.history.length; pre++) { - if ("0" <= can.history[pre] && can.history[pre] <= "9") { continue } break - }; can.count = parseInt(can.history.slice(0, pre).join(""))||1 - - function repeat(cb, count) { - for (var i = 1; i <= count; i++) { if (cb(event, can, count)) { break } }; can.history = [] - } - - var p = can.onsyntax[can.parse] - var cb = (p && p.keymap || can.onkeymap[can.mode])[event.key]; if (typeof cb == "function") { - return repeat(cb, can.count) - } - - var map = can.onkeymap[can.mode]._engine; for (var i = can.history.length-1; i > pre-1; i--) { - var cb = map[can.history[i]]; if (typeof cb == "function") { - return repeat(cb, can.count) - }; if (typeof cb == "object") { map = cb; continue }; break - } - }, - command: { - Escape: function(event, can) { can.onkeymap._normal(can) - can.current.click() - }, - Enter: function(event, can) { var line = can.ui.command.value; var ls = can.core.Split(line, " ", ",", {simple: true}) - var cb = can.onkeymap._engine[ls[0]]; typeof cb == "function"? cb(event, can, line, ls): - can.onkeymap._remote(event, can, line, ["action", "cmd"].concat(ls)) - can.onkeymap.command.Escape(event, can) - }, - jk: function(event, can) { can.history = can.history.slice(0, -1) - can.onkeymap.command.Enter(event, can) - }, - }, - normal: { - ":": function(event, can) { can.onkeymap._command(can) }, - - h: function(event, can) { - can.editor.setSelectionRange(can.editor.selectionStart-1, can.editor.selectionStart-1) - }, - l: function(event, can) { - can.editor.setSelectionRange(can.editor.selectionStart+1, can.editor.selectionStart+1) - }, - j: function(event, can) { can.onaction.selectLine(can, can.current.nextSibling) - var pos = can.current.offsetTop-can._target.scrollTop; if (pos > 22*15) { - can._target.scrollBy(0, 22) - } - }, - k: function(event, can) { can.onaction.selectLine(can, can.current.previousSibling) - var pos = can.current.offsetTop-can._target.scrollTop; if (pos < 22*5) { - can._target.scrollBy(0, -22) - } - }, - - gg: function(event, can, count) { count = count || 1 - can.onaction.selectLine(can, count - 1) - can.current.scrollIntoView() - can._target.scrollBy(0, -22*5) - return true - }, - G: function(event, can, count) { count = count || can.max - can.onaction.selectLine(can, count - 1) - can.current.scrollIntoView() - if (count - can.max < -5) { - can._target.scrollBy(0, -22*5) - } - return true - }, - zt: function(event, can, count) { count = count || 2 - can.current.scrollIntoView() - can._target.scrollBy(0, -22*count) - return true - }, - zz: function(event, can, count) { count = count || 5 - can.current.scrollIntoView() - can._target.scrollBy(0, -22*count) - return true - }, - zb: function(event, can, count) { count = count || 3 - can._target.scrollBy(0, -(can._target.offsetHeight - (can.current.offsetTop - can._target.scrollTop))+22*count) - return true - }, - - i: function(event, can) { can.onkeymap._insert(can) - }, - I: function(event, can) { can.onkeymap._insert(can) - can.editor.setSelectionRange(0, 0) - }, - a: function(event, can) { can.onkeymap._insert(can) - }, - A: function(event, can) { can.onkeymap._insert(can) - can.editor.setSelectionRange(-1, -1) - }, - o: function(event, can) { can.onkeymap._insert(can) - can.onaction.insertLine(can, can.current).click() - }, - O: function(event, can) { can.onkeymap._insert(can) - can.onaction.insertLine(can, can.current, "", true).click() - }, - - yy: function(event, can) { can.last = can.current.innerText }, - dd: function(event, can) { can.last = can.current.innerText - var next = can.current.nextSibling || can.current.previousSibling - can.onaction.deleteLine(can, can.current) - next.click() - }, - p: function(event, can) { - can.onaction.insertLine(can, can.current, can.last).click() - }, - P: function(event, can) { - can.onaction.insertLine(can, can.current, can.last, true).click() - }, - }, - insert: { - Escape: function(event, can) { can.onkeymap._normal(can) - can.onaction.modifyLine(can, can.current, can.editor.value) - event.stopPropagation(), event.preventDefault() - }, - Enter: function(event, can) { - can.onkeymap.insert.Escape(event, can) - can.onaction.insertLine(can, can.current, "", event.shiftKey).click() - }, - Backspace: function(event, can) { if (can.editor.selectionStart > 0) { return } - can.onaction.mergeLine(can, can.current.previousSibling).click() - event.stopPropagation(), event.preventDefault() - }, - ArrowDown: function(event, can) { - can.onaction.selectLine(can, can.current.nextSibling) - }, - ArrowUp: function(event, can) { - can.onaction.selectLine(can, can.current.previousSibling) - }, - jk: function(event, can) { - can.page.DelText(can.editor, can.editor.selectionStart-1, 1) - can.onkeymap.insert.Escape(event, can) - }, - }, -}) -Volcanos("onaction", {help: "控件交互", list: [ - "项目", "搜索", - // "运行", "收藏", - - // "", "项目", "上传", "", "保存", "运行", - // "", "提交", "记录", "复盘", "历史", - // "", "搜索", - ], - modifyLine: function(can, target, value) { var p = can.onsyntax.parse(can, value) - typeof p == "object"? can.page.Appends(can, target, [p]): target.innerHTML = p - }, - deleteLine: function(can, target) { can.page.Remove(can, target) - var ls = can.page.Select(can, can.ui.preview, "div.item") - can.page.Remove(can, ls[ls.length-1]), can.max-- - }, - selectLine: function(can, target) { if (target !== 0 && !target) { return } - can.page.Select(can, can.ui.content, "pre.item", function(item, index) { - can.page.ClassList.del(can, item, "select") - if (item != target && index+1 != target) { return } - can.page.ClassList.add(can, item, "select") - can.Option("line", index+1) - - target = item, can.Status("当前行", can.onexport.position(can, index)) - can.page.Select(can, can.ui.preview, "div.item", function(item, i) { - can.page.ClassList[index==i? "add": "del"](can, item, "select") - }) - }); if (typeof target != "object") { return }; can.current = target - if (target.offsetTop < can.ui.holdon.scrollTop || target.offsetTop > can.ui.holdon.scrollTop+can.ui.holdon.offsetHeight) { - can.ui.holdon.scrollTo(0, target.offsetTop-160) - } - return - - can.page.Modify(can, can.editor, {className: "editor "+can.mode, value: can.current.innerText, style: { - height: target.offsetHeight, width: target.offsetWidth, - left: target.offsetLeft, top: target.offsetTop, - display: "block", - }}), can.editor.focus() - - can.page.Modify(can, can.ui.command, {style: { - height: target.offsetHeight, width: target.offsetWidth, - left: target.offsetLeft, - }}) - }, appendLine: function(can, value) { var index = can.max++ can.page.Append(can, can.ui.preview, [{view: ["item", "div", index+1], onclick: function(event) { can.onaction.selectLine(can, index) @@ -529,14 +245,36 @@ Volcanos("onaction", {help: "控件交互", list: [ }}]).first; value && can.onaction.modifyLine(can, line, value) return line }, - insertLine: function(can, target, value, before) { var line = can.onaction.appendLine(can, value) - can.ui.content.insertBefore(line, before && target || target.nextSibling) - return line + modifyLine: function(can, target, value) { var p = can.onsyntax._parse(can, value) + typeof p == "object"? can.page.Appends(can, target, [p]): target.innerHTML = p }, - mergeLine: function(can, target) { if (!target) {return} - can.onaction.modifyLine(can, target, target.innerHTML + target.nextSibling.innerHTML) - can.onaction.deleteLine(can, target.nextSibling) - return target + selectLine: function(can, target) { if (target !== 0 && !target) { return } + can.page.Select(can, can.ui.content, "pre.item", function(item, index) { + can.page.ClassList.del(can, item, "select") + if (item != target && index+1 != target) { return } + can.page.ClassList.add(can, item, "select") + can.Option("line", index+1) + + target = item, can.Status("当前行", can.onexport.position(can, index)) + can.page.Select(can, can.ui.preview, "div.item", function(item, i) { + can.page.ClassList[index==i? "add": "del"](can, item, "select") + }) + }); if (typeof target != "object") { return }; can.current = target + if (target.offsetTop < can.ui.profile.scrollTop || target.offsetTop > can.ui.profile.scrollTop+can.ui.profile.offsetHeight) { + can.ui.profile.scrollTo(0, target.offsetTop-160) + } + return + + can.page.Modify(can, can.editor, {className: "editor "+can.mode, value: can.current.innerText, style: { + height: target.offsetHeight, width: target.offsetWidth, + left: target.offsetLeft, top: target.offsetTop, + display: "block", + }}), can.editor.focus() + + can.page.Modify(can, can.ui.command, {style: { + height: target.offsetHeight, width: target.offsetWidth, + left: target.offsetLeft, + }}) }, searchLine: function(event, can, value) { can.ui.search.innerHTML = "", value = value.trim() can.page.Modify(can, can.ui.search, {style: {display: ""}}) @@ -552,8 +290,7 @@ Volcanos("onaction", {help: "控件交互", list: [ can.onaction.searchLine(event, can, ui.word.value) }]}, {button: ["返回", function(event) { - var last = can.history.pop() - last = can.history.pop() + var last = can.history.pop(); last = can.history.pop() last && can.onimport.tabview(can, last.path, last.file, last.line) }]}, {button: ["关闭", function(event) { @@ -564,9 +301,9 @@ Volcanos("onaction", {help: "控件交互", list: [ var msg = can.request(event); msg.Option("_path", can.Option("path")) value && can.run(event, ["action", "search", can.parse, value, ""], function(msg) { can.onappend.table(can, can.ui.search, "table", msg, function(value, key, index, line) { - can.Status("npos", index+1) value = value.replace("<", "<").replace(">", ">") value = value.replace("./", "") + can.Status("标签数", index+1) return {text: ["", "td"], list: [{text: [value, "div"]}], onclick: function(event) { line.line && can.onimport.tabview(can, can.Option("path"), line.file.replace("./", ""), parseInt(line.line)) }} @@ -578,77 +315,15 @@ Volcanos("onaction", {help: "控件交互", list: [ }) }, true) }, - - "关闭": function(event, can, msg) { - can.page.Remove(can, can._target.parentNode) - }, - "串行": function(event, can, msg) { - can.core.Next(can.page.Select(can, can._action, "div.file", function(item) { - return item.innerHTML - - }), function(item, next) { - can.run({}, ["action", "run", can.Option("path"), item], function(msg) { - next() - }, true) - - }, function() { - can.user.toast(can, "执行成功") - }) - }, - "项目": function(event, can) { var hide = can.ui.project.style.display == "none" - can.page.Modify(can, can.ui.project, {style: {display: hide? "": "none"}}) - can.page.Modify(can, can.ui.content, {style: {"max-width": can.Conf("width")-(hide? 240: 100)+"px"}}) - }, - "上传": function(event, can) { can.user.upload(event, can) }, - "搜索": function(event, can) { var hide = can.ui.search.style.display == "none" - can.page.Modify(can, can.ui.search, {style: {display: hide? "": "none"}}) - hide && can.onaction.searchLine(event, can, "") - }, - "记录": function(event, can) { var sub = can.request(event) - can.core.Item(can.Option(), sub.Option) - sub.Option("display", can.display.innerText) - can.onkeymap._remote(event, can, "记录", ["action", "记录"]) - }, - "收藏": function(event, can) { - chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { - chrome.tabs.sendMessage(tabs[0].id, { action: "copy" }, function (response) { - var win = chrome.extension.getBackgroundPage(); - win.can.user.toast(response.src) - can.run(event, ["action", "favor", "url.favor", "spide", response.title, response.src, "poster", response.poster], function(msg) { - alert(response.title) - }, true) - }) - }) - }, - "列表": function(event, can) { can.onkeymap._remote(event, can, "收藏", ["action", "favor", "url.favor"]) }, }) -Volcanos("ondetail", {help: "菜单交互", list: [ -// "保存", "运行", "提交", "记录", "删除行", "合并行", "插入行", "添加行", "追加行", - ], - "删除行": function(event, can, msg) { - can.onaction.deleteLine(can, can.current) +Volcanos("onexport", {help: "导出数据", list: ["文件名", "解析器", "当前行", "标签数"], + position: function(can, index, total) { total = total || can.max + return parseInt((index+1)*100/total)+"%"+" = "+(parseInt(index)+1)+"/"+parseInt(total) }, - "合并行": function(event, can, msg) { - can.onaction.mergeLine(can, can.current) - }, - "插入行": function(event, can, msg) { - can.onaction.insertLine(can, can.current, "", true) - }, - "添加行": function(event, can, msg) { - can.onaction.insertLine(can, can.current) - }, - "追加行": function(event, can, msg) { - can.onaction.appendLine(can) - }, -}) -Volcanos("onexport", {help: "导出数据", list: ["输入法", "输入值", "文件名", "解析器", "当前行", "ncmd", "npos"], content: function(can) { return can.page.Select(can, can._output, "div.content>pre.item", function(item) { return can.current == item? can.editor.value: item.innerText }).join("\n") }, - position: function(can, index, total) { total = total || can.max - return parseInt((index+1)*100/total)+"%"+" = "+(parseInt(index)+1)+"/"+parseInt(total) - }, }) diff --git a/plugin/local/code/vimer.css b/plugin/local/code/vimer.css new file mode 100644 index 00000000..48c47679 --- /dev/null +++ b/plugin/local/code/vimer.css @@ -0,0 +1,28 @@ + +fieldset.editor>div.output textarea.editor { + position:absolute; padding:0; margin:0; + font-size:16px; font-family:monospace; + padding-left:12px; + + background-color:#00000000; color:#00000000; + caret-color:yellow; + display:none; + min-width:480px; +} +fieldset.editor>div.output textarea.editor.normal { + caret-color:#00000000; +} +fieldset.editor>div.output textarea.command { + clear:both; + padding:0; margin:0; + font-size:16px; font-family:monospace; + padding-left:12px; + + background-color:black; color:white; + caret-color:red; + + border:solid 1px red; + border-left:solid 3px green; + z-index:200; + min-width:480px; +} diff --git a/plugin/local/code/vimer.js b/plugin/local/code/vimer.js new file mode 100644 index 00000000..b6978da1 --- /dev/null +++ b/plugin/local/code/vimer.js @@ -0,0 +1,253 @@ +Volcanos("onimport", {help: "导入数据", list: [], + _init: function(can, msg, list, cb, target) { + can.require(["/plugin/local/code/inner.js"], function(can) { + can.onimport._init(can, msg, list, function() { + typeof cb == "function" && cb() + }, target) + }) + return + /* + {view: ["editor", "textarea"], onkeydown: function(event) { + can.onkeymap.parse(event, can, "insert"), can.Timer(10, function() { + can.onaction.modifyLine(can, can.current, can.editor.value) + }) + }, onblur: function(event) { + can.onaction.modifyLine(can, can.current, can.editor.value) + }, onclick: function(event) { + + }, ondblclick: function(event) { + can.onkeymap._mode(can, "insert") + }}, + {view: ["command", "textarea"], onkeydown: function(event) { + can.onkeymap.parse(event, can, "command") + }}, + */ + }, +}, ["/plugin/local/code/vimer.css"]) + +Volcanos("onaction", {help: "交互操作", list: [], +}) +Volcanos("onkeymap", {help: "键盘交互", list: ["command", "normal", "insert"], _init: function(can, mode) { + can.page.Modify(can, can.ui.command, {style: {display: "none", width: can._target.offsetWidth-20+"px"}}) + + can.history = [], can.editor = can.ui.editor + can.core.List(can.onkeymap.list, function(item) { var engine = {} + can.core.Item(can.onkeymap[item], function(key, cb) { var map = engine + for (var i = key.length-1; i > -1; i--) { + map = map[key[i]] = i == 0? cb: (map[key[i]]||{}) + } + }), can.onkeymap[item]._engine = engine + }), can.onkeymap._mode(can, mode||"normal") + }, + deleteLine: function(can, target) { can.page.Remove(can, target) + var ls = can.page.Select(can, can.ui.preview, "div.item") + can.page.Remove(can, ls[ls.length-1]), can.max-- + }, + insertLine: function(can, target, value, before) { var line = can.onaction.appendLine(can, value) + can.ui.content.insertBefore(line, before && target || target.nextSibling) + return line + }, + mergeLine: function(can, target) { if (!target) {return} + can.onaction.modifyLine(can, target, target.innerHTML + target.nextSibling.innerHTML) + can.onaction.deleteLine(can, target.nextSibling) + return target + }, + _merge: function(can, value) { return true }, + _mode: function(can, value) { can.Action("mode", can.mode = value) + can.page.Modify(can, can.ui.editor, {className: "editor "+can.mode, style: {display: "none"}}) + can.page.Modify(can, can.ui.command, {className: "command "+can.mode, style: {display: "none"}}) + return value + }, + _command: function(can) { can.onkeymap._mode(can, "command") + can.page.Modify(can, can.ui.command, {value: "", style: {display: "block"}}) + can.ui.command.focus() + }, + _normal: function(can) { can.onkeymap._mode(can, "normal") }, + _insert: function(can) { + can.onkeymap._mode(can, "insert") + can.page.Modify(can, can.ui.editor, {className: "editor "+can.mode, style: {display: ""}}) + }, + + _remote: function(event, can, key, arg, cb) { can.ui.display.innerHTML = "", can.ui.profile.innerHTML = "" + var p = can.onsyntax[can.parse]; can.display = p && p.profile && can.ui.profile || can.ui.display + if (p && p.show) { p.show(can); return } + + can.page.Modify(can, can.display, {innerHTML: "", style: {display: "none"}}) + var msg = can.request(event); msg.Option("content", can.onexport.content(can)) + can.run(event, arg||["action", key, can.Option("path"), can.Option("file")], cb||function(msg) { + (msg.Result() || msg.append && msg.append.length > 0) && can.page.Modify(can, can.display, {innerHTML: "", style: {display: "block"}}) + can.onappend.table(can, can.display, "table", msg) + can.onappend.board(can, can.display, "board", msg) + }, true) + }, + _engine: { + w: function(event, can) { can.onkeymap._remote(event, can, "保存") }, + e: function(event, can, line, ls) { + can.onimport.tabview(can, can.Option("path"), ls[1]) + }, + r: function(event, can) { can.onkeymap._remote(event, can, "运行") }, + + commit: function(event, can) { can.onkeymap._remote(event, can, "提交") }, + history: function(event, can) { can.onkeymap._remote(event, can, "历史") }, + }, + + parse: function(event, can, mode) { + event.key.length == 1 && can.history.push(event.key); if (can.mode != mode) { + event.stopPropagation(), event.preventDefault() + }; can.mode != "command" && can.Status("输入值", can.history.join()) + + for (var pre = 0; pre < can.history.length; pre++) { + if ("0" <= can.history[pre] && can.history[pre] <= "9") { continue } break + }; can.count = parseInt(can.history.slice(0, pre).join(""))||1 + + function repeat(cb, count) { + for (var i = 1; i <= count; i++) { if (cb(event, can, count)) { break } }; can.history = [] + } + + var p = can.onsyntax[can.parse] + var cb = (p && p.keymap || can.onkeymap[can.mode])[event.key]; if (typeof cb == "function") { + return repeat(cb, can.count) + } + + var map = can.onkeymap[can.mode]._engine; for (var i = can.history.length-1; i > pre-1; i--) { + var cb = map[can.history[i]]; if (typeof cb == "function") { + return repeat(cb, can.count) + }; if (typeof cb == "object") { map = cb; continue }; break + } + }, + command: { + Escape: function(event, can) { can.onkeymap._normal(can) + can.current.click() + }, + Enter: function(event, can) { var line = can.ui.command.value; var ls = can.core.Split(line, " ", ",", {simple: true}) + var cb = can.onkeymap._engine[ls[0]]; typeof cb == "function"? cb(event, can, line, ls): + can.onkeymap._remote(event, can, line, ["action", "cmd"].concat(ls)) + can.onkeymap.command.Escape(event, can) + }, + jk: function(event, can) { can.history = can.history.slice(0, -1) + can.onkeymap.command.Enter(event, can) + }, + }, + normal: { + ":": function(event, can) { can.onkeymap._command(can) }, + + h: function(event, can) { + can.editor.setSelectionRange(can.editor.selectionStart-1, can.editor.selectionStart-1) + }, + l: function(event, can) { + can.editor.setSelectionRange(can.editor.selectionStart+1, can.editor.selectionStart+1) + }, + j: function(event, can) { can.onaction.selectLine(can, can.current.nextSibling) + var pos = can.current.offsetTop-can._target.scrollTop; if (pos > 22*15) { + can._target.scrollBy(0, 22) + } + }, + k: function(event, can) { can.onaction.selectLine(can, can.current.previousSibling) + var pos = can.current.offsetTop-can._target.scrollTop; if (pos < 22*5) { + can._target.scrollBy(0, -22) + } + }, + + gg: function(event, can, count) { count = count || 1 + can.onaction.selectLine(can, count - 1) + can.current.scrollIntoView() + can._target.scrollBy(0, -22*5) + return true + }, + G: function(event, can, count) { count = count || can.max + can.onaction.selectLine(can, count - 1) + can.current.scrollIntoView() + if (count - can.max < -5) { + can._target.scrollBy(0, -22*5) + } + return true + }, + zt: function(event, can, count) { count = count || 2 + can.current.scrollIntoView() + can._target.scrollBy(0, -22*count) + return true + }, + zz: function(event, can, count) { count = count || 5 + can.current.scrollIntoView() + can._target.scrollBy(0, -22*count) + return true + }, + zb: function(event, can, count) { count = count || 3 + can._target.scrollBy(0, -(can._target.offsetHeight - (can.current.offsetTop - can._target.scrollTop))+22*count) + return true + }, + + i: function(event, can) { can.onkeymap._insert(can) + }, + I: function(event, can) { can.onkeymap._insert(can) + can.editor.setSelectionRange(0, 0) + }, + a: function(event, can) { can.onkeymap._insert(can) + }, + A: function(event, can) { can.onkeymap._insert(can) + can.editor.setSelectionRange(-1, -1) + }, + o: function(event, can) { can.onkeymap._insert(can) + can.onaction.insertLine(can, can.current).click() + }, + O: function(event, can) { can.onkeymap._insert(can) + can.onaction.insertLine(can, can.current, "", true).click() + }, + + yy: function(event, can) { can.last = can.current.innerText }, + dd: function(event, can) { can.last = can.current.innerText + var next = can.current.nextSibling || can.current.previousSibling + can.onaction.deleteLine(can, can.current) + next.click() + }, + p: function(event, can) { + can.onaction.insertLine(can, can.current, can.last).click() + }, + P: function(event, can) { + can.onaction.insertLine(can, can.current, can.last, true).click() + }, + }, + insert: { + Escape: function(event, can) { can.onkeymap._normal(can) + can.onaction.modifyLine(can, can.current, can.editor.value) + event.stopPropagation(), event.preventDefault() + }, + Enter: function(event, can) { + can.onkeymap.insert.Escape(event, can) + can.onaction.insertLine(can, can.current, "", event.shiftKey).click() + }, + Backspace: function(event, can) { if (can.editor.selectionStart > 0) { return } + can.onaction.mergeLine(can, can.current.previousSibling).click() + event.stopPropagation(), event.preventDefault() + }, + ArrowDown: function(event, can) { + can.onaction.selectLine(can, can.current.nextSibling) + }, + ArrowUp: function(event, can) { + can.onaction.selectLine(can, can.current.previousSibling) + }, + jk: function(event, can) { + can.page.DelText(can.editor, can.editor.selectionStart-1, 1) + can.onkeymap.insert.Escape(event, can) + }, + }, +}) +Volcanos("ondetail", {help: "菜单交互", list: [ +// "保存", "运行", "提交", "记录", "删除行", "合并行", "插入行", "添加行", "追加行", + ], + "删除行": function(event, can, msg) { + can.onaction.deleteLine(can, can.current) + }, + "合并行": function(event, can, msg) { + can.onaction.mergeLine(can, can.current) + }, + "插入行": function(event, can, msg) { + can.onaction.insertLine(can, can.current, "", true) + }, + "添加行": function(event, can, msg) { + can.onaction.insertLine(can, can.current) + }, + "追加行": function(event, can, msg) { + can.onaction.appendLine(can) + }, +})